E. J. Winkleberry
E. J. Winkleberry

Reputation: 149

Xcode 4.2 on Lion OpenCL continually pausing with EXC_BAD_ACCESS

So I am running some simple Hello World OpenCL code in Xcode 4.1 on Lion and it continually breaks at clEnqueueTask. The same thing happens when I run the source from the MacResearch.org OpenCL tutorials, which breaks at clEnqueueNDRangeKernel. lldb gives code 1, address 0x30.

Here is the code:

#include <stdio.h>
#include <stdlib.h>

#include <OpenCL/opencl.h>

#define MEM_SIZE (128)
#define MAX_SOURCE_SIZE (0x100000)

int main ()
{

    char *program_source = "\n"\
    "__kernel void hello(__global char* string) \n"\
    "{                                          \n"\
    "   string[0]  = 'H';                       \n"\
    "   string[1]  = 'e';                       \n"\
    "   string[2]  = 'l';                       \n"\
    "   string[3]  = 'l';                       \n"\
    "   string[4]  = 'o';                       \n"\
    "   string[5]  = ',';                       \n"\
    "   string[6]  = ' ';                       \n"\
    "   string[7]  = 'w';                       \n"\
    "   string[8]  = 'o';                       \n"\
    "   string[9]  = 'r';                       \n"\
    "   string[10] = 'l';                       \n"\
    "   string[11] = 'd';                       \n"\
    "   string[12] = '!';                       \n"\
    "    string[13] = '\0';                     \n"\
    "}                                          \n"\
    "\n";

    size_t source_size = sizeof(program_source);

    cl_device_id device_id         = NULL;
    cl_context context             = NULL;
    cl_command_queue command_queue = NULL;
    cl_mem memobj                  = NULL;
    cl_program program             = NULL;
    cl_kernel kernel               = NULL;
    cl_platform_id platform_id     = NULL;
    cl_uint ret_num_devices;
    cl_uint ret_num_platforms;
    cl_int ret;

    char string[MEM_SIZE];


    // get platform and device information
    ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &ret_num_devices);

    cl_int err = 0;
    size_t returned_size = 0;
    size_t buffer_size;

    // Get some information about the returned device
    cl_char vendor_name[1024] = {0};
    cl_char device_name[1024] = {0};
    err = clGetDeviceInfo(device_id, CL_DEVICE_VENDOR, sizeof(vendor_name), vendor_name, &returned_size);
    err |= clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(device_name),device_name, &returned_size);
//    assert(err == CL_SUCCESS);
    printf("Connecting to %s %s...\n", vendor_name, device_name);

    // create OpenCL context
    context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);

    // create command queue
    command_queue = clCreateCommandQueue(context, device_id, 0, &ret);

    // create memory buffer
    memobj = clCreateBuffer(context,CL_MEM_READ_WRITE, MEM_SIZE*sizeof(char), NULL, &ret);

    // create kernel program from source code
    program = clCreateProgramWithSource(context, 1, (const char **)&program_source, (const size_t*)&source_size, &ret);

    // build kernel program
    ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);

    // create OpenCL Kernel
    kernel = clCreateKernel(program, "hello", &ret);

    // set OpenCL kernel parameters
    ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj);

    // Execute OpenCL kernel
    ret = clEnqueueTask(command_queue, kernel, 0, NULL, NULL);

    // copy results from the memory buffer
    ret = clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, MEM_SIZE*sizeof(char), string, 0, NULL, NULL);

    // display results
    puts(string);

    // finish up
    ret = clFlush(command_queue);
    ret = clFinish(command_queue);
    ret = clReleaseKernel(kernel);
    ret = clReleaseProgram(program);
    ret = clReleaseMemObject(memobj);
    ret = clReleaseCommandQueue(command_queue);
    ret = clReleaseContext(context);

    return 0;
}

Tried using Guard Malloc, got:

GuardMalloc[OCL_HW-1453]: recording malloc stacks to disk using standard recorder
GuardMalloc[OCL_HW-1453]: Allocations will be placed on 16 byte boundaries.
GuardMalloc[OCL_HW-1453]:  - Some buffer overruns may not be noticed.
GuardMalloc[OCL_HW-1453]:  - Applications using vector instructions (e.g., SSE) should work.
GuardMalloc[OCL_HW-1453]: version 24.1
OCL_HW(1453) malloc: process 1423 no longer exists, stack logs deleted from /tmp/stack-logs.1423.OCL_HW.yL5f5u.index
OCL_HW(1453) malloc: stack logs being written into /tmp/stack-logs.1453.OCL_HW.pCjTNR.index
Connecting to NVIDIA GeForce GT 330M...

I had no problems with these codes under Snow Leopard and Xcode 3. I made sure not to compile any .cl files by removing them from the target, and 'OpenCl.framework' is linked and everything.

I actually even wiped my computer and clean installed lion and xcode and still it's a problem. I'm pretty sure at this point it's something stupid.

-Thanks a bunch

Upvotes: 1

Views: 1711

Answers (1)

James
James

Reputation: 2413

You're right -- it's something silly. You are passing an incorrect value to the fourth parameter of clCreateProgramWithSource. You should be passing the length of your source string, but you are passing the size of the pointer. You can fix it like this:

size_t source_size = strlen(program_source);

Note that I found this by checking the return value from clBuildProgram. It was -11, CL_BUILD_PROGRAM_FAILURE, which means your kernel compilation failed. Since your kernel looked fine, I did this on the command line:

CL_LOG_ERRORS=stdout ./test

Which caused the Apple OpenCL implementation to dump the compiler build log to standard output. I saw this:

[CL_BUILD_ERROR] : OpenCL Build Error : Compiler build log:
<program source>:2:1: error: unknown type name '__kerne'
__kerne

<program source>:2:8: error: expected identifier or '('
__kerne

Which made me immediately think something was up with your source code length parameter.

Also note that you need to change this in your kernel:

string[13] = '\0';

to

string[13] = 0;

After making these changes, I see this on my Macbook Pro:

Connecting to AMD ATI Radeon HD 6490M...
Hello, world!

Upvotes: 3

Related Questions