عالق حول سبب عدم تنفيذ kernel opencl الخاص بي مع معلمات معينة
سؤال
لدي نواة opencl التي أديرها في JOCL وهي تجتاز جميع اختبارات Junit الخاصة بي. قمت بنقل الكود الخاص بي إلى C ++ حتى أتمكن من ملف تعريف kernel في نفس الظروف. يعمل السائق بشكل جيد في جميع الحالات باستثناء حالة واحدة. إنه يعمل بشكل جيد تمامًا في JOCL ، لذا أعتقد أن شيئًا ما في رمز C ++ الخاص بي خاطئ. الكود الخاص بي أدناه ، لقد قمت بمراجعته حتى الموت. إذا كان بإمكان أي شخص مساعدتي في اكتشاف ما هو الخطأ ، فسأقدر ذلك.
يعمل رمز السائق بشكل جيد مع Args 1 و 2 AS 8192 ، Arg 3 AS 512. كما أنه يعمل بشكل جيد مع Args 1 و 2 AS 512 و Arg 3 AS 8192. Arg 4 هو دائمًا 1 ، وهو ما يضع kernel على أرقام حقيقية. عندما قمت بتعيين args 1 و 2 إلى 262144 و Arg 3 إلى 16 ، يتم تنفيذها ، لا يتم الإبلاغ عن أي أخطاء ، ولا توجد أخطاء SEG ، لكن kernel لا يغير البيانات في النهاية. لاحظ أن Arg 1*3 في جميع الحالات أعلاه يساوي 2^22. أعتقد أنني أقوم بتخصيص نفس كمية العوامات في جميع الحالات. أنا متعثر. لا يمكنني الحصول على opencl لأخبرني ما هو الخطأ :(
void HelperFunctions::callKernel(int windowSize, int primitivesPerDataFrame, int nInFramesThisCall, int realOrComplex)
{
// OpenCL Vars
cl_platform_id platform; // OpenCL platform
cl_device_id device; // OpenCL device
cl_context gpuContext; // OpenCL context
cl_command_queue commandQueue; // OpenCL command queue
cl_program clProgram; // OpenCL program
cl_kernel clkernel; // OpenCL kernel
void *dataHostBuffer; // Host buffer
void *windowDataHostBuffer; // Host buffer
cl_mem inData; // OpenCL device buffer
cl_mem windowData; // OpenCL device source buffer
size_t szKernelLength; // Byte size of kernel code
cl_int errCode; // Error code var
long gridX = 256;
long gridY = 16384;
long gridZ = 1;
size_t global_work_size[] = {gridX, gridY, gridZ};
size_t local_work_size[] = {gridX, 1, 1};
const char* cSourceCL = NULL; // Buffer to hold source for compilation
// Allocate and initialize host arrays
dataHostBuffer = (void *)malloc(sizeof(cl_float) * primitivesPerDataFrame * nInFramesThisCall);
windowDataHostBuffer = (void *)malloc(sizeof(cl_float) * windowSize);
//Populate the data buffers
dataHostBuffer = generateRampData(primitivesPerDataFrame * nInFramesThisCall);
windowDataHostBuffer = blackman(windowSize);
//Get an OpenCL platform
errCode = clGetPlatformIDs(1, &platform, NULL);
cout << "Error Code: " << errCode << endl;
//Get the devices
errCode = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
cout << "Error Code: " << errCode << endl;
//Create the context
gpuContext = clCreateContext(0, 1, &device, NULL, NULL, &errCode);
cout << "Error Code: " << errCode << endl;
// Create a command-queue
commandQueue = clCreateCommandQueue(gpuContext, device, 0, &errCode);
// Read the OpenCL kernel in from source file
cSourceCL = oclLoadProgSource("/home/djkasht/workspaceBlueprint/bp/bp-trunk/bundles/CopperShark/src/coppershark/dsp/blocks/opencl/dsp/window/Window.cl", "", &szKernelLength);
szKernelLength = strlen(cSourceCL);
// Create the program
clProgram = clCreateProgramWithSource(gpuContext, 1, (const char **)&cSourceCL, &szKernelLength, &errCode);
cout << "Error Code: " << errCode << endl;
// Build the program
errCode = clBuildProgram(clProgram, 0, NULL, NULL, NULL, NULL);
cout << "Error Code: " << errCode << endl;
size_t log_size = 1000000 * sizeof(char);
char build_log[log_size];
size_t len;
errCode = clGetProgramBuildInfo(clProgram, device, CL_PROGRAM_BUILD_LOG, log_size, build_log, &len);
cout << build_log << endl;
// Create the kernel
clkernel = clCreateKernel(clProgram, "window", &errCode);
cout << "Error Code: " << errCode << endl;
// Allocate the OpenCL buffer memory objects
inData = clCreateBuffer(gpuContext, CL_MEM_READ_WRITE, sizeof(cl_float) * primitivesPerDataFrame * nInFramesThisCall, NULL, &errCode);
cout << "Error Code: " << errCode << endl;
windowData = clCreateBuffer(gpuContext, CL_MEM_READ_ONLY, sizeof(cl_float) * windowSize, NULL, &errCode);
cout << "Error Code: " << errCode << endl;
// Set the Argument values
errCode = clSetKernelArg(clkernel, 0, sizeof(cl_mem), (void*)&inData);
cout << "Error Code: " << errCode << endl;
errCode = clSetKernelArg(clkernel, 1, sizeof(cl_mem), (void*)&windowData);
cout << "Error Code: " << errCode << endl;
errCode = clSetKernelArg(clkernel, 2, sizeof(cl_int), (void*)&windowSize);
cout << "Error Code: " << errCode << endl;
errCode = clSetKernelArg(clkernel, 3, sizeof(cl_int), (void*)&primitivesPerDataFrame);
cout << "Error Code: " << errCode << endl;
errCode = clSetKernelArg(clkernel, 4, sizeof(cl_int), (void*)&nInFramesThisCall);
cout << "Error Code: " << errCode << endl;
errCode = clSetKernelArg(clkernel, 5, sizeof(cl_int), (void*)&realOrComplex);
cout << "Error Code: " << errCode << endl;
// Asynchronous write of data to GPU device
errCode = clEnqueueWriteBuffer(commandQueue, inData, CL_FALSE, 0, sizeof(cl_float) * primitivesPerDataFrame * nInFramesThisCall, dataHostBuffer, 0, NULL, NULL);
cout << "Error Code: " << errCode << endl;
// Synchronous/blocking read of results, and check accumulated errors
errCode = clEnqueueWriteBuffer(commandQueue, windowData, CL_FALSE, 0, sizeof(cl_float) * windowSize, windowDataHostBuffer, 0, NULL, NULL);
cout << "Error Code: " << errCode << endl;
errCode = clEnqueueNDRangeKernel(commandQueue, clkernel, 3, NULL, &(global_work_size[0]), &(local_work_size[0]), 0, NULL, NULL);
cout << "Error Code: " << errCode << endl;
void* dataHostBuffer2 = (void *)malloc(sizeof(cl_float) * primitivesPerDataFrame * nInFramesThisCall);
errCode = clEnqueueReadBuffer(commandQueue, inData, CL_TRUE, 0, sizeof(cl_float) * primitivesPerDataFrame * nInFramesThisCall, dataHostBuffer2, 0, NULL, NULL);
}
المحلول
تحديث ، لقد اكتشفت ذلك! المشكلة في نواة بلدي. أستخدم ذاكرة ثابتة. يمثل رمز Java الخاص بي هذا ويعالج رمزًا حتى إذا كان حجم المخزن المؤقت لـ Arg 2> 16384 ، فإنه يغير __constant إلى __global. كان يجب أن أعرف هذا ، لكني نسيت ...