【问题标题】:problem with nvmex in matlabmatlab中nvmex的问题
【发布时间】:2011-09-08 08:58:00
【问题描述】:

我已经在我的系统上安装了 matlab,并且还安装了 CUDA SDK for windows。但是我无法编译任何 .cu 文件。我已将 nvmex 脚本文件包含在 Matlab 安装路径的 bin 目录中。身体能帮忙吗?

【问题讨论】:

    标签: matlab cuda matlab-engine


    【解决方案1】:

    任何最新版本的 Matlab 或 Cuda SDK 都不真正支持 nvmex。相反,我建议在 Visual Studio 中编写一个简单的 DLL,它使用标准 MEX 接口来运行 Cuda。我将假设您的项目名为“addAtoB”,并且您只想将两个数字相加以使示例更简单。

    安装 Cuda SDK 后,您需要告诉它将 CUDA 自定义构建规则添加到 Visual Studio,以便它知道如何编译 .CU 文件。

    您的主 cpp 应如下所示:

    // addAtoB.cpp
    #include <mex.h>
    #include <cuda.h>
    #include <driver_types.h>
    #include <cuda_runtime_api.h>
    
    #pragma comment(lib,"libmx.lib") // link with the Matlab MEX API
    #pragma comment(lib,"libmex.lib")
    #pragma comment(lib,"cudart.lib") // link with CUDA
    
    // forward declare the function in the .cu file
    void runMyCUDAKernel(void);
    
    // input and output variables for the function in the .cu file
    float A, B, C;
    
    void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
    {
        A = (float) mxGetScalar(prhs[0]);
        B = (float) mxGetScalar(prhs[1]);
    
        runMyCUDAKernel();
    
        // allocate output
        nlhs = 1;
        plhs[0] = mxCreateDoubleScalar(C);
    
        mexPrintf("GPU: %f + %f = %f\nCPU: %f", A, B, C, A+B);
    
        cudaDeviceReset();
    }
    

    您需要在包含路径中添加几个目录:C:\Program Files\MATLAB\R2009a\extern\include 和 CUDA 目录。

    添加到您的链接器路径:C:\Program Files\MATLAB\R2009a\extern\lib\win32\microsoft , $(CUDA_PATH)\lib\$(PlatformName)

    接下来,将 .DEF 文件添加到您的项目中,如下所示:

    LIBRARY    "addAtoB"
    EXPORTS
        mexFunction
    

    接下来,在当前目录中创建一个名为 runMyCUDAKernel.cu 的文件,输入类似这样的内容,然后将该文件添加到您的项目中:

    // runMyCUDAKernel.cu:
    #include <cuda.h>
    extern float A, B, C;
    
    // Device kernel
    __global__ void addAtoB(float A1, float B1, float* C1)
    {
        *C1 = A1+B1;
    }
    
    void runMyCUDAKernel(void)
    {
        float* pOutput;
        cudaMalloc( (void**) &pOutput, 1*sizeof(float));
        dim3 dimBlock(1, 1);
        dim3 dimGrid(1, 1);
    
        addAtoB<<< dimGrid, dimBlock >>>(A, B, pOutput);
    
        cudaMemcpy( &C, pOutput, 1*sizeof(float), cudaMemcpyDeviceToHost);
        cudaDeviceSynchronize();
        cudaFree(pOutput);
    }
    

    构建 DLL 并将其从 .dll 重命名为 .mexw32(或 .mexw64,如果您使用的是 64 位 Matlab)。然后您应该可以使用命令addAtoB(1, 2) 运行它。

    【讨论】:

    • 我的 matlab 版本是 R2010a,Microsoft Visual Studio 的版本是 2008。我将 nvmexopts.bat 文件复制到我的 matlab 安装路径的 buin 目录中,当我运行链接中提供的示例时:developer.download.nvidia.com/compute/cuda/1_1/… ,我收到以下错误: Undefined subroutine &main::uuidgen called at C:\Program Files\MATLAB\R2010a\bin\nvmex.pl line 728. ???在 206 处使用 ==> nvmex 时出错无法成功完成。
    • nvmex 在 Matlab 2010a 中不受支持。您必须改为创建一个 DLL。在 Visual Studio 中:文件 -> 新建 -> 项目。选择 Win32。选择应用程序类型 -> DLL。
    【解决方案2】:

    我建议使用来自 Matlab 文件交换的CUDA mex

    它使您可以通过 Matlab 进行编译。通过不强制您通过 Visual Studio 显式指定 mex 依赖项,这在 Matlab 和 Visual Studio 版本之间获得了更好的兼容性。

    【讨论】:

    • "CUDA mex" 实际上只是对 nvmex 的重新实现。我不同意它具有“更好的兼容性”——无论您是否要明确指出它,Cuda Runtime 依赖项都存在。您仍然需要将 cudart32_40_17.dll 与您的 .mexw32 文件一起分发到其他计算机,否则它将无法运行或 Matlab 将崩溃。
    • 当然可以,但是在最新版本的 Matlab(R2010b 和 R2011a)上对我来说效果很好。在 VS 解决方案中重新编译而不是更改 mexversion.rc 更容易。
    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 2011-11-29
    • 2013-10-01
    • 2013-05-04
    相关资源
    最近更新 更多