2011-02-11 82 views
3

我有一個C++例程standalone_c.cpp和一個用於包裝standalone_c.cpp的fortran standalone_f.f90中的包裝器。 standalone_c.cpp是使用openmp編譯指示的多線程。我能夠編譯standalone_c.cpp和wrapper standalone_f.f90。但是,當我試圖鏈接這兩個時,我遇到了像omp_get_thread_num的未定義引用,omp_get_num_procs的未定義引用等錯誤。有沒有人有從Fortran例程調用多線程C或C++代碼的經驗?有誰能猜到爲什麼會發生這種情況?從Fortran例程調用多線程(openmp)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是這些庫中的連接標誌。

+0

用於編譯和鏈接的命令將有助於查看。 – suszterpatt 2011-02-11 17:55:45

+0

哎呀,意思是包括那些 – Anu 2011-02-11 17:59:58

回答

3

ifort上的-openmp標誌不僅僅是打開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

謝謝!真的很清楚答案,我錯過了-openmp-lib compat標誌。 – Anu 2011-02-14 19:14:37

0

對於GNU編譯器,啓用OpenMP的命令行選項是-fopenmp,而不是您的示例中的-openmp。其次,使用-fopenmp選項時,編譯器會生成對GNU OpenMP支持庫(libgomp)的調用。當你使用ifort而不是gfortran進行最後的鏈接時,你需要明確鏈接到該庫。

即使如此,case -fopenmp可能會在主程序中添加一些設置調用。首先,我會檢查是否可以使用GNU Fortran編譯器(gfortran)而不是ifort來運行程序。請記住,即使Fortran代碼本身不使用OpenMP,也要將-fopenmp添加到gfortran標誌中。