有没有简单的方法来准备并行调用的Fortran代码 [英] Is there an easy way to prepare Fortran code for parallel invocation
问题描述
我想在C ++程序中使用OpenMP并行地解决多个大型ODE系统。由于某些原因,我需要使用一个ODE解算器,因为我只能找到一个Fortran 90子程序,而且代码太大,无法简单地将它转换为C.
I知道Fortran广泛使用静态内存,因此我必须为并行调用启动代码;但我对这种语言并不熟悉:
- 是否有针对我的问题的标准(自动)解决方案?
- 我必须修改哪部分代码?
第二个问题归结到:Fortran如何以及何时为变量分配和释放内存以及(如何)从函数参数中重用内存?
到目前为止,我已经发现 COMMON
部分对应于C中的全局变量,但可以使用Fortran的OpenMP指令!$ OMP THREADPRIVATE(/ ... /)进行线程本地化。 code>。它是否正确?其他局部变量呢?他们也是静态分配的,对吗?告诉Fortran动态分配它们的最简单方法是什么?我应该使用
ALLOCATE
语句,还是使用 RECURSIVE
关键字, gfortran的 -frecursive
,help,还是有某种方法可以从C ++传递大量内存,让Fortran将其用于所有变量? ( EQUIVALENCE
?)OpenMP的 THREADPRIVATE
总是从堆中分配,所以我不想将它用于所有本地变量 - 正确吗?
标准并没有讨论静态内存,堆栈或堆栈。如果使用递归
或者强制它的编译器选项,那么您可以确定子例程的每个副本都使用它们自己的变量副本,除非它们是保存
。他们通常会在堆栈中。如果你不使用递归
,编译器可以自由使用静态内存。大多数情况下它使用堆栈,但不能依赖它。顺便说一句,在 gfortran
编译器中使用 -fopenmp
意味着 -f递归
自动。
当心!显式初始化的每个变量都隐式地为 save
!
real :: ivar = 1
就是这样一个例子。使用 DATA
的初始化具有相同的效果。这个变量不会是线程安全的,除非你删除初始化或使用 threadprivate
。
对于动态分配,当然使用分配
。这是安全的。每个openmp线程将分配它自己的变量和数组。
不是只有 common
对应于C全局变量。也是模块变量。它们也隐式地 save
。
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:
- Is there a standard (automated) solution for my problem?
- Which parts of the code do I have to modify?
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?
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.
这篇关于有没有简单的方法来准备并行调用的Fortran代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!