[Bf-blender-cvs] [049d66aa80e] functions: initial support for lazy inputs in new fgraph evaluation
Jacques Lucke
noreply at git.blender.org
Sun Apr 28 18:57:39 CEST 2019
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. @@
More information about the Bf-blender-cvs
mailing list