Browse Source

Enhance reporting of OpenCL errors

master
samr7 13 years ago
parent
commit
317cade95f
  1. 268
      oclvanitygen.c

268
oclvanitygen.c

@ -86,6 +86,187 @@ vg_exec_upgrade_lock(vg_exec_context_t *vxcp) @@ -86,6 +86,187 @@ vg_exec_upgrade_lock(vg_exec_context_t *vxcp)
}
/*
* OpenCL debugging and support
*/
const char *
vg_ocl_strerror(cl_int ret)
{
#define OCL_STATUS(st) case st: return #st;
switch (ret) {
OCL_STATUS(CL_SUCCESS);
OCL_STATUS(CL_DEVICE_NOT_FOUND);
OCL_STATUS(CL_DEVICE_NOT_AVAILABLE);
OCL_STATUS(CL_COMPILER_NOT_AVAILABLE);
OCL_STATUS(CL_MEM_OBJECT_ALLOCATION_FAILURE);
OCL_STATUS(CL_OUT_OF_RESOURCES);
OCL_STATUS(CL_OUT_OF_HOST_MEMORY);
OCL_STATUS(CL_PROFILING_INFO_NOT_AVAILABLE);
OCL_STATUS(CL_MEM_COPY_OVERLAP);
OCL_STATUS(CL_IMAGE_FORMAT_MISMATCH);
OCL_STATUS(CL_IMAGE_FORMAT_NOT_SUPPORTED);
OCL_STATUS(CL_BUILD_PROGRAM_FAILURE);
OCL_STATUS(CL_MAP_FAILURE);
#if defined(CL_MISALIGNED_SUB_BUFFER_OFFSET)
OCL_STATUS(CL_MISALIGNED_SUB_BUFFER_OFFSET);
#endif /* defined(CL_MISALIGNED_SUB_BUFFER_OFFSET) */
#if defined(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST)
OCL_STATUS(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
#endif /* defined(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST) */
OCL_STATUS(CL_INVALID_VALUE);
OCL_STATUS(CL_INVALID_DEVICE_TYPE);
OCL_STATUS(CL_INVALID_PLATFORM);
OCL_STATUS(CL_INVALID_DEVICE);
OCL_STATUS(CL_INVALID_CONTEXT);
OCL_STATUS(CL_INVALID_QUEUE_PROPERTIES);
OCL_STATUS(CL_INVALID_COMMAND_QUEUE);
OCL_STATUS(CL_INVALID_HOST_PTR);
OCL_STATUS(CL_INVALID_MEM_OBJECT);
OCL_STATUS(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
OCL_STATUS(CL_INVALID_IMAGE_SIZE);
OCL_STATUS(CL_INVALID_SAMPLER);
OCL_STATUS(CL_INVALID_BINARY);
OCL_STATUS(CL_INVALID_BUILD_OPTIONS);
OCL_STATUS(CL_INVALID_PROGRAM);
OCL_STATUS(CL_INVALID_PROGRAM_EXECUTABLE);
OCL_STATUS(CL_INVALID_KERNEL_NAME);
OCL_STATUS(CL_INVALID_KERNEL_DEFINITION);
OCL_STATUS(CL_INVALID_KERNEL);
OCL_STATUS(CL_INVALID_ARG_INDEX);
OCL_STATUS(CL_INVALID_ARG_VALUE);
OCL_STATUS(CL_INVALID_ARG_SIZE);
OCL_STATUS(CL_INVALID_KERNEL_ARGS);
OCL_STATUS(CL_INVALID_WORK_DIMENSION);
OCL_STATUS(CL_INVALID_WORK_GROUP_SIZE);
OCL_STATUS(CL_INVALID_WORK_ITEM_SIZE);
OCL_STATUS(CL_INVALID_GLOBAL_OFFSET);
OCL_STATUS(CL_INVALID_EVENT_WAIT_LIST);
OCL_STATUS(CL_INVALID_EVENT);
OCL_STATUS(CL_INVALID_OPERATION);
OCL_STATUS(CL_INVALID_GL_OBJECT);
OCL_STATUS(CL_INVALID_BUFFER_SIZE);
OCL_STATUS(CL_INVALID_MIP_LEVEL);
OCL_STATUS(CL_INVALID_GLOBAL_WORK_SIZE);
#if defined(CL_INVALID_PROPERTY)
OCL_STATUS(CL_INVALID_PROPERTY);
#endif /* defined(CL_INVALID_PROPERTY) */
#undef OCL_STATUS
default: {
static char tmp[64];
snprintf(tmp, sizeof(tmp), "Unknown code %d", ret);
return tmp;
}
}
}
/* Get device strings, using a static buffer -- caveat emptor */
const char *
vg_ocl_device_getstr(cl_device_id did, cl_device_info param)
{
static char device_str[1024];
cl_int ret;
size_t size_ret;
ret = clGetDeviceInfo(did, param,
sizeof(device_str), device_str,
&size_ret);
if (ret != CL_SUCCESS) {
snprintf(device_str, sizeof(device_str),
"clGetDeviceInfo: %s",
vg_ocl_strerror(ret));
}
return device_str;
}
void
vg_ocl_dump_info(vg_ocl_context_t *vocp)
{
cl_device_id did;
if (vocp->base.vxc_vc && (vocp->base.vxc_vc->vc_verbose < 1))
return;
did = vocp->voc_ocldid;
printf("Device: %s\n",
vg_ocl_device_getstr(did, CL_DEVICE_NAME));
printf("Vendor: %s\n",
vg_ocl_device_getstr(did, CL_DEVICE_VENDOR));
printf("Driver: %s\n",
vg_ocl_device_getstr(did, CL_DRIVER_VERSION));
printf("Profile: %s\n",
vg_ocl_device_getstr(did, CL_DEVICE_PROFILE));
printf("Version: %s\n",
vg_ocl_device_getstr(did, CL_DEVICE_VERSION));
}
void
vg_ocl_error(vg_ocl_context_t *vocp, int code, const char *desc)
{
const char *err = vg_ocl_strerror(code);
if (desc) {
printf("%s: %s\n", desc, err);
} else {
printf("%s\n", err);
}
if (vocp && vocp->voc_ocldid)
vg_ocl_dump_info(vocp);
}
void
vg_ocl_buildlog(vg_ocl_context_t *vocp, cl_program prog)
{
size_t logbufsize, logsize;
char *log;
int off = 0;
cl_int ret;
ret = clGetProgramBuildInfo(prog,
vocp->voc_ocldid,
CL_PROGRAM_BUILD_LOG,
0, NULL,
&logbufsize);
if (ret != CL_SUCCESS) {
vg_ocl_error(NULL, ret, "clGetProgramBuildInfo");
return;
}
log = (char *) malloc(logbufsize);
if (!log) {
printf("Could not allocate build log buffer\n");
return;
}
ret = clGetProgramBuildInfo(prog,
vocp->voc_ocldid,
CL_PROGRAM_BUILD_LOG,
logbufsize,
log,
&logsize);
if (ret != CL_SUCCESS) {
vg_ocl_error(NULL, ret, "clGetProgramBuildInfo");
} else {
/* Remove leading newlines and trailing newlines/whitespace */
log[logbufsize-1] = '\0';
for (off = logsize - 1; off >= 0; off--) {
if ((log[off] != '\r') &&
(log[off] != '\n') &&
(log[off] != ' ') &&
(log[off] != '\t') &&
(log[off] != '\0'))
break;
log[off] = '\0';
}
for (off = 0; off < logbufsize; off++) {
if ((log[off] != '\r') &&
(log[off] != '\n'))
break;
}
printf("Build log:\n%s\n", &log[off]);
}
free(log);
}
/*
* OpenCL per-exec functions
*/
@ -100,7 +281,8 @@ vg_ocl_create_kernel(vg_ocl_context_t *vocp, int knum, const char *func) @@ -100,7 +281,8 @@ vg_ocl_create_kernel(vg_ocl_context_t *vocp, int knum, const char *func)
for (i = 0; i < MAX_SLOT; i++) {
krn = clCreateKernel(vocp->voc_oclprog, func, &ret);
if (!krn) {
printf("clCreateKernel(%d): %d\n", i, ret);
printf("clCreateKernel(%d): ", i);
vg_ocl_error(vocp, ret, NULL);
while (--i >= 0) {
clReleaseKernel(vocp->voc_oclkernel[i][knum]);
vocp->voc_oclkernel[i][knum] = NULL;
@ -125,8 +307,10 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp, @@ -125,8 +307,10 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp,
cl_int ret;
buf = (char *) malloc(128 * 1024);
if (!buf)
if (!buf) {
printf("Could not allocate program buffer\n");
return 0;
}
kfp = fopen(filename, "r");
if (!kfp) {
@ -144,7 +328,7 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp, @@ -144,7 +328,7 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp,
&ret);
free(buf);
if (!prog) {
printf("clCreateProgramWithSource: %d\n", ret);
vg_ocl_error(vocp, ret, "clCreateProgramWithSource");
return 0;
}
@ -156,30 +340,15 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp, @@ -156,30 +340,15 @@ vg_ocl_load_program(vg_context_t *vcp, vg_ocl_context_t *vocp,
if (ret != CL_SUCCESS) {
if (vcp->vc_verbose > 0)
printf("failure.\n");
printf("clBuildProgram: %d\n", ret);
vg_ocl_error(NULL, ret, "clBuildProgram");
} else if (vcp->vc_verbose > 0) {
printf("done!\n");
}
if ((ret != CL_SUCCESS) || (vcp->vc_verbose > 1)) {
const size_t logbufsize = 1024 * 16;
char *log = (char*) malloc(logbufsize);
size_t logsize;
cl_int ret2;
ret2 = clGetProgramBuildInfo(prog,
vocp->voc_ocldid,
CL_PROGRAM_BUILD_LOG,
logbufsize,
log,
&logsize);
if (ret2 != CL_SUCCESS) {
printf("clGetProgramBuildInfo: %d\n", ret2);
} else {
printf("Build log:%s\n", log);
}
free(log);
vg_ocl_buildlog(vocp, prog);
}
if (ret != CL_SUCCESS) {
vg_ocl_dump_info(vocp);
clReleaseProgram(prog);
return 0;
}
@ -223,7 +392,7 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did) @@ -223,7 +392,7 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did)
NULL,
&ret);
if (!vocp->voc_oclctx) {
printf("clCreateContext failed: %d\n", ret);
vg_ocl_error(vocp, ret, "clCreateContext");
return 0;
}
@ -231,17 +400,15 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did) @@ -231,17 +400,15 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did)
vocp->voc_ocldid,
0, &ret);
if (!vocp->voc_oclcmdq) {
printf("clCreateCommandQueue failed: %d\n", ret);
vg_ocl_error(vocp, ret, "clCreateCommandQueue");
return 0;
}
if (!vg_ocl_load_program(vcp, vocp,
"calc_addrs.cl",
//"-cl-nv-verbose "
"-DUNROLL_MAX=16")) {
printf("Could not load kernel\n");
"-DUNROLL_MAX=16"))
return 0;
}
return 1;
}
@ -305,7 +472,8 @@ vg_ocl_kernel_arg_alloc(vg_ocl_context_t *vocp, int slot, @@ -305,7 +472,8 @@ vg_ocl_kernel_arg_alloc(vg_ocl_context_t *vocp, int slot,
NULL,
&ret);
if (!clbuf) {
printf("Could not create argument buffer: %d\n", ret);
printf("clCreateBuffer(%d,%d): ", slot, arg);
vg_ocl_error(vocp, ret, NULL);
return 0;
}
@ -326,8 +494,8 @@ vg_ocl_kernel_arg_alloc(vg_ocl_context_t *vocp, int slot, @@ -326,8 +494,8 @@ vg_ocl_kernel_arg_alloc(vg_ocl_context_t *vocp, int slot,
&clbuf);
if (ret) {
printf("Could not set kernel argument: %d\n",
ret);
printf("clSetKernelArg(%d,%d): ", knum, karg);
vg_ocl_error(vocp, ret, NULL);
return 0;
}
}
@ -357,7 +525,8 @@ vg_ocl_copyout_arg(vg_ocl_context_t *vocp, int wslot, int arg, @@ -357,7 +525,8 @@ vg_ocl_copyout_arg(vg_ocl_context_t *vocp, int wslot, int arg,
NULL);
if (ret) {
printf("Could not copyout argument buffer: %d\n", ret);
printf("clEnqueueWriteBuffer(%d): ", arg);
vg_ocl_error(vocp, ret, NULL);
return 0;
}
@ -383,7 +552,8 @@ vg_ocl_map_arg_buffer(vg_ocl_context_t *vocp, int slot, @@ -383,7 +552,8 @@ vg_ocl_map_arg_buffer(vg_ocl_context_t *vocp, int slot,
NULL,
&ret);
if (!buf) {
printf("Could not map argument buffer: %d\n", ret);
printf("clEnqueueMapBuffer(%d): ", arg);
vg_ocl_error(vocp, ret, NULL);
return NULL;
}
return buf;
@ -404,14 +574,16 @@ vg_ocl_unmap_arg_buffer(vg_ocl_context_t *vocp, int slot, @@ -404,14 +574,16 @@ vg_ocl_unmap_arg_buffer(vg_ocl_context_t *vocp, int slot,
0, NULL,
&ev);
if (ret != CL_SUCCESS) {
printf("Could not unmap buffer: %d\n", ret);
printf("clEnqueueUnmapMemObject(%d): ", arg);
vg_ocl_error(vocp, ret, NULL);
return;
}
ret = clWaitForEvents(1, &ev);
clReleaseEvent(ev);
if (ret != CL_SUCCESS) {
printf("Error waiting for event: %d\n", ret);
printf("clWaitForEvent(clUnmapMemObject,%d): ", arg);
vg_ocl_error(vocp, ret, NULL);
}
}
@ -430,8 +602,8 @@ vg_ocl_kernel_int_arg(vg_ocl_context_t *vocp, int slot, @@ -430,8 +602,8 @@ vg_ocl_kernel_int_arg(vg_ocl_context_t *vocp, int slot,
sizeof(value),
&value);
if (ret) {
printf("Could not set kernel argument: %d\n",
ret);
printf("clSetKernelArg(%d): ", arg);
vg_ocl_error(vocp, ret, NULL);
return 0;
}
}
@ -459,7 +631,7 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow) @@ -459,7 +631,7 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow)
sizeof(val),
&val);
if (ret != CL_SUCCESS) {
printf("Could not set column count for 2nd kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clSetKernelArg(ncol)");
return 0;
}
ret = clEnqueueNDRangeKernel(vocp->voc_oclcmdq,
@ -469,14 +641,14 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow) @@ -469,14 +641,14 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow)
0, NULL,
&ev);
if (ret != CL_SUCCESS) {
printf("Could not queue 1st kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clEnqueueNDRange(0)");
return 0;
}
ret = clWaitForEvents(1, &ev);
clReleaseEvent(ev);
if (ret != CL_SUCCESS) {
printf("Error waiting for 1st kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clWaitForEvents(NDRange,0)");
return 0;
}
@ -487,14 +659,14 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow) @@ -487,14 +659,14 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow)
0, NULL,
&ev);
if (ret != CL_SUCCESS) {
printf("Could not queue 2nd kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clEnqueueNDRange(1)");
return 0;
}
ret = clWaitForEvents(1, &ev);
clReleaseEvent(ev);
if (ret != CL_SUCCESS) {
printf("Error waiting for 2nd kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clWaitForEvents(NDRange,1)");
return 0;
}
@ -505,7 +677,7 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow) @@ -505,7 +677,7 @@ vg_ocl_kernel_start(vg_ocl_context_t *vocp, int slot, int ncol, int nrow)
0, NULL,
&ev);
if (ret != CL_SUCCESS) {
printf("Could not queue 3rd kernel: %d\n", ret);
vg_ocl_error(vocp, ret, "clEnqueueNDRange(2)");
return 0;
}
@ -525,7 +697,7 @@ vg_ocl_kernel_wait(vg_ocl_context_t *vocp, int slot) @@ -525,7 +697,7 @@ vg_ocl_kernel_wait(vg_ocl_context_t *vocp, int slot)
ret = clWaitForEvents(1, &ev);
clReleaseEvent(ev);
if (ret != CL_SUCCESS) {
printf("Error waiting for event: %d\n", ret);
vg_ocl_error(vocp, ret, "clWaitForEvents(NDRange,e)");
return 0;
}
}
@ -1163,7 +1335,7 @@ get_device_list(cl_platform_id pid, cl_device_id **list_out) @@ -1163,7 +1335,7 @@ get_device_list(cl_platform_id pid, cl_device_id **list_out)
cl_device_id *ids;
res = clGetDeviceIDs(pid, CL_DEVICE_TYPE_ALL, 0, NULL, &nd);
if (res != CL_SUCCESS) {
printf("clGetDeviceIDs(0) failed: %d\n", res);
vg_ocl_error(NULL, res, "clGetDeviceIDs(0)");
*list_out = NULL;
return -1;
}
@ -1176,7 +1348,7 @@ get_device_list(cl_platform_id pid, cl_device_id **list_out) @@ -1176,7 +1348,7 @@ get_device_list(cl_platform_id pid, cl_device_id **list_out)
}
res = clGetDeviceIDs(pid, CL_DEVICE_TYPE_ALL, nd, ids, NULL);
if (res != CL_SUCCESS) {
printf("clGetDeviceIDs(n) failed: %d\n", res);
vg_ocl_error(NULL, res, "clGetDeviceIDs(n)");
free(ids);
*list_out = NULL;
return -1;
@ -1250,7 +1422,7 @@ get_platform_list(cl_platform_id **list_out) @@ -1250,7 +1422,7 @@ get_platform_list(cl_platform_id **list_out)
cl_platform_id *ids;
res = clGetPlatformIDs(0, NULL, &np);
if (res != CL_SUCCESS) {
printf("clGetPlatformIDs(0) failed: %d\n", res);
vg_ocl_error(NULL, res, "clGetPlatformIDs(0)");
*list_out = NULL;
return -1;
}
@ -1263,7 +1435,7 @@ get_platform_list(cl_platform_id **list_out) @@ -1263,7 +1435,7 @@ get_platform_list(cl_platform_id **list_out)
}
res = clGetPlatformIDs(np, ids, NULL);
if (res != CL_SUCCESS) {
printf("clGetPlatformIDs(n) failed: %d\n", res);
vg_ocl_error(NULL, res, "clGetPlatformIDs(n)");
free(ids);
*list_out = NULL;
return -1;
@ -1286,7 +1458,7 @@ show_platforms(cl_platform_id *ids, int np, int base) @@ -1286,7 +1458,7 @@ show_platforms(cl_platform_id *ids, int np, int base)
res = clGetPlatformInfo(ids[i], CL_PLATFORM_NAME,
sizeof(nbuf), nbuf, &len);
if (res != CL_SUCCESS) {
printf("Failed to enumerate platform ID: %d\n", res);
vg_ocl_error(NULL, res, "clGetPlatformInfo(NAME)");
continue;
}
if (len >= sizeof(nbuf))
@ -1295,7 +1467,7 @@ show_platforms(cl_platform_id *ids, int np, int base) @@ -1295,7 +1467,7 @@ show_platforms(cl_platform_id *ids, int np, int base)
res = clGetPlatformInfo(ids[i], CL_PLATFORM_VENDOR,
sizeof(vbuf), vbuf, &len);
if (res != CL_SUCCESS) {
printf("Failed to enumerate platform ID: %d\n", res);
vg_ocl_error(NULL, res, "clGetPlatformInfo(VENDOR)");
continue;
}
if (len >= sizeof(vbuf))

Loading…
Cancel
Save