2010-11-29 4 views
1

J'ai un noyau OpenCL que je cours dans JOCL et qui passe tous mes tests JUnit. J'ai porté mon code en C++ afin que je puisse profiler le noyau dans les mêmes conditions. Le conducteur fonctionne bien dans tous les cas sauf un. Il fonctionne parfaitement bien dans JOCL donc je crois que quelque chose dans mon code C++ est faux. Mon code est ci-dessous, je l'ai audité à mort. Si quelqu'un peut m'aider à voir ce qui ne va pas, je l'apprécierais. Le code du pilote fonctionne bien avec les args 1 et 2 comme 8192, arg 3 comme 512. Il fonctionne également bien avec les args 1 et 2 comme 512 et arg 3 comme 8192. Arg 4 est toujours juste 1, ce qui définit le noyau aux nombres réels. Lorsque je mets les arguments 1 et 2 à 262144 et arg 3 à 16, il s'exécute, aucune erreur n'est signalée, aucun défaut de segmentation, mais le noyau ne change pas les données à la fin. Notez que arg 1 * 3 dans tous les cas ci-dessus est égal à 2^22. Je crois que j'attribue la même quantité de flotteurs dans tous les cas. Je suis perplexe. Je ne peux pas me OpenCL pour me dire ce qui est mal :(Bloqué sur pourquoi mon noyau OpenCL ne s'exécutera pas avec des paramètres particuliers

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

}

Répondre

2

UPDATE, j'ai tout compris! Le problème est dans mon noyau. J'utilise la mémoire constante. Mon compte code java pour ceci et textuellement manipule le code de sorte que si ma taille de tampon pour arg 2> 16384, il change le __constant en __global. J'aurais dû le savoir, mais j'ai oublié ...

Questions connexes