- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page