Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/device/opencl/opencl_util.cpp')
-rw-r--r--intern/cycles/device/opencl/opencl_util.cpp404
1 files changed, 328 insertions, 76 deletions
diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp
index 82e1640e508..8128fcee09b 100644
--- a/intern/cycles/device/opencl/opencl_util.cpp
+++ b/intern/cycles/device/opencl/opencl_util.cpp
@@ -16,11 +16,12 @@
#ifdef WITH_OPENCL
-#include "opencl.h"
+#include "device/opencl/opencl.h"
-#include "util_logging.h"
-#include "util_path.h"
-#include "util_time.h"
+#include "util/util_logging.h"
+#include "util/util_md5.h"
+#include "util/util_path.h"
+#include "util/util_time.h"
using std::cerr;
using std::endl;
@@ -234,7 +235,7 @@ string OpenCLCache::get_kernel_md5()
thread_scoped_lock lock(self.kernel_md5_lock);
if(self.kernel_md5.empty()) {
- self.kernel_md5 = path_files_md5_hash(path_get("kernel"));
+ self.kernel_md5 = path_files_md5_hash(path_get("source"));
}
return self.kernel_md5;
}
@@ -309,6 +310,8 @@ bool OpenCLDeviceBase::OpenCLProgram::build_kernel(const string *debug_src)
string build_options;
build_options = device->kernel_build_options(debug_src) + kernel_build_options;
+ VLOG(1) << "Build options passed to clBuildProgram: '"
+ << build_options << "'.";
cl_int ciErr = clBuildProgram(program, 0, NULL, build_options.c_str(), NULL, NULL);
/* show warnings even if build is successful */
@@ -336,12 +339,13 @@ bool OpenCLDeviceBase::OpenCLProgram::build_kernel(const string *debug_src)
bool OpenCLDeviceBase::OpenCLProgram::compile_kernel(const string *debug_src)
{
- string source = "#include \"kernels/opencl/" + kernel_file + "\" // " + OpenCLCache::get_kernel_md5() + "\n";
+ string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
/* We compile kernels consisting of many files. unfortunately OpenCL
* kernel caches do not seem to recognize changes in included files.
* so we force recompile on changes by adding the md5 hash of all files.
*/
- source = path_source_replace_includes(source, path_get("kernel"));
+ source = path_source_replace_includes(source, path_get("source"));
+ source += "\n// " + util_md5_string(source) + "\n";
if(debug_src) {
path_write_text(*debug_src, source);
@@ -352,10 +356,10 @@ bool OpenCLDeviceBase::OpenCLProgram::compile_kernel(const string *debug_src)
cl_int ciErr;
program = clCreateProgramWithSource(device->cxContext,
- 1,
- &source_str,
- &source_len,
- &ciErr);
+ 1,
+ &source_str,
+ &source_len,
+ &ciErr);
if(ciErr != CL_SUCCESS) {
add_error(string("OpenCL program creation failed: ") + clewErrorString(ciErr));
@@ -438,7 +442,11 @@ void OpenCLDeviceBase::OpenCLProgram::load()
if(!program) {
add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
- string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + OpenCLCache::get_kernel_md5();
+ /* need to create source to get md5 */
+ string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
+ source = path_source_replace_includes(source, path_get("source"));
+
+ string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
basename = path_cache_get(path_join("kernels", basename));
string clbin = basename + ".clbin";
@@ -544,6 +552,11 @@ bool OpenCLInfo::use_debug()
return DebugFlags().opencl.debug;
}
+bool OpenCLInfo::use_single_program()
+{
+ return DebugFlags().opencl.single_program;
+}
+
bool OpenCLInfo::kernel_use_advanced_shading(const string& platform)
{
/* keep this in sync with kernel_types.h! */
@@ -587,11 +600,20 @@ bool OpenCLInfo::device_supported(const string& platform_name,
const cl_device_id device_id)
{
cl_device_type device_type;
- clGetDeviceInfo(device_id,
- CL_DEVICE_TYPE,
- sizeof(cl_device_type),
- &device_type,
- NULL);
+ if(!get_device_type(device_id, &device_type)) {
+ return false;
+ }
+ string device_name;
+ if(!get_device_name(device_id, &device_name)) {
+ return false;
+ }
+ /* It is possible tyo have Iris GPU on AMD/Apple OpenCL framework
+ * (aka, it will not be on Intel framework). This isn't supported
+ * and needs an explicit blacklist.
+ */
+ if(strstr(device_name.c_str(), "Iris")) {
+ return false;
+ }
if(platform_name == "AMD Accelerated Parallel Processing" &&
device_type == CL_DEVICE_TYPE_GPU)
{
@@ -705,39 +727,30 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
return;
}
+ cl_int error;
vector<cl_device_id> device_ids;
- cl_uint num_devices = 0;
vector<cl_platform_id> platform_ids;
- cl_uint num_platforms = 0;
- /* Get devices. */
- if(clGetPlatformIDs(0, NULL, &num_platforms) != CL_SUCCESS ||
- num_platforms == 0)
- {
- FIRST_VLOG(2) << "No OpenCL platforms were found.";
+ /* Get platforms. */
+ if(!get_platforms(&platform_ids, &error)) {
+ FIRST_VLOG(2) << "Error fetching platforms:"
+ << string(clewErrorString(error));
first_time = false;
return;
}
- platform_ids.resize(num_platforms);
- if(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL) != CL_SUCCESS) {
- FIRST_VLOG(2) << "Failed to fetch platform IDs from the driver..";
+ if(platform_ids.size() == 0) {
+ FIRST_VLOG(2) << "No OpenCL platforms were found.";
first_time = false;
return;
}
/* Devices are numbered consecutively across platforms. */
- for(int platform = 0; platform < num_platforms; platform++) {
+ for(int platform = 0; platform < platform_ids.size(); platform++) {
cl_platform_id platform_id = platform_ids[platform];
- char pname[256];
- if(clGetPlatformInfo(platform_id,
- CL_PLATFORM_NAME,
- sizeof(pname),
- &pname,
- NULL) != CL_SUCCESS)
- {
+ string platform_name;
+ if(!get_platform_name(platform_id, &platform_name)) {
FIRST_VLOG(2) << "Failed to get platform name, ignoring.";
continue;
}
- string platform_name = pname;
FIRST_VLOG(2) << "Enumerating devices for platform "
<< platform_name << ".";
if(!platform_version_check(platform_id)) {
@@ -745,39 +758,28 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
<< " due to too old compiler version.";
continue;
}
- num_devices = 0;
- cl_int ciErr;
- if((ciErr = clGetDeviceIDs(platform_id,
- device_type,
- 0,
- NULL,
- &num_devices)) != CL_SUCCESS || num_devices == 0)
+ if(!get_platform_devices(platform_id,
+ device_type,
+ &device_ids,
+ &error))
{
FIRST_VLOG(2) << "Ignoring platform " << platform_name
- << ", failed to fetch number of devices: " << string(clewErrorString(ciErr));
+ << ", failed to fetch of devices: "
+ << string(clewErrorString(error));
continue;
}
- device_ids.resize(num_devices);
- if(clGetDeviceIDs(platform_id,
- device_type,
- num_devices,
- &device_ids[0],
- NULL) != CL_SUCCESS)
- {
+ if(device_ids.size() == 0) {
FIRST_VLOG(2) << "Ignoring platform " << platform_name
- << ", failed to fetch devices list.";
+ << ", it has no devices.";
continue;
}
- for(int num = 0; num < num_devices; num++) {
- cl_device_id device_id = device_ids[num];
- char device_name[1024] = "\0";
- if(clGetDeviceInfo(device_id,
- CL_DEVICE_NAME,
- sizeof(device_name),
- &device_name,
- NULL) != CL_SUCCESS)
- {
- FIRST_VLOG(2) << "Failed to fetch device name, ignoring.";
+ for(int num = 0; num < device_ids.size(); num++) {
+ const cl_device_id device_id = device_ids[num];
+ string device_name;
+ if(!get_device_name(device_id, &device_name, &error)) {
+ FIRST_VLOG(2) << "Failed to fetch device name: "
+ << string(clewErrorString(error))
+ << ", ignoring.";
continue;
}
if(!device_version_check(device_id)) {
@@ -789,24 +791,28 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
device_supported(platform_name, device_id))
{
cl_device_type device_type;
- if(clGetDeviceInfo(device_id,
- CL_DEVICE_TYPE,
- sizeof(cl_device_type),
- &device_type,
- NULL) != CL_SUCCESS)
- {
+ if(!get_device_type(device_id, &device_type, &error)) {
FIRST_VLOG(2) << "Ignoring device " << device_name
- << ", failed to fetch device type.";
+ << ", failed to fetch device type:"
+ << string(clewErrorString(error));
continue;
}
- FIRST_VLOG(2) << "Adding new device " << device_name << ".";
+ string readable_device_name =
+ get_readable_device_name(device_id);
+ if(readable_device_name != device_name) {
+ FIRST_VLOG(2) << "Using more readable device name: "
+ << readable_device_name;
+ }
+ FIRST_VLOG(2) << "Adding new device "
+ << readable_device_name << ".";
string hardware_id = get_hardware_id(platform_name, device_id);
- usable_devices->push_back(OpenCLPlatformDevice(platform_id,
- platform_name,
- device_id,
- device_type,
- device_name,
- hardware_id));
+ usable_devices->push_back(OpenCLPlatformDevice(
+ platform_id,
+ platform_name,
+ device_id,
+ device_type,
+ readable_device_name,
+ hardware_id));
}
else {
FIRST_VLOG(2) << "Ignoring device " << device_name
@@ -817,6 +823,252 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices
first_time = false;
}
+bool OpenCLInfo::get_platforms(vector<cl_platform_id> *platform_ids,
+ cl_int *error)
+{
+ /* Reset from possible previous state. */
+ platform_ids->resize(0);
+ cl_uint num_platforms;
+ if(!get_num_platforms(&num_platforms, error)) {
+ return false;
+ }
+ /* Get actual platforms. */
+ cl_int err;
+ platform_ids->resize(num_platforms);
+ if((err = clGetPlatformIDs(num_platforms,
+ &platform_ids->at(0),
+ NULL)) != CL_SUCCESS) {
+ if(error != NULL) {
+ *error = err;
+ }
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
+}
+
+vector<cl_platform_id> OpenCLInfo::get_platforms()
+{
+ vector<cl_platform_id> platform_ids;
+ get_platforms(&platform_ids);
+ return platform_ids;
+}
+
+bool OpenCLInfo::get_num_platforms(cl_uint *num_platforms, cl_int *error)
+{
+ cl_int err;
+ if((err = clGetPlatformIDs(0, NULL, num_platforms)) != CL_SUCCESS) {
+ if(error != NULL) {
+ *error = err;
+ }
+ *num_platforms = 0;
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
+}
+
+cl_uint OpenCLInfo::get_num_platforms()
+{
+ cl_uint num_platforms;
+ if(!get_num_platforms(&num_platforms)) {
+ return 0;
+ }
+ return num_platforms;
+}
+
+bool OpenCLInfo::get_platform_name(cl_platform_id platform_id,
+ string *platform_name)
+{
+ char buffer[256];
+ if(clGetPlatformInfo(platform_id,
+ CL_PLATFORM_NAME,
+ sizeof(buffer),
+ &buffer,
+ NULL) != CL_SUCCESS)
+ {
+ *platform_name = "";
+ return false;
+ }
+ *platform_name = buffer;
+ return true;
+}
+
+string OpenCLInfo::get_platform_name(cl_platform_id platform_id)
+{
+ string platform_name;
+ if (!get_platform_name(platform_id, &platform_name)) {
+ return "";
+ }
+ return platform_name;
+}
+
+bool OpenCLInfo::get_num_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type,
+ cl_uint *num_devices,
+ cl_int *error)
+{
+ cl_int err;
+ if((err = clGetDeviceIDs(platform_id,
+ device_type,
+ 0,
+ NULL,
+ num_devices)) != CL_SUCCESS)
+ {
+ if(error != NULL) {
+ *error = err;
+ }
+ *num_devices = 0;
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
+}
+
+cl_uint OpenCLInfo::get_num_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type)
+{
+ cl_uint num_devices;
+ if(!get_num_platform_devices(platform_id,
+ device_type,
+ &num_devices))
+ {
+ return 0;
+ }
+ return num_devices;
+}
+
+bool OpenCLInfo::get_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type,
+ vector<cl_device_id> *device_ids,
+ cl_int* error)
+{
+ /* Reset from possible previous state. */
+ device_ids->resize(0);
+ /* Get number of devices to pre-allocate memory. */
+ cl_uint num_devices;
+ if(!get_num_platform_devices(platform_id,
+ device_type,
+ &num_devices,
+ error))
+ {
+ return false;
+ }
+ /* Get actual device list. */
+ device_ids->resize(num_devices);
+ cl_int err;
+ if((err = clGetDeviceIDs(platform_id,
+ device_type,
+ num_devices,
+ &device_ids->at(0),
+ NULL)) != CL_SUCCESS)
+ {
+ if(error != NULL) {
+ *error = err;
+ }
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
+}
+
+vector<cl_device_id> OpenCLInfo::get_platform_devices(cl_platform_id platform_id,
+ cl_device_type device_type)
+{
+ vector<cl_device_id> devices;
+ get_platform_devices(platform_id, device_type, &devices);
+ return devices;
+}
+
+bool OpenCLInfo::get_device_name(cl_device_id device_id,
+ string *device_name,
+ cl_int* error)
+{
+ char buffer[1024];
+ cl_int err;
+ if((err = clGetDeviceInfo(device_id,
+ CL_DEVICE_NAME,
+ sizeof(buffer),
+ &buffer,
+ NULL)) != CL_SUCCESS)
+ {
+ if(error != NULL) {
+ *error = err;
+ }
+ *device_name = "";
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ *device_name = buffer;
+ return true;
+}
+
+string OpenCLInfo::get_device_name(cl_device_id device_id)
+{
+ string device_name;
+ if(!get_device_name(device_id, &device_name)) {
+ return "";
+ }
+ return device_name;
+}
+
+bool OpenCLInfo::get_device_type(cl_device_id device_id,
+ cl_device_type *device_type,
+ cl_int* error)
+{
+ cl_int err;
+ if((err = clGetDeviceInfo(device_id,
+ CL_DEVICE_TYPE,
+ sizeof(cl_device_type),
+ device_type,
+ NULL)) != CL_SUCCESS)
+ {
+ if(error != NULL) {
+ *error = err;
+ }
+ *device_type = 0;
+ return false;
+ }
+ if(error != NULL) {
+ *error = CL_SUCCESS;
+ }
+ return true;
+}
+
+cl_device_type OpenCLInfo::get_device_type(cl_device_id device_id)
+{
+ cl_device_type device_type;
+ if(!get_device_type(device_id, &device_type)) {
+ return 0;
+ }
+ return device_type;
+}
+
+string OpenCLInfo::get_readable_device_name(cl_device_id device_id)
+{
+ char board_name[1024];
+ if(clGetDeviceInfo(device_id,
+ CL_DEVICE_BOARD_NAME_AMD,
+ sizeof(board_name),
+ &board_name,
+ NULL) == CL_SUCCESS)
+ {
+ return board_name;
+ }
+ /* Fallback to standard device name API. */
+ return get_device_name(device_id);
+}
+
CCL_NAMESPACE_END
#endif