- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I have a main program, written in C, that utilizes a threadpool of 12 threads (using pthreads)to perform parallel processing of some science data. Our group has a legacy Fortran subroutine that we need to call from each of thread to do the actual processing on a subset of the data. What are some basic guidelines for converting this Fortran subroutine so that it is thread safe?
I'm getting run-time errors in the Fortran code (forrtl severe 29). The subroutine reads/writes to several thread-specific files and allocates/deallocates memory structures. I'm fluent in C/C++ but a novice in Fortran. It seems as though the Fortran subroutine is not creating thread-specific local memory or io units?
I'm usingifortv11.1 to compile the Fortran code and gcc v4.1.2 to compile and link the program in Linux.
Thanks,
Phil Losie
Raytheon Co.
I have a main program, written in C, that utilizes a threadpool of 12 threads (using pthreads)to perform parallel processing of some science data. Our group has a legacy Fortran subroutine that we need to call from each of thread to do the actual processing on a subset of the data. What are some basic guidelines for converting this Fortran subroutine so that it is thread safe?
I'm getting run-time errors in the Fortran code (forrtl severe 29). The subroutine reads/writes to several thread-specific files and allocates/deallocates memory structures. I'm fluent in C/C++ but a novice in Fortran. It seems as though the Fortran subroutine is not creating thread-specific local memory or io units?
I'm usingifortv11.1 to compile the Fortran code and gcc v4.1.2 to compile and link the program in Linux.
Thanks,
Phil Losie
Raytheon Co.
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
correct, IO units are a process-wide shared table. So each thread will need a unique IO unit. You'll need to coordinate the threads so they don't reuse the same unit number. And like in C, if you have unique file pointers BUT they point to the same file, you'll have to synchronize or coordinate the accesses. Unique IO units to unique files. I've always used an array of unit numbers indexed by the thread logical number ( base 1 for Fortran ).
Avoid the -SAVE compiler option and SAVE attribute. Avoid COMMON blocks. Avoid writing to variables in MODULEs : all of these are shared
Do not use the -heap-arrays compiler option
local variables declared within the subroutines/functions will be thread-local as long as you don't see SAVE or compile with -save.
ron
Avoid the -SAVE compiler option and SAVE attribute. Avoid COMMON blocks. Avoid writing to variables in MODULEs : all of these are shared
Do not use the -heap-arrays compiler option
local variables declared within the subroutines/functions will be thread-local as long as you don't see SAVE or compile with -save.
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ron, thanks for the quick reply!
Are there any compiler options like -threadsthatare necessary for safemultithreaded code?
Phil
Are there any compiler options like -threadsthatare necessary for safemultithreaded code?
Phil
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also,
Declare the functions and subroutines with the prefix RECURSIVE.
RECURSIVESUBROUTINE FOO(...
RECURSIVE INTEGER FUNCTION FEE(...
The default for function/subroutine declared "local" arrays are SAVE. RECURSIVE defaults "local" arrays to stack.
(In this case RECURSIVE means REENTRANT - FORTRAN does not have a REENTRANT function/subroutine attribute.)
Jim Dempsey
Declare the functions and subroutines with the prefix RECURSIVE.
RECURSIVESUBROUTINE FOO(...
RECURSIVE INTEGER FUNCTION FEE(...
The default for function/subroutine declared "local" arrays are SAVE. RECURSIVE defaults "local" arrays to stack.
(In this case RECURSIVE means REENTRANT - FORTRAN does not have a REENTRANT function/subroutine attribute.)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As Jim said, RECURSIVE declaration assures that local arrays and variables are on stack, consistent with threading. Without that declaration, you would depend on setting -auto, or other options which imply it, including -openmp or -reentrant. Yes, there is an ifort option -reentrant, although it's not a Fortran declaration.
With such options set, you must take care to avoid uninitialized variables (which in any case aren't compatible with threading).
With such options set, you must take care to avoid uninitialized variables (which in any case aren't compatible with threading).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WARNING: Local variables that are initialized within the declaration e.g.
INTEGER :: number = 999
are implicitly persistent, justas with the SAVE attribute, and thus NOT thread safe.
This construct is only thread safe when used in derived type declarations.
INTEGER :: number = 999
are implicitly persistent, justas with the SAVE attribute, and thus NOT thread safe.
This construct is only thread safe when used in derived type declarations.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page