调用多线程(openmp)c++来自 Fortran 例程的例程

发布于 2024-10-16 18:39:49 字数 603 浏览 1 评论 0原文

我有一个 C++ 例程standalone_c.cpp 和一个包装器,用于包装standalone_c.cpp 的fortranstandalone_f.f90。 standalone_c.cpp 是使用 openmp pragma 的多线程。我能够编译standalone_c.cpp 和包装器standalone_f.f90。然而,当我尝试链接这两个时,我收到诸如对 omp_get_thread_num 的未定义引用、对 omp_get_num_procs 的未定义引用之类的错误。有人有从 Fortran 例程调用多线程 C 或 C++ 代码的经验吗?谁能猜出为什么会发生这种情况?

如果有足够的兴趣,我可以发布一些伪代码。

编辑:编译命令:

gcc-4.3.3/bin/g++ -O -openmp $(IFLAGS) -c standalone_c.cpp 
fce/10.1.015/bin/ifort -g -O0 standalone_f.f90
fce/10.1.015/bin/ifort $(LFLAGS) standalone_c.o standalone_f.o -o standalone

IFLAGS 用于我需要的某些库,LFLAGS 是这些库的链接器标志。

I have a c++ routine standalone_c.cpp and a wrapper for this in fortran standalone_f.f90 which wraps standalone_c.cpp. standalone_c.cpp is multithreaded using a openmp pragma. I am able to compile both standalone_c.cpp and the wrapper standalone_f.f90. However when I try to link these two, I get errors like undefined reference to omp_get_thread_num, undefined reference to omp_get_num_procs. Does anyone have any experience calling multithreaded c or c++ code from a fortran routine? Can anyone guess why this is happening?

I can post some pseudo code if there is enough interest.

Edit: Compiling commands:

gcc-4.3.3/bin/g++ -O -openmp $(IFLAGS) -c standalone_c.cpp 
fce/10.1.015/bin/ifort -g -O0 standalone_f.f90
fce/10.1.015/bin/ifort $(LFLAGS) standalone_c.o standalone_f.o -o standalone

IFLAGS are for some libraries that I need, LFLAGS are the linker flags for those libraries.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云胡 2024-10-23 18:39:49

ifort 上的 -openmp 标志不仅仅是打开 OpenMP 指令处理。它还链接到适当的库。假设您已经处理了子例程命名问题中的下划线,那么如果您将 -openmp 添加到 ifort 链接步骤,则将处理 OpenMP 库,并添加 -lstdc++ 将处理 C++ 引用(如 __gxx_personality_v0)。

或者您可以使用 ifort 提供的选项。简单的例子:

gt; cat a.f90
program a
  print *, "calling C++ program"
  call b()
end program a

gt; cat b.cpp
#include <omp.h>
#include <stdio.h> 

extern "C" {
void b_(void); }

void b_(void) {
  int i;

  #pragma omp parallel for
  for (i = 0; i < 10; i++)
    printf("t#: %i  i: %i\n", omp_get_thread_num(), i);

}

gt; g++ -fopenmp -c -o b.o b.cpp
gt; ifort -g -O0 -c -o a.o a.f90
gt; ifort -openmp -cxxlib -openmp-lib compat b.o a.o
gt; export OMP_NUM_THREADS=4
gt; a.out
 calling C++ program
t#: 2  i: 6
t#: 2  i: 7
t#: 2  i: 8
t#: 3  i: 9
t#: 0  i: 0
t#: 0  i: 1
t#: 0  i: 2
t#: 1  i: 3
t#: 1  i: 4
t#: 1  i: 5

你必须告诉 ifort 使用 OpenMP (-openmp),与 GNU OpenMP 运行时库 libgomp (-openmp-lib compat) 兼容,并使用 g++ 提供的 C++ 运行时库进行链接 (- cxxlib)。

The -openmp flag on ifort does more than just turn on OpenMP directive processing. It also links in the proper libraries. Assuming that you have handled the underscore in the subroutine naming problem already, then if you add -openmp to the ifort link step, that will take care of the OpenMP libraries and adding -lstdc++ will handle the C++ references (like __gxx_personality_v0).

Or you can use the options provided by ifort. Simple example:

gt; cat a.f90
program a
  print *, "calling C++ program"
  call b()
end program a

gt; cat b.cpp
#include <omp.h>
#include <stdio.h> 

extern "C" {
void b_(void); }

void b_(void) {
  int i;

  #pragma omp parallel for
  for (i = 0; i < 10; i++)
    printf("t#: %i  i: %i\n", omp_get_thread_num(), i);

}

gt; g++ -fopenmp -c -o b.o b.cpp
gt; ifort -g -O0 -c -o a.o a.f90
gt; ifort -openmp -cxxlib -openmp-lib compat b.o a.o
gt; export OMP_NUM_THREADS=4
gt; a.out
 calling C++ program
t#: 2  i: 6
t#: 2  i: 7
t#: 2  i: 8
t#: 3  i: 9
t#: 0  i: 0
t#: 0  i: 1
t#: 0  i: 2
t#: 1  i: 3
t#: 1  i: 4
t#: 1  i: 5

You have to tell ifort to use OpenMP (-openmp), be compatible with the GNU OpenMP run-time library libgomp (-openmp-lib compat), and to link using the C++ run-time libraries provided by g++ (-cxxlib).

孤独岁月 2024-10-23 18:39:49

对于 GNU 编译器,启用 OpenMP 的命令行选项是 -fopenmp,而不是示例中的 -openmp。

其次,当使用 -fopenmp 选项时,编译器会生成对 GNU OpenMP 支持库 (libgomp) 的调用。当您使用 ifort 而不是 gfortran 执行最后的链接步骤时,您需要显式链接到该库。

即便如此,如果 -fopenmp 添加一些设置调用到主程序,可能会出现问题。首先,我会检查是否可以使用 GNU Fortran 编译器 (gfortran) 而不是 ifort 来运行程序。请记住将 -fopenmp 添加到 gfortran 标志,即使 Fortran 代码本身不使用 OpenMP。

For the GNU compilers, the command line option to enable OpenMP is -fopenmp, not -openmp as in your example.

Secondly, when using the -fopenmp option, the compiler generates calls to the GNU OpenMP support library (libgomp). As you do the final linking step with ifort and not gfortran, you need to explicitly link to that library.

Even so, there might be problems in case -fopenmp adds some setup calls to the main program. To begin with, I would check if I could get the program running using the GNU Fortran compiler (gfortran) instead of ifort. Remember to add -fopenmp to the gfortran flags even if the Fortran code doesn't use OpenMP itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文