5

如何初始化使用分配的设备数组cudaMalloc()

我试过cudaMemset了,但它无法初始化除 之外的所有值0.code,因为 cudaMemset 如下所示,其中值初始化为 5。

cudaMemset(devPtr,value,number_bytes)
4

2 回答 2

12

正如您所发现的,cudaMemset它的工作方式类似于 C 标准库memset。从文档中引用:

cudaError_t cudaMemset  (   void *      devPtr,
                            int         value,
                            size_t      count    
                        )           

用常量字节值填充 devPtr 指向的内存区域的第一个 count 字节。

字节value也是如此。如果您执行以下操作:

int *devPtr;
cudaMalloc((void **)&devPtr,number_bytes);
const int value = 5;
cudaMemset(devPtr,value,number_bytes);

您要求发生的事情是将 的每个字节设置devPtr为 5。如果devPtr是整数数组,则结果将是每个整数字的值都为 84215045。这可能不是您的想法。

使用运行时 API,您可以编写自己的通用内核来执行此操作。它可能很简单

template<typename T>
__global__ void initKernel(T * devPtr, const T val, const size_t nwords)
{
    int tidx = threadIdx.x + blockDim.x * blockIdx.x;
    int stride = blockDim.x * gridDim.x;

    for(; tidx < nwords; tidx += stride)
        devPtr[tidx] = val;
}

(标准免责声明:用浏览器编写,从未编译,从未测试,使用风险自负)。

只需为您需要的类型实例化模板并使用合适的网格和块大小调用它,注意最后一个参数现在是word count,而不是 byte count cudaMemset。这与无论如何都没有什么不同cudaMemset,使用该 API 调用会导致内核启动,这与我在上面发布的内容太不同了。

或者,如果您可以使用驱动程序 API,还有cuMemsetD16and cuMemsetD32,它们可以做同样的事情,但用于半和全 32 位字类型。如果您需要设置 64 位或更大的类型(所以双精度或向量类型),您最好的选择是使用您自己的内核。

于 2012-05-15T10:51:17.047 回答
1

我还需要这个问题的解决方案,但我并不真正理解其他提议的解决方案。特别是我不明白为什么它会迭代网格块for(; tidx < nwords; tidx += stride)以及内核调用以及为什么使用违反直觉的字长。

因此,我创建了一个更简单的单片通用内核并对其进行了大步定制,即您可以使用它以多种方式初始化矩阵,例如将行或列设置为任何值:

template <typename T>
__global__ void kernelInitializeArray(T* __restrict__ a, const T value, 
   const size_t n, const size_t incx) {
      int tid = threadIdx.x + blockDim.x * blockIdx.x;
      if (tid*incx < n) {
           a[tid*incx] = value;
       }
}

然后你可以像这样调用内核:

template <typename T>
void deviceInitializeArray(T* a, const T value, const size_t n, const size_t incx) {
      int number_of_blocks = ((n / incx) + BLOCK_SIZE - 1) / BLOCK_SIZE;
      dim3 gridDim(number_of_blocks, 1);
      dim3 blockDim(BLOCK_SIZE, 1);
      kernelInitializeArray<T> <<<gridDim, blockDim>>>(a, value, n, incx);
}
于 2014-01-24T08:19:39.477 回答