【发布时间】:2020-07-03 14:24:18
【问题描述】:
我正在尝试在 python 库 pyopencl 的帮助下添加 2 个三维复杂数组。在 gpu 上获得的结果与使用 cpu 获得的参考结果不同。为什么 GPU 代码不提供复数的正确加法?我希望相应的变量 res 和 ref 彼此相等。我使用的代码:
import pyopencl as cl
import numpy as np
from numpy.fft import fftn, ifftn
from numpy.random import random, normal
import os
os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
Lx = 100
Ly = 100
Lz = 1
L = Lx * Ly * Lz
const = np.zeros(4).astype(np.float32)
const[0] = Lx
const[1] = Ly
const[2] = Lz
const[3] = L
const_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=const)
arr1 = np.random.rand(Lz, Ly, Lx).astype(np.float32)
arr2 = np.random.rand(Lz, Ly, Lx).astype(np.float32)
F1 = fftn(arr1)
F2 = fftn(arr2)
out = np.zeros((Lz,Ly,Lx)).astype(np.complex64)
out_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, out.nbytes)
do_it_code = """
#include <pyopencl-complex.h>
__kernel void doit(__global const float *constants,
__global const cfloat_t *IN1,__global const cfloat_t *IN2,
__global cfloat_t *out)
{ int z = get_global_id(0);
int y = get_global_id(1);
int x = get_global_id(2);
const int len = constants[3];
const int lx = constants[0];
const int ly = constants[1];
const int lz = constants[2];
const int pl = lx * ly;
int i = x + y * lx + z * pl;
if (x <= lx-1 && y <= ly-1 && z <= lz-1) {
out[i] = cfloat_add(IN1[i],IN2[i]);
};
};
"""
bld_do_it = cl.Program(ctx, do_it_code).build()
def do_it(a,b):
a_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=a.astype(np.complex64))
b_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=b.astype(np.complex64))
launch = bld_do_it.doit(queue, a.shape, None, const_buf, a_buf, b_buf, out_buf)
launch.wait()
cl.enqueue_copy(queue, out, out_buf)
return out
ref=F1+F2
print(ref)
print("_________")
res=do_it(F1,F2)
print(res)
【问题讨论】:
-
结果的差异似乎是逗号后面的几位数字,这表明这可能是由于 CPU 和加速器上的不同 FPU 单元造成的。查看更多here
-
不,区别不仅仅是逗号后面的几个数字。
-
是的,你是对的,还有更多——看我的回答。
标签: python complex-numbers pyopencl