Anonymous
Ядро продукта Opencl Dot дает сбой при работе с конкретными данными
Сообщение
Anonymous » 21 янв 2026, 19:03
У меня есть ядро opencl, которое выполняет скалярное произведение. Когда я запускаю его на случайном массиве numpy, созданном rng.random, он дает процентную ошибку по сравнению с numpy, равную -0,011454765, но когда я запускаю его на (rng.random*10)-5)/1000, ошибка равна -72,45019. Что может быть причиной этого? Я думал, что исходная ошибка была вызвана различиями в округлении. Кажется, разница заключается в том, что значения равномерно распределены вокруг нуля. Возможно ли, что, будучи распределенным вокруг нуля, он вызывает выход ошибки с плавающей запятой? Или это что-то другое?
Код: Выделить всё
#!/usr/bin/env python
import numpy as np
import pyopencl as cl
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
a_x=4096
a_y=1
b_x=256
b_y=4096
knl_code = """
float get_from_2d_index(__global const float *a, int x, int y, int dim_x)
{
return a[(x*dim_x)+y];
}
int get_2d_index(int x, int y, int dim_x)
{
return (x*dim_x)+y;
}
__kernel void dot_knl_soft(__global const float *a, __global const float *b, __global float *o, uint2 a_dims, uint2 b_dims)
{
int2 gid = (int2)(get_global_id(0), get_global_id(1));
float rtn = 0;
for (int i = 0; i < a_dims.x; i++)
{
rtn += get_from_2d_index(a, gid.y, i, a_dims.x)*get_from_2d_index(b, i, gid.x, b_dims.x);
}
o[get_2d_index(gid.y, gid.x, a_dims.x)]=rtn;
}
"""
prg = cl.Program(ctx, knl_code).build()
rng = np.random.default_rng(12345)
a_np = rng.random((a_y,a_x), dtype=np.float32)
b_np = rng.random((b_y,b_x), dtype=np.float32)
b_np2 = ((rng.random((b_y,b_x), dtype=np.float32)*10)-5)/1000
o_np = np.empty((b_x, a_y), dtype=np.float32)
o_np2 = np.empty((b_x, a_y), dtype=np.float32)
a_g = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=a_np)
b_g = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=b_np)
b_g2 = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=b_np2)
o_g = cl.Buffer(ctx, mf.READ_WRITE, o_np.nbytes)
va = np.array((a_x, a_y), dtype=cl.cltypes.uint2)
vb = np.array((b_x, b_y), dtype=cl.cltypes.uint2)
prg.dot_knl_soft(queue, (b_x, a_y), None, a_g, b_g, o_g, va, vb)
cl.enqueue_copy(queue, o_np, o_g)
prg.dot_knl_soft(queue, (b_x, a_y), None, a_g, b_g2, o_g, va, vb)
cl.enqueue_copy(queue, o_np2, o_g)
answer_np = np.dot(a_np, b_np)
error = o_np-answer_np
print(f"Average error percentage:")
print(np.mean((error/answer_np)*100))
answer_np = np.dot(a_np, b_np2)
error_np = o_np2-answer_np
print(f"Average error percentage:")
print(np.mean((error_np/answer_np)*100))
Будем благодарны за любую помощь.
Изменить: в коде, который я загрузил сначала, был ошибочный расчет ошибок. Я обновил его, чтобы исправить это.
Подробнее здесь:
https://stackoverflow.com/questions/798 ... cific-data
1769011408
Anonymous
У меня есть ядро opencl, которое выполняет скалярное произведение. Когда я запускаю его на случайном массиве numpy, созданном rng.random, он дает процентную ошибку по сравнению с numpy, равную -0,011454765, но когда я запускаю его на (rng.random*10)-5)/1000, ошибка равна -72,45019. Что может быть причиной этого? Я думал, что исходная ошибка была вызвана различиями в округлении. Кажется, разница заключается в том, что значения равномерно распределены вокруг нуля. Возможно ли, что, будучи распределенным вокруг нуля, он вызывает выход ошибки с плавающей запятой? Или это что-то другое? [code]#!/usr/bin/env python import numpy as np import pyopencl as cl ctx = cl.create_some_context() queue = cl.CommandQueue(ctx) mf = cl.mem_flags a_x=4096 a_y=1 b_x=256 b_y=4096 knl_code = """ float get_from_2d_index(__global const float *a, int x, int y, int dim_x) { return a[(x*dim_x)+y]; } int get_2d_index(int x, int y, int dim_x) { return (x*dim_x)+y; } __kernel void dot_knl_soft(__global const float *a, __global const float *b, __global float *o, uint2 a_dims, uint2 b_dims) { int2 gid = (int2)(get_global_id(0), get_global_id(1)); float rtn = 0; for (int i = 0; i < a_dims.x; i++) { rtn += get_from_2d_index(a, gid.y, i, a_dims.x)*get_from_2d_index(b, i, gid.x, b_dims.x); } o[get_2d_index(gid.y, gid.x, a_dims.x)]=rtn; } """ prg = cl.Program(ctx, knl_code).build() rng = np.random.default_rng(12345) a_np = rng.random((a_y,a_x), dtype=np.float32) b_np = rng.random((b_y,b_x), dtype=np.float32) b_np2 = ((rng.random((b_y,b_x), dtype=np.float32)*10)-5)/1000 o_np = np.empty((b_x, a_y), dtype=np.float32) o_np2 = np.empty((b_x, a_y), dtype=np.float32) a_g = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=a_np) b_g = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=b_np) b_g2 = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=b_np2) o_g = cl.Buffer(ctx, mf.READ_WRITE, o_np.nbytes) va = np.array((a_x, a_y), dtype=cl.cltypes.uint2) vb = np.array((b_x, b_y), dtype=cl.cltypes.uint2) prg.dot_knl_soft(queue, (b_x, a_y), None, a_g, b_g, o_g, va, vb) cl.enqueue_copy(queue, o_np, o_g) prg.dot_knl_soft(queue, (b_x, a_y), None, a_g, b_g2, o_g, va, vb) cl.enqueue_copy(queue, o_np2, o_g) answer_np = np.dot(a_np, b_np) error = o_np-answer_np print(f"Average error percentage:") print(np.mean((error/answer_np)*100)) answer_np = np.dot(a_np, b_np2) error_np = o_np2-answer_np print(f"Average error percentage:") print(np.mean((error_np/answer_np)*100)) [/code] Будем благодарны за любую помощь. Изменить: в коде, который я загрузил сначала, был ошибочный расчет ошибок. Я обновил его, чтобы исправить это. Подробнее здесь: [url]https://stackoverflow.com/questions/79872305/opencl-dot-product-kernel-fails-on-specific-data[/url]