Commit: 049d66aa80e5276e545d013ab366f1f5cdb05516 Author: Jacques Lucke Date: Sun Apr 28 18:25:29 2019 +0200 Branches: functions https://developer.blender.org/rB049d66aa80e5276e545d013ab366f1f5cdb05516
initial support for lazy inputs in new fgraph evaluation =================================================================== M source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp M source/blender/functions/core/data_flow_graph.hpp =================================================================== 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 7e9f6af2630..c5b3b6f57d1 100644 --- a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp +++ b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp @@ -29,24 +29,14 @@ class ExecuteFGraph : public TupleCallBody { DataFlowGraph *m_graph; struct NodeInfo { - union { - TupleCallBody *direct; - LazyInTupleCallBody *lazy; - } body; + TupleCallBodyBase *body; uint input_start; uint output_start; bool is_lazy; - NodeInfo(TupleCallBody *body, uint input_start, uint output_start) - : input_start(input_start), output_start(output_start), is_lazy(false) + NodeInfo(TupleCallBodyBase *body, bool is_lazy, uint input_start, uint output_start) + : body(body), input_start(input_start), output_start(output_start), is_lazy(is_lazy) { - this->body.direct = body; - } - - NodeInfo(LazyInTupleCallBody *body, uint input_start, uint output_start) - : input_start(input_start), output_start(output_start), is_lazy(true) - { - this->body.lazy = body; } }; @@ -76,8 +66,20 @@ class ExecuteFGraph : public TupleCallBody { { for (uint node_id : m_graph->node_ids()) { SharedFunction &fn = m_graph->function_of_node(node_id); - TupleCallBody *body = fn->body<TupleCallBody>(); - m_node_info.append(NodeInfo(body, m_inputs_buffer_size, m_outputs_buffer_size)); + + TupleCallBodyBase *body; + bool is_lazy_body; + if (fn->has_body<LazyInTupleCallBody>()) { + body = fn->body<LazyInTupleCallBody>(); + is_lazy_body = true; + } + else { + body = fn->body<TupleCallBody>(); + is_lazy_body = false; + } + + m_node_info.append( + NodeInfo(body, is_lazy_body, m_inputs_buffer_size, m_outputs_buffer_size)); m_inputs_init_buffer_size += fn->signature().inputs().size(); m_outputs_init_buffer_size += fn->signature().outputs().size(); @@ -231,11 +233,21 @@ class ExecuteFGraph : public TupleCallBody { } } + struct LazyStateOnStack { + uint node_id; + LazyState state; + + LazyStateOnStack(uint node_id, LazyState state) : node_id(node_id), state(state) + { + } + }; + void evaluate_graph_to_compute_outputs(SocketValueStorage &storage, Tuple &fn_out, ExecutionContext &ctx) const { SmallStack<DFGraphSocket, 64> sockets_to_compute; + SmallStack<LazyStateOnStack> lazy_states; for (auto socket : m_fgraph.outputs()) { sockets_to_compute.push(socket); @@ -264,44 +276,134 @@ class ExecuteFGraph : public TupleCallBody { sockets_to_compute.pop(); } else { - bool all_inputs_computed = true; uint node_id = m_graph->node_id_of_output(socket.id()); - for (uint input_id : m_graph->input_ids_of_node(node_id)) { - if (!storage.is_input_initialized(input_id)) { - sockets_to_compute.push(DFGraphSocket::FromInput(input_id)); - all_inputs_computed = false; - } - } - - if (all_inputs_computed) { - BLI_assert(!m_node_info[node_id].is_lazy); - TupleCallBody *body = m_node_info[node_id].body.direct; - BLI_assert(body); + if (m_node_info[node_id].is_lazy) { + LazyInTupleCallBody *body = (LazyInTupleCallBody *)m_node_info[node_id].body; Tuple body_in(body->meta_in(), storage.node_input_values_ptr(node_id), storage.node_input_inits_ptr(node_id), true, - true); + false); Tuple body_out(body->meta_out(), storage.node_output_values_ptr(node_id), storage.node_output_inits_ptr(node_id), true, false); - SourceInfoStackFrame frame(m_graph->source_info_of_node(node_id)); - body->call__setup_stack(body_in, body_out, ctx, frame); - BLI_assert(body_out.all_initialized()); + if (lazy_states.empty() || lazy_states.peek().node_id != node_id) { + + bool required_inputs_computed = true; + + for (uint input_index : body->always_required()) { + uint input_id = m_graph->id_of_node_input(node_id, input_index); + if (!storage.is_input_initialized(input_id)) { + sockets_to_compute.push(DFGraphSocket::FromInput(input_id)); + required_inputs_computed = false; + } + } + + if (required_inputs_computed) { + void *user_data = alloca(body->user_data_size()); + LazyState state(user_data); + state.start_next_entry(); + + SourceInfoStackFrame frame(m_graph->source_info_of_node(node_id)); + ctx.stack().push(&frame); + body->call(body_in, body_out, ctx, state); + ctx.stack().pop(); + + if (state.is_done()) { + for (uint output_id : m_graph->output_ids_of_node(node_id)) { + if (m_output_info[output_id].is_fn_output) { + uint index = m_fgraph.outputs().index(DFGraphSocket::FromOutput(output_id)); + fn_out.copy_in__dynamic(index, storage.output_value_ptr(output_id)); + } + } + sockets_to_compute.pop(); + } + else { + for (uint requested_input_index : state.requested_inputs()) { + uint input_id = m_graph->id_of_node_input(node_id, requested_input_index); + if (!storage.is_input_initialized(input_id)) { + sockets_to_compute.push(DFGraphSocket::FromInput(input_id)); + } + } + lazy_states.push(LazyStateOnStack(node_id, state)); + } + } + } + else { + LazyState &state = lazy_states.peek().state; + state.start_next_entry(); + + SourceInfoStackFrame frame(m_graph->source_info_of_node(node_id)); + ctx.stack().push(&frame); + body->call(body_in, body_out, ctx, state); + ctx.stack().pop(); + + if (state.is_done()) { + for (uint output_id : m_graph->output_ids_of_node(node_id)) { + if (m_output_info[output_id].is_fn_output) { + uint index = m_fgraph.outputs().index(DFGraphSocket::FromOutput(output_id)); + fn_out.copy_in__dynamic(index, storage.output_value_ptr(output_id)); + } + } + sockets_to_compute.pop(); + lazy_states.pop(); + + // TODO: destruct inputs + } + else { + for (uint requested_input_index : state.requested_inputs()) { + uint input_id = m_graph->id_of_node_input(node_id, requested_input_index); + if (!storage.is_input_initialized(input_id)) { + sockets_to_compute.push(DFGraphSocket::FromInput(input_id)); + } + } + } + } + } + else { + bool all_inputs_computed = true; - for (uint output_id : m_graph->output_ids_of_node(node_id)) { - if (m_output_info[output_id].is_fn_output) { - uint index = m_fgraph.outputs().index(DFGraphSocket::FromOutput(output_id)); - fn_out.copy_in__dynamic(index, storage.output_value_ptr(output_id)); + for (uint input_id : m_graph->input_ids_of_node(node_id)) { + if (!storage.is_input_initialized(input_id)) { + sockets_to_compute.push(DFGraphSocket::FromInput(input_id)); + all_inputs_computed = false; } } - sockets_to_compute.pop(); + if (all_inputs_computed) { + BLI_assert(!m_node_info[node_id].is_lazy); + TupleCallBody *body = (TupleCallBody *)m_node_info[node_id].body; + BLI_assert(body); + + Tuple body_in(body->meta_in(), + storage.node_input_values_ptr(node_id), + storage.node_input_inits_ptr(node_id), + true, + true); + Tuple body_out(body->meta_out(), + storage.node_output_values_ptr(node_id), + storage.node_output_inits_ptr(node_id), + true, + false); + + SourceInfoStackFrame frame(m_graph->source_info_of_node(node_id)); + body->call__setup_stack(body_in, body_out, ctx, frame); + BLI_assert(body_out.all_initialized()); + + for (uint output_id : m_graph->output_ids_of_node(node_id)) { + if (m_output_info[output_id].is_fn_output) { + uint index = m_fgraph.outputs().index(DFGraphSocket::FromOutput(output_id)); + fn_out.copy_in__dynamic(index, storage.output_value_ptr(output_id)); + } + } + + sockets_to_compute.pop(); + } } } } diff --git a/source/blender/functions/core/data_flow_graph.hpp b/source/blender/functions/core/data_flow_graph.hpp index ffe266492c6..38865b373dc 100644 --- a/source/blender/functions/core/data_flow_graph.hpp +++ b/source/blender/functions/core/data_flow_graph.hpp @@ -184,6 +184,18 @@ class DataFlowGraph : public RefCountedBase { return m_nodes[node_id].function; } + uint id_of_node_input(uint node_id, uint input_index) + { + BLI_assert(input_index < this->input_ids_of_node(node_id @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs