【问题标题】:cuda device function that return array返回数组的 cuda 设备函数
【发布时间】:2018-12-10 12:07:57
【问题描述】:

尝试为此找到解决方案: Cuda Kernel 使用了几个设备函数,其中一些需要返回数组。

我尝试这样做:

__device__ float *MatProd2dWxC(float *a2d, float  *b2d, int mGl, int nGl)
{
    int aRows = mGl; int aCols = nGl;
    int bRows = nGl; int bCols = 1;

    float *result;
    //result.resize(mGl*aRows);

    for (int i = 0; i < aRows; ++i) // each row of a
        for (int j = 0; j < bCols; ++j) // each col of b
            for (int k = 0; k < aCols; ++k) 
                result[i*mGl + j] += a2d[i*mGl + k] * b2d[k*mGl + j];

    return result;
}

不要编译这个,因为函数名中的指针不是好主意。但是如何做正确的事情,包括额外的临时数组并将函数更改为无效。但后来我需要在内核代码中多次使用它,寻找更优雅的解决方案。

【问题讨论】:

    标签: cuda


    【解决方案1】:

    从设备函数返回一个指针是可以的,而且工作得很好。

    您的代码中的问题是您没有为 result 指针分配任何值,然后您取消引用并稍后从函数返回。你需要使用float *result = malloc(mGl*aRows * sizeof(float));来分配内存(以后别忘了free()!)。

    然而更好的设计是将一个已经分配的指针传入你的设备函数。这建立了分配的明确所有权(即在您的代码中明确应该调用 free() 的位置),并且在某些情况下可以避免不必要的分配,例如分配可以被拉到循环之外。

    这个问题与 CUDA 无关,它也适用于标准 C。

    【讨论】:

    • 感谢您的回答。此函数将在每个线程中使用,因此result 需要每个线程独立,因此是否可以不从__host__ 而是从__device__ 侧分配它以排除冲突?
    • 更详细的Kernel需要计算下一个公式ft2d = MatSig2d(MatSum2d(MatProd2dWx(Wf2d, xt2d,m,n), MatProd2dUh(Uf2d, h_prev2d.m,n), bf2d));,所以建议直接把result放在公式中
    • 我认为,你是对的,制作 3d 数组:线程的 2d +1 附加维度
    • 如果将指针传递给函数(而不是 malloc() 将其放入内部并返回它),则可以使用自动数组,该数组在堆栈上分配。这比为其线程使用额外维度要高效得多,因为堆栈分配将仅用于所有 同时运行的线程,而您的 3d 数组将为 all i> 线程。当然,在堆栈上分配也会限制您使用相当小的数组。在这种情况下,您可能需要增加堆栈大小。
    • 我需要 2500 个元素附近的数组,这个 50x50 二维数组,这适合堆栈吗?以及如何将指针传递给函数,如果我需要通过内核将数组的大小发送给函数。
    猜你喜欢
    • 2017-10-29
    • 2015-03-11
    • 1970-01-01
    • 2014-08-04
    • 2015-09-09
    • 2012-05-22
    • 2014-02-15
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多