| #ifndef CAFFE2_OPENCL_CONTEXT_H_ |
| #define CAFFE2_OPENCL_CONTEXT_H_ |
| |
| #include "caffe2/core/context.h" |
| |
| #define CL_HPP_ENABLE_EXCEPTIONS 1 |
| #define CL_HPP_CL_1_2_DEFAULT_BUILD 1 |
| #define CL_HPP_TARGET_OPENCL_VERSION 120 |
| #define CL_HPP_MINIMUM_OPENCL_VERSION 120 |
| //#include "libopencl.h" |
| #if defined(__APPLE__) || defined(__MACOSX) |
| #include <OpenCL/cl.hpp> |
| #else |
| #include <CL/cl.hpp> |
| #endif |
| |
| #define OPENCL_CHECK(expr) (void)expr |
| |
| namespace caffe2 { |
| |
| struct OpenCLContextSingleton { |
| private: |
| OpenCLContextSingleton(); |
| OpenCLContextSingleton(const OpenCLContextSingleton &) = delete; |
| OpenCLContextSingleton(OpenCLContextSingleton&&) = delete; |
| public: |
| static OpenCLContextSingleton& getInstance(); |
| cl::Platform platform; |
| cl::Device device; |
| std::vector<cl::Device> devices; |
| cl::Context context; |
| cl::CommandQueue queue; |
| }; |
| |
| class OpenCLContext final { |
| public: |
| explicit OpenCLContext(); |
| explicit OpenCLContext(const DeviceOption& option) { |
| DCHECK_EQ(option.device_type(), PROTO_OPENCL); |
| OpenCLContext(); |
| } |
| ~OpenCLContext() {} |
| |
| /* |
| * Everything below is basically boiler plate for Context classes |
| */ |
| static std::pair<void*, MemoryDeleter> New(size_t nbytes); |
| |
| static void Delete(void* data); |
| |
| template <class SrcContext, class DstContext> |
| inline void CopyBytes(size_t nbytes, const void* src, void* dst) {} |
| |
| template <typename T, class SrcContext, class DstContext> |
| inline void Copy(int n, const T* src, T* dst) { |
| CopyBytes<SrcContext, DstContext>( |
| n * sizeof(T), static_cast<const void*>(src), static_cast<void*>(dst)); |
| } |
| |
| template <class SrcContext, class DstContext> |
| inline void |
| CopyItems(const TypeMeta& meta, size_t n, const void* src, void* dst) { |
| CAFFE_ENFORCE(!meta.copy(), "OpenCLContext requires fundamental types."); |
| CopyBytes<SrcContext, DstContext>(n * meta.itemsize(), src, dst); |
| } |
| |
| void SwitchToDevice(int a, ...) { |
| auto& ctx = GetSingleton(); |
| CAFFE_ENFORCE(a < ctx.devices.size()); |
| ctx.device = ctx.devices[a]; |
| } |
| void SwitchToDevice() { |
| SwitchToDevice(0); |
| } |
| |
| inline void WaitEvent(const Event& ev) { /* TODO */ |
| } |
| void FinishDeviceComputation() { |
| auto& ctx = GetSingleton(); |
| ctx.queue.finish(); |
| } |
| |
| inline void Record(Event* ev, const char*&) const { /* TODO */ |
| } |
| static bool IsStreamFree(const DeviceOption& /* unused */, int /* unused */) { |
| return true; |
| } |
| bool HasAsyncPartDefault() const { |
| return false; |
| } |
| bool SupportsAsyncScheduling() const { |
| return false; |
| } |
| |
| // OpenCL specific helper functions |
| cl::Kernel BuildKernel(const char* src, std::string additional_options = "", const char* fn_name = "K"); |
| static struct OpenCLContextSingleton& GetSingleton(); |
| static std::string BuildArgumentList(std::vector<std::pair<std::string, std::string>> args); |
| }; |
| |
| |
| } // namespace caffe2 |
| |
| #endif /* CAFFE2_OPENCL_CONTEXT_H_ */ |