单独编译模式下 cuda 代码的 mex 链接

2023-12-07

我正在尝试在 Linux 下的 MATLAB mex 中使用 CUDA 代码。使用“整个程序编译”模式,它对我来说效果很好。我在 Nsight 中执行以下两个步骤:

(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) 调用 mex,输入 lib 文件和另一个包含 mexFunction 条目的 cpp 文件。

这样,mex 编译就可以工作,并生成一个 mex 可执行文件作为输出。但是,在 MATLAB 下运行生成的 mex 可执行文件会立即产生分段错误并使 MATLAB 崩溃。

我不确定这种链接方式是否会导致任何问题。更奇怪的是,我发现 mex 链接步骤似乎很简单地完成,甚至没有检查可执行文件的完整性,因为即使我错过了 mexFunction 将使用的某些函数的 .cpp 文件,它仍然可以编译。

EDIT:

我弄清楚了如何手动链接到可以在 MATLAB 下正确运行的 mex 可执行文件,但我还没有弄清楚如何在 Nsight 下自动执行此操作,我可以在“整个程序编译”模式下执行此操作。这是我的方法:

(1) 从构建中排除包含 mexFunction 条目的 cpp 文件。使用命令“mex -c”手动编译它。

(2) 将“-fPIC”作为编译器选项添加到其余的每个.cpp 或.cu 文件中,然后分别编译它们,每个文件生成一个.o 文件。

(3) 由于找不到main函数,链接会失败。我们没有它,因为我们使用 mexFunction 并且它被排除在外。这并不重要,我就把它留在那里。

(4) 按照下面帖子中的方法手动将.o文件链接到设备目标文件中

cuda 共享库链接:对 cudaRegisterLinkedBinary 的未定义引用

例如,如果步骤(2)产生 a.o 和 b.o,这里我们做

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)的原因是因为它涉及两个命令,我不知道如何将它们放入。如果您知道如何执行这些操作,请告诉我。谢谢!


好的,我找到了解决方案。以下是在Nsight中使用“单独编译模式”编译mex程序的完整步骤:

  1. 创建一个cuda项目。
  2. 在项目级别,更改以下构建选项:

    • 打开-fPIC在项目级别的“NVCC编译器”的编译器选项中。
    • Add -dlink -Xcompiler '-fPIC'到链接器“NVCC Linker”的“专家设置”“命令行模式”
    • 添加字母o到“构建工件”->“工件扩展”,因为通过-dlink在最后一步中,我们将输出a.o file.
    • Add mex -cxx -o path_to_mex_bin/mex_bin_filename ./*.o ./src/*.o -lcudadevrt到“构建后步骤”,(添加其他必要的库)

    更新:在我的实际项目中,我将最后一步移至 MATLAB 中的 .m 文件,因为否则如果我在 mex 程序运行时执行此操作,可能会导致 MATLAB 崩溃。

  3. 对于需要使用 mex 编译的文件,请更改每个文件的构建选项:

    • 将编译器更改为GCC C++ Compiler在工具链编辑器中。
    • 返回到编译器设置GCC C++ Compiler并将命令更改为mex
    • 将命令行模式更改为${COMMAND} -c -outdir "src" ${INPUTS}

几个附加说明:

(1) 必须对 mex 编译器隐藏 Cuda 特定细节(例如内核函数和对内核函数的调用)。因此它们应该放在 .cu 文件中而不是头文件中。这是将涉及 cuda 详细信息的模板放入 .cu 文件的技巧。

在头文件中(例如,f.h),您只需要像这样放置函数的声明:

template<typename ValueType>
void func(ValueType x);

添加一个名为f.inc,其中包含定义

template<>
void func(ValueType x) {
  // possible kernel launches which should be hidden from mex
}

在源代码文件中(例如,f.cu),你把这个

#define ValueType float
#include "f.inc"
#undef ValueType

#define ValueType double
#include "f.inc"
#undef ValueType

// Add other types you want.

这个技巧可以很容易地推广到模板类来隐藏细节。

(2) mex 的具体细节也应该从 cuda 源文件中隐藏,因为mex.h会改变一些系统函数的定义,例如printf。因此,“mex.h”的包含不应出现在可能包含在 cuda 源文件中的头文件中。

(3) 在包含mexFunction入口的mex源代码文件中,可以使用编译器宏MATLAB_MEX_FILE有选择地编译代码部分。这样源代码文件就可以编译成 mex 可执行文件或普通可执行文件,从而允许在 Nsight 下进行调试,而无需使用 matlab。这是在 Nsight 下构建多个目标的技巧:在一个 Eclipse 项目中构建多个二进制文件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单独编译模式下 cuda 代码的 mex 链接 的相关文章

  • 使用推力来处理 CUDA 类中的向量?

    我对 C 类的推力的适用性有疑问 我正在尝试实现一个类对象 该对象接收顶点的 x y z 坐标作为 ver1 ver2 和 ver3 然后 分配给一个三角形并计算面积和法向量 然而 我不太明白如何创建一类推力向量 这是我从文件中读取的顶点坐
  • Matlab 和 Python 中的优化算法(dog-leg trust-region)

    我正在尝试使用 Matlab 和 Python 中的狗腿信赖域算法求解一组非线性方程 在Matlab中有fsolve https www mathworks com help optim ug fsolve html其中此算法是默认算法 而
  • 对 CUDA 操作进行计时

    我需要计算 CUDA 内核执行的时间 最佳实践指南说我们可以使用事件或标准计时函数 例如clock 在Windows中 我的问题是使用这两个函数给出了完全不同的结果 事实上 与实践中的实际速度相比 事件给出的结果似乎是巨大的 我实际上需要这
  • 使用符号求解器仅求解某些变量

    我正在尝试在 MATLAB 中求解包含 3 个变量和 5 个常量的方程组 是否可以使用solve求解三个变量 同时保持常量为符号而不用数值替换它们 当您使用SOLVE http www mathworks com access helpde
  • GCC编译非常慢(文件大)

    我正在尝试编译一个大的 C 文件 专门用于 MATLAB mexing C 文件大约 20 MB 可用来自 GCC 错误跟踪器 https gcc gnu org bugzilla attachment cgi id 36632如果你想玩一
  • 如何告诉 mex 链接到 /usr/lib 中的 libstdc++.so.6 而不是 MATLAB 目录中的 libstdc++.so.6?

    现在 MATLAB 2012a 中的 mex 仅正式支持 gcc 4 4 6 但我想使用 gcc 4 7 风险自负 现在如果我直接用 mex 编译一些东西 它会抱怨 usr lib gcc i686 linux gnu 4 7 cc1plu
  • 完全禁用 NVCC 优化

    我正在尝试测量 GPU 上的峰值单精度触发器 为此我正在修改 PTX 文件以在寄存器上执行连续的 MAD 指令 不幸的是 编译器正在删除所有代码 因为它实际上没有做任何有用的事情 因为我没有执行任何数据的加载 存储 是否有编译器标志或编译指
  • 如何找到平面和 3d 矩阵之间的交平面

    如果我有一堆图像并且尺寸如下 size M 256 256 124 我有 3 个点 它们的坐标是 coor a 100 100 124 coor b 256 156 0 coor c 156 256 0 如何创建 M 与这 3 个点定义的平
  • CUDA cutil.h 在哪里?

    有谁知道包含 cutil h 的 SDK 工具包在哪里 我尝试了 CUDA toolkits3 2 和 toolkits5 0 我知道这个版本已经不支持 cutil h 我还注意到一些提到的如何在 Linux 中包含 cutil h htt
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • 将数据从 GPU 复制到 CPU - CUDA

    我在将数据从 GPU 复制到 CPU 时遇到问题 一开始我在 GPU 空间中创建变量 device float gpu array 在此 GPU 函数中 我想将数据从 od fS gi 值 0 43 复制到 gpu array global
  • goto 指令对 CUDA 代码中扭曲内发散的影响

    对于CUDA中简单的warp内线程发散 我所知道的是SM选择一个重新收敛点 PC地址 并在两个 多个路径中执行指令 同时禁用未采用该路径的线程的执行效果 例如 在下面的代码中 if threadIdx x lt 16 A do someth
  • 图像处理 - 使用 opencv 进行服装分割

    我正在使用 opencv 进行服装特征识别 第一步 我需要通过从图像中移除脸部和手来分割 T 恤 任何建议表示赞赏 我建议采用以下方法 Use 阿德里安 罗斯布鲁克的用于检测皮肤的皮肤检测算法 谢谢罗莎 格隆奇以获得他的评论 在方差图上使用
  • ROC曲线和libsvm

    给定一条 ROC 曲线plotroc m see here http www csie ntu edu tw cjlin libsvmtools roc curve for binary svm 理论问题 如何选择要使用的最佳阈值 编程问题
  • @(t)在Matlab中是什么意思? [复制]

    这个问题在这里已经有答案了 正如标题所示 考虑到下面的上下文 t 在 Matlab 中到底意味着什么 computeNumericalGradient 是一个函数 cofiCostFunc 也是一个接受一堆参数的函数 问题是 t 对 cof
  • 如何在MATLAB中显示由三个矩阵表示的图像?

    我有 3 个相同大小的 2D 矩阵 假设 200 行和 300 列 每个矩阵代表三种 基本 颜色 红色 绿色和蓝色 之一的值 矩阵的值可以在 0 到 255 之间 现在我想组合这些矩阵以将它们显示为彩色图像 200 x 300 像素 我怎样
  • 如何将复杂的 csv 文件导入到 Matlab 中的数值向量

    我想知道我们应该如何读取由字符串 双精度数和字符等组成的复杂 csv 文件 例如 您能否提供一个可以在此 csv 文件中提取数值的成功命令 Click here http www ecb europa eu stats money yc d
  • 如何使用 Visual Studio 2008 调试 CUDA 内核代码?

    嘿 我正在使用带有 CUDA 3 2 的 Visual Studio 2008 我正在尝试调试具有此签名的函数 MatrixMultiplication Kernel lt lt
  • 如何知道Matlab中系统命令执行过程中经过的时间?

    我有一个运行系统脚本的 Matlab 代码 该脚本可能会因命令运行而停止 我想知道是否有一种方法可以让程序知道它是否花费了很长时间并执行其他操作 这是代码 tic status cmdout system iperfcmd The prog
  • 如何使用SIFT算法计算两幅图像的相似度?

    我已经用过SIFT http en wikipedia org wiki Scale invariant feature transform实施安德里亚 维达尔迪 http www vlfeat org overview sift html

随机推荐