我试图在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提供了很大的灵活性。 –