【问题标题】:pyOpenCL getting different results compared to numpy与 numpy 相比,pyOpenCL 得到不同的结果
【发布时间】:2014-10-01 14:22:03
【问题描述】:

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

对于下面的点积代码,我在 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

【问题讨论】:

    标签: python numpy opencl pyopencl


    【解决方案1】:

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

    我已经在我自己的机器上运行了您的示例代码,并在最终结果中获得了类似的差异 (~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 操作。

    【讨论】:

    • 谢谢@jprice!我接受了这个作为答案。看起来是使用 pyOpenCL/pyCuda 进行繁重工作的另一个原因!
    • 仅供参考——我在 MATLAB 中进行了类似的测试,但无法使用其 GPU 实现,因为 AFAIK,它基于 Cuda,而我的 GPU 未启用 Cuda。结果如下:
    • 天真:1.4725e+04 MATLAB:1.4725e+04(3.8913e-14 差异)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2021-05-17
    • 2021-07-19
    相关资源
    最近更新 更多