我在MATLAB MEX代碼中使用CUDA Thrust庫時遇到了問題。在MATLAB MEX文件中使用Thrust運行時鏈接程序錯誤
我有一個外部運行良好的例子,但是如果我編譯並運行它作爲MEX文件,它會在運行時產生「丟失符號」錯誤。
它似乎特定於推力庫。如果不是thrust::device_vector
我使用cudaMalloc
與cudaMemcpy
或cublasSetVector
然後一切都很好。
最小示例
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 R2017a內mexcuda thrustDemo.cu
)建立這個作爲一個MATLAB MEX文件,它編譯和鏈接就好:
>> 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是一個模板庫,那麼鏈接到哪裏?
最後,用cudaMalloc
和cudaMemcpy
或cublasSetVector
代替thrust::device_vector
就行了。所以現在我被我的代碼卡住了一堆cudaMalloc
,這似乎......令人厭惡。我真的很想能夠使用Thrust。
版本
MATLAB R2017a
nvcc
V8.0.61,gcc
5.4.0,Ubuntu的16.04.2
NVIDIA驅動375.39,1060 GTX顯卡(計算能力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必須找錯了地方。
這不是一個運行時錯誤。加載mex文件時發生該錯誤。我不知道錯誤的原因。但是你應該能夠在linux中使用ldd等工具檢查你的mex文件來檢查依賴關係。 – Navan
這是某種破碎的C++/stdlib問題或主機編譯器不匹配。涉及的函數是'std :: __ cxx11 :: basic_string,std :: allocator > :: c_str()const'與CUDA無關 –
talonmies
我看到了;錯誤輸出現在變得更有意義。我認爲MATLAB傾向於使用自己的'libstdC++'版本,這可能是根本原因。謝謝你的評論。 – KQS