Как вызвать boost_compute определенной функции BOOST_COMPUTE_FUNCTION?

В настоящее время я изучаю boost_compute. К сожалению, страниц и примеров документации меньше, чем мне нужно, чтобы понять, что делать.

Учитывая следующий минимизированный код:

BOOST_COMPUTE_FUNCTION(bool, add, (int* values, int* results, int constant),
{
// Whats the indexing variable?
// In opencl it would be get_global_id(0)
int index = // ?

results[index] = values[index] + values[index + 1] + values[index + 2] + constant;
});

void compute(float* results, compute::context* ctx, compute::command_queue* queue)
{
compute::vector<float> device_values(100, *ctx);
compute::vector<float> device_results(98, *ctx);

compute::copy(
parameters->values.begin(), parameters->values.end(), device_values.begin(), *queue
);

// Actual computation
// HOW TO CALL 'add' for every device_results element?

compute::copy(
device_results.begin(), device_results.end(), results, *queue
);
}

Как вызвать функцию ‘add’ и что за переменная переменная внутри этой функции? Кроме того, мне нужна эта структура кода, чтобы сделать более сложный расчет.

С уважением,
Toni

5

Решение

Короче boost:compute функции не OpenCL функции ядра. Они больше похожи OpenGL функции ядра.

Я считаю, что ваша функция принимает слишком много параметров для использования с boost:compute алгоритмы.
Однако, немного более простая функция, просто добавляющая соседние значения без константы, была бы:

BOOST_COMPUTE_FUNCTION(boost::compute::float_, add,
(boost::compute::float_ values0, boost::compute::float_ values1),
{
return values0 + values1;
});

И может быть вызван с помощью boost::compute::transform как @ddemidov предложил:

boost::compute::transform(values.begin(), values.end() -1, // values0
values.begin() +1, // values1
results.begin(), // results
add, queue);

Может быть возможно реализовать вашу функцию, используя boost::compute::lambda функции. например.:

using namespace boost::compute::lambda;

float c = 1.234; // some constant

boost::compute::transform(values.begin(), values.end() -1, // values0
values.begin() +1, // values1
results.begin(), // results
_1 + _2 + c, queue);

Но это все еще не хватает набора ценностей …

Ваша функция может быть написана как OpenCL ядро в boost:compute с использованием BOOST_COMPUTE_STRINGIZE_SOURCE макрос:

const char kernel_function_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(

kernel void add(global float* values, global float* results, global float* constant)
{
size_t index = get_global_id(0);
results[index] = values[index] + values[index + 1] + values[index + 2] + *constant;
}

);

После того, как вы собрали программу ядра и создали ядро ​​(используя boost::compute::program), вы можете установить аргументы ядра индивидуально и вызвать boost::compute::command_queue enqueue_1d_range_kernel функция:

kernel.set_arg(0, values.get_buffer());
kernel.set_arg(1, results.get_buffer());
kernel.set_arg(2, &constant);
queue.enqueue_1d_range_kernel(kernel, 0, count, 0);
1

Другие решения

Других решений пока нет …