#ifndef OPENCLHELPER_H #define OPENCLHELPER_H #define CL_HPP_MINIMUM_OPENCL_VERSION 120 #define CL_HPP_TARGET_OPENCL_VERSION 120 #include #include #include #include "CL/cl2.hpp" #include "ESeverityLevel.h" #include "ELogId.h" using namespace cl; class OpenCLHelper : public QObject { Q_OBJECT private: inline void handleError(ESeverityLevel::eSeverityLevel severityLevel, ELogID::eLogId logID, QString logText, bool emitThrow = true) const; inline std::vector getPlatforms(); inline std::vector getDevices(std::vector platforms); inline QString getDeviceName(const Device& device); public: inline Context getContext(); inline Kernel createKernel(const Context context, const QString kernelPath, const QString KernelName); inline Buffer* array2CLBuffer(const Context &context, quint64 size, bool read); inline Image* frame2CLFrame(const Context& context, ImageFormat clFrameFormat, QVector dimensions, bool read); inline CommandQueue createCommandQueue(const Context& context, const Device& device, const cl_command_queue_properties properties); template inline KernelFunctor createKernelFunctor(const Kernel& kernel); inline QVector getDevicesByContext(const Context& context); inline size_t* getMaxGlobalWorkSize(const Kernel& kernel, const Device& device); template inline void runKernelFunctor(KernelFunctor& kernelFunctor, EnqueueArgs args, Ts... ts); signals: void sgl_sendLog (ESeverityLevel::eSeverityLevel severityLevel, ELogID::eLogId logID, QString logText) const; }; void OpenCLHelper::handleError(ESeverityLevel::eSeverityLevel severityLevel, ELogID::eLogId logID, QString logText, bool emitThrow) const { qDebug() << logText; } std::vector OpenCLHelper::getPlatforms() { std::vector platforms; try { if (Platform::get(&platforms) == CL_INVALID_VALUE) { handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, "(CL_INVALID_VALUE)Error getting CL Platforms"); } } catch (...) { throw; } /// Removes platforms which are not nvidia or amd based try { std::vector temp(platforms); platforms.clear(); for (auto it = temp.begin(); it != temp.end(); it++) { string currentPlatformName = it->getInfo(); handleError(ESeverityLevel::Debug, ELogID::CLPlatformInfo, "Platform Name: " + QString::fromStdString(currentPlatformName), false); if (!(it->getInfo().find("NVIDIA") == string::npos) || !(it->getInfo().find("AMD") == string::npos)) { platforms.push_back(*it); } } } catch (...) { throw; } try { if (platforms.size() == 0) { handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, "No valid NVIDIA or AMD platform available."); } } catch (...) { throw; } return platforms; } std::vector OpenCLHelper::getDevices(std::vector platforms) { vector devices; try { if (platforms.size() == 0) { handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, "No valid platforms."); } } catch (...) { throw; } for (auto platform = platforms.begin(); platform != platforms.end(); platform++) { vector tempDevices; try { switch(cl_int err = platform->getDevices(CL_DEVICE_TYPE_GPU, &devices)) { case CL_INVALID_DEVICE_TYPE: { QString messageText = QString::fromStdString( "(CL_INVALID_DEVICE_TYPE) Invalid CL device type (" + std::to_string(CL_DEVICE_TYPE_GPU) + ") while getting devices of platform " + platform->getInfo()); handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, messageText, false); break; } case CL_INVALID_ARG_VALUE: { QString messageText = QString::fromStdString( "(CL_INVALID_ARG_VALUE) Null device while getting devices of platform " + platform->getInfo()); handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, messageText, false); break; } case CL_SUCCESS: { devices.insert(devices.begin(), tempDevices.begin(), tempDevices.end()); QString logText = "Devices registered successfuly: \""; for (auto deviceIt = devices.begin(); deviceIt != devices.end(); deviceIt++) { logText = logText + QString::fromStdString(deviceIt->getInfo() + ","); } logText = logText + "\""; handleError(ESeverityLevel::Debug, ELogID::CLPlatformInfo, logText, false); break; } default: { QString messageText = "Unknown error occured while getting devices of platform " + QString::fromStdString(platform->getInfo()) + ". CL error: " + QString::number(err); break; } } // end of switch } catch (...) { throw; } } return devices; } Context OpenCLHelper::getContext() { static Context* context = nullptr; if (context) { return *context; } vector allPlatforms; try { allPlatforms = getPlatforms(); } catch(...) { throw; } vector allDevices; try { allDevices = getDevices(allPlatforms); } catch(...) { throw; } if (allDevices.size() == 0) { try { handleError(ESeverityLevel::Alert, ELogID::CLPlatformError, "No processing devices found."); } catch(...) { throw; } } cl_int err; context = new Context(allDevices, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR, &err); try { switch (err) { case CL_INVALID_PROPERTY: { handleError(ESeverityLevel::Critical, ELogID::CLContextError, "Error occured while creating CL context: CL_INVALID_PROPERTY"); break; } case CL_INVALID_DEVICE_TYPE: { handleError(ESeverityLevel::Critical, ELogID::CLContextError, "Error occured while creating CL context: CL_INVALID_DEVICE_TYPE"); break; } case CL_DEVICE_NOT_AVAILABLE: { handleError(ESeverityLevel::Critical, ELogID::CLContextError, "Error occured while creating CL context: CL_DEVICE_NOT_AVAILABLE"); break; } case CL_DEVICE_NOT_FOUND: { handleError(ESeverityLevel::Critical, ELogID::CLContextError, "Error occured while creating CL context: CL_DEVICE_NOT_FOUND"); break; } case CL_OUT_OF_HOST_MEMORY: { handleError(ESeverityLevel::Critical, ELogID::CLContextError, "Error occured while creating CL context: CL_OUT_OF_HOST_MEMORY"); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLContextInfo, "CL Context created successfully.", false); break; } default: { QString logText = "Unknown error while creating CL context. CL error: " + QString::number(err); handleError(ESeverityLevel::Critical, ELogID::CLContextError, logText); } } // end of switch } catch (...) { throw; } return *context; } Kernel OpenCLHelper::createKernel(const Context context, const QString kernelPath, const QString kernelName) { QString kernelFullPath = kernelPath + "/" + kernelName + ".cl"; QFile kernelFile(kernelFullPath); try { if (!kernelFile.open(QIODevice::ReadOnly | QIODevice::Text)) { handleError(ESeverityLevel::Critical, ELogID::FileOpenError, "Could not open kernel file: " + kernelFullPath); } } catch (...) { } QString kernelSource = kernelFile.readAll(); cl_int buildError; Program program(context, kernelSource.toStdString(), true, &buildError); try { switch (buildError) { case CL_INVALID_CONTEXT: { QString logText = " (CL_INVALID_CONTEXT) Error building kernel \"" + kernelFullPath + "\". Context is not valid."; handleError(ESeverityLevel::Critical, ELogID::CLKernelBuildError, logText); break; } case CL_INVALID_VALUE: { QString logText = "(CL_INVALID_VALUE) Error building kernel \"" + kernelFullPath + "\". Source contains zero entries or any entry contains a tuple with NULL."; handleError(ESeverityLevel::Critical, ELogID::CLKernelBuildError, logText); break; } case CL_OUT_OF_RESOURCES: { QString logText = "(CL_OUT_OF_RESOURCES) Error building kernel \"" + kernelFullPath + "\". Failure to allocate resources on the device."; handleError(ESeverityLevel::Critical, ELogID::CLKernelBuildError, logText); break; } case CL_OUT_OF_HOST_MEMORY: { QString logText = "(CL_OUT_OF_HOST_MEMORY) Error building kernel \"" + kernelFullPath + "\". Failure to allocate resources on the host."; handleError(ESeverityLevel::Critical, ELogID::CLKernelBuildError, logText); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Informational, ELogID::CLKernelBuilt, "Kernel \"" + kernelFullPath + "\" built successfully.", false); break; } default: { QString logText = "Unknown error occured whild building kernel \"" + kernelFullPath + "\". Error: " + QString::number(buildError); handleError(ESeverityLevel::Critical, ELogID::CLKernelBuildError, logText); } } // end of switch } catch (...) { } // It is considered that there is only one kernel in the program and it's name is known. cl_int kernelError; Kernel kernel(program, kernelName.toStdString().c_str(), &kernelError); try { switch (kernelError) { case CL_INVALID_PROGRAM: { QString logText = "(CL_INVALID_PROGRAM) Kernel creation error (" + kernelName + "): Invalid program object."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_INVALID_PROGRAM_EXECUTABLE: { QString logText = "(CL_INVALID_PROGRAM_EXECUTABLE) Kernel creation error (" + kernelName + "): There is no valid built executable."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_INVALID_KERNEL_NAME: { QString logText = "(CL_INVALID_KERNEL_NAME) Kernel creation error (" + kernelName + "): Name is not found int the program."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_INVALID_KERNEL_DEFINITION: { QString logText = "(CL_INVALID_KERNEL_DEFINITION) Kernel creation error (" + kernelName + "): Invalid kernel definition."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_INVALID_VALUE: { QString logText = "(CL_INVALID_VALUE) Kernel creation error (" + kernelName + "): Name is NULL"; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_OUT_OF_RESOURCES: { QString logText = "(CL_OUT_OF_RESOURCES) Kernel creation error (" + kernelName + "): Failure to allocate resources on the device."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_OUT_OF_HOST_MEMORY: { QString logText = "(CL_OUT_OF_HOST_MEMORY) Kernel creation error (" + kernelName + "): Failure to allocate resources on the host."; handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLKernelCreated, "Kernel created successfully for kernel: " + kernelName, false); break; } default: { QString logText = "Kernel creation error (" + kernelName + "): Unknown error: " + QString::number(kernelError); handleError(ESeverityLevel::Critical, ELogID::CLKernelCreationError, logText); } } //end of switch } catch (...) { } return kernel; } Buffer* OpenCLHelper::array2CLBuffer(const Context &context, quint64 size, bool read = true) { Buffer* buffer = Q_NULLPTR; cl_mem_flags clMemFlags = read ? CL_MEM_READ_ONLY : CL_MEM_WRITE_ONLY; cl_int error; buffer = new Buffer(context, clMemFlags, size, NULL, &error); if(error != 0) qDebug() << error; return buffer; } Image* OpenCLHelper::frame2CLFrame(const Context &context, ImageFormat clFrameFormat, QVector dimensions, bool read = true) { Image* image = Q_NULLPTR; cl_mem_flags clMemFlags = CL_MEM_READ_WRITE; cl_int* error = Q_NULLPTR; switch (dimensions.size()) { case 1: image = new Image1D(context, clMemFlags, clFrameFormat, dimensions[0], error); break; case 2: image = new Image2D(context, clMemFlags, clFrameFormat, dimensions[0], dimensions[1], 0, error); break; case 3: image = new Image3D(context, clMemFlags, clFrameFormat, dimensions[0], dimensions[1], dimensions[2], 0, 0, error); break; default: try { handleError(ESeverityLevel::Error, ELogID::CLFrameError, "Number of dimenstions is not supported: " + QString::number(dimensions.size())); } catch (...) { throw; } } try { if (error) { QString logText; switch (*error) { case CL_INVALID_CONTEXT: logText = QString("(CL_INVALID_CONTEXT) The context is not valid ") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_INVALID_VALUE: logText = QString("(CL_INVALID_VALUE) Invalid memory flags ") + "while creating CLImage: " + QString::number(clMemFlags); handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: logText = QString("(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR) Invalid CL frame format ") + "while creating CLImage: image_channel_order: " + QString::number(clFrameFormat.image_channel_order) + " image_channel_data_type: " + QString::number(clFrameFormat.image_channel_data_type); handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_INVALID_IMAGE_SIZE: logText = QString("(CL_INVALID_IMAGE_SIZE) Invalid CL frame size ") + "while creating CLImage: "; foreach (quint64 dimension, dimensions) { logText += QString::number(dimension) + ","; } handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_INVALID_HOST_PTR: logText = QString("(CL_INVALID_HOST_PTR) Invalid host pointer ") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_IMAGE_FORMAT_NOT_SUPPORTED : logText = QString("(CL_IMAGE_FORMAT_NOT_SUPPORTED) CL Frame format not supported ") + "while creating CLImage: image_channel_order: " + QString::number(clFrameFormat.image_channel_order) + " image_channel_data_type: " + QString::number(clFrameFormat.image_channel_data_type); handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_MEM_OBJECT_ALLOCATION_FAILURE: logText = QString("(CL_MEM_OBJECT_ALLOCATION_FAILURE) Failed to allocate memory ") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_INVALID_OPERATION: logText = QString("(CL_INVALID_OPERATION) No device in context to support CL frame ") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_OUT_OF_RESOURCES: logText = QString("(CL_OUT_OF_RESOURCES ) Failed to allocate resources on the device") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; case CL_OUT_OF_HOST_MEMORY: logText = QString("(CL_OUT_OF_RESOURCES ) Failed to allocate resources on the host") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; default: logText = QString("An unknown error occured ") + "while creating CLImage."; handleError(ESeverityLevel::Error, ELogID::CLFrameError, logText); break; } // end of switch } else { handleError(ESeverityLevel::Debug, ELogID::CLFrameInfo, "Frame successfully converted to CL Frame.", false); } } catch (...) { throw; } return image; } template KernelFunctor OpenCLHelper::createKernelFunctor(const Kernel& kernel) { QString kernelName = QString::fromStdString(kernel.getInfo()); cl_int error; KernelFunctor kernelFunctor(kernel.getInfo(), kernelName, &error); try { switch (error) { case CL_INVALID_PROGRAM: { QString logText = "(CL_INVALID_PROGRAM) KernelFunctor creation error (" + kernelName + "): Invalid program object."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_INVALID_PROGRAM_EXECUTABLE: { QString logText = "(CL_INVALID_PROGRAM_EXECUTABLE) KernelFunctor creation error (" + kernelName + "): There is no valid built executable."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_INVALID_KERNEL_NAME: { QString logText = "(CL_INVALID_KERNEL_NAME) KernelFunctor creation error (" + kernelName + "): Name is not found int the program."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_INVALID_KERNEL_DEFINITION: { QString logText = "(CL_INVALID_KERNEL_DEFINITION) KernelFunctor creation error (" + kernelName + "): Invalid kernel definition."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_INVALID_VALUE: { QString logText = "(CL_INVALID_VALUE) KernelFunctor creation error (" + kernelName + "): Name is NULL"; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_OUT_OF_RESOURCES: { QString logText = "(CL_OUT_OF_RESOURCES) KernelFunctor creation error (" + kernelName + "): Failure to allocate resources on the device."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_OUT_OF_HOST_MEMORY: { QString logText = "(CL_OUT_OF_HOST_MEMORY) KernelFunctor creation error (" + kernelName + "): Failure to allocate resources on the host."; handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLKernelFunctorCreated, "KernelFunctor created successfully for kernel: " + kernelName, false); break; } default: { QString logText = "KernelFunctor creation error (" + kernelName + "): Unknown error: " + QString::number(error); handleError(ESeverityLevel::Error, ELogID::CLKernelFunctorError, logText); break; } } // end of switch } catch (...) { throw; } return (kernelFunctor); } CommandQueue OpenCLHelper::createCommandQueue(const Context& context, const Device& device, const cl_command_queue_properties properties = 0) { cl_int error; CommandQueue commandQ(context, properties, &error); try { switch (error) { case CL_INVALID_CONTEXT: { QString logText = QString("(CL_INVALID_CONTEXT) An error occured while creating Queue. ") + "Invalid context on device: " + QString::fromStdString(device.getInfo()); handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_INVALID_DEVICE: { QString logText = QString("(CL_INVALID_DEVICE) An error occured while creating Queue on device. ") + "Invalid device or not associated with the provided context: " + QString::fromStdString(device.getInfo()); handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_INVALID_VALUE: { QString logText = QString("(CL_INVALID_VALUE) An error occured while creating Queue on device. ") + "Invalid properties: " + QString::number(properties); handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_INVALID_QUEUE_PROPERTIES: { QString logText = QString("(CL_INVALID_QUEUE_PROPERTIES) An error occured while creating Queue on device. ") + "Properties \"" + QString::number(properties) + "\" " + "not supperted by device: " + QString::fromStdString(device.getInfo()); handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_OUT_OF_RESOURCES: { QString logText = QString("(CL_OUT_OF_RESOURCES) An error occured while creating Queue on device. ") + "Failed to allocate resources on device: " + QString::fromStdString(device.getInfo()); handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_OUT_OF_HOST_MEMORY: { QString logText = QString("(CL_OUT_OF_HOST_MEMORY) An error occured while creating Queue on device. ") + "Failed to allocate resources on the host."; handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, logText); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLCommandQueueCreated, "CL Command Queue created successfully for device: " + QString::fromStdString(device.getInfo()), false); break; } default: { handleError(ESeverityLevel::Error, ELogID::CLCommandQueueCreationError, "Unknown error occured while creating command queue on device " + QString::fromStdString(device.getInfo()) + " : " + QString::number(error)); break; } } // end of switch } catch(...) { throw; } return commandQ; } size_t* OpenCLHelper::getMaxGlobalWorkSize(const Kernel& kernel, const Device& device) { size_t* maxGlobalWorkSize = new size_t[3]; QString deviceName; try { deviceName = getDeviceName(device); } catch (...) { handleError(ESeverityLevel::Warning, ELogID::CLKernelError, "An error occured while querying name of a CL device.", false); deviceName = "UNKNOWN_DEVICE"; } auto error = kernel.getWorkGroupInfo(device, CL_KERNEL_GLOBAL_WORK_SIZE, &maxGlobalWorkSize); try { switch (error) { case CL_INVALID_DEVICE: { QString logText = "(CL_INVALID_DEVICE) An error occured while querying maximum global work size from device: " + deviceName + ". The device is invalid."; handleError(ESeverityLevel::Error, ELogID::CLKernelError, logText); break; } case CL_INVALID_VALUE: { QString logText = "(CL_INVALID_VALUE) An error occured while querying maximum global work size from device: " + deviceName + ". Invlid passed parameters."; handleError(ESeverityLevel::Error, ELogID::CLKernelError, logText); break; } case CL_INVALID_KERNEL: { QString logText = "(CL_INVALID_KERNEL) An error occured while querying maximum global work size from device: " + deviceName + ". Invalid kernel object."; handleError(ESeverityLevel::Error, ELogID::CLKernelError, logText); break; } case CL_OUT_OF_RESOURCES: { QString logText = "(CL_OUT_OF_RESOURCES) An error occured while querying maximum global work size from device: " + deviceName + ". Failed to allocate resources on the device."; handleError(ESeverityLevel::Error, ELogID::CLKernelError, logText); break; } case CL_OUT_OF_HOST_MEMORY: { QString logText = "(CL_OUT_OF_HOST_MEMORY) An error occured while querying maximum global work size from device: " + deviceName + ". Failed to allocate resources on the host."; handleError(ESeverityLevel::Error, ELogID::CLKernelError, logText); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLKernelInfo, "Successfully queried the maximum global work size from device: " + deviceName, false); break; } default: { handleError(ESeverityLevel::Error, ELogID::CLKernelError, "Unknown error occured while querying the maximum global work size from device: " + deviceName); break; } } // end of switch } catch (...) { throw; } return (maxGlobalWorkSize); } QString OpenCLHelper::getDeviceName(const Device& device) { cl_int error; auto deviceName = device.getInfo(&error); try { switch (error) { case CL_INVALID_DEVICE: { handleError(ESeverityLevel::Error, ELogID::CLDeviceError, "(CL_INVALID_DEVICE) An error occured while querying name of a CL device."); break; } case CL_INVALID_VALUE: { handleError(ESeverityLevel::Error, ELogID::CLDeviceError, "(CL_INVALID_VALUE) An error occured related to passed parameters while querying name of a CL device."); break; } case CL_OUT_OF_RESOURCES: { handleError(ESeverityLevel::Error, ELogID::CLDeviceError, QString("(CL_OUT_OF_RESOURCES) An error occured while querying name of a CL device. ") + "Failed to allocate resources on the device."); break; } case CL_OUT_OF_HOST_MEMORY: { handleError(ESeverityLevel::Error, ELogID::CLDeviceError, QString("(CL_OUT_OF_HOST_MEMORY) An error occured while querying name of a CL device. ") + "Failed to allocate resources on the host."); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLDeviceInfo, "Successfully queried the name of a device: " + QString::fromStdString(deviceName), false); break; } default: { handleError(ESeverityLevel::Error, ELogID::CLDeviceError, "An unknown error occured while quering name of a CL device. error: " + QString::number(error)); break; } } // end of switch } catch (...) { throw; } return QString::fromStdString(deviceName); } QVector OpenCLHelper::getDevicesByContext(const Context &context) { std::vector devices; auto error = context.getInfo>(CL_CONTEXT_DEVICES, &devices); try { switch (error) { case CL_INVALID_CONTEXT: { handleError(ESeverityLevel::Error, ELogID::CLContextError, "(CL_INVALID_CONTEXT) An error occured while getting devices from a context."); break; } case CL_INVALID_VALUE: { handleError(ESeverityLevel::Error, ELogID::CLContextError, QString("(CL_INVALID_VALUE) An error occured while getting devices from a context.") + "Something went wrong with the parsed parameter value."); break; } case CL_OUT_OF_RESOURCES: { handleError(ESeverityLevel::Error, ELogID::CLContextError, "(CL_OUT_OF_RESOURCES) An error occured while getting devices from a context."); break; } case CL_OUT_OF_HOST_MEMORY: { handleError(ESeverityLevel::Error, ELogID::CLContextError, "(CL_OUT_OF_HOST_MEMORY) An error occured while getting devices from a context."); break; } case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLContextInfo, "Devices successfully queried from context.", false); break; } default: { handleError(ESeverityLevel::Error, ELogID::CLContextError, "Unknown error occured while quering devices from context. error: " + QString::number(error)); break; } } // end of switch } catch (...) { throw; } // qDebug() << "End of kernel functor"; return (QVector::fromStdVector(devices)); } template void OpenCLHelper::runKernelFunctor (KernelFunctor& kernelFunctor, EnqueueArgs args, Ts... ts) { cl_int error; kernelFunctor(args, ts..., error); if(error != 0) qDebug() << "Error : "<< error; try { switch(error) { case CL_INVALID_PROGRAM_EXECUTABLE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_PROGRAM_EXECUTABLE) There is no successfully built program executable."); break; case CL_INVALID_KERNEL: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_KERNEL) Invalid kernel object."); break; case CL_INVALID_CONTEXT: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_CONTEXT) Invalid context associated with the command queue and kernel."); break; case CL_INVALID_KERNEL_ARGS: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_KERNEL_ARGS) Kernel arguments has not been specified."); break; case CL_INVALID_GLOBAL_WORK_SIZE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_GLOBAL_WORK_SIZE) Invalid global work size specified."); break; case CL_INVALID_GLOBAL_OFFSET: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_GLOBAL_OFFSET) Invalid offset size specified."); break; case CL_INVALID_WORK_GROUP_SIZE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_WORK_GROUP_SIZE) Work group size mismatch."); break; case CL_INVALID_WORK_ITEM_SIZE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_WORK_ITEM_SIZE) Work item size mismatch."); break; case CL_MISALIGNED_SUB_BUFFER_OFFSET: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_MISALIGNED_SUB_BUFFER_OFFSET) Subbuffer offset mismatch."); break; case CL_INVALID_IMAGE_SIZE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_IMAGE_SIZE) Image dimension not supported by the device."); break; case CL_OUT_OF_RESOURCES: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_OUT_OF_RESOURCES) Insufficient resources needed to execute the kernel."); break; case CL_MEM_OBJECT_ALLOCATION_FAILURE: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_MEM_OBJECT_ALLOCATION_FAILURE) Failure to allocate memory."); break; case CL_INVALID_EVENT_WAIT_LIST: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_INVALID_EVENT_WAIT_LIST) Invalid event objects in events wait list."); break; case CL_OUT_OF_HOST_MEMORY: handleError(ESeverityLevel::Error, ELogID::CLKernelRunError, "(CL_OUT_OF_HOST_MEMORY) Failure to allocate resources on the host."); break; case CL_SUCCESS: { handleError(ESeverityLevel::Debug, ELogID::CLKernelRunInfo, "Successfully ran the kernel.", false); break; } default: handleError(ESeverityLevel::Error, ELogID::CLKernelRunInfo, "There was an unknown error while running the kernel."); break; } // end of switch } catch (...) { throw; } } #endif