Я пытаюсь добавить 2 трехмерных сложных массива с помощью библиотеки Python pyopencl. Результат, полученный на графическом процессоре, отличается от эталонного результата, полученного при использовании процессора. Почему код 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)