Skip to content

Instantly share code, notes, and snippets.

@baixiaohub
Forked from allanmac/README.md
Last active May 17, 2018 14:33
Show Gist options
  • Select an option

  • Save baixiaohub/14be02b9ec600f5ea7763af8080aa838 to your computer and use it in GitHub Desktop.

Select an option

Save baixiaohub/14be02b9ec600f5ea7763af8080aa838 to your computer and use it in GitHub Desktop.
Macros for neatly error checking OpenCL API functions.

Simply adding two parentheses cl(...) gives you error checking for OpenCL API functions that return a cl_int error code.

The second cl_ok(err) macro is for error checking API functions that initialize their error code as an argument.

The header also includes a useful function for converting OpenCL errors to strings:

char const * clGetErrorString(cl_int const err);

Example 1:


cl(Finish(command_queue));

cl_ulong start_time,end_time;

cl(GetEventProfilingInfo(start == NULL ? end : start,
                         CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&start_time,NULL));
cl(GetEventProfilingInfo(end,
                         CL_PROFILING_COMMAND_END,  sizeof(cl_ulong),&end_time,  NULL));

elapsed_ns += end_time - start_time;

if (start != NULL)
  cl(ReleaseEvent(start));

cl(ReleaseEvent(end));

Example 2:


cl_program program = clCreateProgramWithSource(context,
                                               1,
                                               strings,
                                               strings_sizeof,
                                               &err);
cl_ok(err);

char const * const options = 
  "-cl-std=CL2.0 -cl-fast-relaxed-math "
  "-cl-no-signed-zeros -cl-mad-enable "
  "-cl-denorms-are-zero "
  "-cl-kernel-arg-info";

cl(BuildProgram(program,
                1,
                &device_id,
                options,
                NULL,
                NULL));

//
//
//
#include <stdlib.h>
#include <stdio.h>
//
//
//
#include "assert_cl.h"
//
//
//
#define CL_ERR_TO_STR(err) case err: return #err
//
//
//
char const *
clGetErrorString(cl_int const err)
{
switch(err)
{
CL_ERR_TO_STR(CL_SUCCESS);
CL_ERR_TO_STR(CL_DEVICE_NOT_FOUND);
CL_ERR_TO_STR(CL_DEVICE_NOT_AVAILABLE);
CL_ERR_TO_STR(CL_COMPILER_NOT_AVAILABLE);
CL_ERR_TO_STR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
CL_ERR_TO_STR(CL_OUT_OF_RESOURCES);
CL_ERR_TO_STR(CL_OUT_OF_HOST_MEMORY);
CL_ERR_TO_STR(CL_PROFILING_INFO_NOT_AVAILABLE);
CL_ERR_TO_STR(CL_MEM_COPY_OVERLAP);
CL_ERR_TO_STR(CL_IMAGE_FORMAT_MISMATCH);
CL_ERR_TO_STR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
CL_ERR_TO_STR(CL_BUILD_PROGRAM_FAILURE);
CL_ERR_TO_STR(CL_MAP_FAILURE);
CL_ERR_TO_STR(CL_MISALIGNED_SUB_BUFFER_OFFSET);
CL_ERR_TO_STR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
CL_ERR_TO_STR(CL_COMPILE_PROGRAM_FAILURE);
CL_ERR_TO_STR(CL_LINKER_NOT_AVAILABLE);
CL_ERR_TO_STR(CL_LINK_PROGRAM_FAILURE);
CL_ERR_TO_STR(CL_DEVICE_PARTITION_FAILED);
CL_ERR_TO_STR(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
CL_ERR_TO_STR(CL_INVALID_VALUE);
CL_ERR_TO_STR(CL_INVALID_DEVICE_TYPE);
CL_ERR_TO_STR(CL_INVALID_PLATFORM);
CL_ERR_TO_STR(CL_INVALID_DEVICE);
CL_ERR_TO_STR(CL_INVALID_CONTEXT);
CL_ERR_TO_STR(CL_INVALID_QUEUE_PROPERTIES);
CL_ERR_TO_STR(CL_INVALID_COMMAND_QUEUE);
CL_ERR_TO_STR(CL_INVALID_HOST_PTR);
CL_ERR_TO_STR(CL_INVALID_MEM_OBJECT);
CL_ERR_TO_STR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
CL_ERR_TO_STR(CL_INVALID_IMAGE_SIZE);
CL_ERR_TO_STR(CL_INVALID_SAMPLER);
CL_ERR_TO_STR(CL_INVALID_BINARY);
CL_ERR_TO_STR(CL_INVALID_BUILD_OPTIONS);
CL_ERR_TO_STR(CL_INVALID_PROGRAM);
CL_ERR_TO_STR(CL_INVALID_PROGRAM_EXECUTABLE);
CL_ERR_TO_STR(CL_INVALID_KERNEL_NAME);
CL_ERR_TO_STR(CL_INVALID_KERNEL_DEFINITION);
CL_ERR_TO_STR(CL_INVALID_KERNEL);
CL_ERR_TO_STR(CL_INVALID_ARG_INDEX);
CL_ERR_TO_STR(CL_INVALID_ARG_VALUE);
CL_ERR_TO_STR(CL_INVALID_ARG_SIZE);
CL_ERR_TO_STR(CL_INVALID_KERNEL_ARGS);
CL_ERR_TO_STR(CL_INVALID_WORK_DIMENSION);
CL_ERR_TO_STR(CL_INVALID_WORK_GROUP_SIZE);
CL_ERR_TO_STR(CL_INVALID_WORK_ITEM_SIZE);
CL_ERR_TO_STR(CL_INVALID_GLOBAL_OFFSET);
CL_ERR_TO_STR(CL_INVALID_EVENT_WAIT_LIST);
CL_ERR_TO_STR(CL_INVALID_EVENT);
CL_ERR_TO_STR(CL_INVALID_OPERATION);
CL_ERR_TO_STR(CL_INVALID_GL_OBJECT);
CL_ERR_TO_STR(CL_INVALID_BUFFER_SIZE);
CL_ERR_TO_STR(CL_INVALID_MIP_LEVEL);
CL_ERR_TO_STR(CL_INVALID_GLOBAL_WORK_SIZE);
CL_ERR_TO_STR(CL_INVALID_PROPERTY);
CL_ERR_TO_STR(CL_INVALID_IMAGE_DESCRIPTOR);
CL_ERR_TO_STR(CL_INVALID_COMPILER_OPTIONS);
CL_ERR_TO_STR(CL_INVALID_LINKER_OPTIONS);
CL_ERR_TO_STR(CL_INVALID_DEVICE_PARTITION_COUNT);
CL_ERR_TO_STR(CL_INVALID_PIPE_SIZE);
CL_ERR_TO_STR(CL_INVALID_DEVICE_QUEUE);
//TODO: extension errors
default:
return "UNKNOWN ERROR CODE";
}
}
//
//
//
cl_int
cl_assert(cl_int const code, char const * const file, int const line, bool const abort)
{
if (code != CL_SUCCESS)
{
char const * const err_str = clGetErrorString(code);
fprintf(stderr,
"\"%s\", line %d: cl_assert (%d) = \"%s\"",
file,line,code,err_str);
if (abort)
{
// stop profiling and reset device here if necessary
exit(code);
}
}
return code;
}
//
//
//
//
//
//
#pragma once
//
//
//
#include <CL/opencl.h>
#include <stdbool.h>
//
//
//
char const * clGetErrorString(cl_int const err);
//
//
//
cl_int cl_assert(cl_int const code, char const * const file, int const line, bool const abort);
#define cl(...) cl_assert((cl##__VA_ARGS__), __FILE__, __LINE__, true);
#define cl_ok(err) cl_assert(err, __FILE__, __LINE__, true);
//
//
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment