Reputation: 13678
I want to solve multiple large ODE systems in a C++ program in parallel using OpenMP. For certain reasons I need to use an ODE solver for which I could only find a Fortran 90 subroutine, and the code is too large to simply translate it to C.
I know that Fortran uses static memory extensively and that I therefore have to prime the code for parallel invocations; but I am not really familiar with the language so:
The second question boils down to: How and when does Fortran allocate and free memory for variables and (how) does it reuse memory from function arguments?
So far, I've already found out that COMMON
sections correspond to global variables in C, but can be made thread-local using Fortran's OpenMP directive !$OMP THREADPRIVATE(/…/)
. Is this correct? What about other local variables? They are statically allocated, too, right? What is the easiest way to tell Fortran to allocate them dynamically? Should I use the ALLOCATE
statement, or does the RECURSIVE
keyword, resp. gfortran's -frecursive
, help, or is there some way to just pass a large chunk of memory from C++ and let Fortran use that for all its variables? (EQUIVALENCE
?) OpenMP's THREADPRIVATE
always allocates from the heap, so I wouldn't want to use it for all local variables – correct?
Upvotes: 2
Views: 1691
Reputation: 60123
The standard doesn't talk about anything like static memory, heap or stack. If you userecursive
or a compiler option that forces it, then you can be sure every copy of the subroutine uses their own copy of the variables, unless they are save
. They will be typically on the stack. If you do not use recursive
the compiler is free to use the static memory. Most often it uses the stack, but you cannot rely on it. BTW, in gfortran
compiler using -fopenmp
implies -frecursive
automatically.
Beware! Every variable that is explicitly initialized is save
implicitly!
real :: ivar = 1
is such an example. The initialization using DATA
has the same effect. This variable will not be thread-safe, unless you remove the initialization or use threadprivate
.
For dynamic allocation, use allocate
of course. It is safe. Each openmp thread will allocate it's own variables and arrays.
The threadprivate
directive is indeed useful, as you found out yourself. I am not sure whether you can guarantee it will use the stack or the heap, but the heap is more likely as they have to remain in scope throughout the execution.
Not only common
corresponds to C globals. Also module variables do. They are also save
implicitly.
Upvotes: 4