Я пробую OpenCL и задавался вопросом, есть ли способ передать функции в качестве параметра в ядро или каково ближайшее доступное соответствие для него (с использованием OpenCL 1.2).
В качестве примера рассмотрим простую интеграцию Монте-Карло, например:
/* this is 1/(2^32) */
#define MULTI (2.3283064365386962890625e-10)
/* for more information see: https://arxiv.org/pdf/2004.06278v2.pdf*/
uint
squares(ulong ctr, ulong key)
{
ulong x, y, z;
y = x = ctr * key;
z = y + key;
x = x * x + y;
x = (x >> 32) | (x << 32); /* round 1 */
x = x * x + z; x = (x >> 32) | (x << 32); /* round 2 */
return (x * x + y) >> 32; /* round 3 */
}
void
kernel
reduce(ulong key,
float low,
float high,
global float* partialSums,
local float* localSums)
{
uint lid = get_local_id(0);
float rand = squares(get_global_id(0), key) * MULTI;
localSums[lid] = f((rand * (high - low)) + low);
for (uint stride = get_local_size(0) / 2; stride > 0; stride /= 2) {
barrier(CLK_LOCAL_MEM_FENCE);
if (lid < stride)
localSums[lid] += localSums[lid + stride];
}
if (lid == 0)
partialSums[get_group_id(0)] = localSums[0];
}
Я обнаружил Передача функции в качестве аргумента в OpenCL , которая сообщает мне, что передача указателей на функции не будет работать. Итак, я предполагаю, что будет работать, если генерировать исходный код ядра с f, определенным во время выполнения, а затем компилировать его (было ли это сделано раньше? Если да, то где мне его найти?). Может быть, эту проблему легче решить не с помощью OpenCL, а с помощью SYCL (о котором я практически ничего не знаю)?
Я относительно новичок в этом, поэтому, если такого рода проблемы решаются совершенно другим дайте мне знать.