Commit: 4ce9785e01587638ae26256fe23315e436c658ff
Author: Brecht Van Lommel
Date:   Fri Feb 15 08:18:38 2019 +0100
Branches: master
https://developer.blender.org/rB4ce9785e01587638ae26256fe23315e436c658ff

Cycles: Support multithreaded compilation of kernels

This patch implements a workaround to get the multithreaded compilation from 
D2231 working.
So far, it only works for Blender, not for Cycles Standalone. Also, I have only 
tested the Linux codepath in the helper function.
Depends on D2231.

Reviewers: brecht, dingto, sergey, juicyfruit, lukasstockner97

Reviewed By: brecht

Subscribers: Loner, jbakker, candreacchio, 3dLuver, LazyDodo, bliblubli

Differential Revision: https://developer.blender.org/D2264

===================================================================

M       intern/cycles/blender/CMakeLists.txt
M       intern/cycles/blender/blender_python.cpp
M       intern/cycles/device/device_intern.h
M       intern/cycles/device/opencl/opencl.h
M       intern/cycles/device/opencl/opencl_base.cpp
M       intern/cycles/device/opencl/opencl_mega.cpp
M       intern/cycles/device/opencl/opencl_split.cpp
M       intern/cycles/device/opencl/opencl_util.cpp
M       intern/cycles/kernel/CMakeLists.txt
A       intern/cycles/kernel/kernels/opencl/kernel_split_bundle.cl
M       intern/cycles/util/util_system.cpp
M       intern/cycles/util/util_system.h

===================================================================

diff --git a/intern/cycles/blender/CMakeLists.txt 
b/intern/cycles/blender/CMakeLists.txt
index 84e2690333e..f8720de366f 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -51,6 +51,10 @@ set(ADDON_FILES
 
 add_definitions(${GL_DEFINITIONS})
 
+if(WITH_CYCLES_DEVICE_OPENCL)
+    add_definitions(-DWITH_OPENCL)
+endif()
+
 if(WITH_CYCLES_NETWORK)
        add_definitions(-DWITH_NETWORK)
 endif()
diff --git a/intern/cycles/blender/blender_python.cpp 
b/intern/cycles/blender/blender_python.cpp
index de702337f98..a720a60c05b 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -40,6 +40,10 @@
 #include <OSL/oslconfig.h>
 #endif
 
+#ifdef WITH_OPENCL
+#include "device/device_intern.h"
+#endif
+
 CCL_NAMESPACE_BEGIN
 
 namespace {
@@ -628,6 +632,31 @@ static PyObject *opencl_disable_func(PyObject * /*self*/, 
PyObject * /*value*/)
        DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
        Py_RETURN_NONE;
 }
+
+static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
+{
+       PyObject *sequence = PySequence_Fast(args, "Arguments must be a 
sequence");
+       if(sequence == NULL) {
+               Py_RETURN_FALSE;
+       }
+
+       vector<string> parameters;
+       for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+               PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+               PyObject *item_as_string = PyObject_Str(item);
+               const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
+               parameters.push_back(parameter_string);
+               Py_DECREF(item_as_string);
+       }
+       Py_DECREF(sequence);
+
+       if (device_opencl_compile_kernel(parameters)) {
+               Py_RETURN_TRUE;
+       }
+       else {
+               Py_RETURN_FALSE;
+       }
+}
 #endif
 
 static bool denoise_parse_filepaths(PyObject *pyfilepaths, vector<string>& 
filepaths)
@@ -903,6 +932,7 @@ static PyMethodDef methods[] = {
        {"system_info", system_info_func, METH_NOARGS, ""},
 #ifdef WITH_OPENCL
        {"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
+       {"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
 #endif
 
        /* Standalone denoising */
diff --git a/intern/cycles/device/device_intern.h 
b/intern/cycles/device/device_intern.h
index 0b26057c3ba..94df1e009eb 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -24,6 +24,7 @@ class Device;
 Device *device_cpu_create(DeviceInfo& info, Stats &stats, Profiler &profiler, 
bool background);
 bool device_opencl_init();
 Device *device_opencl_create(DeviceInfo& info, Stats &stats, Profiler 
&profiler, bool background);
+bool device_opencl_compile_kernel(const vector<string>& parameters);
 bool device_cuda_init();
 Device *device_cuda_create(DeviceInfo& info, Stats &stats, Profiler &profiler, 
bool background);
 Device *device_network_create(DeviceInfo& info, Stats &stats, Profiler 
&profiler, const char *address);
diff --git a/intern/cycles/device/opencl/opencl.h 
b/intern/cycles/device/opencl/opencl.h
index 9b763167459..a2c0e53b3e7 100644
--- a/intern/cycles/device/opencl/opencl.h
+++ b/intern/cycles/device/opencl/opencl.h
@@ -268,6 +268,7 @@ public:
        cl_platform_id cpPlatform;
        cl_device_id cdDevice;
        cl_int ciErr;
+       int device_num;
 
        class OpenCLProgram {
        public:
@@ -293,7 +294,15 @@ public:
 
        private:
                bool build_kernel(const string *debug_src);
+               /* Build the program by calling the own process.
+                * This is required for multithreaded OpenCL compilation, since 
most Frameworks serialize
+                * build calls internally if they come from the same process.
+                * If that is not supported, this function just returns false.
+                */
+               bool compile_separate(const string& clbin);
+               /* Build the program by calling OpenCL directly. */
                bool compile_kernel(const string *debug_src);
+               /* Loading and saving the program from/to disk. */
                bool load_binary(const string& clbin, const string *debug_src = 
NULL);
                bool save_binary(const string& clbin);
 
@@ -342,12 +351,17 @@ public:
        bool opencl_version_check();
 
        string device_md5_hash(string kernel_custom_build_options = "");
-       bool load_kernels(const DeviceRequestedFeatures& requested_features);
+       virtual bool load_kernels(const DeviceRequestedFeatures& 
requested_features);
 
        /* Has to be implemented by the real device classes.
         * The base device will then load all these programs. */
-       virtual bool load_kernels(const DeviceRequestedFeatures& 
requested_features,
-                                 vector<OpenCLProgram*> &programs) = 0;
+       virtual bool add_kernel_programs(const DeviceRequestedFeatures& 
requested_features,
+                                        vector<OpenCLProgram*> &programs) = 0;
+
+       /* Get the name of the opencl program for the given kernel */
+       virtual const string get_opencl_program_name(bool single_program, const 
string& kernel_name) = 0;
+       /* Get the program file name to compile (*.cl) for the given kernel */
+       virtual const string get_opencl_program_filename(bool single_program, 
const string& kernel_name) = 0;
 
        void mem_alloc(device_memory& mem);
        void mem_copy_to(device_memory& mem);
diff --git a/intern/cycles/device/opencl/opencl_base.cpp 
b/intern/cycles/device/opencl/opencl_base.cpp
index 4417065bb7f..d8f9a242ac8 100644
--- a/intern/cycles/device/opencl/opencl_base.cpp
+++ b/intern/cycles/device/opencl/opencl_base.cpp
@@ -93,6 +93,7 @@ OpenCLDeviceBase::OpenCLDeviceBase(DeviceInfo& info, Stats 
&stats, Profiler &pro
        }
        assert(info.num < usable_devices.size());
        OpenCLPlatformDevice& platform_device = usable_devices[info.num];
+       device_num = info.num;
        cpPlatform = platform_device.platform_id;
        cdDevice = platform_device.device_id;
        platform_name = platform_device.platform_name;
@@ -143,7 +144,6 @@ OpenCLDeviceBase::OpenCLDeviceBase(DeviceInfo& info, Stats 
&stats, Profiler &pro
        texture_info.resize(1);
        memory_manager.alloc("texture_info", texture_info);
 
-       fprintf(stderr, "Device init success\n");
        device_initialized = true;
 }
 
@@ -251,15 +251,13 @@ bool OpenCLDeviceBase::load_kernels(const 
DeviceRequestedFeatures& requested_fea
        programs.push_back(&base_program);
        programs.push_back(&denoising_program);
        /* Call actual class to fill the vector with its programs. */
-       if(!load_kernels(requested_features, programs)) {
+       if(!add_kernel_programs(requested_features, programs)) {
                return false;
        }
 
-       /* Parallel compilation is supported by Cycles, but currently all 
OpenCL frameworks
-        * serialize the calls internally, so it's not much use right now.
-        * Note: When enabling parallel compilation, use_stdout in the 
OpenCLProgram constructor
-        * should be set to false as well. */
-#if 0
+       /* Parallel compilation of Cycles kernels, this launches multiple
+        * processes to workaround OpenCL frameworks serializing the calls
+        * internally within a single process. */
        TaskPool task_pool;
        foreach(OpenCLProgram *program, programs) {
                task_pool.push(function_bind(&OpenCLProgram::load, program));
@@ -273,14 +271,6 @@ bool OpenCLDeviceBase::load_kernels(const 
DeviceRequestedFeatures& requested_fea
                        return false;
                }
        }
-#else
-       foreach(OpenCLProgram *program, programs) {
-               program->load();
-               if(!program->is_loaded()) {
-                       return false;
-               }
-       }
-#endif
 
        return true;
 }
diff --git a/intern/cycles/device/opencl/opencl_mega.cpp 
b/intern/cycles/device/opencl/opencl_mega.cpp
index 0a7bf96fed7..c0b9e81d4d3 100644
--- a/intern/cycles/device/opencl/opencl_mega.cpp
+++ b/intern/cycles/device/opencl/opencl_mega.cpp
@@ -35,19 +35,35 @@ public:
 
        OpenCLDeviceMegaKernel(DeviceInfo& info, Stats &stats, Profiler 
&profiler, bool background_)
        : OpenCLDeviceBase(info, stats, profiler, background_),
-         path_trace_program(this, "megakernel", "kernel.cl", 
"-D__COMPILE_ONLY_MEGAKERNEL__ ")
+         path_trace_program(this,
+                            get_opencl_program_name(false, "megakernel"),
+                            get_opencl_program_filename(false, "megakernel"),
+                            "-D__COMPILE_ONLY_MEGAKERNEL__ ")
        {
        }
 
-       virtual bool show_samples() const {
+
+       virtual bool show_samples() const
+       {
                return true;
        }
 
-       virtual BVHLayoutMask get_bvh_layout_mask() const {
+       virtual BVHLayoutMask get_bvh_layout_mask() const
+       {
                return BVH_LAYOUT_BVH2;
        }
 
-       virtual bool load_kernels(const DeviceRequestedFeatures& 
/*requested_features*/,
+       const string get_opencl_program_name(bool /*single_program*/, const 
string& kernel_name)
+       {
+               return kernel_name;
+       }
+
+       const string get_opencl_program_filename(bool /*single_program*/, const 
string& /*kernel_name*/)
+       {
+               return "kernel.cl";
+       }
+
+       virtual bool add_kernel_programs(const DeviceRequestedFeatures& 
/*requested_features*/,
                                  vector<OpenCLProgram*> &programs)
        {
                path_trace_program.add_kernel(ustring("path_trace"));
diff --git a/intern/cycles/device/opencl/opencl_split.cpp 
b/intern/cycles/device/opencl/opencl_split.cpp
index 5a2555f9f80..b759f69d3ab 100644
--- a/intern/cycles/device/opencl/opencl_split.cpp
+++ b/intern/cycles/device/opencl/opencl_split.cpp
@@ -79,6 +79,27 @@ public:
        OpenCLProgram program_data_init;
        OpenCLProgram program_state_buffer_size;
 
+       OpenCLProgram program_split;
+
+       OpenCLProgram program_path_init;
+       OpenCLProgram program_scene_intersect;
+       OpenCLProgram program_lamp_emission;
+       OpenCLProgram program_do_volume;
+       OpenCLProgram program_queue_enqueue;
+       OpenCLProgram program_indirect_background;
+       OpenCLProgram program_shader_setup;
+       OpenCLProgram program_shader_sort;
+       OpenCLProgram program_shader_eval;
+       OpenCLProgram program_holdout_emission_blurring_pathtermination_ao;
+       OpenCLProgram program_subsurface_scatter;
+       OpenCLProgram program_direct_lighting;
+       OpenCLProgram program_shadow_blocked_ao;
+       OpenCLProgram program_shadow_blocked_dl;
+       OpenCLProgram program_enqueue_inactive;
+       OpenCLProgram program_next_iteration_setup;
+       OpenCLProgram program_indirect_subsurface;
+       OpenCLProgram program_buffer_update;
+
        OpenCLDeviceSplitKernel(DeviceInfo& info, Stats &stats, Profiler 
&profiler, bool background_);
 
        ~OpenCLDeviceSplitKernel()
@@ -99,26 +120,150 @@ public:
                return BVH_LAYOUT_BVH2;
        }
 
-       virtual bool load_kernels(const DeviceRequestedFeatures& 
requested_features,
+       virtual bool load_kernels(const DeviceRequestedFeatures& 
requested_featur

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to