[Bf-blender-cvs] [bf8a98ffc5a] functions: experimental lazy fgraph evaluation

Jacques Lucke noreply at git.blender.org
Mon Mar 25 09:57:58 CET 2019


Commit: bf8a98ffc5a0a0d7a7059d14af1fc257fa53cc2b
Author: Jacques Lucke
Date:   Mon Mar 25 09:57:44 2019 +0100
Branches: functions
https://developer.blender.org/rBbf8a98ffc5a0a0d7a7059d14af1fc257fa53cc2b

experimental lazy fgraph evaluation

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

M	source/blender/blenlib/BLI_small_vector.hpp
M	source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
M	source/blender/functions/backends/tuple_call/tuple.hpp
M	source/blender/functions/backends/tuple_call/tuple_call.hpp

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

diff --git a/source/blender/blenlib/BLI_small_vector.hpp b/source/blender/blenlib/BLI_small_vector.hpp
index 182164b428b..8e86cb53861 100644
--- a/source/blender/blenlib/BLI_small_vector.hpp
+++ b/source/blender/blenlib/BLI_small_vector.hpp
@@ -85,6 +85,12 @@ namespace BLI {
 			this->grow(size);
 		}
 
+		void clear()
+		{
+			this->destruct_elements_but_keep_memory();
+			this->m_size = 0;
+		}
+
 		void append(const T &value)
 		{
 			this->ensure_space_for_one();
diff --git a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
index 476ae8f2230..b4174be2637 100644
--- a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
+++ b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
@@ -400,12 +400,167 @@ namespace FN {
 		}
 	};
 
+	class LazyExecFGraph : public TupleCallBody {
+	private:
+		FunctionGraph m_fgraph;
+
+	public:
+		LazyExecFGraph(FunctionGraph &fgraph)
+			: m_fgraph(fgraph)
+		{
+			auto *context = new llvm::LLVMContext();
+
+			for (Node *node : fgraph.graph()->all_nodes()) {
+				if (node->function()->has_body<TupleCallBody>()) {
+					continue;
+				}
+				if (node->function()->has_body<LazyInTupleCallBody>()) {
+					continue;
+				}
+				if (node->function()->has_body<LLVMBuildIRBody>()) {
+					derive_TupleCallBody_from_LLVMBuildIRBody(node->function(), *context);
+				}
+			}
+		}
+
+		void call(Tuple &fn_in, Tuple &fn_out) const override
+		{
+			SocketSet required_sockets = m_fgraph.find_required_sockets();
+			for (Socket socket : m_fgraph.inputs()) {
+				required_sockets.add(socket);
+			}
+
+			SmallVector<SharedType> temp_storage_types;
+			SmallMap<Socket, uint> socket_indices;
+
+			uint index = 0;
+			for (Socket socket : required_sockets) {
+				temp_storage_types.append(socket.type());
+				socket_indices.add(socket, index);
+				index++;
+			}
+
+			auto temp_meta = SharedTupleMeta::New(temp_storage_types);
+			Tuple temp_storage(temp_meta);
+
+			for (uint i = 0; i < m_fgraph.inputs().size(); i++) {
+				Socket socket = m_fgraph.inputs()[i];
+				Tuple::relocate_element(
+					fn_in, i,
+					temp_storage, socket_indices.lookup(socket));
+			}
+
+			for (uint i = 0; i < m_fgraph.outputs().size(); i++) {
+				Socket socket = m_fgraph.outputs()[i];
+				this->compute_socket(socket, temp_storage, socket_indices);
+			}
+
+			for (uint i = 0; i < m_fgraph.outputs().size(); i++) {
+				Socket socket = m_fgraph.outputs()[i];
+				Tuple::relocate_element(
+					temp_storage, socket_indices.lookup(socket),
+					fn_out, i);
+			}
+		}
+
+		void compute_socket(
+			Socket socket,
+			Tuple &temp_storage,
+			const SmallMap<Socket, uint> &socket_indices) const
+		{
+			uint socket_index = socket_indices.lookup(socket);
+			if (temp_storage.is_initialized(socket_index)) {
+				/* do nothing */
+			}
+			else if (socket.is_input()) {
+				Socket origin_socket = socket.origin();
+				this->compute_socket(origin_socket, temp_storage, socket_indices);
+				Tuple::copy_element(
+					temp_storage, socket_indices.lookup(origin_socket),
+					temp_storage, socket_indices.lookup(socket));
+			}
+			else if (socket.is_output()) {
+				Node *node = socket.node();
+				SharedFunction &fn = node->function();
+
+				if (fn->has_body<LazyInTupleCallBody>()) {
+					auto *body = node->function()->body<LazyInTupleCallBody>();
+
+					FN_TUPLE_STACK_ALLOC(fn_in, body->meta_in());
+					FN_TUPLE_STACK_ALLOC(fn_out, body->meta_out());
+
+					for (uint input_index : body->always_required()) {
+						Socket input_socket = node->input(input_index);
+						this->compute_socket(
+							input_socket, temp_storage, socket_indices);
+						Tuple::copy_element(
+							temp_storage, socket_indices.lookup(input_socket),
+							fn_in, input_index);
+					}
+
+					void *user_data = alloca(body->user_data_size());
+					LazyState lazy_state(user_data);
+
+					while (!lazy_state.is_done()) {
+						lazy_state.start_next_entry();
+						body->call(fn_in, fn_out, lazy_state);
+						for (uint input_index : lazy_state.requested_inputs()) {
+							Socket input_socket = node->input(input_index);
+							this->compute_socket(
+								input_socket, temp_storage, socket_indices);
+							Tuple::copy_element(
+								temp_storage, socket_indices.lookup(input_socket),
+								fn_in, input_index);
+						}
+					}
+					BLI_assert(fn_out.all_initialized());
+
+					for (uint output_index = 0; output_index < node->output_amount(); output_index++) {
+						Socket output_socket = node->output(output_index);
+						Tuple::relocate_element(
+							fn_out, output_index,
+							temp_storage, socket_indices.lookup(output_socket));
+					}
+				}
+				else if (fn->has_body<TupleCallBody>()) {
+					auto *body = node->function()->body<TupleCallBody>();
+
+					FN_TUPLE_STACK_ALLOC(fn_in, body->meta_in());
+					FN_TUPLE_STACK_ALLOC(fn_out, body->meta_out());
+
+					for (uint input_index = 0; input_index < node->input_amount(); input_index++) {
+						Socket input_socket = node->input(input_index);
+						this->compute_socket(
+							input_socket, temp_storage, socket_indices);
+						Tuple::copy_element(
+							temp_storage, socket_indices.lookup(input_socket),
+							fn_in, input_index);
+					}
+
+					body->call(fn_in, fn_out);
+					BLI_assert(fn_out.all_initialized());
+
+					for (uint output_index = 0; output_index < node->output_amount(); output_index++) {
+						Socket output_socket = node->output(output_index);
+						Tuple::relocate_element(
+							fn_out, output_index,
+							temp_storage, socket_indices.lookup(output_socket));
+					}
+				}
+				else {
+					BLI_assert(false);
+				}
+			}
+		}
+	};
+
 	void fgraph_add_TupleCallBody(
 		SharedFunction &fn,
 		FunctionGraph &fgraph)
 	{
 		// fn->add_body(new ExecuteGraph(fgraph));
-		fn->add_body(new InterpretFGraph(fgraph));
+		// fn->add_body(new InterpretFGraph(fgraph));
+		fn->add_body(new LazyExecFGraph(fgraph));
 	}
 
 } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/tuple_call/tuple.hpp b/source/blender/functions/backends/tuple_call/tuple.hpp
index 356d405de45..506d517a17a 100644
--- a/source/blender/functions/backends/tuple_call/tuple.hpp
+++ b/source/blender/functions/backends/tuple_call/tuple.hpp
@@ -236,6 +236,12 @@ namespace FN {
 			return this->element_ref<T>(index);
 		}
 
+		inline bool is_initialized(uint index) const
+		{
+			BLI_assert(index < m_meta->element_amount());
+			return m_initialized[index];
+		}
+
 		static inline void copy_element(
 			const Tuple &from, uint from_index,
 			Tuple &to, uint to_index)
@@ -256,6 +262,28 @@ namespace FN {
 			}
 		}
 
+		static inline void relocate_element(
+			Tuple &from, uint from_index,
+			Tuple &to, uint to_index)
+		{
+			BLI_assert(from.m_initialized[from_index]);
+			BLI_assert(from.m_meta->types()[from_index] == to.m_meta->types()[to_index]);
+
+			void *src = from.element_ptr(from_index);
+			void *dst = to.element_ptr(to_index);
+			CPPTypeInfo *type_info = from.m_meta->type_infos()[from_index];
+
+			if (to.m_initialized[to_index]) {
+				type_info->relocate_to_initialized(src, dst);
+			}
+			else {
+				type_info->relocate_to_uninitialized(src, dst);
+				to.m_initialized[to_index] = true;
+			}
+
+			from.m_initialized[from_index] = false;
+		}
+
 		inline void init_default(uint index) const
 		{
 			CPPTypeInfo *type_info = m_meta->type_infos()[index];
diff --git a/source/blender/functions/backends/tuple_call/tuple_call.hpp b/source/blender/functions/backends/tuple_call/tuple_call.hpp
index adab1a12efd..295d9406723 100644
--- a/source/blender/functions/backends/tuple_call/tuple_call.hpp
+++ b/source/blender/functions/backends/tuple_call/tuple_call.hpp
@@ -49,6 +49,7 @@ namespace FN {
 		void start_next_entry()
 		{
 			m_entry_count++;
+			m_requested_inputs.clear();
 		}
 
 		void request_input(uint index)
@@ -61,6 +62,11 @@ namespace FN {
 			m_is_done = true;
 		}
 
+		const SmallVector<uint> &requested_inputs() const
+		{
+			return m_requested_inputs;
+		}
+
 		bool is_first_entry() const
 		{
 			return m_entry_count == 1;



More information about the Bf-blender-cvs mailing list