【问题标题】:Problems with C++ Pointers in CUDA-Matlab compilationCUDA-Matlab 编译中的 C++ 指针问题
【发布时间】:2011-08-21 18:56:42
【问题描述】:

你好, 我有以下代码-sn-p:

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));) 的输出按预期工作...但是在调用 @987654327 后 不是 @...

澄清两种编译方法: FIRST(工作中) 执行这个脚本:http://www-europe.mathworks.com/matlabcentral/fileexchange/25314-cuda-mex 生成一个新的 m 文件,像通常的 mex 脚本一样编译(只包括 CUDA):-)

SECOND(不工作) (发现于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));

编辑 这是返回指针的函数:

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;
}

【问题讨论】:

  • a_function如何创建它返回的数组?
  • 哦,谢谢你指点我,我现在就在第一篇文章中发布!
  • 您是否收到任何 CUDA 错误?是否有任何设备代码开头?
  • 目前我没有在这段代码中使用 CUDA;但我将编译器设置为与 CUDA 一起编译,因为我想尽快集成 CUDA :)

标签: c++ matlab pointers cuda


【解决方案1】:

您将数组声明为将在函数末尾超出范围的局部变量。 f 指针指向数组曾经存在但不再存在的位置。

你应该动态分配数组:

double *vals = new double[5];
vals[0] = dat[0]*dat[0]*dat[0];
vals[1] = dat[1]*dat[1]*dat[1];
// ... 

// Or use a for-loop for the initialization:
for (int i=0; i<5; i++)
   vals[i] = dat[i]*dat[i]*dat[i];

当你完成数组后,再次删除它:

delete[] f;

【讨论】:

  • 谢谢!所以我会有double *vals = new double[5]; vals = { CODE FROM ABOVE ... }; *pnt = vals; return pnt; 对吗? :-) 编辑:好的,谢谢,所以没有办法一步完全初始化它?
  • @Col:在这种情况下,您不能使用 {...} 初始化语法,而必须“手动”初始化 val[0] = ... 之类的值。我将其添加到我的答案中的代码中。
  • 刚看到。很遗憾,但还好,还不错:-) 还有一个问题:delete[] f; 必须在我不再需要f 的程序的真正末尾,对吗? 编辑:所以这是普遍现象?每次我有一个返回数组的函数时,我都需要动态创建它并返回一个指向它的指针?
  • @Col:当你完成数组并且内存可以再次用于其他事情时,请执行delete[]。当您调用 a_function 时使用 new double[5] 分配的每个数组都应该在不再使用时使用 delete[] 释放。
  • 您必须在每个循环结束时删除fdelete[] 不会删除 f 本身,它会删除 f 指向的数组。由于每次调用a_function 都会创建一个新数组,因此需要删除这些数组中的每一个。否则所有这些数组仍然存在并耗尽内存,即使没有人再使用它们了。 “非动态”与“动态”数组之间的区别在于stack and the heap 上的分配。 a_func 返回一个指向栈上数组的指针,new 在堆上分配。
【解决方案2】:

函数a_function 正在返回一个分配在其堆栈上的数组。只要a_function 返回,数组就无效了。在某些情况下——编译器标志会影响这一点——数组似乎部分或全部可用,但严格来说它是垃圾。如果需要从函数返回指向数组的指针,则必须使用 new 分配数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-02
    • 2023-01-19
    • 2011-09-08
    • 1970-01-01
    • 2014-07-19
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多