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
1 Answer
Reset to default 1I 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.
valgrind
(or similar)? – CoffeeTableEspresso Commented Mar 5 at 21:09clBuildProgram
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 withclGetProgramBuildInfo
after. – Ilian Zapryanov Commented Mar 5 at 22:47clBuildProgram
call as you recommend unfortunately still segfaults. Though I've noticed in the valgrind output, there are a lot of references to theclGetPlatformIDs(0, NULL, &num_platforms)
call so maybe that's the issue? – Lemma Commented Mar 5 at 23:53