有没有简单的方法来准备并行调用的Fortran代码 [英] Is there an easy way to prepare Fortran code for parallel invocation

查看:190
本文介绍了有没有简单的方法来准备并行调用的Fortran代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在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线程将分配它自己的变量和数组。

threadprivate 指令确实很有用,正如你发现的你自己。我不确定你是否可以保证它会使用堆栈或堆,但堆更有可能,因为它们必须在整个执行过程中保持在范围内。



不是只有 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆