3
#include "caffe2/core/allocator.h"
4
#include "caffe2/core/context.h"
5
#include "caffe2/core/logging.h"
6
#include "caffe2/core/tensor.h"
10
CAFFE_KNOWN_TYPE(Tensor<OpenCLContext>);
12
OpenCLContextSingleton::OpenCLContextSingleton() {
13
const auto platform_id = 0;
14
const auto device_id = 0;
16
auto platforms = std::vector<cl::Platform>();
17
cl::Platform::get(&platforms);
18
if (platforms.size() == 0 || platform_id >= platforms.size()) {
19
CAFFE_THROW("Cannot find platform for OpenCL.");
21
platform = platforms[platform_id];
23
devices = std::vector<cl::Device>();
24
platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
25
if (devices.size() == 0 || device_id >= devices.size()) {
26
CAFFE_THROW("Cannot find OpenCL compatible device.");
28
device = devices[device_id];
30
context = cl::Context({device});
31
queue = cl::CommandQueue(context, device);
34
OpenCLContextSingleton& OpenCLContextSingleton::getInstance() {
35
static OpenCLContextSingleton* instance;
36
if (instance == nullptr) {
37
instance = new OpenCLContextSingleton();
42
std::pair<void*, MemoryDeleter> OpenCLContext::New(size_t nbytes) {
43
auto& ctx = GetSingleton();
46
cl::Buffer* buffer = new cl::Buffer(ctx.context, CL_MEM_READ_WRITE,
47
nbytes, nullptr, &err);
49
// TODO(bwasti): use host ptr if possible to make CopyBytes free
50
return std::make_pair((void *)buffer, OpenCLContext::Delete);
53
void OpenCLContext::Delete(void *ptr) {
54
delete (cl::Buffer *)ptr;
57
struct OpenCLContextSingleton& OpenCLContext::GetSingleton() {
58
return OpenCLContextSingleton::getInstance();
61
cl::Kernel OpenCLContext::BuildKernel(const char* src, std::string additional_options, const char* fn_name) {
62
auto& ctx = GetSingleton();
64
cl::Program::Sources source(1,
65
std::make_pair(src, strlen(src)));
67
cl::Program p = cl::Program(ctx.context, source);
68
cl_int err = CL_SUCCESS;
69
std::string options = "-cl-std=CL1.1 -cl-fast-relaxed-math -cl-single-precision-constant";
70
options += additional_options;
71
err = p.build(ctx.devices, options.c_str());
72
cl_build_status build_status = p.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(ctx.device);
73
if (err != CL_SUCCESS || build_status != CL_BUILD_SUCCESS) {
74
auto str = p.getBuildInfo<CL_PROGRAM_BUILD_LOG>(ctx.device);
79
auto kernel = cl::Kernel(p, fn_name, &err);
84
std::string OpenCLContext::BuildArgumentList(std::vector<std::pair<std::string, std::string>> args) {
85
std::string out = " "; // There may be args before this
86
for (auto arg : args) {
87
out += "-D " + arg.first + "=" + arg.second + " ";
92
void EventCreateOPENCL(const DeviceOption& /* unused */, Event* /* unused */) {}
93
void EventRecordOPENCL(
95
const void* /* unused */,
96
const char* /* unused */) {}
97
void EventWaitOPENCL(const Event* /* unused */, void* /* unused */) {}
98
void EventFinishOPENCL(const Event* /* unused */) {}
99
void EventResetOPENCL(Event* /* unused */) {}
101
REGISTER_EVENT_CREATE_FUNCTION(OPENCL, EventCreateOPENCL);
102
REGISTER_EVENT_RECORD_FUNCTION(OPENCL, EventRecordOPENCL);
103
REGISTER_EVENT_WAIT_FUNCTION(OPENCL, OPENCL, EventWaitOPENCL);
104
REGISTER_EVENT_FINISH_FUNCTION(OPENCL, EventFinishOPENCL);
105
REGISTER_EVENT_RESET_FUNCTION(OPENCL, EventResetOPENCL);