2017-04-26 3 views
3

MATLAB MEXコードでCUDA Thrustライブラリを使用する際に問題があります。MATLAB MEXファイルの推力を使用したランタイムリンカエラー

私は外部でうまく動作する例がありますが、コンパイルしてMEXファイルとして実行すると、実行時に "missing symbol"エラーが発生します。

これはThrustライブラリに固有のようです。 thrust::device_vectorの代わりにcudaMemcpyまたはcublasSetVectorcudaMallocを使用すると、すべて正常です。

最小例

thrustDemo.cu:

#ifdef MATLAB_MEX_FILE 
    #include "mex.h" 
    #include "gpu/mxGPUArray.h" 
#endif 
#include <thrust/device_vector.h> 
#include <vector> 

void thrustDemo() { 
    std::vector<double> foo(65536, 3.14); 
    thrust::device_vector<double> device_foo(foo); 
} 

#ifdef MATLAB_MEX_FILE 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray const *prhs[]) { 
    thrustDemo(); 
} 
#else 
int main(void) { thrustDemo(); } 
#endif 

問題

私は、コマンドライン(nvcc thrustDemo.cu)からこれをコンパイルしてうまく結果の実行可能ファイルを実行することができます。

私はMATLAB MEXファイル(MATLAB R2017aの中からmexcuda thrustDemo.cu)としてこれを構築しようとした際、それがうまくコンパイルとリンク:

>> mexcuda thrustDemo.cu 
Building with 'nvcc'. 
MEX completed successfully. 

しかし、私はそれを実行しようとすると、私は次のエラーを取得します:

>> thrustDemo() 
Invalid MEX-file '/home/kqs/thrustDemo.mexa64': 
Missing symbol '_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5emptyEv' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt12length_errorC1EPKc' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt13runtime_errorC2EPKc' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc' required by '/home/kqs/thrustDemo.mexa64' 
Missing symbol '_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLERKS4_' required by '/home/kqs/thrustDemo.mexa64'. 

これは私にとってはかなり外国語です。誰かがこれが何を意味するのか教えていただけますか?これらはリンカエラーのように見えますが、実行時に生成されています。また、推力はテンプレートライブラリであると思ったので、リンクするのは何ですか?

最後に、thrust::device_vectorcudaMallocと置き換えて、cudaMemcpyまたはcublasSetVectorのいずれかが問題なく機能します。だから今は私のコードでcudaMallocの束で立ち往生しています。私は本当に推力を使うことができたいと思っています。

バージョン

MATLAB R2017a

nvcc V8.0.61、gcc 5.4.0、Ubuntuの16.04.2

NVIDIAドライバ375.39、GTX 1060グラフィックスカード(6.1計算能力)

更新:ldd出力

コメントごとに、私はtの依存関係を調べましたldd thrustDemo.mexa64を使用して、彼MEXファイル:

linux-vdso.so.1 => (0x00007ffdd35ea000) 
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f097eccf000) 
libcudart.so.8.0 => /usr/local/cuda-8.0/targets/x86_64-linux/lib/libcudart.so.8.0 (0x00007f097ea69000) 
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f097e852000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f097e489000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f097e180000) 
/lib64/ld-linux-x86-64.so.2 (0x0000562df178c000) 
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f097df7b000) 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f097dd5e000) 
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f097db56000) 

は、私はこれらの不足しているシンボルの一つを探してみました、そして、それを見つけることができた:

$ nm -D /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep "_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv" 
0000000000120be0 W _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv 

だからそれはMATLABが間違った場所で探してしなければならないようです。

+0

それは実行時エラーではありません。 mexファイルがロードされているときにエラーが発生しています。私はエラーの原因を知りません。しかしlinuxのlddのようなツールを使ってmexファイルを調べて、依存関係を調べることができるはずです。 – Navan

+0

これはある種の壊れたC++/stdlibの問題またはホストコンパイラの不一致です。関連する機能は、私が見CUDA – talonmies

+0

とは何の関係もない 'のstd :: __ cxx11 ::のbasic_string 、STD ::アロケータ> :: c_str()const'です。エラー出力は今より多くの意味があります。私は、MATLABが根本的な原因であるかもしれない 'libstdC++'の独自のバージョンを使用することを好むと思います。皆さんのご意見ありがとうございます。 – KQS

答えて

4

これはThrustとは無関係ですが、C++標準ライブラリの独自のバージョンを持つMATLABではむしろ問題になります。

@Navanと@talonmiesのおかげで彼らの有益なコメントがありました。それはMEXファイルをロードしていますときにエラー

初の解釈

、MATLABは、これらのエラーを上げています。 MEXファイルには外部依存関係があり、MATLABはそれらを見つけることができませんでした。シンボルを一覧表示するnmを使用して、その後、Linuxのユーティリティlddでこれらの依存関係をチェックした後

は、これらのライブラリで定義され、私はlibstdc++共有ライブラリのシステムのバージョンが実際にこれらの「行方不明の記号が」含まれていることがわかりました。したがって、外部コンパイルされたバージョンがうまく動作する理由は?根本的な問題発行し

を解決

は、その後、libstdc++の独自の、旧バージョンとMATLABの船は、これらの機能を欠いているということです。確かに私の問題のために成功した回避策について説明し

How to tell mex to link with the libstdc++.so.6 in /usr/lib instead of the one in the MATLAB directory?

Version GLIBCXX_3.4.11 not found (required by buildW.mexglx)

:根本原因を知って、私はこれらのような質問を見つけました。特に

MATLABではなく、自身のコピーのシステムlibstdc++を使用するためにMATLABを強制的に起動するとき、私はLD_PRELOADを使用:

$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/local/MATLAB/R2017a/bin/matlab 

更新:より良いソリューション

をそれは人々であることが判明しましたGCCは、この非互換性とdiscuss it hereのよく知っている:

In the GCC 5.1 release libstdc++ introduced a new library ABI that includes new implementations of std::string and std::list. These changes were necessary to conform to the 2011 C++ standard which forbids Copy-On-Write strings and requires lists to keep track of their size.

In order to maintain backwards compatibility for existing code linked to libstdc++ the library's soname has not changed and the old implementations are still supported in parallel with the new ones. ... The _GLIBCXX_USE_CXX11_ABI macro (see Macros) controls whether the declarations in the library headers use the old or new ABI.

伝えるためにgccより古いABIを使用するには、_GLIBCXX_USE_CXX11_ABI0と定義する必要があります。コンパイラに-Dオプションを渡すことによって:

-D_GLIBCXX_USE_CXX11_ABI=0 

を完全を期すために、私は私の完全なmexcuda呼び出しはこのようになっていることを言及します:

nvcc_opts = [... 
    '-gencode=arch=compute_30,code=sm_30 ' ... 
    '-gencode=arch=compute_50,code=sm_50 ' ... 
    '-gencode=arch=compute_60,code=sm_60 ' ... 
    '-std=c++11 ' ... 
    '-D_GLIBCXX_USE_CXX11_ABI=0 ' % MATLAB's libstdc++ uses old library ABI 
    ]; 
mexcuda_opts = { 
    '-lcublas'      % Link to cuBLAS 
    '-lmwlapack'     % Link to LAPACK 
    '-lcufft'      % Link to cuFFT 
    ['NVCCFLAGS="' nvcc_opts '"'] 
    '-L/usr/local/cuda/lib64'  % Location of CUDA libraries 
    }; 
mexcuda(mexcuda_opts{:}, src_file); 
関連する問題