2017-12-18 50 views
2

私はwrap.pyによって生成されたCPPプログラムを持っています。 wrap.pyは、MPIプログラムのラッパーを生成するために使用されます。これは、通常のMPIコールをPMPIコールにリダイレクトし、例えば、パフォーマンス分析。生成されたコードhereをダウンロードします。私はotf2を使ってMPIプログラムをトレースします。PMPIとotf2:CPPプログラムのCコードのリンク

コードを説明するには、次の

// test4.cpp 
__attribute__((constructor)) void init(void) 
{ 
    if(!is_init) 
    { 
    archive = OTF2_Archive_Open("./", 
           "ArchiveTest", 
           OTF2_FILEMODE_WRITE, 
           1024 * 1024 /* event chunk size */, 
           4 * 1024 * 1024 /* def chunk size */, 
           OTF2_SUBSTRATE_POSIX, 
           OTF2_COMPRESSION_NONE); 
    is_init = true; 
    } 
} 

__attribute__((destructor)) void fini(void) 
{ 
    if(is_init) 
    { 
    OTF2_Archive_Close(archive); 
    is_init = false; 
    } 
} 

を私がする.soファイルにコードをコンパイルするつもりです。したがって、インポートするとconstructorが呼び出されます。 .soがデタッチされると、destructorが呼び出されます。

はotf2 hereの公式ドキュメントによると、私はプログラムをコンパイル:

mpic++ -fpic -c `otf2-config --cflags` -o test4.o test4.cpp 
mpic++ -shared -o libtest4.so `otf2-config --ldflags` `otf2-config --libs` test4.o 

あなたは、上のコマンドラインを拡張する場合は、あなたが得るでしょう:

mpic++ -fpic -c -I/usr/include -o test4.o test4.cpp 
mpic++ -shared -o libtest4.so -L/usr/lib -lotf2 -lm test4.o 

ザ・がMPIプログラムから提示された傍受しましたhere

は、傍受を実行します。

$ mpirun -n 2 -x LD_PRELOAD=./libtest4.so ./send_recv 
./send_recv: symbol lookup error: ./libtest4.so: undefined symbol: OTF2_Archive_Open 
./send_recv: symbol lookup error: ./libtest4.so: undefined symbol: OTF2_Archive_Open 
------------------------------------------------------- 
Primary job terminated normally, but 1 process returned 
a non-zero exit code.. Per user-direction, the job has been aborted. 
------------------------------------------------------- 
-------------------------------------------------------------------------- 
mpirun detected that one or more processes exited with non-zero status, thus causing 
the job to be terminated. The first process to do so was: 

    Process name: [[20246,1],0] 
    Exit code: 127 
-------------------------------------------------------------------------- 

は、だから、Cの混合のように見え、CPPは、問題が発生します。リンカはC関数のシンボルを正しく生成できませんでした。つまり、OTF2_Archive_OpenOTF2_Archive_Closeです。

_EXTERN_C_ OTF2_Archive* OTF2_Archive_Open (const char * archivePath, 
const char * archiveName, 
const OTF2_FileMode fileMode, 
const uint64_t chunkSizeEvents, 
const uint64_t chunkSizeDefs, 
const OTF2_FileSubstrate fileSubstrate, 
const OTF2_Compression compression 
); 
_EXTERN_C_ OTF2_ErrorCode OTF2_Archive_Close (OTF2_Archive * archive); 

しかし、滞在上述した問題:

は、私はそれらがC関数(here修正プログラムをダウンロード)されているリンカを伝えるために2つの宣言を追加します。そしてアドバイス?

UPDATE1: OTF2は、.soファイルではなく.aファイルを提供します。

$ nm /usr/lib/libotf2.a| grep -i OTF2_Archive_Open 
       U otf2_archive_open 
0000000000000000 T OTF2_Archive_Open 
       U otf2_archive_open_def_files 
00000000000032e0 T OTF2_Archive_OpenDefFiles 
       U otf2_archive_open_evt_files 
00000000000030e0 T OTF2_Archive_OpenEvtFiles 
       U otf2_archive_open_snap_files 
00000000000034e0 T OTF2_Archive_OpenSnapFiles 
       U OTF2_Archive_Open 
0000000000001180 T otf2_archive_open 
0000000000005a40 T otf2_archive_open_def_files 
       U OTF2_Archive_OpenDefFiles 
0000000000005880 T otf2_archive_open_evt_files 
       U OTF2_Archive_OpenEvtFiles 
0000000000005c00 T otf2_archive_open_snap_files 
       U OTF2_Archive_OpenSnapFiles 


$ ldd ./libtest4.so 
    linux-vdso.so.1 => (0x00007ffe3a6ce000) 
    libmpi_cxx.so.1 => /usr/lib/libmpi_cxx.so.1 (0x00007f4757d67000) 
    libmpi.so.12 => /usr/lib/libmpi.so.12 (0x00007f4757a91000) 
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f475770e000) 
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f47574f8000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f475712e000) 
    libibverbs.so.1 => /usr/lib/libibverbs.so.1 (0x00007f4756f1e000) 
    libopen-rte.so.12 => /usr/lib/libopen-rte.so.12 (0x00007f4756ca4000) 
    libopen-pal.so.13 => /usr/lib/libopen-pal.so.13 (0x00007f4756a07000) 
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f47567e9000) 
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f47564e0000) 
    /lib64/ld-linux-x86-64.so.2 (0x00005620bef03000) 
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f47562dc000) 
    libhwloc.so.5 => /usr/lib/x86_64-linux-gnu/libhwloc.so.5 (0x00007f47560a1000) 
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f4755e99000) 
    libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f4755c96000) 
    libnuma.so.1 => /usr/lib/x86_64-linux-gnu/libnuma.so.1 (0x00007f4755a8a000) 
    libltdl.so.7 => /usr/lib/x86_64-linux-gnu/libltdl.so.7 (0x00007f4755880000) 



$ nm ./libtest4.so | grep -i OTF2_Archive_Open 
       U OTF2_Archive_Open 

奇妙な、私はlddの出力に任意のlibotf2.aが表示されない、です。しかし、あなたがウェブサイトからotf2 mpi作家の標準的な例を試してみると、それはうまくいきます。また、otf2 mpiライターの標準例のlddの出力にはlibotf2.aも含まれていません。

hereがあります。

+1

アンダースコアで始まり、その後に大文字の が付く識別子は予約されています。 – VTT

+0

だから、このシンボルはどこに定義されていますか?外部ライブラリをtest4にリンクすることはありません –

+0

'ldd。/ libtest4.so'、' nm ./libtest4.so 'の出力を追加してください。 grep -i OTF2_Archive_Open'、 'nm libotf2.so | grep -i OTF2_Archive_Open'を実行します。 '-x LD_DEBUG = all'をmpi呼び出しに追加することもできます。 – Zulan

答えて

1

リンクの順番。リンクしている図書館の前に独自の図書館が必要です。

mpic++ -shared test4.o -o libtest4.so `otf2-config --ldflags` `otf2-config --libs` 

リンカーは未知のシンボルを左から右に解決します。詳細はthis answerを参照してください。 otf2.a-fPICで構築されていないと、それでも動作しないでしょう。私は--enable-sharedでotf2を構成し、代わりに.soを使用することをお勧めします。