1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
#pragma once #ifndef _OPENCL_AUTO_h_
#define _OPENCL_AUTO_h_
#include <CL/cl.h> #include <iostream>
// check the opencl status, if there is an error, return the error type and exit #define CHECK_STATUS( status ) if ( status != CL_SUCCESS ) { fprintf( stderr, "OpenCL error in file %s line %d, error code %sn", __FILE__, __LINE__, opencl_error_to_str( status ) ); exit(-1); }
#define CASE_CL_ERROR( NAME ) case NAME: return #NAME;
const char* opencl_error_to_str( cl_int error ) { switch ( error ) { // error codes CASE_CL_ERROR( CL_SUCCESS ) CASE_CL_ERROR( CL_DEVICE_NOT_FOUND ) CASE_CL_ERROR( CL_DEVICE_NOT_AVAILABLE ) CASE_CL_ERROR( CL_COMPILER_NOT_AVAILABLE ) CASE_CL_ERROR( CL_MEM_OBJECT_ALLOCATION_FAILURE ) CASE_CL_ERROR( CL_OUT_OF_RESOURCES ) CASE_CL_ERROR( CL_OUT_OF_HOST_MEMORY ) CASE_CL_ERROR( CL_PROFILING_INFO_NOT_AVAILABLE ) CASE_CL_ERROR( CL_MEM_COPY_OVERLAP ) CASE_CL_ERROR( CL_IMAGE_FORMAT_MISMATCH ) CASE_CL_ERROR( CL_IMAGE_FORMAT_NOT_SUPPORTED ) CASE_CL_ERROR( CL_BUILD_PROGRAM_FAILURE ) CASE_CL_ERROR( CL_MAP_FAILURE ) CASE_CL_ERROR( CL_MISALIGNED_SUB_BUFFER_OFFSET ) CASE_CL_ERROR( CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST ) CASE_CL_ERROR( CL_COMPILE_PROGRAM_FAILURE ) CASE_CL_ERROR( CL_LINKER_NOT_AVAILABLE ) CASE_CL_ERROR( CL_LINK_PROGRAM_FAILURE ) CASE_CL_ERROR( CL_DEVICE_PARTITION_FAILED ) CASE_CL_ERROR( CL_KERNEL_ARG_INFO_NOT_AVAILABLE ) CASE_CL_ERROR( CL_INVALID_VALUE ) CASE_CL_ERROR( CL_INVALID_DEVICE_TYPE ) CASE_CL_ERROR( CL_INVALID_PLATFORM ) CASE_CL_ERROR( CL_INVALID_DEVICE ) CASE_CL_ERROR( CL_INVALID_CONTEXT ) CASE_CL_ERROR( CL_INVALID_QUEUE_PROPERTIES ) CASE_CL_ERROR( CL_INVALID_COMMAND_QUEUE ) CASE_CL_ERROR( CL_INVALID_HOST_PTR ) CASE_CL_ERROR( CL_INVALID_MEM_OBJECT ) CASE_CL_ERROR( CL_INVALID_IMAGE_FORMAT_DESCRIPTOR ) CASE_CL_ERROR( CL_INVALID_IMAGE_SIZE ) CASE_CL_ERROR( CL_INVALID_SAMPLER ) CASE_CL_ERROR( CL_INVALID_BINARY ) CASE_CL_ERROR( CL_INVALID_BUILD_OPTIONS ) CASE_CL_ERROR( CL_INVALID_PROGRAM ) CASE_CL_ERROR( CL_INVALID_PROGRAM_EXECUTABLE ) CASE_CL_ERROR( CL_INVALID_KERNEL_NAME ) CASE_CL_ERROR( CL_INVALID_KERNEL_DEFINITION ) CASE_CL_ERROR( CL_INVALID_KERNEL ) CASE_CL_ERROR( CL_INVALID_ARG_INDEX ) CASE_CL_ERROR( CL_INVALID_ARG_VALUE ) CASE_CL_ERROR( CL_INVALID_ARG_SIZE ) CASE_CL_ERROR( CL_INVALID_KERNEL_ARGS ) CASE_CL_ERROR( CL_INVALID_WORK_DIMENSION ) CASE_CL_ERROR( CL_INVALID_WORK_GROUP_SIZE ) CASE_CL_ERROR( CL_INVALID_WORK_ITEM_SIZE ) CASE_CL_ERROR( CL_INVALID_GLOBAL_OFFSET ) CASE_CL_ERROR( CL_INVALID_EVENT_WAIT_LIST ) CASE_CL_ERROR( CL_INVALID_EVENT ) CASE_CL_ERROR( CL_INVALID_OPERATION ) CASE_CL_ERROR( CL_INVALID_GL_OBJECT ) CASE_CL_ERROR( CL_INVALID_BUFFER_SIZE ) CASE_CL_ERROR( CL_INVALID_MIP_LEVEL ) CASE_CL_ERROR( CL_INVALID_GLOBAL_WORK_SIZE ) CASE_CL_ERROR( CL_INVALID_PROPERTY ) CASE_CL_ERROR( CL_INVALID_IMAGE_DESCRIPTOR ) CASE_CL_ERROR( CL_INVALID_COMPILER_OPTIONS ) CASE_CL_ERROR( CL_INVALID_LINKER_OPTIONS ) CASE_CL_ERROR( CL_INVALID_DEVICE_PARTITION_COUNT ) CASE_CL_ERROR( CL_INVALID_PIPE_SIZE ) CASE_CL_ERROR( CL_INVALID_DEVICE_QUEUE ) default: return "UNKNOWN ERROR CODE"; } }
struct openclStruct { private: cl_platform_id clPlatform; cl_device_id clDevice; cl_context clContext; cl_command_queue clCmdQueue; cl_program clProgram; char* clFilePath; char* readFile(); // read the kernel source code to a char*
public: cl_int clStatus; cl_context& getContext() { return clContext; } cl_command_queue& getCommandQueue() { return clCmdQueue; } cl_program& getProgram() { return clProgram; } cl_kernel createKernel( char* kernelName ); // create the kernel cl_mem createMem( cl_mem_flags clMemType, size_t dataSize ); openclStruct( char* filePath ); // filePatth is the path of the kernel file, init the opencl and get a --GPU-- device ~openclStruct(); };
openclStruct::openclStruct( char* filePath ) { clFilePath = filePath; clStatus = clGetPlatformIDs( 1, &clPlatform, NULL ); CHECK_STATUS( clStatus ); clStatus = clGetDeviceIDs( clPlatform, CL_DEVICE_TYPE_GPU, 1, &clDevice, NULL ); // if want to return other type device, change the CL_DEVICE_TYPE_GPU CHECK_STATUS( clStatus ); clContext = clCreateContext( 0, 1, &clDevice, NULL, NULL, &clStatus ); CHECK_STATUS( clStatus ); clCmdQueue = clCreateCommandQueueWithProperties( clContext, clDevice, 0, &clStatus ); CHECK_STATUS( clStatus ); const char* programSource = readFile(); size_t sourceSize[] = {strlen( programSource )}; clProgram = clCreateProgramWithSource( clContext, 1, &programSource, sourceSize, &clStatus ); CHECK_STATUS( clStatus ); clStatus = clBuildProgram( clProgram, 1, &clDevice, NULL, NULL, NULL ); // if build program failed, print the log if ( clStatus != CL_SUCCESS ) { size_t len; char buffer[8 * 1024]; clGetProgramBuildInfo( clProgram, clDevice, CL_PROGRAM_BUILD_LOG, sizeof( buffer ), buffer, &len ); printf( "%sn", buffer ); exit(-1); } }
openclStruct::~openclStruct() { clReleaseProgram( clProgram ); clReleaseCommandQueue( clCmdQueue ); clReleaseContext( clContext ); }
cl_kernel openclStruct::createKernel( char* kernelName ) { cl_kernel clKernel = clCreateKernel( clProgram, kernelName, &clStatus ); CHECK_STATUS( clStatus ); return clKernel; }
cl_mem openclStruct::createMem( cl_mem_flags clMemType, size_t dataSize ) { cl_mem bufTemp = clCreateBuffer( clContext, clMemType, dataSize, NULL, &clStatus ); CHECK_STATUS( clStatus ); return bufTemp; }
char* openclStruct::readFile() { FILE* fp; char* fileData; fp = fopen( clFilePath, "rb" ); if ( !fp ) { std::cout << "Could not open the file" << std::endl; exit( -1 ); } if ( fseek( fp, 0, SEEK_END ) ) { std::cout << "Error read the file" << std::endl; exit( -1 ); } long fileSize = ftell( fp ); if ( fileSize < 0 ) { std::cout << "Error read the file" << std::endl; exit( -1 ); } if ( fseek( fp, 0, SEEK_SET ) ) { std::cout << "Error read the file" << std::endl; exit( -1 ); } fileData = (char*)malloc( fileSize + 1 ); fileData[fileSize] = '
|
近期评论