OpenCL создает ядро ​​из функции хоста во время выполнения - PullRequest
0 голосов
/ 02 августа 2020

Я пробую 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 (о котором я практически ничего не знаю)?

Я относительно новичок в этом, поэтому, если такого рода проблемы решаются совершенно другим дайте мне знать.

1 Ответ

1 голос
/ 03 августа 2020

создание исходного кода ядра с f, определенным во время выполнения, а затем его компиляция

Да, это можно сделать. Вы можете просто создать весь исходный код с нуля, а затем classi c clCreateProgram + clBuildProgram.

Другой вариант - разделить вашу программу на stati c и динамически сгенерированные части, а затем скомпилировать их отдельно во время выполнения через clCompileProgram (stati c часть только один раз), затем свяжите их оба с помощью clLinkProgram. Это могло бы быть несколько быстрее.

Возможно, эту проблему легче решить без использования OpenCL, но с помощью SYCL

на самом деле может быть сложнее решить с помощью SYCL; Я не уверен, поддерживает ли SYCL компиляцию динамического c (времени выполнения) вообще.

...