使用 Visual Studio 2013 IDE 编译 CUDA Mex 文件
Posted
技术标签:
【中文标题】使用 Visual Studio 2013 IDE 编译 CUDA Mex 文件【英文标题】:Compiling CUDA Mex Files using Visual Studio 2013 IDE 【发布时间】:2015-05-23 02:27:53 【问题描述】:我正在尝试使用 Visual Studio 2013 编译以下程序,它是 MATLAB 的 CUDA mex 文件。 MATLAB 官方网站上有 instructions 仅适用于 C++ Mex 文件,不适用于 CUDA mex。 因此,我按照 Mathworks 上的官方说明对项目设置进行了以下额外更改: 1. 我使用 Visual Studio 项目和我安装的 CUDA 6.5 运行时创建了一个项目。 2. 在我的 VS 项目的链接器属性中包含库(libmx.lib、libmex.lib、libmat.lib、gpu.lib), 3.新增目录include,(MATLABROOT)\toolbox\distcomp\gpu\extern\include;
我仍然收到许多未解决的外部符号错误。什么是正确的方法,因为没有可用于使用 VS IDE 编译 CUDA Mex 的官方文档?有谁知道这样做的正确方法是什么?当然我错过了一些设置,有人可以帮忙吗?
我的程序(从 MATLAB 示例文件 mexGPUExample.cu 复制)如下:
**
/*
* Example of how to use the mxGPUArray API in a MEX file. This example shows
* how to write a MEX function that takes a gpuArray input and returns a
* gpuArray output, e.g. B=mexFunction(A).
*
* Copyright 2012 The MathWorks, Inc.
*/
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "mex.h"
#include "gpu/mxGPUArray.h"
/*
* Device code
*/
void __global__ TimesTwo(double const * const A,
double * const B,
int const N)
/* Calculate the global linear index, assuming a 1-d grid. */
int const i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < N)
B[i] = 2.0 * A[i];
/*
* Host code
*/
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, mxArray const *prhs[])
/* Declare all variables.*/
mxGPUArray const *A;
mxGPUArray *B;
double const *d_A;
double *d_B;
int N;
char const * const errId = "parallel:gpu:mexGPUExample:InvalidInput";
char const * const errMsg = "Invalid input to MEX file.";
/* Choose a reasonably sized number of threads for the block. */
int const threadsPerBlock = 256;
int blocksPerGrid;
/* Initialize the MathWorks GPU API. */
mxInitGPU();
/* Throw an error if the input is not a GPU array. */
if ((nrhs != 1) || !(mxIsGPUArray(prhs[0])))
mexErrMsgIdAndTxt(errId, errMsg);
A = mxGPUCreateFromMxArray(prhs[0]);
/*
* Verify that A really is a double array before extracting the pointer.
*/
if (mxGPUGetClassID(A) != mxDOUBLE_CLASS)
mexErrMsgIdAndTxt(errId, errMsg);
/*
* Now that we have verified the data type, extract a pointer to the input
* data on the device.
*/
d_A = (double const *)(mxGPUGetDataReadOnly(A));
/* Create a GPUArray to hold the result and get its underlying pointer. */
B = mxGPUCreateGPUArray(mxGPUGetNumberOfDimensions(A),
mxGPUGetDimensions(A),
mxGPUGetClassID(A),
mxGPUGetComplexity(A),
MX_GPU_DO_NOT_INITIALIZE);
d_B = (double *)(mxGPUGetData(B));
/*
* Call the kernel using the CUDA runtime API. We are using a 1-d grid here,
* and it would be possible for the number of elements to be too large for
* the grid. For this example we are not guarding against this possibility.
*/
N = (int)(mxGPUGetNumberOfElements(A));
blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
TimesTwo <<< blocksPerGrid, threadsPerBlock >>>(d_A, d_B, N);
/* Wrap the result up as a MATLAB gpuArray for return. */
plhs[0] = mxGPUCreateMxArrayOnGPU(B);
/*
* The mxGPUArray pointers are host-side structures that refer to device
* data. These must be destroyed before leaving the MEX function.
*/
mxGPUDestroyGPUArray(A);
mxGPUDestroyGPUArray(B);
我在尝试编译程序时遇到的错误:
Error 66 error LNK1120: 64 unresolved externals
Error 64 error LNK2001: unresolved external symbol _fltused
Error 62 error LNK2001: unresolved external symbol _RTC_InitBase
Error 63 error LNK2001: unresolved external symbol _RTC_Shutdown
Error 65 error LNK2001: unresolved external symbol mainCRTStartup
Error 58 error LNK2019: unresolved external symbol __imp__dsign referenced in function "bool __cdecl signbit(double)" (?signbit@@YA_NN@Z)
Error 60 error LNK2019: unresolved external symbol __imp__fdsign referenced in function "bool __cdecl signbit(float)" (?signbit@@YA_NM@Z)
Error 61 error LNK2019: unresolved external symbol __imp__hypotf referenced in function hypotf
Error 59 error LNK2019: unresolved external symbol __imp__ldsign referenced in function "bool __cdecl signbit(long double)" (?signbit@@YA_NO@Z)
Error 39 error LNK2019: unresolved external symbol __imp_acosf referenced in function "float __cdecl acos(float)" (?acos@@YAMM@Z)
Error 12 error LNK2019: unresolved external symbol __imp_acoshf referenced in function "float __cdecl acosh(float)" (?acosh@@YAMM@Z)
Error 40 error LNK2019: unresolved external symbol __imp_asinf referenced in function "float __cdecl asin(float)" (?asin@@YAMM@Z)
Error 13 error LNK2019: unresolved external symbol __imp_asinhf referenced in function "float __cdecl asinh(float)" (?asinh@@YAMM@Z)
Error 42 error LNK2019: unresolved external symbol __imp_atan2f referenced in function "float __cdecl atan2(float,float)" (?atan2@@YAMMM@Z)
Error 41 error LNK2019: unresolved external symbol __imp_atanf referenced in function "float __cdecl atan(float)" (?atan@@YAMM@Z)
Error 14 error LNK2019: unresolved external symbol __imp_atanhf referenced in function "float __cdecl atanh(float)" (?atanh@@YAMM@Z) D:\GitHub\arrayfire-windows-scripts\SimpleCUDAProj\CUDA_Mex\CUDA_Mex\CUDA_Times_Two.cu.obj CUDA_Mex
Error 29 error LNK2019: unresolved external symbol __imp_cbrtf referenced in function "float __cdecl cbrt(float)" (?cbrt@@YAMM@Z)
Error 55 error LNK2019: unresolved external symbol __imp_ceilf referenced in function "float __cdecl ceil(float)" (?ceil@@YAMM@Z)
Error 36 error LNK2019: unresolved external symbol __imp_copysignf referenced in function "float __cdecl copysign(float,float)" (?copysign@@YAMMM@Z)
Error 43 error LNK2019: unresolved external symbol __imp_cosf referenced in function "float __cdecl cos(float)" (?cos@@YAMM@Z)
Error 46 error LNK2019: unresolved external symbol __imp_coshf referenced in function "float __cdecl cosh(float)" (?cosh@@YAMM@Z)
Error 33 error LNK2019: unresolved external symbol __imp_erfcf referenced in function "float __cdecl erfc(float)" (?erfc@@YAMM@Z)
Error 32 error LNK2019: unresolved external symbol __imp_erff referenced in function "float __cdecl erf(float)" (?erf@@YAMM@Z)
Error 8 error LNK2019: unresolved external symbol __imp_exp2f referenced in function "float __cdecl exp2(float)" (?exp2@@YAMM@Z)
Error 49 error LNK2019: unresolved external symbol __imp_expf referenced in function "float __cdecl exp(float)" (?exp@@YAMM@Z)
Error 9 error LNK2019: unresolved external symbol __imp_expm1f referenced in function "float __cdecl expm1(float)" (?expm1@@YAMM@Z)
Error 28 error LNK2019: unresolved external symbol __imp_fdimf referenced in function "float __cdecl fdim(float,float)" (?fdim@@YAMMM@Z)
Error 56 error LNK2019: unresolved external symbol __imp_floorf referenced in function "float __cdecl floor(float)" (?floor@@YAMM@Z)
Error 38 error LNK2019: unresolved external symbol __imp_fmaf referenced in function "float __cdecl fma(float,float,float)" (?fma@@YAMMMM@Z)
Error 7 error LNK2019: unresolved external symbol __imp_fmaxf referenced in function "float __cdecl fmax(float,float)" (?fmax@@YAMMM@Z)
Error 6 error LNK2019: unresolved external symbol __imp_fminf referenced in function "float __cdecl fmin(float,float)" (?fmin@@YAMMM@Z)
Error 57 error LNK2019: unresolved external symbol __imp_fmodf referenced in function "float __cdecl fmod(float,float)" (?fmod@@YAMMM@Z)
Error 19 error LNK2019: unresolved external symbol __imp_frexp referenced in function frexpf
Error 17 error LNK2019: unresolved external symbol __imp_ilogbf referenced in function "int __cdecl ilogb(float)" (?ilogb@@YAHM@Z)
Error 15 error LNK2019: unresolved external symbol __imp_ldexp referenced in function ldexpf
Error 34 error LNK2019: unresolved external symbol __imp_lgammaf referenced in function "float __cdecl lgamma(float)" (?lgamma@@YAMM@Z)
Error 25 error LNK2019: unresolved external symbol __imp_llrintf referenced in function "__int64 __cdecl llrint(float)" (?llrint@@YA_JM@Z)
Error 22 error LNK2019: unresolved external symbol __imp_llroundf referenced in function "__int64 __cdecl llround(float)" (?llround@@YA_JM@Z)
Error 51 error LNK2019: unresolved external symbol __imp_log10f referenced in function "float __cdecl log10(float)" (?log10@@YAMM@Z)
Error 11 error LNK2019: unresolved external symbol __imp_log1pf referenced in function "float __cdecl log1p(float)" (?log1p@@YAMM@Z)
Error 10 error LNK2019: unresolved external symbol __imp_log2f referenced in function "float __cdecl log2(float)" (?log2@@YAMM@Z)
Error 16 error LNK2019: unresolved external symbol __imp_logbf referenced in function "float __cdecl logb(float)" (?logb@@YAMM@Z)
Error 50 error LNK2019: unresolved external symbol __imp_logf referenced in function "float __cdecl log(float)" (?log@@YAMM@Z)
Error 24 error LNK2019: unresolved external symbol __imp_lrintf referenced in function "long __cdecl lrint(float)" (?lrint@@YAJM@Z)
Error 21 error LNK2019: unresolved external symbol __imp_lroundf referenced in function "long __cdecl lround(float)" (?lround@@YAJM@Z)
Error 52 error LNK2019: unresolved external symbol __imp_modff referenced in function "float __cdecl modf(float,float *)" (?modf@@YAMMPEAM@Z)
Error 26 error LNK2019: unresolved external symbol __imp_nearbyintf referenced in function "float __cdecl nearbyint(float)" (?nearbyint@@YAMM@Z)
Error 37 error LNK2019: unresolved external symbol __imp_nextafterf referenced in function "float __cdecl nextafter(float,float)" (?nextafter@@YAMMM@Z)
Error 53 error LNK2019: unresolved external symbol __imp_powf referenced in function "float __cdecl pow(float,float)" (?pow@@YAMMM@Z)
Error 30 error LNK2019: unresolved external symbol __imp_remainderf referenced in function "float __cdecl remainder(float,float)" (?remainder@@YAMMM@Z)
Error 31 error LNK2019: unresolved external symbol __imp_remquof referenced in function "float __cdecl remquo(float,float,int *)" (?remquo@@YAMMMPEAH@Z)
Error 23 error LNK2019: unresolved external symbol __imp_rintf referenced in function "float __cdecl rint(float)" (?rint@@YAMM@Z)
Error 20 error LNK2019: unresolved external symbol __imp_roundf referenced in function "float __cdecl round(float)" (?round@@YAMM@Z)
Error 18 error LNK2019: unresolved external symbol __imp_scalblnf referenced in function "float __cdecl scalbln(float,long)" (?scalbln@@YAMMJ@Z)
Error 44 error LNK2019: unresolved external symbol __imp_sinf referenced in function "float __cdecl sin(float)" (?sin@@YAMM@Z)
Error 47 error LNK2019: unresolved external symbol __imp_sinhf referenced in function "float __cdecl sinh(float)" (?sinh@@YAMM@Z)
Error 54 error LNK2019: unresolved external symbol __imp_sqrtf referenced in function "float __cdecl sqrt(float)" (?sqrt@@YAMM@Z)
Error 45 error LNK2019: unresolved external symbol __imp_tanf referenced in function "float __cdecl tan(float)" (?tan@@YAMM@Z)
Error 48 error LNK2019: unresolved external symbol __imp_tanhf referenced in function "float __cdecl tanh(float)" (?tanh@@YAMM@Z)
Error 35 error LNK2019: unresolved external symbol __imp_tgammaf referenced in function "float __cdecl tgamma(float)" (?tgamma@@YAMM@Z)
Error 27 error LNK2019: unresolved external symbol __imp_truncf referenced in function "float __cdecl trunc(float)" (?trunc@@YAMM@Z)
Error 2 error LNK2019: unresolved external symbol atexit referenced in function "void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXPEAPEAX@Z)
Error 5 error LNK2019: unresolved external symbol fabs referenced in function "double __cdecl abs(double)" (?abs@@YANN@Z)
Error 3 error LNK2019: unresolved external symbol labs referenced in function "long __cdecl abs(long)" (?abs@@YAJJ@Z)
Error 4 error LNK2019: unresolved external symbol llabs referenced in function "__int64 __cdecl abs(__int64)" (?abs@@YA_J_J@Z)
【问题讨论】:
这个article 可能很有趣。 【参考方案1】:您的主要问题似乎是您选择了错误的项目类型。可能您使用的是 MFC DLL 而不是常规的 Win32 项目(带有 DLL 选项)。但是,构建 MEX 文件需要更多设置,这些文件 (a) 使用作为并行计算工具箱一部分的 mxGPUArray
类型,并且 (b) 包含使用 NVIDIA CUDA 编译的 CUDA 内核(自定义 GPU 设备代码) SDK 编译器,nvcc。
假设您已经配置了通常的 MEX 相关设置,您选择 CUDA“构建自定义”来将 nvcc 配置为 .cu 文件的编译器。然后您可能还需要指定 CUDA 运行时库,同时通过选中“从父级或项目默认值继承”框确保您仍然拥有链接的所有标准 Windows 库依赖项:
它以这种方式编译和链接对我来说很好。
但是,我设置了我的 Visual Studio 项目using a property sheet (MATLAB.props) as described here。这将自动获得我上面提到的标准 MEX 设置。 编辑:我在属性表中添加了 Parallel Computing Toolbox 支持。您只需要添加如上所示的 cudart_static.lib 部分并选择 CUDA Build Customization 即可使用 nvcc 编译 .cu 文件。
通过 Build Customizations 添加 CUDA 6.5 SDK 设置。 首先,右键单击项目(不是解决方案):
检查您要使用的 CUDA 自定义(在本例中为 SDK 6.5):
如果您想编辑这些字段,请不要编辑它们:
【讨论】:
这个属性表不起作用,它给我一个错误,无效的属性表或添加它会导致循环继承。我尝试手动按照道具表中的设置列表进行操作,但这对我也不起作用。它需要什么设置才能工作,或者文件不工作? @SyedAlamAbbas 我刚刚更新了它,所以它可能已经破坏了它,尽管它对我有用。您能否尝试不支持并行工具箱的the previous version 并手动添加并行部分。让我知道更多关于错误的信息吗?如果这不起作用,那么还有其他问题。我想让它与并行计算工具箱一起工作。顺便说一句,开始一个新项目,然后添加它。顺便说一句,您是否将环境变量设置为指向 MATLAB 根目录? 是的,MATLAB 根设置正确,我从您的属性表中读取了配置设置,然后手动进行了所有设置。但正如我所说,它对我不起作用。这是我创建的项目,1. Win32 dll 如您的帖子所示。然后我尝试使用属性管理器添加您在 GitHub 上的属性表,然后我立即得到该错误。您在空白项目中没有收到该错误吗? 我试了以前的版本,还是一样的错误信息,“要么是无效的属性表,要么包含它会导致循环继承” 您的解决方案非常有效。您在创建 VC++ 项目时使用什么模板,您能详细说明一下吗?再次非常感谢。以上是关于使用 Visual Studio 2013 IDE 编译 CUDA Mex 文件的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft Visual Studio Professional 2013,变量在哪里定义和编辑?
C#基础总结 —— C#开发工具 Visual Studio(IDE)
Visual Studio 2013 为C#类文件添加版权信息