How to call boost_compute function 'BOOST_COMPUTE_FUNCTION'?

I am currently studying boost_compute. Unfortunately, there are fewer pages of documentation and examples than I need to understand what to do.

Given the following abbreviated code:

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 ); } 

How to call the "add" function and which iteration variable inside this function? Also, I need this code structure for more complex calculations.

Regards, Toni

+5
source share
1 answer

In short, boost:compute functions are not OpenCL kernel functions. They are more like OpenGL kernel functions.

I believe that your function accepts too many parameters that will be used with boost:compute algorithms.
However, a slightly simpler function, simply adding adjacent values ​​without a constant, would be:

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

And it could be called using boost::compute::transform , as @ddemidov suggested:

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

You may be able to implement your function using boost::compute::lambda functions. eg:.

 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); 

But it still does not match the set of values ​​...

Your function can be written as the OpenCL core in boost:compute using the macro 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; } ); 

After you have created your kernel program and created your kernel (using boost::compute::program ), you can set the kernel arguments separately and call the 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
source

Source: https://habr.com/ru/post/1262869/


All Articles