cl_errors.c 9.25 KB
/*
 * cl_errors.c
 *
 *  Created on: 15/11/2014
 *      Author: pedro
 */

#include "cl_errors.h"

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

/*
 * Print the Opencl error
 * ret - OpenCL error code
 * operation - name of the operation
 */
void cl_check_error(cl_int ret, const char* operation, char* dev_name) {
	if (ret != CL_SUCCESS) {
		fprintf(stderr, "OpenCL Error on %s: %s returned %s!\n", dev_name, operation, cl_get_err_str(ret));

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
		printf("\nPress a key to exit\n");
		int a = getchar();
#endif

		exit(-1);
	}
}

/*
 * Print the Opencl clBuildProgram error with log
 * ret - OpenCL error code
 * prog - OpenCL program to compile
 * device_id - OpenCL device ID
 */
void cl_check_build_error(cl_int ret, cl_program* prog, cl_device_id* device_id, char* dev_name) {
	if (ret != CL_SUCCESS) {
		fprintf(stderr, "OpenCL Error on %s -> clBuildProgram returned %s\n", dev_name, cl_get_err_str(ret));

		if (ret == CL_BUILD_PROGRAM_FAILURE || ret == CL_INVALID_BINARY) {
			size_t log_size;
			ret = clGetProgramBuildInfo(*prog, *device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
			if (ret != CL_SUCCESS) {
				printf("clGetProgramBuildInfo failed at line %d\n", __LINE__);
				exit(-1);
			}
			char *log = (char *) malloc(log_size);
			ret = clGetProgramBuildInfo(*prog, *device_id, CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
			if (ret != CL_SUCCESS) {
				printf("clGetProgramBuildInfo failed at line %d\n", __LINE__);
				exit(-1);
			}
			printf("%s\n", log);
			free(log);
		}

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
		printf("\nPress a key to exit\n");
		int a = getchar();
#endif

		exit(-1);
	}
}

/*
 * Identify and describes opencl errors returned from host functions
 * error_code - opencl error code returned from opencl host functions
 */
const char* cl_get_err_str(cl_int err_cod) {
	static const char* err_str[] =
	{ "CL_SUCCESS (Everything is good)", "CL_DEVICE_NOT_FOUND (No OpenCL devices that matched given device type were found)",
			"CL_DEVICE_NOT_AVAILABLE (No OpenCL compatible device was found)",
			"CL_COMPILER_NOT_AVAILABLE (OpenCL Compiler perhaps failed to configure itself, or check your OpenCL installation)",
			"CL_MEM_OBJECT_ALLOCATION_FAILURE (Failed to allocate memory for buffer object)",
			"CL_OUT_OF_RESOURCES (failure to allocate resources required by the OpenCL implementation on the device)",
			"CL_OUT_OF_HOST_MEMORY (failure to allocate resources required by the OpenCL implementation on the host)",
			"CL_PROFILING_INFO_NOT_AVAILABLE (CL_QUEUE_PROFILING_ENABLE f is not set for the command-queue and if the profiling information is "
			"currently not available)",
			"CL_MEM_COPY_OVERLAP (source and destination buffers are the same buffer object and the source and destination regions overlap)",
			"CL_IMAGE_FORMAT_MISMATCH (src and dst image do not use the same image format)", "CL_IMAGE_FORMAT_NOT_SUPPORTED (the image format is not supported)",
			"CL_BUILD_PROGRAM_FAILURE (program build error for given device) Compilation error should follow:\n",
			"CL_MAP_FAILURE (failed to map the requested region into the host address space. This error does not occur for buffer objects created with "
			"CL_MEM_USE_HOST_PTR or CL_MEM_ALLOC_HOST_PTR)",
			"CL_MISALIGNED_SUB_BUFFER_OFFSET (no devices in given context associated with buffer for which the origin value is aligned to the "
			"CL_DEVICE_MEM_BASE_ADDR_ALIGN value)",
			"CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST (execution status of any of the events in event list is a negative integer value i.e., error)",
			"CL_COMPILE_PROGRAM_FAILURE (failed to compile the program source. Error occurs if clCompileProgram does not return until the compile has completed)",
			"CL_LINKER_NOT_AVAILABLE (Linker unavailable )", "CL_LINK_PROGRAM_FAILURE ( 	failed to link the compiled binaries and perhaps libraries)",
			"CL_DEVICE_PARTITION_FAILED (given partition name is supported by the implementation but input device couldn't be partitioned further)",
			"CL_KERNEL_ARG_INFO_NOT_AVAILABLE (argument information is not available for the given kernel)", "", "", "", "", "", "", "", "", "", "",
			"CL_INVALID_VALUE (values passed in the fs parameter is not valid)",
			"CL_INVALID_DEVICE_TYPE (device type specified is not valid, its returned by clCreateContextFromType / clGetDeviceIDs)",
			"CL_INVALID_PLATFORM (the specified platform is not a valid platform, its returned by clGetPlatformInfo /clGetDeviceIDs / clCreateContext / "
			"clCreateContextFromType )",
			"CL_INVALID_DEVICE (devices specified are not valid)",
			"CL_INVALID_CONTEXT (the given context is invalid OpenCL context, or the context associated with certain parameters are not the same)",
			"CL_INVALID_QUEUE_PROPERTIES (specified properties are valid but are not supported by the device, its returned by clCreateCommandQueue / "
			"clSetCommandQueueProperty)",
			"CL_INVALID_COMMAND_QUEUE (the specified command-queue is not a valid command-queue)",
			"CL_INVALID_HOST_PTR (host pointer is NULL and CL_MEM_COPY_HOST_PTR or CL_MEM_USE_HOST_PTR are set in fs or if host_ptr is not NULL but "
			"CL_MEM_COPY_HOST_PTR or CL_MEM_USE_HOST_PTR are not set in fs. returned by clCreateBuffer / clCreateImage2D / clCreateImage3D )",
			"CL_INVALID_MEM_OBJECT (the passed parameter is not a valid memory, image, or buffer object)",
			"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR (image format specified is not valid or is NULL, clCreateImage2D /clCreateImage3D returns this)",
			"CL_INVALID_IMAGE_SIZE (Its returned by create Image functions 2D/3D, if specified image width or height are outbound or 0 )",
			"CL_INVALID_SAMPLER (specified sampler is an invalid sampler object)",
			"CL_INVALID_BINARY (program binary is not a valid binary for the specified device)",
			"CL_INVALID_BUILD_OPTIONS (the given build options are not valid)",
			"CL_INVALID_PROGRAM (the given program is an invalid program object, returned by clRetainProgram / clReleaseProgram / clBuildProgram / "
			"clGetProgramInfo / clGetProgramBuildInfo / clCreateKernel / clCreateKernelsInProgram )",
			"CL_INVALID_PROGRAM_EXECUTABLE (there is no successfully built executable for program returned by clCreateKernel, there is no device in program "
			"then returned by clCreateKernelsInProgram, if no successfully built program executable present for device associated with command queue then returned "
			"by clEnqueueNDRangeKernel / clEnqueueTask)",
			"CL_INVALID_KERNEL_NAME (mentioned kernel name is not found in program)",
			"CL_INVALID_KERNEL_DEFINITION (arguments mismatch for the __kernel function definition and the passed ones, returned by clCreateKernel)",
			"CL_INVALID_KERNEL (specified kernel is an invalid kernel object)", "CL_INVALID_ARG_INDEX (clSetKernelArg if an invalid argument index is specified)",
			"CL_INVALID_ARG_VALUE (the argument value specified is NULL, returned by clSetKernelArg)",
			"CL_INVALID_ARG_SIZE (the given argument size (arg_size) do not match size of the data type for an argument, returned by clSetKernelArg)",
			"CL_INVALID_KERNEL_ARGS (the kernel argument values have not been specified, returned by clEnqueueNDRangeKernel / clEnqueueTask)",
			"CL_INVALID_WORK_DIMENSION (given work dimension is an invalid value, returned by clEnqueueNDRangeKernel)",
			"CL_INVALID_WORK_GROUP_SIZE (the specified local work group size and numb of work items specified by global work group size is not evenly divisible by "
			"local work group size)",
			"CL_INVALID_WORK_ITEM_SIZE (no. of work items specified in any of local work group sizes is greater than the corresponding values specified by "
			"CL_DEVICE_MAX_WORK_ITEM_SIZES in that particular dimension)",
			"CL_INVALID_GLOBAL_OFFSET (global_work_offset is not NULL. Must currently be a NULL value. In a future revision of OpenCL, global_work_offset can be "
			"used but not until OCL 1.2)",
			"CL_INVALID_EVENT_WAIT_LIST (event wait list is NULL and (no. of events in wait list > 0), or event wait list is not NULL and no. of events in wait "
			"list is 0, or specified event objects are not valid events)",
			"CL_INVALID_EVENT (invalid event objects specified)", "CL_INVALID_OPERATION ()", "CL_INVALID_GL_OBJECT (not a valid GL buffer object)",
			"CL_INVALID_BUFFER_SIZE (the value of the parameter size is 0 or exceeds CL_DEVICE_MAX_MEM_ALLOC_SIZE for all devices specified in the parameter context, "
			"returned by clCreateBuffer)",
			"CL_INVALID_MIP_LEVEL ()",
			"CL_INVALID_GLOBAL_WORK_SIZE (specified global work size is NULL, or any of the values specified in global work dimensions are 0 or exceeds the range "
			"given by the sizeof(size_t) for the device on which the kernel will be enqueued, returned by clEnqueueNDRangeKernel)",
			"CL_INVALID_PROPERTY (context property name in properties is not a supported property name, returned by clCreateContext)",
			"CL_INVALID_IMAGE_DESCRIPTOR (values specified in image description are invalid)",
			"CL_INVALID_COMPILER_OPTIONS (compiler options specified by options are invalid, returned by clCompileProgram)",
			"CL_INVALID_LINKER_OPTIONS (linker options specified by options are invalid, returned by clLinkProgram)", "CL_INVALID_DEVICE_PARTITION_COUNT ()" };
	const int err_cnt = sizeof(err_str) / sizeof(err_str[0]);
	const int idx = -err_cod;
	return (idx >= 0 && idx < err_cnt) ? err_str[idx] : "";
}