2010-11-29 8 views
1

Ich habe einen OpenCL-Kernel, den ich in JOCL ausführe und er gibt alle meine JUnit-Tests weiter. Ich portierte meinen Code in C++, damit ich den Kernel unter den gleichen Bedingungen profilieren konnte. Der Treiber funktioniert in allen Fällen außer einem. Es läuft perfekt in JOCL, also glaube ich, dass etwas in meinem C++ Code falsch ist. Mein Code ist unten, ich habe es zu Tode auditiert. Wenn mir jemand helfen kann zu erkennen, was falsch ist, würde ich es begrüßen. Der Treibercode funktioniert gut mit den Argumenten 1 und 2 als 8192, arg 3 als 512. Er funktioniert auch gut mit den Argumenten 1 und 2 als 512 und arg 3 als 8192. Arg 4 ist immer nur 1, was den Kernel einstellt zu reellen Zahlen. Wenn ich args 1 und 2 auf 262144 und arg 3 auf 16 setze, wird es ausgeführt, es werden keine Fehler gemeldet, keine seg-Fehler, aber der Kernel ändert die Daten am Ende nicht. Beachten Sie, dass arg 1 * 3 in allen obigen Fällen gleich 2^22 ist. Ich glaube, dass ich in allen Fällen die gleiche Menge an Floats verteile. Ich bin ratlos. Ich kann nicht OpenCL bekommen, mir zu sagen, was falsch ist :(Festhalten, warum mein OpenCL-Kernel nicht mit bestimmten Parametern ausgeführt wird

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); 

}

Antwort

2

UPDATE ich es herausgefunden! Das Problem in meinem Kernel ist. Ich verwende konstante Speicher. Mein Java-Code macht Dies und textuell manipuliert den Code, so dass, wenn meine Puffergröße für arg 2> 16384, ändert sich die __constant zu __global. Ich hätte dies wissen müssen, aber ich habe vergessen ...