簡體   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