inline void createContext(CLcontext& c){ cl_int err = CL_SUCCESS; err |= clGetPlatformIDs(1, &c.platform, NULL); if(err != CL_SUCCESS){ THROW_EXCEPTION("Failed to find platform ID"); } err |= clGetDeviceIDs(c.platform, CL_DEVICE_TYPE_GPU, 1, &c.device, NULL); if(c.device == NULL){ err &= clGetDeviceIDs(c.platform, CL_DEVICE_TYPE_CPU, 1, &c.device, NULL); } if(err != CL_SUCCESS){ THROW_EXCEPTION("Failed to find device ID"); } // Create the properties for this context. cl_context_properties prop[] = { // We need to add information about the OpenGL context with // which we want to exchange information with the OpenCL context CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE , (cl_context_properties) CGLGetShareGroup(CGLGetCurrentContext()) , CL_CONTEXT_PLATFORM , (cl_context_properties) c.platform , 0 , 0 , }; c.context = clCreateContext(prop, 1, &c.device, NULL, NULL, &err); if(err != CL_SUCCESS){ THROW_EXCEPTION("Failed to create context"); } c.queue = clCreateCommandQueue(c.context, c.device, NULL, &err); if(err != CL_SUCCESS){ THROW_EXCEPTION("Failed to initialize command queue"); } }
cl_context createOpenCLContext() { int ret; CGLContextObj cglContext = CGLGetCurrentContext(); if (!cglContext) { log_error("Could not get CGLContext"); exit(1); } CGLShareGroupObj cglShareGroup = CGLGetShareGroup(cglContext); if (!cglShareGroup) { log_error("Could not get share group"); exit(1); } cl_context_properties clProperties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)cglShareGroup, 0 }; /* Create OpenCL context using share group so we can do efficient rendering from OpenCL kernel */ cl_context context = clCreateContext(clProperties, 0, NULL, clNotify, NULL, &ret); if (ret) { log_error("Could not create context, ret %d", ret); exit(1); } return context; }
void OCLContextProperties::AddOpenGLContextProperties() { #ifdef __linux__ cl_context_properties props[7] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), 0 }; #elif __APPLE__ CGLContextObj kGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kGLContext); cl_context_properties props[5] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) kCGLShareGroup, NULL }; //foundCtx = clCreateContext( //props, 0, 0, NULL, NULL, clerr); #elif WIN32 cl_context_properties props[5] = { CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC() }; #else #error "Platform Not avalible for GL intergration" #endif AddProperties(props); }
void cl_select_context(cl_platform_id* platform, cl_device_id* device, cl_context* context) { cl_int err; #if defined (__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; *context = clCreateContext(props, 0,0, NULL, NULL, &err); #else #ifdef UNIX cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; *context = clCreateContext(props, 1, &cdDevices[uiDeviceUsed], NULL, NULL, &err); #else // Win32 cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)*platform, 0 }; *context = clCreateContext(props, 1, device, NULL, NULL, &err); CHECK_ERR(err); #endif #endif }
static VALUE rogl_method_CGLGetShareGroup( VALUE self, VALUE ctxval ) { CGLContextObj ctxobj = (CGLContextObj)VALUE_AS_CPOINTER(ctxval); CGLShareGroupObj sgobj = CGLGetShareGroup(ctxobj); return CPOINTER_AS_VALUE(sgobj); }
// XXX: initCL should be removed from libosd void OsdClKernelDispatcher::initCL() { cl_int ciErrNum; cl_platform_id cpPlatform = 0; cl_uint num_platforms; ciErrNum = clGetPlatformIDs(0, NULL, &num_platforms); if (ciErrNum != CL_SUCCESS) { OSD_ERROR("Error %i in clGetPlatformIDs call.\n", ciErrNum); exit(1); } if (num_platforms == 0) { OSD_ERROR("No OpenCL platform found.\n"); exit(1); } cl_platform_id *clPlatformIDs; clPlatformIDs = new cl_platform_id[num_platforms]; ciErrNum = clGetPlatformIDs(num_platforms, clPlatformIDs, NULL); char chBuffer[1024]; for (cl_uint i = 0; i < num_platforms; ++i) { ciErrNum = clGetPlatformInfo(clPlatformIDs[i], CL_PLATFORM_NAME, 1024, chBuffer,NULL); if (ciErrNum == CL_SUCCESS) { cpPlatform = clPlatformIDs[i]; } } // ------------- clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &_clDevice, NULL); #if defined(_WIN32) cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0 }; #elif defined(__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #else cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0 }; #endif // XXX context creation should be moved to client code _clContext = clCreateContext(props, 1, &_clDevice, NULL, NULL, &ciErrNum); CL_CHECK_ERROR(ciErrNum, "clCreateContext\n"); _clQueue = clCreateCommandQueue(_clContext, _clDevice, 0, &ciErrNum); CL_CHECK_ERROR(ciErrNum, "clCreateCommandQueue\n"); }
bool Context::createContext(bool glInterop) { if(_initialized) return false; QMutexLocker locker(&_lock); _glInterop= glInterop; QVector<cl_context_properties> props; if(_glInterop) { // Add OpenGL properties #ifdef __MACOSX // Apple (untested) props << CL_CGL_SHAREGROUP_KHR; props << reinterpret_cast<cl_context_properties>(CGLGetShareGroup(CGLGetCurrentContext())); props << CL_CONTEXT_PLATFORM; props << reinterpret_cast<cl_context_properties>(devMgr().platform()); #elif _WIN32 // Windows (untested) props << CL_GL_CONTEXT_KHR props << reinterpret_cast<cl_context_properties>(wglGetCurrentContext()); props << CL_WGL_HDC_KHR props << reinterpret_cast<cl_context_properties>(wglGetCurrentDC()); #else // Linux/GLX props << CL_GL_CONTEXT_KHR; props << (cl_context_properties)glXGetCurrentContext(); props << CL_GLX_DISPLAY_KHR; props << (cl_context_properties)glXGetCurrentDisplay(); props << (cl_context_properties)(devMgr().platform()); #endif props << 0; // Can't use nullptr here } // Create OpenCL context cl_int err; const auto propsPtr= props.count() ? props.data() : nullptr; const auto devs= devMgr().devices(); // Get selected devices from the dev manager _context= clCreateContext(propsPtr, devs.count(), devs.data(), nullptr, nullptr, &err); if(checkCLError(err, "clCreateContext")) return false; // Get list of supported formats cl_uint formatCount; err= clGetSupportedImageFormats(_context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D, 0, nullptr, &formatCount); if(checkCLError(err, "clGetSupportedImageFormats") or formatCount<=0) return false; _imgFormats.resize(formatCount); err= clGetSupportedImageFormats(_context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D, formatCount, _imgFormats.data(), nullptr); if(checkCLError(err, "clGetSupportedImageFormats")) return false; return true; }
void OpenCL::setupFromOpenGL(int deviceNumber) { ofLog(OF_LOG_VERBOSE, "OpenCL::setupFromOpenGL "); if(isSetup) { ofLog(OF_LOG_VERBOSE, "... already setup. returning"); return; } if(deviceInfo.size() == 0) getDeviceInfos(CL_DEVICE_TYPE_GPU); deviceNumber = (deviceNumber + getNumDevices()) % getNumDevices(); clDevice = deviceInfo[deviceNumber].clDeviceId; cl_platform_id clPlatformID = deviceInfo[deviceNumber].clPlatformId; cl_int err; #ifdef TARGET_OSX CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; clContext = clCreateContext(properties, 0, 0, NULL, NULL, &err); #elif defined _WIN32 //aqcuire shared context on windows. { // TODO: we want to be more specific about the platform, // at the moment only the first successful platform is selected. cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)clPlatformID, 0 }; ofLogNotice() << "Using OpenCL Platform: 0x" << std::hex << clPlatformID; ofLogNotice() << "Using OpenCL Device: 0x" << std::hex << clDevice; clContext = clCreateContext(properties, 1, &clDevice, NULL, NULL, &err); ofLogNotice() << "Created OpenCL context: " << (err == CL_SUCCESS ? "SUCCESS" : "ERROR"); } #endif if(clContext == NULL) { ofLog(OF_LOG_ERROR, "Error creating clContext."); assert(err != CL_INVALID_PLATFORM); assert(err != CL_INVALID_VALUE); assert(err != CL_INVALID_DEVICE); assert(err != CL_INVALID_DEVICE_TYPE); assert(err != CL_DEVICE_NOT_AVAILABLE); assert(err != CL_DEVICE_NOT_FOUND); assert(err != CL_OUT_OF_HOST_MEMORY); assert(false); } createQueue(); }
void Particles::_init_cl_context(void) { cl_int ret; std::vector<cl::Platform> platforms; ret = cl::Platform::get(&platforms); // printf("Number of platforms: %ld\n", platforms.size()); std::vector<cl::Device> devices; ret = platforms.front().getDevices(CL_DEVICE_TYPE_GPU, &devices); // printf("Number of devices GPU on first platform: %ld\n", devices.size()); std::string device_name; std::string device_extensions; ret = devices.front().getInfo(CL_DEVICE_NAME, &device_name); // printf("Device name: %s\n", device_name.c_str()); ret = devices.front().getInfo(CL_DEVICE_EXTENSIONS, &device_extensions); if (device_extensions.find(CL_GL_SHARING_EXT) == std::string::npos) { dprintf(2, "This device doesn't support GL/CL sharing...\n"); throw std::exception(); } // Get current CGL Context and CGL Share group CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); // Create CL context properties, add handle & share-group enum cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; this->_cl_context = cl::Context::Context(devices, properties, NULL, NULL, &ret); if (ret != CL_SUCCESS) { dprintf(2, "Error while trying to create context...\n"); throw std::exception(); } this->bind_array(); this->bind_buffer(); glEnableVertexAttribArray(0); glVertexAttribIPointer(0, 2, GL_UNSIGNED_INT, 0, NULL); cl::BufferGL::BufferGL(this->_cl_context, CL_MEM_READ_WRITE, this->_positions_vbo, &ret); if (ret != CL_SUCCESS) { dprintf(2, "Error while trying to create buffer from openGL...\n"); throw std::exception(); } }
void cl_context::init() { // OpenCL try { // Get available platforms vector<cl::Platform> platforms; cl::Platform::get(&platforms); LOG_INFO<<platforms.front().getInfo<CL_PLATFORM_VERSION>(); // context sharing is OS specific #if defined (__APPLE__) || defined(MACOSX) CGLContextObj curCGLContext = CGLGetCurrentContext(); CGLShareGroupObj curCGLShareGroup = CGLGetShareGroup(curCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)curCGLShareGroup, 0 }; #elif defined WIN32 cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0 }; #else 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)(platforms[0])(), 0 }; #endif m_context = cl::Context(CL_DEVICE_TYPE_GPU, properties); // Get a list of devices on this platform vector<cl::Device> devices = m_context.getInfo<CL_CONTEXT_DEVICES>(); m_device = devices[0]; // Create a command queue and use the first device m_queue = cl::CommandQueue(m_context, m_device); } catch(cl::Error &error) { LOG_ERROR << error.what() << "(" << oclErrorString(error.err()) << ")"; } }
void CL::TinyCL::selectInteropDevice(DEVICE dev, bool profile) { try { //We assume only the first device and platform will be used //This is after all a lazy implementation cl::Platform::get(&mPlatforms); //Query the devices for the type desired mPlatforms.at(0).getDevices(static_cast<cl_device_type>(dev), &mDevices); #ifdef _WIN32 cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)(mPlatforms[0])(), 0 }; #elif defined(__linux__) cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)(mPlatforms[0])(), 0 }; #elif defined(__APPLE__) CGLContextObj glContext = CGLGetCurrentContext(); CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)shareGroup, }; #endif mContext = cl::Context(mDevices, properties); //Grab the OpenGL device mDevices = mContext.getInfo<CL_CONTEXT_DEVICES>(); if (profile) mQueue = cl::CommandQueue(mContext, mDevices.at(0), CL_QUEUE_PROFILING_ENABLE); else mQueue = cl::CommandQueue(mContext, mDevices.at(0)); std::cout << "OpenCL Info:" << "\nName: " << mDevices.at(0).getInfo<CL_DEVICE_NAME>() << "\nVendor: " << mDevices.at(0).getInfo<CL_DEVICE_VENDOR>() << "\nDriver Version: " << mDevices.at(0).getInfo<CL_DRIVER_VERSION>() << "\nDevice Profile: " << mDevices.at(0).getInfo<CL_DEVICE_PROFILE>() << "\nDevice Version: " << mDevices.at(0).getInfo<CL_DEVICE_VERSION>() << "\nMax Work Group Size: " << mDevices.at(0).getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>() << std::endl; } catch (const cl::Error &e) { std::cout << "Error selecting GL interop device: " << e.what() << " code: " << e.err() << std::endl; throw e; } }
ClState::Context ClState::createContext(const Device& d){ Context c; c.device= d; cl_int err2=0; #if OS == OS_LINUX cl_context_properties properties[]= { CL_GL_CONTEXT_KHR,(cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR,(cl_context_properties)glXGetCurrentDisplay(), 0 }; c.id = clCreateContext(properties, 1, &d.id, 0, 0, &err2); #elif OS == OS_WINDOWS cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)(platform.id), 0 }; c.id = clCreateContext(properties, 1, &d.id, 0, 0, &err2); #elif OS == OS_MACOSX CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; c.id = clCreateContext(props, 0, 0, NULL, NULL, &err2); #endif errorCheck("ClState::createContext(..): Error on clCreateContext(..):", err2); return c; }
cl_int init_cl_context_from_gl(clctx_t *c, cl_platform_id platform) { cl_int ret=0; ret = clewInit(); if (ret) { fprintf_rl(stderr, "clewInit() failed with code %d\n", ret); return -1024; } #ifdef RL_OPENCL_GL #if defined(_WIN32) // Windows from http://stackoverflow.com/a/30529217/1675589 cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; #elif defined(__APPLE__) // OS X CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) kCGLShareGroup, 0 }; #else // Linux 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 //c->context = clCreateContext(NULL, ret_num_devices, device_id, NULL, NULL, &ret); c->context = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, NULL, NULL, &ret); CL_ERR_RET("clCreateContextFromType (in init_cl_context_from_gl)", ret); #endif return ret; }
cl_context_properties get_apple_cgl_share_group() { #ifdef __APPLE__ #ifdef HAVE_GL CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); return (cl_context_properties)kCGLShareGroup; #else throw clerror("get_apple_cgl_share_group unavailable: " "GL interop not compiled", CL_INVALID_VALUE); #endif #else throw clerror("get_apple_cgl_share_group unavailable: non-Apple platform", CL_INVALID_VALUE); #endif /* __APPLE__ */ }
std::vector<cl_context_properties> OpenCL::getGLSharingContextProperties() { #if WIN32 cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC() }; #elif __APPLE__ CGLContextObj glContext = CGLGetCurrentContext(); CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext); cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)shareGroup }; #else // LINUX cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay() }; #endif return std::vector<cl_context_properties>(props, props + sizeof(props)/sizeof(cl_context_properties)); }
void Context::setup(int device_id, bool withOpenGL) { if (context()) return; std::vector<cl::Platform> platforms; cl::Platform::get(&platforms); cl::Platform platform = platforms.back(); if (!withOpenGL) { cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platform)(), 0}; context = cl::Context(CL_DEVICE_TYPE_ALL, properties); } else { #ifdef TARGET_OSX CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #else cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)clPlatform, 0}; #endif context = cl::Context(CL_DEVICE_TYPE_ALL, properties); } std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>(); device = devices[device_id]; cl_int err = CL_SUCCESS; queue = cl::CommandQueue(context, device, 0, &err); reportError(err); current_context = this; }
ofxClScheduler::ofxClScheduler() { // create the OpenCL context #ifdef GL_INTEROP CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; context = clCreateContext(properties, 0, 0, 0, 0, &clErr); // context = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, NULL, NULL, &clErr); #else context = clCreateContextFromType(0, CL_DEVICE_TYPE_GPU, NULL, NULL, &clErr); #endif checkOpenClError(clErr, "clCreateContextFromType"); device = getMaxFlopsDev(context); globalQ = clCreateCommandQueue(context, device, 0, &clErr); checkOpenClError(clErr, "clCreateCommandQueue: global"); }
bool oclCreateSomeContext(cl_context* context , cl_device_id deviceId,cl_platform_id platformId) { cl_int error = 0; #ifdef OCL_UTIL_GL_SHARING_ENABLE // Define OS-specific context properties and create the OpenCL context #if defined (__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); if( kCGLContext == NULL) printf("CGLGetCurrentContext() returned NULL\n"); if( kCGLShareGroup == NULL) printf("CGLGetShareGroup(kCGLContext) returned NULL\n"); cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; cxGPUContext = clCreateContext(props, 0,0, NULL, NULL, &error); #else #ifdef UNIX GLXContext glxContext = glXGetCurrentContext(); Display* display = glXGetCurrentDisplay(); if(glxContext == NULL) printf("glXGetCurrentContext() returned NULL\n"); if(display == NULL) printf("glXGetCurrentDisplay() returned NULL\n"); cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glxContext, CL_GLX_DISPLAY_KHR, (cl_context_properties)display, CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, 0 }; cxGPUContext = clCreateContext(props, 1, &cdDevices[uiDeviceUsed], NULL, NULL, &error); #else // Win32 HGLRC wglContext = wglGetCurrentContext(); HDC wglDC = wglGetCurrentDC(); if(wglContext == NULL) printf("wglGetCurrentContext() returned NULL\n"); if(wglDC == NULL) printf("wglGetCurrentDC() returned NULL\n"); cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglContext, CL_WGL_HDC_KHR, (cl_context_properties)wglDC, CL_CONTEXT_PLATFORM, (cl_context_properties)platformId, 0 }; *context = clCreateContext(props, 1, &deviceId, NULL, NULL, &error); if( !oclHandleErrorMessage("Creating GL-CL shared context", error) ) return false; #endif #endif #else *context = clCreateContext(NULL, 1, &deviceId, NULL, NULL, &error); if( !oclHandleErrorMessage("Creating CL context", error) ) return false; #endif return true; }
/// Creates a shared OpenCL/OpenGL context for the currently active /// OpenGL context. /// /// Once created, the shared context can be used to create OpenCL memory /// objects which can interact with OpenGL memory objects (e.g. VBOs). /// /// \throws unsupported_extension_error if no CL-GL sharing capable devices /// are found. inline context opengl_create_shared_context() { // name of the OpenGL sharing extension for the system #if defined(__APPLE__) const char *cl_gl_sharing_extension = "cl_APPLE_gl_sharing"; #else const char *cl_gl_sharing_extension = "cl_khr_gl_sharing"; #endif #if defined(__APPLE__) // get OpenGL share group CGLContextObj cgl_current_context = CGLGetCurrentContext(); CGLShareGroupObj cgl_share_group = CGLGetShareGroup(cgl_current_context); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) cgl_share_group, 0 }; cl_int error = 0; cl_context cl_gl_context = clCreateContext(properties, 0, 0, 0, 0, &error); if(!cl_gl_context){ BOOST_THROW_EXCEPTION(opencl_error(error)); } return context(cl_gl_context, false); #else typedef cl_int(*GetGLContextInfoKHRFunction)( const cl_context_properties*, cl_gl_context_info, size_t, void *, size_t * ); std::vector<platform> platforms = system::platforms(); for(size_t i = 0; i < platforms.size(); i++){ const platform &platform = platforms[i]; // load clGetGLContextInfoKHR() extension function GetGLContextInfoKHRFunction GetGLContextInfoKHR = reinterpret_cast<GetGLContextInfoKHRFunction>( reinterpret_cast<size_t>( platform.get_extension_function_address("clGetGLContextInfoKHR") ) ); if(!GetGLContextInfoKHR){ continue; } // create context properties listing the platform and current OpenGL display cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform.id(), #if defined(__linux__) CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), #elif defined(WIN32) CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), #endif 0 }; // lookup current OpenCL device for current OpenGL context cl_device_id gpu_id; cl_int ret = GetGLContextInfoKHR( properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &gpu_id, 0 ); if(ret != CL_SUCCESS){ continue; } // create device object for the GPU and ensure it supports CL-GL sharing device gpu(gpu_id, false); if(!gpu.supports_extension(cl_gl_sharing_extension)){ continue; } // return CL-GL sharing context return context(gpu, properties); } #endif // no CL-GL sharing capable devices found BOOST_THROW_EXCEPTION( unsupported_extension_error(cl_gl_sharing_extension) ); }
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(); } }
void ocl_init(sotl_device_t *dev) { cl_int err = 0; // Create context // #ifdef HAVE_LIBGL if(dev->display) { #ifdef __APPLE__ CGLContextObj cgl_context = CGLGetCurrentContext (); CGLShareGroupObj sharegroup = CGLGetShareGroup (cgl_context); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) sharegroup, 0 }; #else 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) dev->platform->id, 0 }; #endif dev->context = clCreateContext (properties, 1, &dev->id, NULL, NULL, &err); } else #endif { dev->context = clCreateContext (0, 1, &dev->id, NULL, NULL, &err); } check (err, "Failed to create compute context \n"); // Load program source // const char *opencl_prog; opencl_prog = file_get_contents(PROGRAM_NAME); if (!opencl_prog) { sotl_log(CRITICAL, "Failed to read contents of the OpenCL program '%s'.\n", PROGRAM_NAME); } // Build program // dev->program = clCreateProgramWithSource (dev->context, 1, &opencl_prog, NULL, &err); check (err, "Failed to create program"); char options[OPENCL_PROG_MAX_STRING_SIZE_OPTIONS]; // Tile size of 32 works better on Xeon/Xeon Phi // if(dev->type != CL_DEVICE_TYPE_GPU) dev->tile_size = 32; else dev->tile_size = TILE_SIZE; #ifdef SLIDE dev->slide_steps = SLIDE; #else dev->slide_steps = 1; #endif sprintf (options, OPENCL_BUILD_OPTIONS "-DTILE_SIZE=%d " "-DSUBCELL=%d " "-DDELTA_T=%.10f " #ifdef SLIDE "-DSLIDE=%d " #endif OPENCL_PROG_STRING_OPTIONS " -I "OCL_INCLUDE " " LENNARD_STRING, dev->tile_size, SUBCELL, 1.0f, #ifdef SLIDE dev->slide_steps, #endif OPENCL_PROG_PARAM_OPTIONS, LENNARD_PARAM); // If not a GPU, do not use Tiling // if (dev->type != CL_DEVICE_TYPE_GPU) strcat (options, " -DNO_LOCAL_MEM"); #ifdef TILE_CACHE // On GPU, use a cache of TILES // if (dev->type == CL_DEVICE_TYPE_GPU) strcat (options, " -DTILE_CACHE"); #endif // Multi-accelerators configuration // if (sotl_have_multi()) strcat (options, " -DHAVE_MULTI"); #ifdef FORCE_N_UPDATE if (!sotl_have_multi()) strcat (options, " -DFORCE_N_UPDATE"); #endif #ifdef TORUS strcat (options, " -DXY_TORUS -DZ_TORUS"); #endif #ifdef XEON_VECTORIZATION strcat (options, " -DXEON_VECTORIZATION"); #endif #if defined(__APPLE__) strcat(options, " -DHAVE_PRINTF"); #endif if (sotl_verbose) sotl_log(INFO, "--- Compiler flags ---\n%s\n----------------------\n", options); err = clBuildProgram (dev->program, 0, NULL, options, NULL, NULL); if(sotl_verbose || err != CL_SUCCESS) { size_t len; // Display compiler error log // clGetProgramBuildInfo (dev->program, dev->id, CL_PROGRAM_BUILD_LOG, 0, NULL, &len); { char buffer[len + 1]; clGetProgramBuildInfo (dev->program, dev->id, CL_PROGRAM_BUILD_LOG, sizeof (buffer), buffer, NULL); sotl_log(INFO, "---- Compiler log ----\n%s\n----------------------\n", buffer); } check (err, "Failed to build program"); } // Create an OpenCL command queue // dev->queue = clCreateCommandQueue (dev->context, dev->id, CL_QUEUE_PROFILING_ENABLE, &err); check (err, "Failed to create a command queue"); cl_create_kernels(dev); }
/* Initialize OpenCL processing */ void init_cl() { char *program_buffer, *program_log; size_t program_size, log_size; cl_image_format png_format; int err; /* Identify a platform */ err = clGetPlatformIDs(1, &platform, NULL); if(err < 0) { perror("Couldn't identify a platform"); exit(1); } /* Access a device */ err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL); if(err == CL_DEVICE_NOT_FOUND) { err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &device, NULL); } if(err < 0) { perror("Couldn't access any devices"); exit(1); } /* Create OpenCL context properties */ #ifdef MAC CGLContextObj mac_context = CGLGetCurrentContext(); CGLShareGroupObj group = CGLGetShareGroup(mac_context); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)group, 0}; #else #ifdef UNIX 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}; #else cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; #endif #endif /* Create context */ context = clCreateContext(properties, 1, &device, NULL, NULL, &err); if(err < 0) { perror("Couldn't create a context"); exit(1); } /* Create program from file */ program_buffer = read_file(PROGRAM_FILE, &program_size); program = clCreateProgramWithSource(context, 1, (const char**)&program_buffer, &program_size, &err); if(err < 0) { perror("Couldn't create the program"); exit(1); } free(program_buffer); /* Build program */ err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); if(err < 0) { /* Find size of log and print to std output */ clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); program_log = (char*) malloc(log_size + 1); program_log[log_size] = '\0'; clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size + 1, program_log, NULL); printf("%s\n", program_log); free(program_log); exit(1); } /* Create a command queue */ queue = clCreateCommandQueue(context, device, 0, &err); if(err < 0) { perror("Couldn't create a command queue"); exit(1); }; /* Create kernel */ kernel = clCreateKernel(program, KERNEL_FUNC, &err); if(err < 0) { printf("Couldn't create a kernel: %d", err); exit(1); }; /* Read pixel data */ read_image_data(TEXTURE_FILE, &tex_pixels, &width, &height); /* Create the input image object from the PNG data */ png_format.image_channel_order = CL_R; png_format.image_channel_data_type = CL_UNSIGNED_INT8; in_texture = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &png_format, width, height, 0, (void*)tex_pixels, &err); if(err < 0) { perror("Couldn't create the image object"); exit(1); }; /* Create kernel arguments */ err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &in_texture); if(err < 0) { printf("Couldn't set a kernel argument"); exit(1); }; }
CLContext::CLContext() { #if defined(__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; context_ = clCreateContext(properties, 0, 0, clLogMessagesToStdoutAPPLE, 0, 0); if (!context_) crash("failed to create context"); uint device_count; cl_device_id device_ids[16]; size_t returned_size; int err = clGetContextInfo(context_, CL_CONTEXT_DEVICES, sizeof(device_ids), device_ids, &returned_size); if (err != CL_SUCCESS) crash("failed to get devices"); device_count = (int)returned_size / sizeof(cl_device_id); int i = 0; bool device_found = false; cl_device_type device_type; for (i = 0; i < device_count; i++) { clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &device_type, NULL); if (device_type == CL_DEVICE_TYPE_GPU) { device_id_ = device_ids[i]; device_found = true; break; } } if (!device_found) crash("no GPU device found"); #elif defined(WIN32) HGLRC hrc = wglGetCurrentContext(); HDC hdc = wglGetCurrentDC(); if (!hrc || !hdc) crash("failed to get HDC or HGLRC"); cl_platform_id platform_ids[16]; size_t platform_count; int err = clGetPlatformIDs(sizeof(platform_ids) / sizeof(platform_ids[0]), platform_ids, &platform_count); if (err != CL_SUCCESS || !platform_count) crash("failed to get platforms"); for (uint i = 0; i < platform_count; ++i) { char platform_name[100]; char platform_version[100]; char platform_vendor[100]; char platform_extensions[1000]; err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, sizeof(platform_name), platform_name, NULL); if (err != CL_SUCCESS) crash("failed to get platform name"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, NULL); if (err != CL_SUCCESS) crash("failed to get platform version"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_VENDOR, sizeof(platform_vendor), platform_vendor, NULL); if (err != CL_SUCCESS) crash("failed to get platform vendor"); err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_EXTENSIONS, sizeof(platform_extensions), platform_extensions, NULL); if (err != CL_SUCCESS) crash("failed to get platform extensions"); cout << "platform name: " << platform_name << endl; cout << "platform version: " << platform_version << endl; cout << "platform vendor: " << platform_vendor << endl; cout << "platform extensions: " << platform_extensions << endl; cout << endl; } cl_platform_id platform_id = platform_ids[0]; typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)( 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); clGetGLContextInfoKHR_fn clGetGLContextInfoKHR; clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); if (!clGetGLContextInfoKHR) crash("failed to query proc address for clGetGLContextInfoKHR"); #ifndef NO_OPENGL_SHARING cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_id, CL_GL_CONTEXT_KHR, (cl_context_properties) hrc, CL_WGL_HDC_KHR, (cl_context_properties) hdc, 0 }; size_t device_count; err = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(device_id_), &device_id_, &device_count); if (err != CL_SUCCESS || !device_count) crash("failed to get CL device from GL context"); char device_name[100]; char device_version[100]; cl_device_type device_type; cl_bool device_image_support; err = clGetDeviceInfo(device_id_, CL_DEVICE_NAME, sizeof(device_name), device_name, NULL); if (err != CL_SUCCESS) crash("failed to get device name"); err = clGetDeviceInfo(device_id_, CL_DEVICE_VERSION, sizeof(device_version), device_version, NULL); if (err != CL_SUCCESS) crash("failed to get device version"); err = clGetDeviceInfo(device_id_, CL_DEVICE_TYPE, sizeof(device_type), &device_type, NULL); if (err != CL_SUCCESS) crash("failed to get device type"); err = clGetDeviceInfo(device_id_, CL_DEVICE_IMAGE_SUPPORT, sizeof(device_image_support), &device_image_support, NULL); if (err != CL_SUCCESS) crash("failed to get device image support"); cout << "device name: " << device_name << endl; cout << "device version: " << device_version << endl; cout << "device type: " << ((device_type & CL_DEVICE_TYPE_GPU) ? "GPU" : "not GPU") << endl; cout << "device image support: " << (device_image_support ? "yes" : "no") << endl; cout << endl; context_ = clCreateContext(properties, 1, &device_id_, 0, 0, &err); #else cl_int error = 0; cl_platform_id platform; // Platform error = clGetPlatformIDs(1, &platform, NULL); if (error != CL_SUCCESS) { cout << "Error getting platform id: " << error << endl; exit(error); } // Device error = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id_, NULL); if (err != CL_SUCCESS) { cout << "Error getting device ids: " << error << endl; exit(error); } // Context context_ = clCreateContext(0, 1, &device_id_, NULL, NULL, &error); if (error != CL_SUCCESS) { cout << "Error creating context: " << error << endl; exit(error); } #endif #endif cl_command_queue_properties queue_properties = 0; queue_properties |= CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE; #ifdef PROFILING_ENABLED queue_properties |= CL_QUEUE_PROFILING_ENABLE; #endif queue_ = clCreateCommandQueue(context_, device_id_, queue_properties, NULL); if (!queue_) crash("failed to create command queue"); }
bool initCLGLContext(boost::compute::context & ctx) { INFOM("Initializing OpenCL/OpenGL shared context"); #if 1 /* select appropriate device and platform */ cl_platform_id platform = nullptr; cl_device_id device = nullptr; if ((!utils::ocl::selectGLDeviceAndPlatform(&device, &platform)) && (!utils::ocl::selectPlatformAndDevice(&device, &platform))) { ERRORM("Failed to select an appropriate device or platform"); return false; } /* setup context */ cl_context_properties props[] = { #if defined(FLUIDSIM_OS_MAC) CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) CGLGetShareGroup(CGLGetCurrentContext()), #elif defined(FLUIDSIM_OS_UNIX) CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties) platform, #elif defined(FLUIDSIM_OS_WIN) CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) platform, #else # error "Unsupported OS platform" #endif 0 }; /* create opencl context */ cl_int err = CL_SUCCESS; cl_context ctx_ = clCreateContext(props, 1, &device, nullptr, nullptr, &err); if (err != CL_SUCCESS) { ERRORM("Failed to create OpenCL context: " << utils::ocl::errorToStr(err)); return false; } ctx = boost::compute::context(ctx_, false); utils::ocl::printDeviceInfo(ctx.get_devices()); #else try { /* create opencl context */ ctx = boost::compute::opengl_create_shared_context(); utils::ocl::printDeviceInfo(ctx.get_devices()); } catch (const boost::compute::opencl_error & e) { ERRORM(e.what()); return false; } catch (const boost::compute::unsupported_extension_error & e) { ERRORM(e.what()); return false; } catch (const std::exception & e) { ERRORM("An unexpected error occured during opencl context initialization: " << e.what()); return false; } #endif INFOM("Successfully initialized OpenCL context"); INFOM("Using device : " << ctx.get_device().name()); INFOM("Using platform : " << ctx.get_device().platform().name()); return true; }
bool selectGLDeviceAndPlatform(cl_device_id *device, cl_platform_id *platform) { assert(device != nullptr); assert(platform != nullptr); /* first try to get the necessary extension */ clGetGLContextInfoKHR_fn clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR"); if (clGetGLContextInfoKHR == nullptr) { ERRORM("clGetGLContextInfoKHR extension function not supproted."); return false; } #if defined(FLUIDSIM_OS_MAC) cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) CGLGetShareGroup(CGLGetCurrentContext()), 0 }; cl_int err = clGetGLContextInfoKHR(props, // the OpenGL context CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, // get the id of the device currently executing OpenGL sizeof(*device), device, nullptr); if (err != CL_SUCCESS) { ERRORM("Failed to retrieve the OpenCL id of the device executing OpenGL: " << errorToStr(err)); return false; } /* get the platform associated with the device */ err = clGetDeviceInfo(*device, CL_DEVICE_PLATFORM, sizeof(*platform), platform, nullptr); if (err != CL_SUCCESS) { ERRORM("Failed to retirieve platform id for the device executing OpenGL: " << errorToStr(err)); return false; } #else cl_context_properties props[] = { #if defined(FLUIDSIM_OS_UNIX) CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties) nullptr, #elif defined(FLUIDSIM_OS_WIN) CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) nullptr, #else # error "Unsupported OS platform" #endif 0 }; std::vector<boost::compute::platform> platform_list = boost::compute::system::platforms(); for (const boost::compute::platform & p : platform_list) { WARNM("platform: " << p.name()); props[5] = (cl_context_properties) p.id(); cl_int err = clGetGLContextInfoKHR(props, // the OpenGL context CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, // get the id of the device currently executing OpenGL sizeof(*device), device, nullptr); if ((err == CL_SUCCESS) && (boost::compute::device(*device).type() == CL_DEVICE_TYPE_GPU)) { *platform = (cl_platform_id) props[5]; return true; } else { WARNM("clGetGLContextInfoKHR: " << errorToStr(err)); } } #endif return false; }
void ConfigManager::CreateConfigs(Mode mode, bool interop, std::vector<Config>& configs) { std::vector<CLWPlatform> platforms; CLWPlatform::CreateAllPlatforms(platforms); if (platforms.size() == 0) { throw std::runtime_error("No OpenCL platforms installed."); } configs.clear(); bool hasprimary = false; for (int i = 0; i < platforms.size(); ++i) { std::vector<CLWDevice> devices; int startidx = configs.size(); for (int d = 0; d < (int)platforms[i].GetDeviceCount(); ++d) { if ((mode == kUseGpus || mode == kUseSingleGpu) && platforms[i].GetDevice(d).GetType() != CL_DEVICE_TYPE_GPU) continue; if ((mode == kUseCpus || mode == kUseSingleCpu) && platforms[i].GetDevice(d).GetType() != CL_DEVICE_TYPE_CPU) continue; Config cfg; cfg.caninterop = false; #ifdef WIN32 if (platforms[i].GetDevice(d).HasGlInterop() && !hasprimary && interop) { cl_context_properties props[] = { //OpenCL platform CL_CONTEXT_PLATFORM, (cl_context_properties)((cl_platform_id)platforms[i]), //OpenGL context CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), //HDC used to create the OpenGL context CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), 0 }; cfg.context = CLWContext::Create(platforms[i].GetDevice(d), props); devices.push_back(platforms[i].GetDevice(d)); cfg.devidx = 0; cfg.type = kPrimary; cfg.caninterop = true; hasprimary = true; } else #elif __linux__ if (platforms[i].GetDevice(d).HasGlInterop() && !hasprimary && interop) { cl_context_properties props[] = { //OpenCL platform CL_CONTEXT_PLATFORM, (cl_context_properties)((cl_platform_id)platforms[i]), //OpenGL context CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), //HDC used to create the OpenGL context CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), 0 }; cfg.context = CLWContext::Create(platforms[i].GetDevice(d), props); devices.push_back(platforms[i].GetDevice(d)); cfg.devidx = 0; cfg.type = kPrimary; cfg.caninterop = true; hasprimary = true; } else #elif __APPLE__ if (platforms[i].GetDevice(d).HasGlInterop() && !hasprimary && interop) { CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); // Create CL context properties, add handle & share-group enum ! cl_context_properties props[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; cfg.context = CLWContext::Create(platforms[i].GetDevice(d), props); devices.push_back(platforms[i].GetDevice(d)); cfg.devidx = 0; cfg.type = kPrimary; cfg.caninterop = true; hasprimary = true; } else #endif { cfg.context = CLWContext::Create(platforms[i].GetDevice(d)); cfg.devidx = 0; cfg.type = kSecondary; } configs.push_back(cfg); if (mode == kUseSingleGpu || mode == kUseSingleCpu) break; } if (configs.size() == 1 && (mode == kUseSingleGpu || mode == kUseSingleCpu)) break; } if (!hasprimary) { configs[0].type = kPrimary; } for (int i = 0; i < configs.size(); ++i) { configs[i].renderer = new FrRenderer(configs[i].context, configs[i].devidx); } }
static void init_ocl_device(QSP_ARG_DECL cl_device_id dev_id, Compute_Platform *cpp) { cl_int status; //long param_data[MAX_PARAM_SIZE/sizeof(long)]; // force alignment //char name[LLEN]; static int n_ocl_devs=0; Platform_Device *pdp; CGLContextObj cgl_ctx=NULL; cl_context context; cl_command_queue command_queue; //"stream" in CUDA cl_context_properties props[3]={ CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, 0, // need to put cgl_ctx here 0 }; pdp = create_ocl_device(QSP_ARG dev_id, cpp); if( pdp == NULL ) return; /* Remember this name in case the default is not found */ if( first_ocl_dev_name == NULL ) first_ocl_dev_name = PFDEV_NAME(pdp); /* Compare this name against the default name set in * the environment, if it exists... */ if( default_ocl_dev_name != NULL && ! default_ocl_dev_found ){ if( !strcmp(PFDEV_NAME(pdp),default_ocl_dev_name) ) default_ocl_dev_found=1; } get_extensions(QSP_ARG pdp); SET_OCLDEV_DEV_ID(pdp,dev_id); SET_PFDEV_PLATFORM(pdp,cpp); if( n_ocl_devs >= MAX_OPENCL_DEVICES ){ sprintf(ERROR_STRING,"More than %d OpenCL devices found;" "need to increase MAX_OPENCL_DEVICES and recompile", MAX_OPENCL_DEVICES); error1(ERROR_STRING); } fprintf(stderr,"Setting %s device index to %d\n",PFDEV_NAME(pdp),n_ocl_devs); SET_PFDEV_SERIAL(pdp,n_ocl_devs++); SET_PFDEV_MAX_DIMS(pdp,DEFAULT_PFDEV_MAX_DIMS); // On the new MacBook Pro, with two devices, the Iris_Pro // throws an error at clCreateCommandQueue *iff* we set // the share group property here... Presumably because // that device doesn't handle the display? // We insert a hack below by excluding that device name, // but maybe there is another model where that would be // inappropriate? if( extension_supported(pdp,"cl_APPLE_gl_sharing") && strcmp(PFDEV_NAME(pdp),"Iris_Pro")){ CGLShareGroupObj share_group; cgl_ctx = CGLGetCurrentContext(); if( cgl_ctx != NULL){ // This means that we have an OpenGL window available... share_group = CGLGetShareGroup(cgl_ctx); assert( share_group != NULL ); props[1] = (cl_context_properties) share_group; } else { // If we let this go, it sometimes causes a seg fault // when we try to set the GL window afterwards!? // // But it should not be an error, because we don't know // for sure that we will ever attempt it. // We need to set a flag to prohibit it later... advise("init_ocl_device: OpenCL initialized without an OpenGL context;"); advise("init_ocl_device: Prohibiting OpenGL operations."); prohibit_opengl(); } } // Check for OpenGL capabilities //opengl_check(pdp); #ifdef TAKEN_FROM_DEMO_PROG #if (USE_GL_ATTACHMENTS) printf(SEPARATOR); printf("Using active OpenGL context...\n"); CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; // Create a context from a CGL share group // ComputeContext = clCreateContext(properties, 0, 0, clLogMessagesToStdoutAPPLE, 0, 0); if(!ComputeContext) return -2; #else // ! USE_GL_ATTACHMENTS // Connect to a compute device // err = clGetDeviceIDs(NULL, ComputeDeviceType, 1, &ComputeDeviceId, NULL); if (err != CL_SUCCESS) { printf("Error: Failed to locate compute device!\n"); return EXIT_FAILURE; } // Create a compute context // ComputeContext = clCreateContext(0, 1, &ComputeDeviceId, clLogMessagesToStdoutAPPLE, NULL, &err); if (!ComputeContext) { printf("Error: Failed to create a compute context!\n"); return EXIT_FAILURE; } #endif // ! USE_GL_ATTACHMENTS #endif // TAKEN_FROM_DEMO_PROG //create context on the specified device //if( cgl_ctx != NULL ) //fprintf(stderr,"creating clContext with share properties for %s...\n",PFDEV_NAME(pdp)); if( cgl_ctx == NULL ){ context = clCreateContext( NULL, // cl_context_properties *properties 1, // num_devices &dev_id, // devices NULL, // void *pfn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data ) NULL, // void *user_data &status // cl_int *errcode_ret ); } else { context = clCreateContext( props, // cl_context_properties *properties 0, // num_devices NULL, // devices clLogMessagesToStdoutAPPLE, // void *pfn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data ) NULL, // void *user_data &status // cl_int *errcode_ret ); } if( status != CL_SUCCESS ){ report_ocl_error(status, "clCreateContext"); SET_OCLDEV_CTX(pdp,NULL); //return; } // BUG check return value for error SET_OCLDEV_CTX(pdp,context); //create the command_queue (stream) //fprintf(stderr,"clContext = 0x%lx...\n",(long)context); //fprintf(stderr,"init_ocl_device: dev_id = 0x%lx\n",(long)dev_id); // At least once we have gotten an invalid value error here, // after receiving the advisory "OpenCL initialized without an OpenGL context // (which may or may not be relevant). This behavior was not repeatable, // perhaps because of different stack contents??? // The third arg is a properties bit field, with valid values being: // CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE // CL_QUEUE_PROFILING_ENABLE command_queue = clCreateCommandQueue(context, dev_id, 0, &status); if( status != CL_SUCCESS ){ report_ocl_error(status, "clCreateCommandQueue"); SET_OCLDEV_QUEUE(pdp,NULL); //return; } else { SET_OCLDEV_QUEUE(pdp,command_queue); } // set a ready flag? init_ocl_dev_memory(QSP_ARG pdp); curr_pdp = pdp; }
static cl::Context PlatformContext(cl_device_type device_type, char* platform_vendor_name, bool enable_gl_interop = false) { cl_uint numPlatforms; cl_platform_id platform = NULL; clGetPlatformIDs(0, NULL, &numPlatforms); if (numPlatforms > 0) { cl_platform_id* platforms = new cl_platform_id[numPlatforms]; clGetPlatformIDs(numPlatforms, platforms, NULL); for (unsigned i = 0; i < numPlatforms; ++i) { char pbuf[100]; clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL); platform = platforms[i]; std::cout << "platform: " << pbuf << std::endl; if (!strcmp(pbuf, platform_vendor_name)) { break; } } delete[] platforms; } if (enable_gl_interop) { // Define OS-specific context properties and create the OpenCL context #if defined (__APPLE__) CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties cps[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; #else #if defined(linux) cl_context_properties cps[] = { CL_GL_CONTEXT_KHR, cl_context_properties(glXGetCurrentContext()), CL_GLX_DISPLAY_KHR, cl_context_properties(glXGetCurrentDisplay()), CL_CONTEXT_PLATFORM, cl_context_properties(platform), 0 }; #else // Win32 cl_context_properties cps[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; #endif #endif cl::Platform _platform(platform); cl::vector<cl::Device> *_devices = new cl::vector<cl::Device>(); _platform.getDevices(CL_DEVICE_TYPE_GPU, _devices); if(_devices->size() > 1) _devices->pop_back(); if (platform == NULL) return cl::Context(device_type, NULL); else return cl::Context(*_devices,cps); return (NULL == platform) ? cl::Context(device_type, NULL) : cl::Context(*_devices, cps); }else //no opengl interoperability { cl_context_properties cps[] = { CL_CONTEXT_PLATFORM, cl_context_properties(platform), 0 }; return (NULL == platform) ? cl::Context(device_type, NULL) : cl::Context(device_type, cps); } }
void init_cl(const char ** sources, int count) { int err = CL_SUCCESS; // get the platform id for this system cl_platform_id platform; err = clGetPlatformIDs(1, &platform, NULL); cl_check_err(err, "clGetPlatformIDs(...)"); // connect to the compute device err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); cl_check_err(err, "clGetDeviceIDs(...)"); // set the platform specific context properties for OpenGL + OpenCL sharing #ifdef __APPLE__ cl_context_properties ctx_prop[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)CGLGetShareGroup(CGLGetCurrentContext()), 0}; #elif defined __linux__ cl_context_properties ctx_prop[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glfwGetGLXContext(window), CL_GLX_DISPLAY_KHR, (cl_context_properties)glfwGetX11Display(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; #elif defined __MINGW32__ cl_context_properties ctx_prop[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; #endif // create the working context context = clCreateContext(ctx_prop, 1, &device_id, NULL, NULL, &err); cl_check_err(err, "clCreateContext(...)"); // next up is the command queue command_queue = clCreateCommandQueue(context, device_id, 0, &err); cl_check_err(err, "clCreateCommandQueue(...)"); // create a single source buffer for the program from the input files size_t length = 0; for (int i = 0; i < count; i++) { length += file_length(sources[i]); } char * buffer = (char *)malloc(length); buffer[0] = '\0'; for (int i = 0; i < count; i++) { char * tmp = read_file(sources[i]); strcat(buffer, tmp); free(tmp); } // create the compute program from 'kernels.cl' program = clCreateProgramWithSource(context, 1, (const char **)&buffer, NULL, &err); cl_check_err(err, "clCreateProgramWithSource(...)"); free(buffer); // program already read, we don't need the buffer anymore // compile the program for our device err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); cl_check_err(err, "clBuildProgram(...)"); // create the computer kernel in the program we wish to run kernel = clCreateKernel(program, "ray_tracer", &err); cl_check_err(err, "clCreateKernel(...)"); }
static int SetupComputeDevices(int gpu) { int err; size_t returned_size; ComputeDeviceType = gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU; #if (USE_GL_ATTACHMENTS) printf(SEPARATOR); printf("Using active OpenGL context...\n"); CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 }; // Create a context from a CGL share group // ComputeContext = clCreateContext(properties, 0, 0, clLogMessagesToStdoutAPPLE, 0, 0); if (!ComputeContext) { printf("Error: Failed to create a compute context!\n"); return EXIT_FAILURE; } #else // Locate a compute device // err = clGetDeviceIDs(NULL, ComputeDeviceType, 1, &ComputeDeviceId, NULL); if (err != CL_SUCCESS) { printf("Error: Failed to locate compute device!\n"); return EXIT_FAILURE; } // Create a context containing the compute device(s) // ComputeContext = clCreateContext(0, 1, &ComputeDeviceId, clLogMessagesToStdoutAPPLE, NULL, &err); if (!ComputeContext) { printf("Error: Failed to create a compute context!\n"); return EXIT_FAILURE; } #endif unsigned int device_count; cl_device_id device_ids[16]; err = clGetContextInfo(ComputeContext, CL_CONTEXT_DEVICES, sizeof(device_ids), device_ids, &returned_size); if(err) { printf("Error: Failed to retrieve compute devices for context!\n"); return EXIT_FAILURE; } device_count = returned_size / sizeof(cl_device_id); int i = 0; int device_found = 0; cl_device_type device_type; for(i = 0; i < device_count; i++) { clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &device_type, NULL); if(device_type == ComputeDeviceType) { ComputeDeviceId = device_ids[i]; device_found = 1; break; } } if(!device_found) { printf("Error: Failed to locate compute device!\n"); return EXIT_FAILURE; } // Create a command queue // ComputeCommands = clCreateCommandQueue(ComputeContext, ComputeDeviceId, 0, &err); if (!ComputeCommands) { printf("Error: Failed to create a command queue!\n"); return EXIT_FAILURE; } // Report the device vendor and device name // cl_char vendor_name[1024] = {0}; cl_char device_name[1024] = {0}; err = clGetDeviceInfo(ComputeDeviceId, CL_DEVICE_VENDOR, sizeof(vendor_name), vendor_name, &returned_size); err|= clGetDeviceInfo(ComputeDeviceId, CL_DEVICE_NAME, sizeof(device_name), device_name, &returned_size); if (err != CL_SUCCESS) { printf("Error: Failed to retrieve device info!\n"); return EXIT_FAILURE; } printf(SEPARATOR); printf("Connecting to %s %s...\n", vendor_name, device_name); return CL_SUCCESS; }