pyopencl 在数组中返回错误的 float3 值
Posted
技术标签:
【中文标题】pyopencl 在数组中返回错误的 float3 值【英文标题】:pyopencl returns wrong float3 values in array 【发布时间】:2013-01-28 20:13:38 【问题描述】:我的 pyopencl 程序的行为很奇怪,我认为我从 opencl 内核接收到不准确的值。
举个例子:
import pyopencl as cl
import pyopencl.array as cl_array
import numpy
from pyopencl.elementwise import ElementwiseKernel
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
n = 20
kernel = ElementwiseKernel(ctx,
"float3 *x",
"x[i] = (float3)(1,1,1)",
"assign")
x = numpy.empty(n, dtype=cl_array.vec.float3)
x_gpu = cl_array.to_device(queue, x)
kernel(x_gpu)
print x_gpu.get()
我希望它返回一个充满 (1, 1, 1)s 的数组。但是,输出如下所示:
[(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)
(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)
(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)
(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)
(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)]
或者像这样
[(1.0, 1.0, 1.0) (4.588972210970911e-41, 1.0, 1.0)
(1.0, 4.203895392974451e-45, 1.0) (1.0, 1.0, 1.3592595103950726e-43)
(1.0, 1.0, 1.0) (0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 0.0)
(1.0, 1.0, 1.0) (1.401298464324817e-45, 1.0, 1.0)
(1.0, 2.0795269210580285e-42, 1.0) (1.0, 1.0, 0.0) (1.0, 1.0, 1.0)
(0.0, 1.0, 1.0) (1.0, 0.0, 1.0) (1.0, 1.0, 1.401298464324817e-45)
(1.0, 1.0, 1.0) (4.792440747990874e-43, 1.0, 1.0) (1.0, 0.0, 1.0)
(1.0, 1.0, 0.0)]
我不确定这是 OpenCL、PyOpenCL 的问题还是我做错了什么。
感谢任何帮助。谢谢。
【问题讨论】:
我对 PyOpenCL 一无所知,但在 C 语言中,float *x; x[0]=1.0;
正在为您尚未分配的内存分配值,基本上 x 没有任何意义。
@GradyPlayer float3 *x
是 OpenCL 中内核函数的函数头,x[i] = (float3)(1,1,1)
是函数体。
函数头?我知道 C 语言中的 OpenCL……不知道这意味着什么。
【参考方案1】:
按照here 给出的建议,我已将所有代码更改为使用float4
而不是float3
,所有问题都消失了。
确实,这非常令人沮丧,但是我不鼓励使用任何与 3*sizeof() 对齐的类型,因为 GPU 不能很好地处理它。如果在主机端询问这些类型的大小,您将得到 sizeof(cl_float3) = sizeof(cl_float4)。因此,即使主机端没有正确使用它,它也会变得非常混乱,即使设备可以正确使用它。 GPU 针对对齐到 4 字节或 16 字节的类型进行了高度优化。即使您只需要一个向量中的 3 个变量,也可以使用 float4 并忽略最后一个元素。如果您不想浪费内存,请使用三个独立的浮点数组。
【讨论】:
【参考方案2】:根据official OpenCL specs,任何由 3 分量元素组成的向量都将被对齐,就好像每个元素都有 4 个分量一样。
6.1.5 类型对齐
在内存中声明为数据类型的数据项始终与数据类型的大小(以字节为单位)对齐。为了 例如,一个 float4 变量将与一个 16 字节的边界对齐,一个 char2 变量将与 2 字节边界对齐。对于 3 组分 矢量数据类型,数据类型的大小为 4 * sizeof(component)。 这意味着 3 分量矢量数据类型将与 4 * sizeof(component) 边界。
【讨论】:
以上是关于pyopencl 在数组中返回错误的 float3 值的主要内容,如果未能解决你的问题,请参考以下文章