大家, 我是OpenCL的初学者,我在C中编写了一些简单的代码,它总结了两个数组。以下是代码的一部分:
// Create Kernel.
cl_kernel kernelSum = clCreateKernel( myProgram, "sum", &error );
// Set Input Array.
size_t arraySize = 1000;
char* a = ( char* ) malloc( sizeof( char ) * arraySize );
char* b = ( char* ) malloc( sizeof( char ) * arraySize );
char* c = ( char* ) malloc( sizeof( char ) * arraySize );
for (int i = 0; i < arraySize; i += 1)
{
a[ i ] = 1;
b[ i ] = 2;
c[ i ] = -1;
}
// Set Buffers.
cl_mem a_buffer = clCreateBuffer(
myContext,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
arraySize * sizeof( char ), a,
&error );
cl_mem b_buffer = clCreateBuffer(
myContext,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
arraySize * sizeof( char ), b,
&error );
cl_mem c_buffer = clCreateBuffer(
myContext,
CL_MEM_WRITE_ONLY,
arraySize * sizeof( char ), NULL,
&error );
printf( "Buffers created.\n" );
// Setting Kernel Arguments.
error = clSetKernelArg( kernelSum, 0, sizeof( cl_mem ), &a_buffer );
error |= clSetKernelArg( kernelSum, 1, sizeof( cl_mem ), &b_buffer );
error |= clSetKernelArg( kernelSum, 2, sizeof( cl_mem ), &c_buffer );
printf( "Arguments Set.\n" );
// Enqueue kernels to execute.
cl_event event;
size_t globalWorkOffset = 0;
size_t globalWorkSize[ 1 ] = { arraySize };
size_t localWorkSize[ 1 ] = { 1 };
clEnqueueNDRangeKernel(
myCommandQueue,
kernelSum,
1, // work_dim
0, // global work offset
globalWorkSize,
localWorkSize, // local work offset
0, NULL,
&event
);
printf( "Kernel Enqueued.\n" );
error = clEnqueueReadBuffer(
myCommandQueue,
c_buffer,
CL_TRUE, // blocking option
( size_t ) 0, arraySize * sizeof( char ), // offset, data_size
c, // host_ptr
0, NULL,
&event );
if ( error != CL_SUCCESS )
{
printf( "Buffer Reading Back Failed.\n" );
exit( 1 );
}
然而,我的结果不正确:&#34; c&#34;中的所有数字数组为零。我认为这与clEnqueueReadBuffer有关,或许不是。关于这个问题的任何想法?期待你的建议! : - )
答案 0 :(得分:0)
您对clEnqueueReadBuffer
的调用不会等待内核完成。它很可能与内核同时执行。将通话更改为:
error = clEnqueueReadBuffer(
myCommandQueue,
c_buffer,
CL_TRUE, // blocking option
( size_t ) 0, arraySize * sizeof( char ), // offset, data_size
c, // host_ptr
1, &event,
NULL );
这将导致clEnqueueReadBuffer
在开始读取缓冲区之前等待内核事件完成。
答案 1 :(得分:0)
的所有人。您的所有建议都非常有用。在你的帮助下,我终于找到了我做错了什么: clBuildProgram(myProgram,1,&amp; device,NULL,NULL,&amp; error); 这是我的原始代码。 该功能的官方定义是: cl_int clBuildProgram(cl_program program, cl_uint num_devices, const cl_device_id * device_list, const char *选项, void(CL_CALLBACK * pfn_notify) (cl_program程序, void * user_data), void * user_data) 我发现我将参数列表的最后一个设置为“&amp; error”;我将此函数与其他一些函数混合在一起,其参数列表通常以错误号结尾。在这里,我应该这样称呼它: clBuildProgram(myProgram,1,&amp; device,NULL,NULL,NULL); 最后一个设置为NULL。程序运行正常。
非常感谢你们! : - )