【问题标题】:Maintaining gpuArray data between CUDA kernel launches in Matlab在 Matlab 中维护 CUDA 内核启动之间的 gpuArray 数据
【发布时间】:2012-04-27 22:51:07
【问题描述】:

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

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

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

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

【问题讨论】:

  • 并行计算工具箱中的 gpuArray 不是很实用。你最好使用夹克。虽然我因为在 Jacket 上工作而有偏见,但当我说你不应该在 gpuArray 上浪费时间时,我并不是在开玩笑。如果您不打算使用 Jacket,最好还是坚持使用 CPU 或编写所有自己的 CUDA 代码。
  • 这似乎是一个很棒的产品。不幸的是,作为一名学生,我仅限于免费软件和我的大学提供的软件。现在我将尝试编写一个 mex 接口。
  • 听起来不错。如果您向 IT 部门发送通知,要求他们购买 Jacket,他们可能会这样做。事实上,他们可能已经拥有 Jacket 许可证(大多数大学现在都有一些 Jacket 许可证)。

标签: matlab cuda


【解决方案1】:

如果您捕获 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 调用可以理解您何时将结果捕获到同一个变量中,并且可以使用就地优化来避免复制。

【讨论】:

    猜你喜欢
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2012-02-24
    • 1970-01-01
    • 2012-10-28
    • 2013-07-15
    • 2012-08-23
    相关资源
    最近更新 更多