3

我正在使用 parallel.gpu.CUDAKernel 在 Matlab 2011a 中启动 CUDA 内核。我已经设计了我的代码,使得相同的 gpuArray 应该由循环内的后续内核启动填充,但每次启动都将自身限制为 gpuArray 的唯一段。

到执行结束时,整个数组应该是满的。但是,当我使用gather() 将内存传输回主机时,只有上次内核启动写入的内存是正确的;其他一切都是空白的。如果我在中间某处跳出循环也是如此。

我已经通过传入一个标志来指示内核迭代来验证确实是这种情况。如果它是除了第一次迭代之外的任何东西,那么内核什么也不做。然而,第一个内核写入的数据位置仍然是空的,即使随后的内核什么都不做!如果我在启动第一个内核后直接跳出循环,情况就不是这样了。

因此,在我看来,Matlab 在内核启动之间重置了 gpuArray。有没有办法阻止它这样做?

4

1 回答 1

2

如果您捕获 feval 调用的输出,这应该可以工作。考虑这样一个简单的内核:

__global__ void setOneEl( double * array, double val, int element ) {
    array[element] = val;
}

然后,我相信你在 MATLAB 中运行以下代码:

>> k = parallel.gpu.CUDAKernel('kern.ptx');
>> g = parallel.gpu.GPUArray.zeros(1,10);
>> for ii = 1:2:10, g = k.feval(g, rand, ii); end
>> gather(g)
ans =
         0    0.0975         0    0.2785         0    0.5469         0    0.9575         0    0.9649

为了与普通 MATLAB 语义保持一致,gpuArray对象是基于值的,因此当您希望修改gpuArray实例时,您必须将输出值捕获回同一数组中,就像处理任何其他 MATLAB 数据类型一样。但是,请注意,CUDAKernel.feval当您将结果捕获到同一个变量中时,该调用可以理解,并且可以使用就地优化来避免复制。

于 2012-04-30T07:06:11.800 回答