繁体   English   中英

与numpy相比,pyOpenCL获得了不同的结果

[英]pyOpenCL getting different results compared to numpy

我正在尝试开始使用pyOpenCL和GPGPU。

对于下面的dot产品代码,我在GPU和CPU版本之间得到了相当不同的结果。 我究竟做错了什么?

对于浮点误差,~0.5%的差异似乎很大,以解释差异。 这种差异似乎随阵列大小而增加(~9e-8相对差异,阵列大小为10000)。 也许这是跨区块结合结果的问题......? 无论哪种方式,让我感到不安。

我不知道它是否重要:我在MacBook Air,Intel(R)Core(TM)i7-4650U CPU @ 1.70GHz上使用Intel HD Graphics 5000运行。

提前致谢。

import pyopencl as cl
import numpy

from   pyopencl.reduction import ReductionKernel
import pyopencl.clrandom  as cl_rand

ctx   = cl.create_some_context()
queue = cl.CommandQueue(ctx)

dot = ReductionKernel( ctx,                                 \
                       dtype_out   = numpy.float32,         \
                       neutral     = "0",                   \
                       map_expr    = "x[i]*y[i]",           \
                       reduce_expr = "a+b",                 \
                       arguments   = "__global const float *x, __global const float *y"
                       )

x = cl_rand.rand(queue, 100000000, dtype = numpy.float32)
y = cl_rand.rand(queue, 100000000, dtype = numpy.float32)

x_dot_y     =       dot(x,y).get()        # GPU: array(25001304.0, dtype=float32)
x_dot_y_cpu = numpy.dot(x.get(), y.get()) # CPU:       24875690.0

print abs(x_dot_y_cpu - x_dot_y)/x_dot_y  # 0.0050496689740063489

在这两种方法之间,值减少的顺序可能会非常不同。 在大型数据集中,浮点舍入中的微小错误很快就会累加起来。 还可能存在影响结果精度的底层实现的其他详细信息。

我在自己的机器上运行你的示例代码,并在最终结果中得到类似的差异(~0.5%)。 作为一个数据点,您可以在原始Python中实现一个非常简单的点积,并查看它与OpenCL结果和Numpy的不同之处。

例如,您可以在示例中添加类似这样的简单内容:

x_dot_y_naive = sum(a*b for a,b in zip(x.get(), y.get()))

这是我在我的机器上得到的结果:

OPENCL: 25003466.000000
NUMPY:  24878146.000000 (0.5012%)
NAIVE:  25003465.601387 (0.0000%)

正如您所看到的,天真的实现比Numpy更接近OpenCL版本。 对此的一种解释可能是Numpy的dot函数可能使用融合乘法 - 加法(FMA)运算,这将改变中间结果舍入的方式。 如果没有任何编译器选项告诉它,OpenCL应该完全符合IEE-754标准,而不是使用更快的FMA操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM