clSetKernelArg возвращает код ошибки -49
Я написал следующий код C++. В clSetKernelArg( kernel, 8, sizeof( cl_mem ), (void *) &mob_whdis );
, это возвращает error code -49
и я не понимаю почему. Все остальное работает правильно. Может кто-нибудь мне помочь?
cl_mem mob_X = NULL;
cl_mem mob_Y = NULL;
cl_mem mob_Z = NULL;
cl_mem mob_WAT = NULL;
cl_mem mob_POL = NULL;
cl_mem mob_FSW = NULL;
cl_mem mob_nop = NULL;
cl_mem mob_nofsw = NULL;
cl_mem mob_whdis = NULL;
cl_mem mob_watwp = NULL;
cl_mem mob_watp = NULL;
cl_mem mob_distp = NULL;
cl_mem mob_watww = NULL;
cl_mem mob_watw = NULL;
cl_mem mob_distw = NULL;
cl_program program = NULL;
cl_kernel kernel = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int err;
float whdis=3.5;
mob_X = clCreateBuffer( context, CL_MEM_READ_WRITE, na * sizeof(float), NULL, &err );
mob_Y = clCreateBuffer( context, CL_MEM_READ_WRITE, na * sizeof(float), NULL, &err );
mob_Z = clCreateBuffer( context, CL_MEM_READ_WRITE, na * sizeof(float), NULL, &err );
mob_WAT = clCreateBuffer( context, CL_MEM_READ_WRITE, now * sizeof(int), NULL, &err );
mob_POL = clCreateBuffer( context, CL_MEM_READ_WRITE, nop * sizeof(int), NULL, &err );
mob_FSW = clCreateBuffer( context, CL_MEM_READ_WRITE, now * sizeof(int), NULL, &err );
mob_nop = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int), NULL, &err );
mob_nofsw = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int), NULL, &err );
mob_whdis = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float), NULL, &err );
mob_watwp = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int) * now * 40, NULL, &err );
mob_watp = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int) * now * 40, NULL, &err );
mob_distp = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float) * now * 40, NULL, &err );
mob_watww = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int) * now * 40, NULL, &err );
mob_watw = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(int) * now * 40, NULL, &err );
mob_distw = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(float) * now * 40, NULL, &err );
err = clEnqueueWriteBuffer( command_queue, mob_X, CL_TRUE, 0, na * sizeof(float), X, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_Y, CL_TRUE, 0, na * sizeof(float), Y, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_Z, CL_TRUE, 0, na * sizeof(float), Z, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_WAT, CL_TRUE, 0, now * sizeof(int), wat, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_POL, CL_TRUE, 0, nop * sizeof(int), pol, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_FSW, CL_TRUE, 0, now * sizeof(int), fsw, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_nop, CL_TRUE, 0, sizeof(int), &nop, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_nofsw, CL_TRUE, 0, sizeof(int), &nofsw, 0, NULL, NULL );
err = clEnqueueWriteBuffer( command_queue, mob_whdis, CL_TRUE, 0, sizeof(float), &whdis, 0, NULL, NULL );
err_check( err, "clSetKernelArg" );
err = clSetKernelArg( kernel, 0, sizeof( cl_mem ), (void *) &mob_X );
err = clSetKernelArg( kernel, 1, sizeof( cl_mem ), (void *) &mob_Y );
err = clSetKernelArg( kernel, 2, sizeof( cl_mem ), (void *) &mob_Z );
err = clSetKernelArg( kernel, 3, sizeof( cl_mem ), (void *) &mob_WAT );
err = clSetKernelArg( kernel, 4, sizeof( cl_mem ), (void *) &mob_POL );
err = clSetKernelArg( kernel, 5, sizeof( cl_mem ), (void *) &mob_FSW );
err = clSetKernelArg( kernel, 6, sizeof( cl_mem ), (void *) &mob_nop );
err = clSetKernelArg( kernel, 7, sizeof( cl_mem ), (void *) &mob_nofsw );
err = clSetKernelArg( kernel, 8, sizeof( cl_mem ), (void *) &mob_whdis );
// Step 11: Execute OpenCL kernel in data parallel
size_t worksize[] = { now, 1, 1 };
clEnqueueNDRangeKernel( command_queue, kernel, 1, NULL, worksize, 0, 0, 0, 0 );
err_check( err, "clEnqueueNDRangeKernel" );
// Step 12: Read (Transfer result) from the memory buffer
2 ответа
Ошибка -49 есть CL_INVALID_ARG_INDEX
, Вы должны проверить свои исходные аргументы ядра opencl.
Кроме того, в вашем коде вы должны clCreateProgramWithSource
с исходным кодом OpenCL вашей программы, clBuildProgram
скомпилировать и связать его, а затем использовать clCreateKernel
чтобы получить действительную ссылку на ядро. И тогда вы можете использовать clSetKernelArg
должным образом.
Просто быстрый встречный вопрос:
mob_whdis - это буфер устройства, который имеет размер size (float). Это означает, что в глобальной памяти есть одно значение с плавающей точкой. Глобальная память сильно страдает при чтении и записи. Можете ли вы вместо этого использовать приватный конст, такой как:
float mob_whdis = 0.0f;... SetKernalArg (ядро, 8, sizeof(float) и &mob_whdis);
Это помещает константу с плавающей точкой во все ваши ядра, которые находятся в частной памяти, что очень быстро, намного быстрее, чем Global.
То же самое касается mob_nofsw и mob_nop.