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

Parallel processing OpenCL中的clEnqueueReadBuffer函数问题-在数组和示例中,parallel-processing,opencl,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

各位,, 我是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 );
}
然而,我得到了错误的结果:c数组中的所有数字都是零。我认为这与克伦奎雷亚德缓冲区有关,也许不是。对这个问题有什么想法吗?期待您的建议!:-

对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在开始读取缓冲区之前等待内核事件完成。

。你所有的建议都很有帮助。在你的帮助下,我终于发现我做错了什么: clBuildProgram myProgram,1,&设备,NULL,NULL,&错误; 这是我的原始代码。 该功能的官方定义为: CLU int CLBUILD program CLU program, cl_uint num_设备, const cl_device_id*device_list, 常量字符*选项, 无效CL_回调*pfn_通知 cl_计划, void*用户_数据, void*用户数据 我发现我将参数列表的最后一个设置为&error;我把这个函数和其他一些函数混合在一起,它们的参数列表通常以错误号结尾。在这里,我应该这样称呼它: clBuildProgram myProgram,1,&设备,NULL,NULL,NULL; 最后一个设置为NULL。然后程序正常运行


非常感谢大家!:-

问题可能出现在调用clenqueueredbuffer之前。要获得一个idea,请在每次发出命令时检查错误变量。您是对的。检查之后,我发现错误源于内核创建失败。clCreateKernelsInProgram返回的错误号与CL_INVALID_KERNEL匹配,这是我的内核:uuu KERNEL void sum uuu global const char*a,uuu global const char*b,uuuu global char*c{int tid=get_global_id 0;c[tid]=a[tid]+b[tid];}当我调用clCreateKernelsInProgram myProgram时,NULL,NULL,NULL,&numbers,数字变为0!我不知道我在哪里处理不当。你是在同时调用clCreateKernel和CLCreateKernelsInProgramm吗?为什么?很抱歉我没有解释。在使用StackOverflow之后,我做了一些修改。我发现clEnqueueNDRangeKernel的返回值与CL_INVALID_KERNEL匹配。我最初使用的是clCreateKernel,在我发现内核排队失败后,添加了CLCreateKernelsInProgramm来查询可用内核的总数,然后我发现该数字为零,这意味着没有可用内核。基于这一点,我意识到造成这种情况的真正原因是一个早期的API调用。谢谢,你的建议是正确的,但我认为我的命令队列具有默认属性,将按顺序执行命令,因为我没有指定CL_OUT_of_ORDER_EXEC_MODE_ENABLE。好吧,我的错误,我总是使用这个标志,所以我习惯了程序以这种方式运行。