OCLRenderEngine::OCLRenderEngine(RenderConfig *rcfg, Film *flm,
	boost::mutex *flmMutex, bool fatal) : RenderEngine(rcfg, flm, flmMutex) {
#if !defined(LUXRAYS_DISABLE_OPENCL)
	const Properties &cfg = renderConfig->cfg;

	const bool useCPUs = (cfg.GetInt("opencl.cpu.use", 1) != 0);
	const bool useGPUs = (cfg.GetInt("opencl.gpu.use", 1) != 0);
	const u_int forceGPUWorkSize = cfg.GetInt("opencl.gpu.workgroup.size", 64);
	const u_int forceCPUWorkSize = cfg.GetInt("opencl.cpu.workgroup.size", 1);
	const string oclDeviceConfig = cfg.GetString("opencl.devices.select", "");

	// Start OpenCL devices
	std::vector<DeviceDescription *> descs = ctx->GetAvailableDeviceDescriptions();
	DeviceDescription::Filter(DEVICE_TYPE_OPENCL_ALL, descs);

	// Device info
	bool haveSelectionString = (oclDeviceConfig.length() > 0);
	if (haveSelectionString && (oclDeviceConfig.length() != descs.size())) {
		stringstream ss;
		ss << "OpenCL device selection string has the wrong length, must be " <<
				descs.size() << " instead of " << oclDeviceConfig.length();
		throw runtime_error(ss.str().c_str());
	}

	for (size_t i = 0; i < descs.size(); ++i) {
		OpenCLDeviceDescription *desc = static_cast<OpenCLDeviceDescription *>(descs[i]);

		if (haveSelectionString) {
			if (oclDeviceConfig.at(i) == '1') {
				if (desc->GetType() == DEVICE_TYPE_OPENCL_GPU)
					desc->SetForceWorkGroupSize(forceGPUWorkSize);
				else if (desc->GetType() == DEVICE_TYPE_OPENCL_CPU)
					desc->SetForceWorkGroupSize(forceCPUWorkSize);
				selectedDeviceDescs.push_back(desc);
			}
		} else {
			if ((useCPUs && desc->GetType() == DEVICE_TYPE_OPENCL_CPU) ||
					(useGPUs && desc->GetType() == DEVICE_TYPE_OPENCL_GPU)) {
				if (desc->GetType() == DEVICE_TYPE_OPENCL_GPU)
					desc->SetForceWorkGroupSize(forceGPUWorkSize);
				else if (desc->GetType() == DEVICE_TYPE_OPENCL_CPU)
					desc->SetForceWorkGroupSize(forceCPUWorkSize);
				selectedDeviceDescs.push_back(descs[i]);
			}
		}
	}
#endif
	if (fatal && selectedDeviceDescs.size() == 0)
		throw runtime_error("No OpenCL device selected or available");
}
Example #2
0
void RenderingConfig::SetUpOpenCLDevices(const bool useCPUs, const bool useGPUs,
	const unsigned int forceGPUWorkSize, const unsigned int oclDeviceThreads, const string &oclDeviceConfig) {

	std::vector<DeviceDescription *> descs = ctx->GetAvailableDeviceDescriptions();
	DeviceDescription::Filter(DEVICE_TYPE_OPENCL, descs);

	// Device info
	bool haveSelectionString = (oclDeviceConfig.length() > 0);
	if (haveSelectionString && (oclDeviceConfig.length() != descs.size())) {
		stringstream ss;
		ss << "OpenCL device selection string has the wrong length, must be " <<
				descs.size() << " instead of " << oclDeviceConfig.length();
		throw runtime_error(ss.str().c_str());
	}

	std::vector<DeviceDescription *> selectedDescs;
#if !defined(LUXRAYS_DISABLE_OPENCL)
	for (size_t i = 0; i < descs.size(); ++i) {
		OpenCLDeviceDescription *desc = (OpenCLDeviceDescription *)descs[i];

		if (haveSelectionString) {
			if (oclDeviceConfig.at(i) == '1') {
				if (desc->GetOpenCLType() == OCL_DEVICE_TYPE_GPU)
					desc->SetForceWorkGroupSize(forceGPUWorkSize);
				selectedDescs.push_back(desc);
			}
		} else {
			if ((useCPUs && desc->GetOpenCLType() == OCL_DEVICE_TYPE_CPU) ||
					(useGPUs && desc->GetOpenCLType() == OCL_DEVICE_TYPE_GPU)) {
				if (desc->GetOpenCLType() == OCL_DEVICE_TYPE_GPU)
					desc->SetForceWorkGroupSize(forceGPUWorkSize);
				selectedDescs.push_back(descs[i]);
			}
		}
	}
#endif

	if (selectedDescs.size() == 0)
		cerr << "No OpenCL device selected" << endl;
	else {
#if !defined(LUXRAYS_DISABLE_OPENCL)
		if (cfg.GetInt("opencl.latency.mode", 1) && (cfg.GetInt("renderengine.type", 0) == 3) &&
				(cfg.GetInt("pathgpu.openglinterop.enable", 0) != 0)) {
			// Ask for OpenGL interoperability on the first device
			((OpenCLDeviceDescription *)selectedDescs[0])->EnableOGLInterop();
		}
#endif

		// Allocate devices
		const size_t gpuRenderThreadCount = (oclDeviceThreads < 1) ?
				(2 * selectedDescs.size()) : oclDeviceThreads;
		if ((gpuRenderThreadCount == 1) && (selectedDescs.size() == 1)) {
			// Optimize the special case of one render thread and one GPU
			intersectionGPUDevices =  ctx->AddIntersectionDevices(selectedDescs);
		} else if ((gpuRenderThreadCount > 1) && (selectedDescs.size() == 1)) {
			// Optimize the special case of many render thread and one GPU
			intersectionGPUDevices =  ctx->AddVirtualM2OIntersectionDevices(gpuRenderThreadCount, selectedDescs);
		} else {
			// Create and start the virtual devices (only if there is more than one GPUs)
			intersectionGPUDevices =  ctx->AddVirtualM2MIntersectionDevices(gpuRenderThreadCount, selectedDescs);
		}

		cerr << "OpenCL Devices used: ";
		for (size_t i = 0; i < intersectionGPUDevices.size(); ++i)
			cerr << "[" << intersectionGPUDevices[i]->GetName() << "]";
		cerr << endl;
	}
}