コード例 #1
0
ファイル: qclcontext.cpp プロジェクト: k0zmo/qt-opencl
/*!
    Creates a new OpenCL context that matches \a type.  Does nothing
    if the context has already been created.  The default value for
    \a type is QCLDevice::Default.

    This function will search for the first platform that has a device
    that matches \a type.  The following code can be used to select
    devices that match \a type on a specific platform:

    \code
    context.create(QCLDevice::devices(type, platform));
    \endcode

    Returns true if the context was created; false otherwise.
    On error, the status can be retrieved by calling lastError().

    \sa isCreated(), setContextId(), release()
*/
bool QCLContext::create(QCLDevice::DeviceTypes type)
{
    Q_D(QCLContext);
    if (d->isCreated)
        return true;
    // The "cl_khr_icd" extension says that a null platform cannot
    // be supplied to OpenCL any more, so find the first platform
    // that has devices that match "type".
    QList<QCLDevice> devices = QCLDevice::devices(type);
    if (!devices.isEmpty()) {
        QVector<cl_device_id> devs;
        foreach (QCLDevice dev, devices)
            devs.append(dev.deviceId());
        cl_context_properties props[] = {
            CL_CONTEXT_PLATFORM,
            cl_context_properties(devices[0].platform().platformId()),
            0
        };
        d->id = clCreateContext
            (props, devs.size(), devs.constData(),
             qt_cl_context_notify, 0, &(d->lastError));
    } else {
        d->lastError = CL_DEVICE_NOT_FOUND;
        d->id = 0;
    }
    d->isCreated = (d->id != 0);
    if (!d->isCreated) {
        qWarning() << "QCLContext::create(type:" << int(type) << "):"
                   << errorName(d->lastError);
    }
    return d->isCreated;
}
コード例 #2
0
ファイル: OpenCL.cpp プロジェクト: william-taylor/raster-js
void createContextFromType(v8::FunctionArgs args)
{
    if (args.Length() == 5)
    {
        auto array = GetArray(args[0]);
        auto flags = GetNumber(args[1]);
   
        const auto platformID = cl_context_properties(UnwrapPointer(array->Get(1)));
        const auto platformType = array->Get(0)->NumberValue();
        const auto platformIndex = array->Get(2)->NumberValue();

        cl_context_properties properties[] = { (cl_prop)platformType, (cl_prop)platformID, (cl_prop)platformIndex };
        cl_context context = clCreateContextFromType(properties, flags, nullptr, nullptr, nullptr);
        
        Return(args, v8::WrapPointer(context));
    }
}
コード例 #3
0
ファイル: MultiOpenCLDev.cpp プロジェクト: guan78001/hello
cl_int MultiOpenCLDev::oclCreateContexts() {
  for (cl_uint i = 0; i < devices_.size(); ++i) {
    // Form common context properties which just select needed platform:
    cl_context_properties context_props[] = {
      CL_CONTEXT_PLATFORM,
      cl_context_properties(devices_[i].plat_form_id),
      0
    };
    cl_int err;
    // Now create context with all devices of a given type available for the selected platform
    devices_[i].context = clCreateContext(
                            context_props,
                            1,
                            &devices_[i].device_id,
                            0,
                            0,
                            &err
                          );
    if (err != CL_SUCCESS) {
      printf("oclCreateContexts failed at i=%d, err=%d\n", i, err);
    }
  }
  return CL_SUCCESS;
}
コード例 #4
0
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);
        }
    }
コード例 #5
0
ファイル: qclcontextgl.cpp プロジェクト: Dem0n3D/qt-opencl
/*!
    Creates an OpenCL context that is compatible with the current
    QGLContext and \a platform.  Returns false if there is no OpenGL
    context current or the OpenCL context could not be created for
    some reason.

    This function will first try to create a QCLDevice::GPU device,
    and will then fall back to QCLDevice::Default if a GPU is not found.

    If \a platform is null, then the first platform that has a GPU
    will be used.  If there is no GPU, then the first platform with a
    default device will be used.

    \sa supportsObjectSharing()
*/
bool QCLContextGL::create(const QCLPlatform &platform)
{
    Q_D(QCLContextGL);

    // Bail out if the context already exists.
    if (isCreated())
        return true;

    // Bail out if we don't have an OpenGL context.
    if (!QGLContext::currentContext()) {
        qWarning() << "QCLContextGL::create: needs a current GL context";
        setLastError(CL_INVALID_CONTEXT);
        return false;
    }

    // Find the first gpu device.
    QList<QCLDevice> devices;
    cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
    devices = QCLDevice::devices(QCLDevice::GPU, platform);
    if (devices.isEmpty()) {
        // Find the first default device.
        devices = QCLDevice::devices(QCLDevice::Default, platform);
        deviceType = CL_DEVICE_TYPE_DEFAULT;
    }
    if (devices.isEmpty()) {
        qWarning() << "QCLContextGL::create: no gpu devices found";
        setLastError(CL_DEVICE_NOT_FOUND);
        return false;
    }
    QCLDevice gpu = devices[0];
    QVarLengthArray<cl_device_id> devs;
    foreach (QCLDevice dev, devices)
        devs.append(dev.deviceId());

    // Add the platform identifier to the properties.
    QVarLengthArray<cl_context_properties> properties;
    properties.append(CL_CONTEXT_PLATFORM);
    properties.append(cl_context_properties(gpu.platform().platformId()));

    bool hasSharing = false;
#ifndef QT_NO_CL_OPENGL
    // Determine what kind of OpenCL-OpenGL sharing we have and enable it.
#if defined(__APPLE__) || defined(__MACOSX)
    bool appleSharing = gpu.hasExtension("cl_apple_gl_sharing");
    if (appleSharing) {
        CGLContextObj cglContext = CGLGetCurrentContext();
        CGLShareGroupObj cglShareGroup = CGLGetShareGroup(cglContext);
        properties.append(CL_CGL_SHAREGROUP_KHR);
        properties.append(cl_context_properties(cglShareGroup));
        hasSharing = true;
    }
#else
    bool khrSharing = gpu.hasExtension("cl_khr_gl_sharing");
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES)
    if (khrSharing) {
        properties.append(CL_EGL_DISPLAY_KHR);
        properties.append(cl_context_properties(eglGetCurrentDisplay()));
#ifdef EGL_OPENGL_ES_API
        eglBindAPI(EGL_OPENGL_ES_API);
#endif
        properties.append(CL_GL_CONTEXT_KHR);
        properties.append(cl_context_properties(eglGetCurrentContext()));
        hasSharing = true;
    }
#elif defined(Q_WS_X11)
    if (khrSharing) {
        properties.append(CL_GLX_DISPLAY_KHR);
        properties.append(cl_context_properties(glXGetCurrentDisplay()));
        properties.append(CL_GL_CONTEXT_KHR);
        properties.append(cl_context_properties(glXGetCurrentContext()));
        hasSharing = true;
    }
#else
    // Needs to be ported to other platforms.
    if (khrSharing)
        qWarning() << "QCLContextGL::create: do not know how to enable sharing";
#endif
#endif
#endif // !QT_NO_CL_OPENGL
    properties.append(0);

#ifndef QT_NO_CL_OPENGL
    // Query the actual OpenCL devices we should use with the OpenGL context.
    typedef cl_int (*q_PFNCLGETGLCONTEXTINFOKHR)
        (const cl_context_properties *, cl_uint, size_t, void *, size_t *);
    q_PFNCLGETGLCONTEXTINFOKHR getGLContextInfo =
        (q_PFNCLGETGLCONTEXTINFOKHR)clGetExtensionFunctionAddress
            ("clGetGLContextInfoKHR");
    if (getGLContextInfo && hasSharing) {
        size_t size;
        cl_device_id currentDev;
        if(getGLContextInfo(properties.data(),
                            CL_DEVICES_FOR_GL_CONTEXT_KHR,
                            0, 0, &size) == CL_SUCCESS && size > 0) {
            QVarLengthArray<cl_device_id> buf(size / sizeof(cl_device_id));
            getGLContextInfo(properties.data(),
                             CL_DEVICES_FOR_GL_CONTEXT_KHR,
                             size, buf.data(), 0);
            devs = buf;
            gpu = QCLDevice(devs[0]);
        }
        if (getGLContextInfo(properties.data(),
                             CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
                             sizeof(currentDev), &currentDev, 0)
                == CL_SUCCESS) {
            gpu = QCLDevice(currentDev);
        }
    }
#endif

    // Create the OpenCL context.
    cl_context id;
    cl_int error;
    id = clCreateContext
        (properties.data(), devs.size(), devs.data(),
         qt_clgl_context_notify, 0, &error);
    if (!id && hasSharing) {
        // Try again without the sharing parameters.
        properties.resize(2);
        properties.append(0);
        hasSharing = false;
        id = clCreateContext
            (properties.data(), devs.size(), devs.data(),
             qt_clgl_context_notify, 0, &error);
    }
    setLastError(error);
    if (id == 0) {
        qWarning() << "QCLContextGL::create:" << errorName(error);
        d->supportsSharing = false;
    } else {
        setContextId(id);
        clReleaseContext(id);   // setContextId() adds an extra reference.
        setDefaultDevice(gpu);
        d->supportsSharing = hasSharing;
    }
    return id != 0;
}
//------------------------------------------------------------------------------
// returns context associated with single device only,
// to make it support multiple devices, a list of
// <device type, device num> pairs is required
cl_context create_cl_context(const std::string& platformName,
                             const std::string& deviceTypeName,
                             int deviceNum) {
    cl_int status = 0;
    //1) get platfors and search for platform matching platformName
    cl_uint numPlatforms = 0;
    status = clGetPlatformIDs(0, 0, &numPlatforms);
    check_cl_error(status, "clGetPlatformIDs");
    if(numPlatforms < 1) {
        std::cout << "No OpenCL platforms found" << std::endl;
        exit(EXIT_SUCCESS);
    }
    typedef std::vector< cl_platform_id > PlatformIDs;
    PlatformIDs platformIDs(numPlatforms);
    status = clGetPlatformIDs(numPlatforms, &platformIDs[0], 0);
    check_cl_error(status, "clGetPlatformIDs");
    std::vector< char > buf(0x10000, char(0));
    cl_platform_id platformID;
    PlatformIDs::const_iterator pi = platformIDs.begin();
    for(; pi != platformIDs.end(); ++pi) {
        status = clGetPlatformInfo(*pi, CL_PLATFORM_NAME,
                                 buf.size(), &buf[0], 0);
        check_cl_error(status, "clGetPlatformInfo");
        if(platformName == &buf[0]) {
            platformID = *pi;
            break; 
        }
    } 
    if(pi == platformIDs.end()) {
        std::cerr << "ERROR - Couldn't find platform " 
                  << platformName << std::endl;
        exit(EXIT_FAILURE);
    }
    //2) get devices of deviceTypeName type and store their ids into
    //   an array then select device id at position deviceNum
    cl_device_type deviceType;
    if(deviceTypeName == "default") 
        deviceType = CL_DEVICE_TYPE_DEFAULT;
    else if(deviceTypeName == "cpu")
        deviceType = CL_DEVICE_TYPE_CPU;
    else if(deviceTypeName == "gpu")
        deviceType = CL_DEVICE_TYPE_GPU;
    else if(deviceTypeName == "acc")
        deviceType = CL_DEVICE_TYPE_ACCELERATOR; 
    else if(deviceTypeName == "all")
        deviceType = CL_DEVICE_TYPE_CPU;
    else {
        std::cerr << "ERROR - device type " << deviceTypeName << " unknown"
                  << std::endl;
        exit(EXIT_FAILURE);          
    }                      
    cl_uint numDevices = 0; 
    status = clGetDeviceIDs(platformID, deviceType, 0, 0, &numDevices);
    check_cl_error(status, "clGetDeviceIDs");
    if(numDevices < 1) {
        std::cerr << "ERROR - Cannot find device of type " 
                  << deviceTypeName << std::endl;
        exit(EXIT_FAILURE);          
    }
    typedef std::vector< cl_device_id > DeviceIDs;
    DeviceIDs deviceIDs(numDevices);
    status = clGetDeviceIDs(platformID, deviceType, numDevices,
                            &deviceIDs[0], 0);
    check_cl_error(status, "clGetDeviceIDs");
    if(deviceNum < 0 || deviceNum >= numDevices) {
        std::cerr << "ERROR - device number out of range: [0," 
                  << (numDevices - 1) << ']' << std::endl;
        exit(EXIT_FAILURE);
    }
    cl_device_id deviceID = deviceIDs[deviceNum]; 
    //3) create and return context
    cl_context_properties ctxProps[] = {
        CL_CONTEXT_PLATFORM,
        cl_context_properties(platformID),
        0
    };
    //only a single device supported
    cl_context ctx = clCreateContext(ctxProps, 1, &deviceID,
                                     &context_callback, 0, &status);
    check_cl_error(status, "clCreateContext");
    return ctx;
}
コード例 #7
0
void cOpenClHardware::CreateContext(
	int platformIndex, cOpenClDevice::enumOpenClDeviceType deviceType)
{
	selectedPlatformIndex = platformIndex;
	if (platformIndex >= 0)
	{
		if (openClAvailable)
		{
			devicesInformation.clear();
			clDeviceWorkers.clear();
			clDevices.clear();

			// platformIndex required
			// context operates exclusively with (1) platform
			cl_context_properties cProps[3] = {
				CL_CONTEXT_PLATFORM, cl_context_properties((clPlatforms[platformIndex])()), 0};

			if (context) delete context;
			contextReady = false;

			cl_int err = 0;

			// Constructs a context including all or a subset of devices of a specified type.
			// supports multiple devices
			switch (deviceType)
			{
				case cOpenClDevice::openClDeviceTypeACC:
					context = new cl::Context(CL_DEVICE_TYPE_ACCELERATOR, cProps, nullptr, nullptr, &err);
					break;
				case cOpenClDevice::openClDeviceTypeALL:
					context = new cl::Context(CL_DEVICE_TYPE_ALL, cProps, nullptr, nullptr, &err);
					break;
				case cOpenClDevice::openClDeviceTypeCPU:
					context = new cl::Context(CL_DEVICE_TYPE_CPU, cProps, nullptr, nullptr, &err);
					break;
				case cOpenClDevice::openClDeviceTypeDEF:
					context = new cl::Context(CL_DEVICE_TYPE_DEFAULT, cProps, nullptr, nullptr, &err);
					break;
				case cOpenClDevice::openClDeviceTypeGPU:
					context = new cl::Context(CL_DEVICE_TYPE_GPU, cProps, nullptr, nullptr, &err);
					break;
			}

			if (checkErr(err, "Context::Context()"))
			{
				contextReady = true;
				ListOpenClDevices();
				isNVidia = platformsInformation[platformIndex].name.contains("nvidia", Qt::CaseInsensitive);
				isAMD = platformsInformation[platformIndex].name.contains("amd", Qt::CaseInsensitive);
			}
			else
			{
				contextReady = false;
				cErrorMessage::showMessage(
					QObject::tr("OpenCL %1 cannot be created!").arg(QObject::tr("context")),
					cErrorMessage::errorMessage);
			}
		}
		else
		{
			qCritical() << "OpenCl is not available";
			contextReady = false;
		}
	}
	else
	{
		qCritical() << "OpenCL platform index is negative number!";
		contextReady = false;
	}
}