最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - OpenCL segfault on clBuildProgram - Stack Overflow

programmeradmin1浏览0评论

I'm building my first OpenCL program in C in order to quickly compute the Mandelbrot Set, and I'm getting a segfault on clBuildProgram. Below is the relevant code:

The kernel code (though the program still segfaults when I comment out every line in the body of the code):

const char *mandelbrot_kernel_source =
    "\n"
    "__kernel void mb(\n"
    "    __global unsigned char *out,\n"
    "    const unsigned int width,\n"
    "    const double real_start,\n"
    "    const double imag_start,\n"
    "    const double stepsize,\n"
    "    const unsigned int max_iters,\n"
    "    const double bailout\n"
    ") {\n"
    "    unsigned int w = get_global_id(0);\n"
    "    unsigned int h = get_global_id(1);\n"
    "    double real = real_start + w * stepsize;\n"
    "    double imag = imag_start - h * stepsize;\n"
    "    unsigned int iters = derbail(real, imag, max_iters, bailout);\n"
    "    if (iters > UCHAR_MAX) {\n"
    "        out[h * width + w] = UCHAR_MAX;\n"
    "    } else {\n"
    "        out[h * width + w] = iters;\n"
    "    }\n"
    "}\n";

And then the code where I build and execute (up to and including the line that segfaults):

int gpu_main(double real_center, double imag_center, unsigned int width,
             unsigned int height, double stepsize, unsigned int max_iters,
             double bailout, const char output[256]) {
    double real_start = real_center - width * stepsize / 2;
    double imag_start = imag_center + height * stepsize / 2;

    cl_int err;
    cl_uint num_platforms;
    err = clGetPlatformIDs(0, NULL, &num_platforms);
    if (num_platforms == 0) {
        printf("Zero platforms! (error code: %d)\n", err);
        return EXIT_FAILURE;
    }

    cl_platform_id platforms[num_platforms];
    err = clGetPlatformIDs(num_platforms, platforms, NULL);

    cl_device_id device_id;
    for (int i = 0; i < num_platforms; ++i) {
        err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_DEFAULT, 1,
                             &device_id, NULL);
        if (err == CL_SUCCESS) {
            break;
        }
    }
    if (device_id == NULL) {
        printf("Failed to acquire device_id (error code: %d)\n", err);
        return EXIT_FAILURE;
    }

    cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to build context (error code: %d)\n", err);
    }
    cl_command_queue commands =
        clCreateCommandQueueWithProperties(context, device_id, 0, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to build commands (error code: %d)\n", err);
    }
    cl_program program = clCreateProgramWithSource(
        context, 1, (const char **)&mandelbrot_kernel_source, NULL, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to create program (error code: %d)\n", err);
    }

    err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

As this is my first program I'm not sure where I've gone wrong. I've gone through the docs of all the OpenCL function calls and it doesn't appear that I've messed up anything in terms of call parameter types, so something must be wrong in the arguments I've passed to them.

EDIT: here's a link to a pastebin of the output of valgrind --track-origins=yes

I'm building my first OpenCL program in C in order to quickly compute the Mandelbrot Set, and I'm getting a segfault on clBuildProgram. Below is the relevant code:

The kernel code (though the program still segfaults when I comment out every line in the body of the code):

const char *mandelbrot_kernel_source =
    "\n"
    "__kernel void mb(\n"
    "    __global unsigned char *out,\n"
    "    const unsigned int width,\n"
    "    const double real_start,\n"
    "    const double imag_start,\n"
    "    const double stepsize,\n"
    "    const unsigned int max_iters,\n"
    "    const double bailout\n"
    ") {\n"
    "    unsigned int w = get_global_id(0);\n"
    "    unsigned int h = get_global_id(1);\n"
    "    double real = real_start + w * stepsize;\n"
    "    double imag = imag_start - h * stepsize;\n"
    "    unsigned int iters = derbail(real, imag, max_iters, bailout);\n"
    "    if (iters > UCHAR_MAX) {\n"
    "        out[h * width + w] = UCHAR_MAX;\n"
    "    } else {\n"
    "        out[h * width + w] = iters;\n"
    "    }\n"
    "}\n";

And then the code where I build and execute (up to and including the line that segfaults):

int gpu_main(double real_center, double imag_center, unsigned int width,
             unsigned int height, double stepsize, unsigned int max_iters,
             double bailout, const char output[256]) {
    double real_start = real_center - width * stepsize / 2;
    double imag_start = imag_center + height * stepsize / 2;

    cl_int err;
    cl_uint num_platforms;
    err = clGetPlatformIDs(0, NULL, &num_platforms);
    if (num_platforms == 0) {
        printf("Zero platforms! (error code: %d)\n", err);
        return EXIT_FAILURE;
    }

    cl_platform_id platforms[num_platforms];
    err = clGetPlatformIDs(num_platforms, platforms, NULL);

    cl_device_id device_id;
    for (int i = 0; i < num_platforms; ++i) {
        err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_DEFAULT, 1,
                             &device_id, NULL);
        if (err == CL_SUCCESS) {
            break;
        }
    }
    if (device_id == NULL) {
        printf("Failed to acquire device_id (error code: %d)\n", err);
        return EXIT_FAILURE;
    }

    cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to build context (error code: %d)\n", err);
    }
    cl_command_queue commands =
        clCreateCommandQueueWithProperties(context, device_id, 0, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to build commands (error code: %d)\n", err);
    }
    cl_program program = clCreateProgramWithSource(
        context, 1, (const char **)&mandelbrot_kernel_source, NULL, &err);
    if (err != CL_SUCCESS) {
        printf("Failed to create program (error code: %d)\n", err);
    }

    err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

As this is my first program I'm not sure where I've gone wrong. I've gone through the docs of all the OpenCL function calls and it doesn't appear that I've messed up anything in terms of call parameter types, so something must be wrong in the arguments I've passed to them.

EDIT: here's a link to a pastebin of the output of valgrind --track-origins=yes

Share Improve this question edited Mar 5 at 22:13 Lemma asked Mar 5 at 20:19 LemmaLemma 1318 bronze badges 5
  • Have you tried running it through valgrind (or similar)? – CoffeeTableEspresso Commented Mar 5 at 21:09
  • @CoffeeTableEspresso Yeah but I'm bad at reading valgrind outputs and the output is too long to reasonably put in a stackoverflow post. I mean, unless I've misunderstood some decorum about what is and isn't appropriate to put in a post – Lemma Commented Mar 5 at 21:39
  • This ` (const char **)&mandelbrot_kernel_source, NULL, &err);` looks odd why do you cast to double pointer here? Also clBuildProgram needs device id and num device: clBuildProgram(program, 1, devId, 0,0,0) Try to change those and if you don't crash check the err with clGetProgramBuildInfo after. – Ilian Zapryanov Commented Mar 5 at 22:47
  • @IlianZapryanov I cast the double pointer here because the parameter calls for a double pointer. Changing the clBuildProgram call as you recommend unfortunately still segfaults. Though I've noticed in the valgrind output, there are a lot of references to the clGetPlatformIDs(0, NULL, &num_platforms) call so maybe that's the issue? – Lemma Commented Mar 5 at 23:53
  • also are you sure your pc enables opencl and have the driver? – Ilian Zapryanov Commented Mar 6 at 0:29
Add a comment  | 

1 Answer 1

Reset to default 1

I noticed that clinfo was segfaulting as well, so I supposed that I had a driver issue, and turns out, yep! So for those wondering, I'm using vanilla Arch with an Intel HD Graphics 5500 GPU and I had intel-opencl as my driver. I uninstalled that and installed intel-compute-runtime-legacy-bin and it no longer segfaults! Sorry for the trouble.

发布评论

评论列表(0)

  1. 暂无评论