Вызов многопоточной (openmp) подпрограммы c ++ из фортрановской подпрограммы - PullRequest
3 голосов
/ 11 февраля 2011

У меня есть подпрограмма c ++ standalone_c.cpp и оболочка для этого в fortran standalone_f.f90, которая упаковывает standalone_c.cpp.standalone_c.cpp является многопоточным с использованием прагмы openmp.Я могу скомпилировать как standalone_c.cpp, так и оболочку standalone_f.f90.Однако, когда я пытаюсь связать эти два, я получаю ошибки, такие как неопределенная ссылка на omp_get_thread_num, неопределенная ссылка на omp_get_num_procs.У кого-нибудь есть опыт вызова многопоточного кода 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 являются флагами компоновщика для этих библиотек.

Ответы [ 2 ]

3 голосов
/ 12 февраля 2011

Флаг -openmp на ifort делает больше, чем просто включает обработку директивы OpenMP. Это также ссылки в соответствующих библиотеках. Предполагая, что вы уже обработали подчеркивание в проблеме именования подпрограмм, тогда, если вы добавите -openmp к шагу ссылки ifort, это позаботится о библиотеках OpenMP, а добавление -lstdc ++ будет обрабатывать ссылки C ++ (например, __gxx_personality_v0).

Или вы можете использовать опции, предоставляемые ifort. Простой пример:

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

$> 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);

}

$> g++ -fopenmp -c -o b.o b.cpp
$> ifort -g -O0 -c -o a.o a.f90
$> ifort -openmp -cxxlib -openmp-lib compat b.o a.o
$> export OMP_NUM_THREADS=4
$> 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) и связываться, используя библиотеки времени выполнения C ++, предоставляемые g ++ (- cxxlib).

0 голосов
/ 12 февраля 2011

Для компиляторов GNU опцией командной строки для включения OpenMP является -fopenmp, а не -openmp, как в вашем примере.

Во-вторых, при использовании опции -fopenmp компилятор генерирует вызовы в библиотеку поддержки GNU OpenMP (libgomp). Выполняя последний шаг связывания с ifort, а не с gfortran, вам нужно явно указать ссылку на эту библиотеку.

Даже в этом случае могут возникнуть проблемы в случае, если -fopenmp добавляет некоторые установочные вызовы в основную программу. Для начала я бы проверил, смогу ли я запустить программу, используя компилятор GNU Fortran (gfortran) вместо ifort. Не забудьте добавить -fopenmp к флагам gfortran, даже если код Fortran не использует сам OpenMP.

...