bool OpenCLPlatform::createContext() { cl_int err; cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_(), 0 }; context_ = cl::Context( CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU, contextProperties, NULL, NULL, &err); if (err != CL_SUCCESS) { LOG(ERROR)<< "failed to create context."; return false; } LOG(INFO)<< "create OpenCL context for platform " << this->name(); std::vector<caffe::OpenCLDevice>::iterator it; for (it = devices.begin(); it != devices.end(); it++) { it->SetContext( context_); } return true; }
CL::CL() { cl_int err; std::vector<cl::Platform> platforms; if(cl::Platform::get(&platforms) == CL_INVALID_VALUE) { fprintf(stderr, "[OpenCL] No platforms available\n"); util_abort(); } platform_ = platforms[0]; //Just select the first platform std::string name, version, extensions; platform_.getInfo(CL_PLATFORM_NAME, &name); platform_.getInfo(CL_PLATFORM_VERSION, &version); platform_.getInfo(CL_PLATFORM_EXTENSIONS, &extensions); fprintf(verbose, "[OpenCL] Platform: %s %s\n" " Extensions: %s\n", name.c_str(), version.c_str() ,extensions.c_str()); #if defined (__APPLE__) || defined(MACOSX) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #elif defined WIN32 HGLRC current_context = wglGetCurrentContext(); HDC current_dc = wglGetCurrentDC(); if(current_dc == NULL || current_context == NULL) { fprintf(stderr,"[OpenCL] No OpenGL context active\n"); util_abort(); } cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_(), CL_WGL_HDC_KHR, (intptr_t) current_dc, CL_GL_CONTEXT_KHR, (intptr_t) current_context, 0 }; #else if(glXGetCurrentContext() == NULL) { fprintf(stderr, "[OpenCL] glXGetCurrentContex() return NULL. Make sure to create OpenGL context before create the CL-context\n"); util_abort(); } cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)(platform_)(), 0 }; #endif static CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)=NULL; clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); cl_device_id devices[32]; size_t deviceSize = 0; err = clGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, 32 * sizeof(cl_device_id), devices, &deviceSize); if(deviceSize == 0) { fprintf(stderr, "[OpenCL] Interop not possible\n"); util_abort(); } cl_bool image_support, available; size_t max_width, max_height; cl_uint num_cores, frequency; cl_device_type _type; std::string type; fprintf(verbose, "[OpenCL] Available devices: \n"); for(int i=0; i< (deviceSize / sizeof(cl_device_id)); ++i) { cl::Device device(devices[i]); device.getInfo(CL_DEVICE_VENDOR, &name); device.getInfo(CL_DEVICE_VERSION, &version); device.getInfo(CL_DEVICE_EXTENSIONS, &extensions); device.getInfo(CL_DEVICE_AVAILABLE, &available); device.getInfo(CL_DEVICE_IMAGE_SUPPORT, &image_support); device.getInfo(CL_DEVICE_IMAGE2D_MAX_WIDTH, &max_width); device.getInfo(CL_DEVICE_IMAGE2D_MAX_HEIGHT, &max_height); device.getInfo( CL_DEVICE_MAX_COMPUTE_UNITS , &num_cores); device.getInfo(CL_DEVICE_MAX_CLOCK_FREQUENCY, &frequency); device.getInfo(CL_DEVICE_TYPE, &_type); switch(_type) { case CL_DEVICE_TYPE_GPU: type = "GPU"; break; case CL_DEVICE_TYPE_CPU: type = "CPU"; break; case CL_DEVICE_TYPE_ACCELERATOR: type = "Accelerator"; break; } fprintf(verbose, "[OpenCL] Device (%p): %s %s (%s)\n" " Cores: %u, Frequency: %u MHz, Available: %s," " Image support: %s, max size: %lux%lu\n" " Extensions: %s\n --- \n", (device)(), name.c_str(), version.c_str(), type.c_str(), num_cores, frequency,available?"YES":"NO",image_support?"YES":"NO", max_width, max_height, extensions.c_str()); devices_.push_back(device); } fprintf(verbose, "\n-------------------\n"); cl_device_id device_id; context_ = cl::Context(devices_, properties, &CL::cl_error_callback, nullptr, &err); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to create context: %s\n", errorString(err)); util_abort(); } err = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(device_id), &device_id, NULL); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to get current device for context: %s\n", errorString(err)); util_abort(); } context_device_ = cl::Device(device_id); context_device_.getInfo(CL_DEVICE_VENDOR, &name); context_device_.getInfo(CL_DEVICE_VERSION, &version); fprintf(verbose, "[OpenCL] Context Device (%p): %s %s\n",(context_device_)(), name.c_str(), version.c_str()); queue_ = cl::CommandQueue(context_, context_device_, 0, &err); if(err != CL_SUCCESS) { fprintf(stderr, "[OpenCL] Failed to create a command queue: %s\n", errorString(err)); util_abort(); } }
bool OpenCLPlatform::Query() { Check(); // get the name cl_int err = 0; name_ = platform_.getInfo<CL_PLATFORM_NAME>( &err); if (!CL_CHECK( err)) { name_ = "Failed to get platform name."; } // get the vendor vendor_ = platform_.getInfo<CL_PLATFORM_VENDOR>( &err); if (!CL_CHECK( err)) { vendor_ = "Failed to get platform vendor."; } version_ = platform_.getInfo<CL_PLATFORM_VERSION>( &err); if (!CL_CHECK( err)) { version_ = "Failed to get platform version."; } extensions_ = platform_.getInfo<CL_PLATFORM_EXTENSIONS>( &err); if (!CL_CHECK( err)) { extensions_ = "failed to get platform extensions."; } profile_ = platform_.getInfo<CL_PLATFORM_PROFILE>( &err); if (!CL_CHECK( err)) { profile_ = "Failed to get platform profile."; } // CPU & GPU devices if (!CL_CHECK( clGetDeviceIDs(platform_(), CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU, 0, NULL, &(numDevices)))) { return false; } devicePtr = reinterpret_cast<cl_device_id*>(malloc( numDevices * sizeof(cl_device_id))); if (!CL_CHECK( clGetDeviceIDs(platform_(), CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU, numDevices, devicePtr, NULL))) { return false; } // CPU devices if (clGetDeviceIDs( platform_(), CL_DEVICE_TYPE_CPU, 0, NULL, &(numCPUDevices)) == CL_SUCCESS) { cpuDevicePtr = reinterpret_cast<cl_device_id*>(malloc( numCPUDevices * sizeof(cl_device_id))); if (!CL_CHECK(clGetDeviceIDs(platform_(), CL_DEVICE_TYPE_CPU, numCPUDevices, cpuDevicePtr, NULL))) { return false; } for (int i = 0; i < numCPUDevices; i++) { OpenCLDevice d( platform_(), cpuDevicePtr[i]); d.query(); devices.push_back( d); } } // GPU DEVICES if (!CL_CHECK(clGetDeviceIDs(platform_(), CL_DEVICE_TYPE_GPU, 0, NULL, &(numGPUDevices)))) { return false; } gpuDevicePtr = reinterpret_cast<cl_device_id*>(malloc( numGPUDevices * sizeof(cl_device_id))); if (!CL_CHECK(clGetDeviceIDs(platform_(), CL_DEVICE_TYPE_GPU, numGPUDevices, gpuDevicePtr, NULL))) { return false; } for (int i = 0; i < numGPUDevices; i++) { OpenCLDevice d( platform_(), gpuDevicePtr[i]); d.query(); devices.push_back( d); } return true; }
// Check that we have an assigned cl::Platform object. void OpenCLPlatform::Check() { if (!platform_()) { LOG(FATAL)<< "Unassigned platform."; } }
cl_platform_id OpenCLPlatform::id() { return platform_(); }