2019-04-17 10:49:11 +08:00
|
|
|
//
|
|
|
|
// OpenCLWrapper.hpp
|
|
|
|
// MNN
|
|
|
|
//
|
|
|
|
// Created by MNN on 2019/01/31.
|
|
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef OpenCLWrapper_hpp
|
|
|
|
#define OpenCLWrapper_hpp
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
#include <Windows.h>
|
|
|
|
#undef min
|
|
|
|
#undef max
|
|
|
|
#undef NO_ERROR
|
|
|
|
#endif
|
2019-04-17 10:49:11 +08:00
|
|
|
#include <memory>
|
2019-12-27 22:16:57 +08:00
|
|
|
#include "core/Macro.h"
|
2019-04-17 10:49:11 +08:00
|
|
|
#define CL_TARGET_OPENCL_VERSION 200
|
|
|
|
#define CL_HPP_TARGET_OPENCL_VERSION 110
|
|
|
|
#define CL_HPP_MINIMUM_OPENCL_VERSION 110
|
|
|
|
|
|
|
|
// #pragma GCC diagnostic push
|
|
|
|
// #pragma GCC diagnostic ignored "-Weffc++"
|
|
|
|
// #pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
|
|
|
#include "CL/cl2.hpp"
|
|
|
|
// #pragma GCC diagnostic pop
|
|
|
|
|
|
|
|
#define MNN_CHECK_NOTNULL(X) MNN_ASSERT(X != NULL)
|
|
|
|
|
|
|
|
#define MNN_CHECK_CL_SUCCESS(error) \
|
|
|
|
if (error != CL_SUCCESS) { \
|
|
|
|
MNN_PRINT("ERROR CODE : %d \n", (int)error); \
|
|
|
|
}
|
2020-03-01 15:33:28 +08:00
|
|
|
#ifdef MNN_USE_LIB_WRAPPER
|
2019-04-17 10:49:11 +08:00
|
|
|
|
|
|
|
namespace MNN {
|
|
|
|
|
|
|
|
void LoadOpenCLSymbols();
|
|
|
|
void UnLoadOpenCLSymbols();
|
|
|
|
|
|
|
|
class OpenCLSymbols {
|
|
|
|
public:
|
|
|
|
bool LoadOpenCLLibrary();
|
|
|
|
bool UnLoadOpenCLLibrary();
|
2019-07-02 18:01:08 +08:00
|
|
|
bool isError();
|
2020-11-05 16:41:56 +08:00
|
|
|
using clGetPlatformIDsFunc = cl_int (CL_API_CALL *)(cl_uint, cl_platform_id *, cl_uint *);
|
|
|
|
using clGetPlatformInfoFunc = cl_int (CL_API_CALL *)(cl_platform_id, cl_platform_info, size_t, void *, size_t *);
|
|
|
|
using clBuildProgramFunc = cl_int (CL_API_CALL *)(cl_program, cl_uint, const cl_device_id *, const char *,
|
|
|
|
void (CL_CALLBACK *pfn_notify)(cl_program, void *), void *);
|
|
|
|
using clEnqueueNDRangeKernelFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_kernel, cl_uint, const size_t *, const size_t *,
|
2019-04-17 10:49:11 +08:00
|
|
|
const size_t *, cl_uint, const cl_event *, cl_event *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clSetKernelArgFunc = cl_int (CL_API_CALL *)(cl_kernel, cl_uint, size_t, const void *);
|
|
|
|
using clRetainMemObjectFunc = cl_int (CL_API_CALL *)(cl_mem);
|
|
|
|
using clReleaseMemObjectFunc = cl_int (CL_API_CALL *)(cl_mem);
|
|
|
|
using clEnqueueUnmapMemObjectFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_mem, void *, cl_uint, const cl_event *,
|
2019-04-17 10:49:11 +08:00
|
|
|
cl_event *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clRetainCommandQueueFunc = cl_int (CL_API_CALL *)(cl_command_queue command_queue);
|
|
|
|
using clCreateContextFunc = cl_context (CL_API_CALL *)(const cl_context_properties *, cl_uint, const cl_device_id *,
|
2019-04-17 10:49:11 +08:00
|
|
|
void(CL_CALLBACK *)( // NOLINT(readability/casting)
|
|
|
|
const char *, const void *, size_t, void *),
|
|
|
|
void *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clEnqueueCopyImageFunc = cl_int (CL_API_CALL *)(cl_command_queue,
|
2019-04-17 10:49:11 +08:00
|
|
|
cl_mem,
|
|
|
|
cl_mem,
|
|
|
|
const size_t*,
|
|
|
|
const size_t*,
|
|
|
|
const size_t*,
|
|
|
|
cl_uint,
|
|
|
|
const cl_event*,
|
|
|
|
cl_event*);
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
using clCreateContextFromTypeFunc = cl_context (CL_API_CALL *)(const cl_context_properties *, cl_device_type,
|
2019-04-17 10:49:11 +08:00
|
|
|
void(CL_CALLBACK *)( // NOLINT(readability/casting)
|
|
|
|
const char *, const void *, size_t, void *),
|
|
|
|
void *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clReleaseContextFunc = cl_int (CL_API_CALL *)(cl_context);
|
|
|
|
using clWaitForEventsFunc = cl_int (CL_API_CALL *)(cl_uint, const cl_event *);
|
|
|
|
using clReleaseEventFunc = cl_int (CL_API_CALL *)(cl_event);
|
|
|
|
using clEnqueueWriteBufferFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *,
|
2019-04-17 10:49:11 +08:00
|
|
|
cl_uint, const cl_event *, cl_event *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clEnqueueReadBufferFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint,
|
2019-12-27 22:16:57 +08:00
|
|
|
const cl_event *, cl_event *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clEnqueueReadImageFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *);
|
|
|
|
using clEnqueueWriteImageFunc = cl_int (CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, const void *,
|
2019-12-27 22:16:57 +08:00
|
|
|
cl_uint, const cl_event *, cl_event * );
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
using clGetProgramBuildInfoFunc = cl_int (CL_API_CALL *)(cl_program, cl_device_id, cl_program_build_info, size_t, void *,
|
2019-04-17 10:49:11 +08:00
|
|
|
size_t *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clRetainProgramFunc = cl_int (CL_API_CALL *)(cl_program program);
|
|
|
|
using clEnqueueMapBufferFunc = void *(CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint,
|
2019-04-17 10:49:11 +08:00
|
|
|
const cl_event *, cl_event *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clEnqueueMapImageFunc = void *(CL_API_CALL *)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t *,
|
2019-04-17 10:49:11 +08:00
|
|
|
const size_t *, size_t *, size_t *, cl_uint, const cl_event *, cl_event *,
|
|
|
|
cl_int *);
|
|
|
|
using clCreateCommandQueueFunc = cl_command_queue(CL_API_CALL *)( // NOLINT
|
|
|
|
cl_context, cl_device_id, cl_command_queue_properties, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clReleaseCommandQueueFunc = cl_int (CL_API_CALL *)(cl_command_queue);
|
|
|
|
using clCreateProgramWithBinaryFunc = cl_program (CL_API_CALL *)(cl_context, cl_uint, const cl_device_id *, const size_t *,
|
2019-04-17 10:49:11 +08:00
|
|
|
const unsigned char **, cl_int *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clRetainContextFunc = cl_int (CL_API_CALL *)(cl_context context);
|
|
|
|
using clGetContextInfoFunc = cl_int (CL_API_CALL *)(cl_context, cl_context_info, size_t, void *, size_t *);
|
|
|
|
using clReleaseProgramFunc = cl_int (CL_API_CALL *)(cl_program program);
|
|
|
|
using clFlushFunc = cl_int (CL_API_CALL *)(cl_command_queue command_queue);
|
|
|
|
using clFinishFunc = cl_int (CL_API_CALL *)(cl_command_queue command_queue);
|
|
|
|
using clGetProgramInfoFunc = cl_int (CL_API_CALL *)(cl_program, cl_program_info, size_t, void *, size_t *);
|
|
|
|
using clCreateKernelFunc = cl_kernel (CL_API_CALL *)(cl_program, const char *, cl_int *);
|
|
|
|
using clRetainKernelFunc = cl_int (CL_API_CALL *)(cl_kernel kernel);
|
|
|
|
using clCreateBufferFunc = cl_mem (CL_API_CALL *)(cl_context, cl_mem_flags, size_t, void *, cl_int *);
|
2019-04-17 10:49:11 +08:00
|
|
|
using clCreateImage2DFunc = cl_mem(CL_API_CALL *)(cl_context, // NOLINT
|
|
|
|
cl_mem_flags, const cl_image_format *, size_t, size_t, size_t,
|
|
|
|
void *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clCreateImageFunc = cl_mem (CL_API_CALL *)(cl_context, cl_mem_flags, const cl_image_format *, const cl_image_desc *,
|
2019-04-17 10:49:11 +08:00
|
|
|
void *, cl_int *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clCreateProgramWithSourceFunc = cl_program (CL_API_CALL *)(cl_context, cl_uint, const char **, const size_t *, cl_int *);
|
|
|
|
using clReleaseKernelFunc = cl_int (CL_API_CALL *)(cl_kernel kernel);
|
|
|
|
using clGetDeviceInfoFunc = cl_int (CL_API_CALL *)(cl_device_id, cl_device_info, size_t, void *, size_t *);
|
|
|
|
using clGetDeviceIDsFunc = cl_int (CL_API_CALL *)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *);
|
|
|
|
using clRetainDeviceFunc = cl_int (CL_API_CALL *)(cl_device_id);
|
|
|
|
using clReleaseDeviceFunc = cl_int (CL_API_CALL *)(cl_device_id);
|
|
|
|
using clRetainEventFunc = cl_int (CL_API_CALL *)(cl_event);
|
|
|
|
using clGetKernelWorkGroupInfoFunc = cl_int (CL_API_CALL *)(cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void *,
|
2019-04-17 10:49:11 +08:00
|
|
|
size_t *);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clGetEventInfoFunc = cl_int (CL_API_CALL *)(cl_event event, cl_event_info param_name, size_t param_value_size,
|
2019-04-17 10:49:11 +08:00
|
|
|
void *param_value, size_t *param_value_size_ret);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clGetEventProfilingInfoFunc = cl_int (CL_API_CALL *)(cl_event event, cl_profiling_info param_name,
|
2019-04-17 10:49:11 +08:00
|
|
|
size_t param_value_size, void *param_value,
|
|
|
|
size_t *param_value_size_ret);
|
2020-11-05 16:41:56 +08:00
|
|
|
using clGetImageInfoFunc = cl_int (CL_API_CALL *)(cl_mem, cl_image_info, size_t, void *, size_t *);
|
2019-04-17 10:49:11 +08:00
|
|
|
|
|
|
|
#define MNN_CL_DEFINE_FUNC_PTR(func) func##Func func = nullptr
|
|
|
|
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetPlatformIDs);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetPlatformInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clBuildProgram);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueNDRangeKernel);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clSetKernelArg);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseKernel);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateProgramWithSource);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateBuffer);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateImage);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateImage2D);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainKernel);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateKernel);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetProgramInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clFlush);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clFinish);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseProgram);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainContext);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetContextInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateProgramWithBinary);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateCommandQueue);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseCommandQueue);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueMapBuffer);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueMapImage);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueCopyImage);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainProgram);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetProgramBuildInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueReadBuffer);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueWriteBuffer);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clWaitForEvents);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseEvent);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateContext);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clCreateContextFromType);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseContext);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainCommandQueue);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueUnmapMemObject);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainMemObject);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseMemObject);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetDeviceInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetDeviceIDs);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainDevice);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clReleaseDevice);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clRetainEvent);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetKernelWorkGroupInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetEventInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetEventProfilingInfo);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clGetImageInfo);
|
2019-12-27 22:16:57 +08:00
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueReadImage);
|
|
|
|
MNN_CL_DEFINE_FUNC_PTR(clEnqueueWriteImage);
|
2019-04-17 10:49:11 +08:00
|
|
|
|
|
|
|
#undef MNN_CL_DEFINE_FUNC_PTR
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool LoadLibraryFromPath(const std::string &path);
|
2020-11-05 16:41:56 +08:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
HMODULE handle_ = nullptr;
|
|
|
|
#else
|
2019-04-17 10:49:11 +08:00
|
|
|
void *handle_ = nullptr;
|
2020-11-05 16:41:56 +08:00
|
|
|
#endif
|
2019-07-02 18:01:08 +08:00
|
|
|
bool mIsError{false};
|
2019-04-17 10:49:11 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class OpenCLSymbolsOperator {
|
|
|
|
public:
|
|
|
|
static OpenCLSymbolsOperator *createOpenCLSymbolsOperatorSingleInstance() {
|
|
|
|
static OpenCLSymbolsOperator symbols_operator;
|
|
|
|
return &symbols_operator;
|
|
|
|
}
|
|
|
|
|
|
|
|
static OpenCLSymbols *getOpenclSymbolsPtr();
|
|
|
|
|
|
|
|
private:
|
|
|
|
OpenCLSymbolsOperator();
|
|
|
|
~OpenCLSymbolsOperator();
|
|
|
|
OpenCLSymbolsOperator(const OpenCLSymbolsOperator &) = delete;
|
|
|
|
OpenCLSymbolsOperator &operator=(const OpenCLSymbolsOperator &) = delete;
|
|
|
|
|
|
|
|
static std::shared_ptr<OpenCLSymbols> gOpenclSymbols;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace MNN
|
|
|
|
#endif
|
|
|
|
#endif /* OpenCLWrapper_hpp */
|