在CUDA中初始化设备阵列

use*_*567 5 memory-management cuda

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

我尝试了cudaMemset,但它无法初始化所有值,除了0.code,因为cudaMemset如下所示,其中value初始化为5.

cudaMemset(devPtr,value,number_bytes)
Run Code Online (Sandbox Code Playgroud)

tal*_*ies 10

正如您所发现的那样,它的cudaMemset工作方式与C标准库类似memset.引用文档:

cudaError_t cudaMemset  (   void *      devPtr,
                            int         value,
                            size_t      count    
                        )           
Run Code Online (Sandbox Code Playgroud)

使用常量字节值填充devPtr指向的内存区域的第一个计数字节.

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

int *devPtr;
cudaMalloc((void **)&devPtr,number_bytes);
const int value = 5;
cudaMemset(devPtr,value,number_bytes);
Run Code Online (Sandbox Code Playgroud)

你问发生的是,每一个字节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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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