《Mali OpenCL SDK v1.1.0》教程样例之二“程序模板”

来源:互联网 发布:linux awk getline 编辑:程序博客网 时间:2024/06/05 20:57


  在OpenCL SDK根目录下的samples/template,存有程序的模板,其中“template.cpp”是宿主机代码模板,“assets/template.cl”是内核代码模板。template.cpp”使用了common目录下的“common.cpp”库来建立环境。


1. 设置OpenCL环境


1.1 创建上下文


  在第一个可用平台上创建一个上下文。

    if (!createContext(&context))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create an OpenCL context. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }

1.2 创建命令队列


  创建一个命令队列,排队到设备队列中。

    if (!createCommandQueue(context, &commandQueue, &device))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create the OpenCL command queue. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }

1.3 创建程序对象


  根据一个给定文件创建一个程序对象并编译。

    if (!createProgram(context, device, "assets/template.cl", &program))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create OpenCL program." << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }

1.4 创建内核对象


  为内核函数创建一个内核对象。

    kernel = clCreateKernel(program, "template", &errorNumber);    if (!checkSuccess(errorNumber))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create OpenCL kernel. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }


2. 设置内存与数据


2.1 创建内存缓冲区


  为任何你需要从设备中访问的数据请求内存缓冲区,更多信息参考样例"hello world"。


2.2 初始化输入数据


  如果你需要从CPU端初始化数据,那么你需要:

    a. 映射缓冲区到本地指针;

    b. 使用映射的指针初始化数据;

    c.  取消映射。

更多信息参考样例"hello world"。


2.3 设置内核参数


  传递内存缓冲区或其它变量到内核对象,以作为参数。更多信息参考样例"hello world"。



3. 执行内核实例


3.1 定义内核实例数量


  globalWorkSize决定运行多少个内核实例。

    const int workDimensions = 1;    size_t globalWorkSize[workDimensions] = {1};

3.2 内核入队


  内核入队等待执行,为获取检索信息,我们定义一个cl_event,并把它传递到clEnqueueNDRangeKernel()。

    /* An event to associate with the kernel. Allows us to retrieve profiling information later. */    cl_event event = 0;    if (!checkSuccess(clEnqueueNDRangeKernel(commandQueue, kernel, workDimensions, NULL, globalWorkSize, NULL, 0, NULL, &event)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed enqueuing the kernel. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }

3.3 等待内核执行


  等待直到所有的内核实例执行完成。注意,这可能并不需要,具体取决于应用场合。

    if (!checkSuccess(clFinish(commandQueue)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed waiting for kernel execution to finish. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }


4. 内核执行后


4.1 打印检索信息


  打印事件的检索信息(排队,等待和运行时间)。

    printProfilingInfo(event);    /* Release the event object. */    if (!checkSuccess(clReleaseEvent(event)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed releasing the event object. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }

4.2 检索结果


  为了在CPU端访问计算结果,那么你需要:
    a. 映射缓冲区到本地指针;
    b. 使用映射的指针初始化数据;
    c.  取消映射。
更多信息参考样例"hello world"。


4.3 释放OpenCL对象


  释放任何已创建的OpenCL对象。

cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);



5. 样例运行


  参考样例"hello world":http://blog.csdn.net/cloud_desktop/article/details/20048917



6. 模板源代码



6.1 宿主机源代码


/* * This confidential and proprietary software may be used only as * authorised by a licensing agreement from ARM Limited *    (C) COPYRIGHT 2013 ARM Limited *        ALL RIGHTS RESERVED * The entire notice above must be reproduced on all authorised * copies and copies may only be made to the extent permitted * by a licensing agreement from ARM Limited. */#include "common.h"#include "image.h"#include <CL/cl.h>#include <iostream>using namespace std;/** * \brief Simple template OpenCL sample. * \details The basic code to run a kernel with no arguments. * \return The exit code of the application, non-zero if a problem occurred. */int main(void){    cl_context context = 0;    cl_command_queue commandQueue = 0;    cl_program program = 0;    cl_device_id device = 0;    cl_kernel kernel = 0;    const int numMemoryObjects = 1;    cl_mem memoryObjects[numMemoryObjects] = {0};    cl_int errorNumber;    /* Set up OpenCL environment: create context, command queue, program and kernel. */    /* [Create Context] */    if (!createContext(&context))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create an OpenCL context. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Create Context] */    /* [Create Command Queue] */    if (!createCommandQueue(context, &commandQueue, &device))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create the OpenCL command queue. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Create Command Queue] */    /* [Create Program] */    if (!createProgram(context, device, "assets/template.cl", &program))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create OpenCL program." << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Create Program] */    /* [Create kernel] */    kernel = clCreateKernel(program, "template", &errorNumber);    if (!checkSuccess(errorNumber))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed to create OpenCL kernel. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Create kernel] */    /*     * Add code here to set up memory/data, for example:     * - Create memory buffers.     * - Initialise the input data.     * - Set up kernel arguments.     */    /* Execute the kernel instances. */    /* [Set the kernel work size] */    const int workDimensions = 1;    size_t globalWorkSize[workDimensions] = {1};    /* [Set the kernel work size] */    /* [Enqueue the kernel] */    /* An event to associate with the kernel. Allows us to retrieve profiling information later. */    cl_event event = 0;    if (!checkSuccess(clEnqueueNDRangeKernel(commandQueue, kernel, workDimensions, NULL, globalWorkSize, NULL, 0, NULL, &event)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed enqueuing the kernel. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Enqueue the kernel] */    /* [Wait for kernel execution completion] */    if (!checkSuccess(clFinish(commandQueue)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed waiting for kernel execution to finish. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Wait for kernel execution completion] */    /* After execution. */    /* [Print the profiling information for the event] */    printProfilingInfo(event);    /* Release the event object. */    if (!checkSuccess(clReleaseEvent(event)))    {        cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);        cerr << "Failed releasing the event object. " << __FILE__ << ":"<< __LINE__ << endl;        return 1;    }    /* [Print the profiling information for the event] */    /* Add code here to retrieve results of the kernel execution. */    /* [Release OpenCL objects] */    cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numMemoryObjects);    /* [Release OpenCL objects] */    return 0;}


6.2 common.cpp库源代码


/* * This confidential and proprietary software may be used only as * authorised by a licensing agreement from ARM Limited *   (C) COPYRIGHT 2013 ARM Limited *       ALL RIGHTS RESERVED * The entire notice above must be reproduced on all authorised * copies and copies may only be made to the extent permitted * by a licensing agreement from ARM Limited. */#include "common.h"#include <iostream>#include <sstream>#include <fstream>using namespace std;bool printProfilingInfo(cl_event event){    cl_ulong queuedTime = 0;    if (!checkSuccess(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &queuedTime, NULL)))    {        cerr << "Retrieving CL_PROFILING_COMMAND_QUEUED OpenCL profiling information failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    cl_ulong submittedTime = 0;    if (!checkSuccess(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &submittedTime, NULL)))    {        cerr << "Retrieving CL_PROFILING_COMMAND_SUBMIT OpenCL profiling information failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    cl_ulong startTime = 0;    if (!checkSuccess(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &startTime, NULL)))    {        cerr << "Retrieving CL_PROFILING_COMMAND_START OpenCL profiling information failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    cl_ulong endTime = 0;    if (!checkSuccess(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &endTime, NULL)))    {        cerr << "Retrieving CL_PROFILING_COMMAND_END OpenCL profiling information failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    cout << "Profiling information:\n";    /* OpenCL returns times in nano seconds. Print out the times in milliseconds (divide by a million). */    cout << "Queued time: \t" << (submittedTime - queuedTime) / 1000000.0 << "ms\n";    cout << "Wait time: \t" << (startTime - submittedTime) / 1000000.0 << "ms\n";    cout << "Run time: \t" << (endTime - startTime) / 1000000.0 << "ms" << endl;    return true;}bool printSupported2DImageFormats(cl_context context){    /* Get the number of supported image formats in order to allocate the correct amount of memory. */    cl_uint numberOfImageFormats;    if (!checkSuccess(clGetSupportedImageFormats(context, 0, CL_MEM_OBJECT_IMAGE2D, 0, NULL, &numberOfImageFormats)))    {        cerr << "Getting the number of supported 2D image formats failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /* Get the list of supported image formats. */    cl_image_format* imageFormats = new cl_image_format[numberOfImageFormats];    if (!checkSuccess(clGetSupportedImageFormats(context, 0, CL_MEM_OBJECT_IMAGE3D, numberOfImageFormats, imageFormats, NULL)))    {        cerr << "Getting the list of supported 2D image formats failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    cout << numberOfImageFormats << " Image formats supported";    if (numberOfImageFormats > 0)    {        cout << " (channel order, channel data type):" << endl;    }    else    {        cout << "." << endl;    }    for (unsigned int i = 0; i < numberOfImageFormats; i++)    {        cout << imageChannelOrderToString(imageFormats[i].image_channel_order) << ", " << imageChannelDataTypeToString(imageFormats[i].image_channel_data_type) << endl;    }    delete[] imageFormats;    return true;}string imageChannelOrderToString(cl_channel_order channelOrder){    switch (channelOrder)    {        case CL_R:            return "CL_R";        case CL_A:            return "CL_A";        case CL_RG:             return "CL_RG";        case CL_RA:             return "CL_RA";        case CL_RGB:            return "CL_RGB";        case CL_RGBA:            return "CL_RGBA";        case CL_BGRA:            return "CL_BGRA";        case CL_ARGB:            return "CL_ARGB";        case CL_INTENSITY:            return "CL_INTENSITY";        case CL_LUMINANCE:            return "CL_LUMINANCE";        case CL_Rx:            return "CL_Rx";        case CL_RGx:            return "CL_RGx";        case CL_RGBx:            return "CL_RGBx";        default:            return "Unknown image channel order";    }}string imageChannelDataTypeToString(cl_channel_type channelDataType){    switch (channelDataType)    {        case CL_SNORM_INT8:            return "CL_SNORM_INT8";        case CL_SNORM_INT16:            return "CL_SNORM_INT16";        case CL_UNORM_INT8:            return "CL_UNORM_INT8";        case CL_UNORM_INT16:            return "CL_UNORM_INT16";        case CL_UNORM_SHORT_565:            return "CL_UNORM_SHORT_565";        case CL_UNORM_SHORT_555:            return "CL_UNORM_SHORT_555";        case CL_UNORM_INT_101010:            return "CL_UNORM_INT_101010";        case CL_SIGNED_INT8:            return "CL_SIGNED_INT8";        case CL_SIGNED_INT16:            return "CL_SIGNED_INT16";        case CL_SIGNED_INT32:            return "CL_SIGNED_INT32";        case CL_UNSIGNED_INT8:            return "CL_UNSIGNED_INT8";        case CL_UNSIGNED_INT16:            return "CL_UNSIGNED_INT16";        case CL_UNSIGNED_INT32:            return "CL_UNSIGNED_INT32";        case CL_HALF_FLOAT:            return "CL_HALF_FLOAT";        case CL_FLOAT:            return "CL_FLOAT";        default:            return "Unknown image channel data type";    }}bool cleanUpOpenCL(cl_context context, cl_command_queue commandQueue, cl_program program, cl_kernel kernel, cl_mem* memoryObjects, int numberOfMemoryObjects){    bool returnValue = true;    if (context != 0)    {        if (!checkSuccess(clReleaseContext(context)))        {            cerr << "Releasing the OpenCL context failed. " << __FILE__ << ":"<< __LINE__ << endl;            returnValue = false;        }    }    if (commandQueue != 0)    {        if (!checkSuccess(clReleaseCommandQueue(commandQueue)))        {            cerr << "Releasing the OpenCL command queue failed. " << __FILE__ << ":"<< __LINE__ << endl;            returnValue = false;        }    }    if (kernel != 0)    {        if (!checkSuccess(clReleaseKernel(kernel)))        {            cerr << "Releasing the OpenCL kernel failed. " << __FILE__ << ":"<< __LINE__ << endl;            returnValue = false;        }    }    if (program != 0)    {        if (!checkSuccess(clReleaseProgram(program)))        {            cerr << "Releasing the OpenCL program failed. " << __FILE__ << ":"<< __LINE__ << endl;            returnValue = false;        }    }    for (int index = 0; index < numberOfMemoryObjects; index++)    {        if (memoryObjects[index] != 0)        {            if (!checkSuccess(clReleaseMemObject(memoryObjects[index])))            {                cerr << "Releasing the OpenCL memory object " << index << " failed. " << __FILE__ << ":"<< __LINE__ << endl;                returnValue = false;            }        }    }    return returnValue;}bool createContext(cl_context* context){    cl_int errorNumber = 0;    cl_uint numberOfPlatforms = 0;    cl_platform_id firstPlatformID = 0;    /* Retrieve a single platform ID. */    if (!checkSuccess(clGetPlatformIDs(1, &firstPlatformID, &numberOfPlatforms)))    {        cerr << "Retrieving OpenCL platforms failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    if (numberOfPlatforms <= 0)    {        cerr << "No OpenCL platforms found. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /* Get a context with a GPU device from the platform found above. */    cl_context_properties contextProperties [] = {CL_CONTEXT_PLATFORM, (cl_context_properties)firstPlatformID, 0};    *context = clCreateContextFromType(contextProperties, CL_DEVICE_TYPE_GPU, NULL, NULL, &errorNumber);    if (!checkSuccess(errorNumber))    {        cerr << "Creating an OpenCL context failed. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    return true;}bool createCommandQueue(cl_context context, cl_command_queue* commandQueue, cl_device_id* device){    cl_int errorNumber = 0;    cl_device_id* devices = NULL;    size_t deviceBufferSize = -1;    /* Retrieve the size of the buffer needed to contain information about the devices in this OpenCL context. */    if (!checkSuccess(clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &deviceBufferSize)))    {        cerr << "Failed to get OpenCL context information. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    if(deviceBufferSize == 0)    {        cerr << "No OpenCL devices found. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /* Retrieve the list of devices available in this context. */    devices = new cl_device_id[deviceBufferSize / sizeof(cl_device_id)];    if (!checkSuccess(clGetContextInfo(context, CL_CONTEXT_DEVICES, deviceBufferSize, devices, NULL)))    {        cerr << "Failed to get the OpenCL context information. " << __FILE__ << ":"<< __LINE__ << endl;        delete [] devices;        return false;    }    /* Use the first available device in this context. */    *device = devices[0];    delete [] devices;    /* Set up the command queue with the selected device. */    *commandQueue = clCreateCommandQueue(context, *device, CL_QUEUE_PROFILING_ENABLE, &errorNumber);    if (!checkSuccess(errorNumber))    {        cerr << "Failed to create the OpenCL command queue. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    return true;}bool createProgram(cl_context context, cl_device_id device, string filename, cl_program* program){    cl_int errorNumber = 0;    ifstream kernelFile(filename.c_str(), ios::in);    if(!kernelFile.is_open())    {        cerr << "Unable to open " << filename << ". " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /*     * Read the kernel file into an output stream.     * Convert this into a char array for passing to OpenCL.     */    ostringstream outputStringStream;    outputStringStream << kernelFile.rdbuf();    string srcStdStr = outputStringStream.str();    const char* charSource = srcStdStr.c_str();    *program = clCreateProgramWithSource(context, 1, &charSource, NULL, &errorNumber);    if (!checkSuccess(errorNumber) || program == NULL)    {        cerr << "Failed to create OpenCL program. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /* Try to build the OpenCL program. */    bool buildSuccess = checkSuccess(clBuildProgram(*program, 0, NULL, NULL, NULL, NULL));    /* Get the size of the build log. */    size_t logSize = 0;    clGetProgramBuildInfo(*program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);    /*     * If the build succeeds with no log, an empty string is returned (logSize = 1),     * we only want to print the message if it has some content (logSize > 1).     */    if (logSize > 1)    {        char* log = new char[logSize];        clGetProgramBuildInfo(*program, device, CL_PROGRAM_BUILD_LOG, logSize, log, NULL);        string* stringChars = new string(log, logSize);        cerr << "Build log:\n " << *stringChars << endl;        delete[] log;        delete stringChars;    }    if (!buildSuccess)    {        clReleaseProgram(*program);        cerr << "Failed to build OpenCL program. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    return true;}inline bool checkSuccess(cl_int errorNumber){    if (errorNumber != CL_SUCCESS)    {        cerr << "OpenCL error: " << errorNumberToString(errorNumber) << endl;        return false;    }    return true;}string errorNumberToString(cl_int errorNumber){    switch (errorNumber)    {        case CL_SUCCESS:            return "CL_SUCCESS";        case CL_DEVICE_NOT_FOUND:            return "CL_DEVICE_NOT_FOUND";        case CL_DEVICE_NOT_AVAILABLE:            return "CL_DEVICE_NOT_AVAILABLE";        case CL_COMPILER_NOT_AVAILABLE:            return "CL_COMPILER_NOT_AVAILABLE";        case CL_MEM_OBJECT_ALLOCATION_FAILURE:            return "CL_MEM_OBJECT_ALLOCATION_FAILURE";        case CL_OUT_OF_RESOURCES:            return "CL_OUT_OF_RESOURCES";        case CL_OUT_OF_HOST_MEMORY:            return "CL_OUT_OF_HOST_MEMORY";        case CL_PROFILING_INFO_NOT_AVAILABLE:            return "CL_PROFILING_INFO_NOT_AVAILABLE";        case CL_MEM_COPY_OVERLAP:            return "CL_MEM_COPY_OVERLAP";        case CL_IMAGE_FORMAT_MISMATCH:            return "CL_IMAGE_FORMAT_MISMATCH";        case CL_IMAGE_FORMAT_NOT_SUPPORTED:            return "CL_IMAGE_FORMAT_NOT_SUPPORTED";        case CL_BUILD_PROGRAM_FAILURE:            return "CL_BUILD_PROGRAM_FAILURE";        case CL_MAP_FAILURE:            return "CL_MAP_FAILURE";        case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:            return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";        case CL_INVALID_VALUE:            return "CL_INVALID_VALUE";        case CL_INVALID_DEVICE_TYPE:            return "CL_INVALID_DEVICE_TYPE";        case CL_INVALID_PLATFORM:            return "CL_INVALID_PLATFORM";        case CL_INVALID_DEVICE:            return "CL_INVALID_DEVICE";        case CL_INVALID_CONTEXT:            return "CL_INVALID_CONTEXT";        case CL_INVALID_QUEUE_PROPERTIES:            return "CL_INVALID_QUEUE_PROPERTIES";        case CL_INVALID_COMMAND_QUEUE:            return "CL_INVALID_COMMAND_QUEUE";        case CL_INVALID_HOST_PTR:            return "CL_INVALID_HOST_PTR";        case CL_INVALID_MEM_OBJECT:            return "CL_INVALID_MEM_OBJECT";        case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:            return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";        case CL_INVALID_IMAGE_SIZE:            return "CL_INVALID_IMAGE_SIZE";        case CL_INVALID_SAMPLER:            return "CL_INVALID_SAMPLER";        case CL_INVALID_BINARY:            return "CL_INVALID_BINARY";        case CL_INVALID_BUILD_OPTIONS:            return "CL_INVALID_BUILD_OPTIONS";        case CL_INVALID_PROGRAM:            return "CL_INVALID_PROGRAM";        case CL_INVALID_PROGRAM_EXECUTABLE:            return "CL_INVALID_PROGRAM_EXECUTABLE";        case CL_INVALID_KERNEL_NAME:            return "CL_INVALID_KERNEL_NAME";        case CL_INVALID_KERNEL_DEFINITION:            return "CL_INVALID_KERNEL_DEFINITION";        case CL_INVALID_KERNEL:            return "CL_INVALID_KERNEL";        case CL_INVALID_ARG_INDEX:            return "CL_INVALID_ARG_INDEX";        case CL_INVALID_ARG_VALUE:            return "CL_INVALID_ARG_VALUE";        case CL_INVALID_ARG_SIZE:            return "CL_INVALID_ARG_SIZE";        case CL_INVALID_KERNEL_ARGS:            return "CL_INVALID_KERNEL_ARGS";        case CL_INVALID_WORK_DIMENSION:            return "CL_INVALID_WORK_DIMENSION";        case CL_INVALID_WORK_GROUP_SIZE:            return "CL_INVALID_WORK_GROUP_SIZE";        case CL_INVALID_WORK_ITEM_SIZE:            return "CL_INVALID_WORK_ITEM_SIZE";        case CL_INVALID_GLOBAL_OFFSET:            return "CL_INVALID_GLOBAL_OFFSET";        case CL_INVALID_EVENT_WAIT_LIST:            return "CL_INVALID_EVENT_WAIT_LIST";        case CL_INVALID_EVENT:            return "CL_INVALID_EVENT";        case CL_INVALID_OPERATION:            return "CL_INVALID_OPERATION";        case CL_INVALID_GL_OBJECT:            return "CL_INVALID_GL_OBJECT";        case CL_INVALID_BUFFER_SIZE:            return "CL_INVALID_BUFFER_SIZE";        case CL_INVALID_MIP_LEVEL:            return "CL_INVALID_MIP_LEVEL";        default:            return "Unknown error";    }}bool isExtensionSupported(cl_device_id device, string extension){    if (extension.empty())    {        return false;    }    /* First find out how large the ouput of the OpenCL device query will be. */    size_t extensionsReturnSize = 0;    if (!checkSuccess(clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, 0, NULL, &extensionsReturnSize)))    {        cerr << "Failed to get return size from clGetDeviceInfo for parameter CL_DEVICE_EXTENSIONS. " << __FILE__ << ":"<< __LINE__ << endl;        return false;    }    /* Allocate enough memory for the output. */    char* extensions = new char[extensionsReturnSize];    /* Get the list of all extensions supported. */    if (!checkSuccess(clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, extensionsReturnSize, extensions, NULL)))    {        cerr << "Failed to get data from clGetDeviceInfo for parameter CL_DEVICE_EXTENSIONS. " << __FILE__ << ":"<< __LINE__ << endl;        delete [] extensions;        return false;    }    /* See if the requested extension is in the list. */    string* extensionsString = new string(extensions);    bool returnResult = false;    if (extensionsString->find(extension) != string::npos)    {        returnResult = true;    }    delete [] extensions;    delete extensionsString;    return returnResult;}




0 0