C++ 的问题CUDA-Matlab 编译中的指针
嘿, 我有以下代码片段:
double *f;
f = a_function(parameters...);
printf("%f", *(f+1));
loopAry(f, 5);
void loopAry(double *in, int size)
{
printf("%f\n", *(in+1));
for(int i = 0; i < size; i++)
{
printf("\nin[%d]=%f ", i, *(in+i));
}
}
(matlab 中的 mex 文件)。现在的问题是:在如何编译带有 CUDA 的 mex 文件之前,我已经找到了两种解决方案,并且我发现当我用第一种方法编译它时,上面的代码可以正常工作,如果我用第二种方法,代码无法运行。 现在我想知道,如果代码包含任何可疑的内容,最终可能会导致一些问题?
方法一执行输出(这是正确的行为):
1.000000 1.000000
in[0]=1.000000
in[1]=1.000000
in[2]=1.000000
in[3]=1.000000
in[4]=1.000000
第二个执行以下操作:
1.000000 0.000000
in[0]=0.000000
in[1]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[2]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[3]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[4]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
因此传递通过指针传递数据,因为第二个元素的输出 (printf("%f", *(fVec0_+1));
) 按预期工作...但是致电后不 loopArray()
...
澄清两种编译方法: 第一(工作中) 执行此脚本: http://www-europe.mathworks.com/matlabcentral /fileexchange/25314-cuda-mex 生成一个新的 m 文件,像通常的 mex 脚本一样进行编译(仅包含 CUDA):-)
第二(不工作) (发现于 http://forums.nvidia.com/index.php?showtopic=172175< /a>)
function nvc(filename)
options='-arch=sm_21';
options=[options ' --use_fast_math'];
txt=sprintf('"C:\\Program Files (x86)\\NVIDIA GPU Computing Toolkit\\CUDA\\v3.2\\bin\\nvcc" %s.cu %s -c -lcufft -lcudart -lcublas -lcuda --ptxas-options=-v -IJ:\\MATLAB32bitR2010b\\extern\\include\\',filename,options);
system(txt)
mex_options='-O'; % enable optimisation
n=getenv('CUDA_LIB_PATH');
mex(['-L' n],mex_options,'-lcudart','-lcufft','-lcublas','-lcuda',sprintf('%s.obj',filename));
delete(sprintf('%s.obj',filename));
编辑 这是返回指针的函数:
double *a_function(const mxArray *point)
{
double *dat = mxGetPr(point);
double vals[ 5 ] = {
dat[0]*dat[0]*dat[0],
dat[1]*dat[1]*dat[1],
dat[2]*dat[2]*dat[2],
dat[3]*dat[3]*dat[3],
dat[4]*dat[4]*dat[4]};
double *pnt = vals;
return pnt;
}
Hey there,
I have the following code-snippet:
double *f;
f = a_function(parameters...);
printf("%f", *(f+1));
loopAry(f, 5);
void loopAry(double *in, int size)
{
printf("%f\n", *(in+1));
for(int i = 0; i < size; i++)
{
printf("\nin[%d]=%f ", i, *(in+i));
}
}
(mex-file in matlab). Now the problem is: I have found two solutions before how to compile mex-files with CUDA in it and I figured out that when I compile it with the first method, the above code works as it should, and if I compile it with the second method, the code just doesn't run. Now I wonder, if the code contains anything suspicious what COULD eventually cause some problems?
Method one does the output (this is correct behaviour):
1.000000 1.000000
in[0]=1.000000
in[1]=1.000000
in[2]=1.000000
in[3]=1.000000
in[4]=1.000000
and the second does the following:
1.000000 0.000000
in[0]=0.000000
in[1]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[2]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[3]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
in[4]=90932971983710041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
so there's something wrong with passing the data via pointer, since the output of the the second element (printf("%f", *(fVec0_+1));
) works as it is supposed to work... but NOT after calling loopArray()
...
To clarify the two compiling methods:
FIRST (working)
Execute this script: http://www-europe.mathworks.com/matlabcentral/fileexchange/25314-cuda-mex which makes a new m-file to compile like the usual mex-script (just with CUDA included) :-)
SECOND (not working)
(found on http://forums.nvidia.com/index.php?showtopic=172175)
function nvc(filename)
options='-arch=sm_21';
options=[options ' --use_fast_math'];
txt=sprintf('"C:\\Program Files (x86)\\NVIDIA GPU Computing Toolkit\\CUDA\\v3.2\\bin\\nvcc" %s.cu %s -c -lcufft -lcudart -lcublas -lcuda --ptxas-options=-v -IJ:\\MATLAB32bitR2010b\\extern\\include\\',filename,options);
system(txt)
mex_options='-O'; % enable optimisation
n=getenv('CUDA_LIB_PATH');
mex(['-L' n],mex_options,'-lcudart','-lcufft','-lcublas','-lcuda',sprintf('%s.obj',filename));
delete(sprintf('%s.obj',filename));
EDIT
This is the function which returns the pointer:
double *a_function(const mxArray *point)
{
double *dat = mxGetPr(point);
double vals[ 5 ] = {
dat[0]*dat[0]*dat[0],
dat[1]*dat[1]*dat[1],
dat[2]*dat[2]*dat[2],
dat[3]*dat[3]*dat[3],
dat[4]*dat[4]*dat[4]};
double *pnt = vals;
return pnt;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将数组声明为局部变量,该变量将在函数末尾超出范围。
f
指针指向数组曾经所在但现在不再所在的位置。您应该动态分配数组:
使用完数组后,再次删除它:
You declare the array as a local variable that will go out of scope at the end of the function. The
f
pointer than points to the location where the array used to be but isn't anymore.You should dynamically allocate the array:
When you are done with the array, delete it again:
函数
a_function
返回一个在其堆栈上分配的数组。一旦a_function
返回,该数组就无效。在某些情况下——编译器标志会影响这一点——数组看起来部分或全部可用,但严格来说它是垃圾。如果需要从函数返回指向数组的指针,则必须使用 new 来分配该数组。The function
a_function
is returning an array that's allocated on its stack. As soon asa_function
returns, the array is invalid. Under some circumstances -- and compiler flags will affect this -- the array will appear to be partially or wholly available, but strictly it's garbage. You must allocate the array usingnew
if you need to return a pointer to it from a function.