Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

using ALLOCATABLE arrays in threadsafe code

William_G_
Beginner
955 Views

Hi Lorri, or others,

I am back again with a question about whether precautions need to be taken for use of ALLOCATE in threadsafe applications.

I have a main routine, which calls a subroutine SUB001 ;

SUB001 has a two dimensional allocatable array PPROP(:,:) which I allocate based on

arguments from the argument list in sub001 ;

Then sub001 calls a subroutine sub002, which has the allocated array PPROP on the argument list of sub002.

After sub002 has finished , the allocated array PPROP is deallocated in SUB001.

 

SO my question is does the use of this allocate create any threadsafe issues ???

(by the way these routines, main, sub001, and sub002 are NOT recursive subroutines.

They Do Not ever call themselves again inside their own definition. By this I mean they are not like a classical subroutine to evaluate a factorial or play nim).

So what the code looks line in more detail is

 

SUBROUTINE SUB001(iarg1,iarg2,xarg3,xarg4)

ALLOCATABLE PPROP(:,:)

jarg1 = iarg1+1

jarg2 = iarg2+1

ALLOCATE PPROP(jarg1,jarg2)

CALL SUB002(jarg1,jarg2,PPROP)

use the results from SUB002

DEALLOCATE (PPROP)

RETURN

END

 

Thanks for your advice.

Bill

0 Kudos
4 Replies
Lorri_M_Intel
Employee
955 Views

Your declaration of PPROP is as a variable local to the subroutine, which will make it local to every thread that calls this subroutine.   Don't put the 'SAVE' attribute on it (SAVE turns it into a shared object, and that's not so good).

Also, any memory allocated in one thread belongs to that thread, unless the thread  *explicitly* does something to share it.

Some of the other people in this forum may have better explanations and cautions than I've listed here, but so far, I think you have not shot yourself in the foot.  :-)

 

                   --Lorri

 

 

0 Kudos
William_G_
Beginner
955 Views

HI Lorri

 

Thank you for your explanation and encouragement.

I have heard not to use SAVE, and I do not use it.....

I will post one more question about file handling, and then

get to work on making some changes to my code....

Bill

I

0 Kudos
jimdempseyatthecove
Honored Contributor III
955 Views

>>I have heard not to use SAVE, and I do not use it.....

For routines that are NOT compiled with OpenMP option (or recursive or reentrant), arrays (at least in earlier version of Fortran) are implicitly save. Therefore, do not assume you do not use it (implicitly).

If, for example, you build a library that does not explicitly use OpenMP, and therefore did not compile it with the -openmp option, then subroutines and functions with locally defined arrays may have these arrays implicitly SAVE. There is an issue with this if you have a program with OpenMP parallel regions calling these routines.

Jim Dempsey

0 Kudos
Martyn_C_Intel
Employee
955 Views

There may also be performance considerations, at least in current compilers. You may get better performance if you use a local array that is allocated on the stack, though you need to be careful about the things that Jim discusses. So:

SUBROUTINE SUB001(iarg1,iarg2,xarg3,xarg4)
  Dimension PPROP(iarg1+1,iarg2+1)
  jarg1 = iarg1+1
  jarg2 = iarg2+1
  CALL SUB002(jarg1,jarg2,PPROP)
  use the results from SUB002
  RETURN
END


Since PPROP here is an adjustable array, (its size depends on the arguments), I think it will naturally be allocated on the stack, making it threadsafe (Lorri is the expert). However, to make sure, you should either compile with /auto or with /Qopenmp, or else declare it using the keyword AUTOMATIC, which is an Intel Fortran extension, e.g.: REAL, AUTOMATIC, DIMENSION(iarg1+1,iarg2+1) :: PPROP

Because the default stack limits are small, if the array PPROP is larger than a few MB, you may need to increase them, e.g. by using the /F option for the linker for the main thread and by setting the environment variable OMP_STACKSIZE for the worker threads, if you thread using OpenMP.

If performance is not an issue, then it is probably simpler to use ALLOCATE/DEALLOCATE as you have done.

0 Kudos
Reply