我試圖在linux下使用MATLAB mex下的CUDA代碼。使用「整個程序編譯」模式,它對我有用。我在Nsight中採取以下兩個步驟:mex鏈接的獨立編譯模式下的cuda代碼
(1)將「-fPIC」作爲編譯器選項添加到每個.cpp或.cu文件,然後分別編譯它們,每個文件生成一個.o文件。 (2)將鏈接器命令設置爲「mex」並添加「-cxx」以表示所有.o輸入文件的類型都是cpp文件,併爲cuda添加庫路徑。還要添加一個包含mexFunction條目的cpp文件作爲附加輸入。
這工作良好,導致mex文件在MATLAB下運行良好。之後,當我需要使用動態並行時,我必須切換到Nsight中的「單獨編譯模式」。我嘗試了上面的同樣的事情,但鏈接器產生了很多錯誤的引用,這是我無法解決的。
然後我檢查了「獨立編譯」模式的編譯和鏈接步驟。我對它正在做的事情感到困惑。看起來,Nsight爲每個.cpp或.cu文件執行兩個編譯步驟,並生成.o文件和.d文件。就像這樣:
/usr/local/cuda-5.5/bin/nvcc -O3 -gencode arch=compute_35,code=sm_35 -odir "src" -M -o "src/tn_matrix.d" "../src/tn_matrix.cu"
/usr/local/cuda-5.5/bin/nvcc --device-c -O3 -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35 -x cu -o "src/tn_matrix.o" "../src/tn_matrix.cu"
的連接命令是這樣的:
/usr/local/cuda-5.5/bin/nvcc --cudart static --relocatable-device-code=true -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35 -link -o "test7" ./src/cu_base.o ./src/exp_bp_wsj_dev_mex.o ./src/tn_main.o ./src/tn_matlab_helper.o ./src/tn_matrix.o ./src/tn_matrix_lib_dev.o ./src/tn_matrix_lib_host.o ./src/tn_model_wsj_dev.o ./src/tn_model_wsj_host.o ./src/tn_utility.o -lcudadevrt -lmx -lcusparse -lcurand -lcublas
有趣的是鏈接器不走.D文件作爲輸入。所以我不確定它是如何處理這些文件的,以及如何在鏈接時使用「mex」命令處理它們?
另一個問題是,鏈接階段有很多我不明白的選項(--cudart static --relocatable-device-code = true),我想這是我無法使它工作的原因在「整個程序編譯」模式下。所以我嘗試了以下內容:
(1)以與帖子開頭相同的方式進行編譯。 (2)保留Nsight提供的鏈接命令,但改爲使用「-shared」選項,以便鏈接器生成一個lib文件。 (3)通過輸入lib文件和另一個包含mexFunction條目的cpp文件調用mex。
這種方式mex編譯工作,它產生一個mex可執行文件作爲輸出。但是,在MATLAB下運行生成的mex可執行文件會立即產生分段錯誤並導致MATLAB崩潰。
我不確定這種連接方式是否會導致任何問題。更奇怪的是,我發現mex鏈接步驟似乎沒有檢查可執行文件的完整性即可完成,因爲即使我錯過了mexFunction將使用的某個函數的.cpp文件,它仍然會編譯。
編輯:
我想出如何手動鏈接成一個可執行MEX可MATLAB下運行正常,但我還沒有想出怎麼做,下Nsight自動,這是我可以在「全程序編譯「模式。這是我的方法:
(1)排除構建包含mexFunction條目的cpp文件。用命令「mex -c」手動編譯它。
(2)將「-fPIC」作爲編譯器選項添加到其餘的.cpp或.cu文件中,然後分別編譯它們,每個文件生成一個.o文件。
(3)鏈接將失敗,因爲它無法找到主要功能。我們沒有它,因爲我們使用mexFunction,它被排除在外。這並不重要,我只是把它留在那裏。
(4)按照在下面的柱的方法手動DLINK .o文件到一個設備對象文件
cuda shared library linking: undefined reference to cudaRegisterLinkedBinary
例如,如果步驟(2)產生A0和B0,這裏我們做
nvcc -gencode arch=compute_35,code=sm_35 -Xcompiler '-fPIC' -dlink a.o b.o -o mex_dev.o -lcudadevrt
請注意,這裏輸出文件mex_dev.o
應該不存在,否則上述命令將失敗。 (5)使用mex命令鏈接步驟(2)和步驟(4)中生成的所有.o文件,並提供所有必需的庫。
這可以工作並生成可運行的mex可執行文件。我無法在Nsight中自動執行步驟(1)的原因是,如果我將編譯命令更改爲「mex」,Nsight也將使用此命令生成依賴文件(問題文本中提到的.d文件)。我之所以不能在Nsight中自動執行步驟(4)和步驟(5),是因爲它涉及兩條命令,我不知道如何將它們放入。請讓我知道如果您知道如何執行這些操作。謝謝!
感謝您的解決方案!不過,我不想使用自定義makefile解決方案,因爲我喜歡Eclipse提供的自動化管理工具。你知道如果我有一個自定義的makefile,那麼我可以稍後將它轉換爲Eclipse項目嗎? 對於mex,它有一個命令行版本,它和matlab裏面調用的一樣。 – shaoyl85
^是的,我已經更新了示例以使用mex的命令行版本,這絕對看起來更好。我還會添加一些關於如何修改自動編譯系統的說明...... –
我做了一些Google搜索,但是我沒有找到將自定義Makefile轉換爲託管項目的方法。我認爲這是因爲,像其他命令行工具一樣,Makefile提供了很大的靈活性。 –