在OpenCL中的clEnqueueReadBuffer函数问题 - 在数组求和示例中

时间:2015-06-14 07:55:24

标签: parallel-processing opencl

大家,    我是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有关,或许不是。关于这个问题的任何想法?期待你的建议! : - )

2 个答案:

答案 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。程序运行正常。

非常感谢你们! : - )