[Bf-blender-cvs] [83308760a26] functions: initial constant folding of multi function network

Jacques Lucke noreply at git.blender.org
Sat Jan 4 16:39:14 CET 2020


Commit: 83308760a26c9265c72bea7b606f425b97092350
Author: Jacques Lucke
Date:   Sat Jan 4 16:07:59 2020 +0100
Branches: functions
https://developer.blender.org/rB83308760a26c9265c72bea7b606f425b97092350

initial constant folding of multi function network

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

M	source/blender/blenlib/BLI_resource_collector.h
M	source/blender/functions/CMakeLists.txt
M	source/blender/functions/FN_cpp_type.h
M	source/blender/functions/FN_multi_function.h
M	source/blender/functions/FN_multi_function_network.h
A	source/blender/functions/FN_multi_function_network_optimization.h
M	source/blender/functions/intern/multi_function_network.cc
A	source/blender/functions/intern/multi_function_network_optimization.cc
M	source/blender/functions/intern/multi_functions/customizable.h
M	source/blender/functions/intern/node_tree_multi_function_network/generate.cc

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

diff --git a/source/blender/blenlib/BLI_resource_collector.h b/source/blender/blenlib/BLI_resource_collector.h
index 6ee066ab360..9de0a553869 100644
--- a/source/blender/blenlib/BLI_resource_collector.h
+++ b/source/blender/blenlib/BLI_resource_collector.h
@@ -71,7 +71,7 @@ class ResourceCollector : NonCopyable {
 
   template<typename T, typename... Args> T &construct(const char *name, Args &&... args)
   {
-    destruct_ptr<T> value = m_allocator.construct(std::forward<Args>(args)...);
+    destruct_ptr<T> value = m_allocator.construct<T>(std::forward<Args>(args)...);
     T &value_ref = *value;
     this->add(std::move(value), name);
     return value_ref;
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index 99e9678f38d..3e8b5110b39 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
   intern/initialize.cc
   intern/multi_function_common_contexts.cc
   intern/multi_function_context.cc
+  intern/multi_function_network_optimization.cc
   intern/multi_function_network.cc
   intern/node_tree.cc
 
@@ -58,6 +59,7 @@ set(SRC
   FN_multi_function_context.h
   FN_multi_function_data_type.h
   FN_multi_function_dependencies.h
+  FN_multi_function_network_optimization.h
   FN_multi_function_network.h
   FN_multi_function_param_type.h
   FN_multi_function.h
diff --git a/source/blender/functions/FN_cpp_type.h b/source/blender/functions/FN_cpp_type.h
index 1ff6b1714e8..c6b30d89a5f 100644
--- a/source/blender/functions/FN_cpp_type.h
+++ b/source/blender/functions/FN_cpp_type.h
@@ -170,6 +170,11 @@ class CPPType {
     m_destruct_indices(ptr, index_mask);
   }
 
+  DestructF destruct_cb() const
+  {
+    return m_destruct;
+  }
+
   void copy_to_initialized(const void *src, void *dst) const
   {
     BLI_assert(this->pointer_has_valid_alignment(src));
diff --git a/source/blender/functions/FN_multi_function.h b/source/blender/functions/FN_multi_function.h
index 27c05c6ec65..fa6ade0320e 100644
--- a/source/blender/functions/FN_multi_function.h
+++ b/source/blender/functions/FN_multi_function.h
@@ -184,6 +184,12 @@ class MultiFunction {
     return m_signature_data.used_element_contexts.size() > 0;
   }
 
+  bool depends_on_context() const
+  {
+    return m_signature_data.used_element_contexts.size() > 0 ||
+           m_signature_data.used_global_contexts.size() > 0;
+  }
+
   template<typename T> bool uses_element_context() const
   {
     BLI::class_id_t id = BLI::get_class_id<T>();
diff --git a/source/blender/functions/FN_multi_function_network.h b/source/blender/functions/FN_multi_function_network.h
index 84e37df891c..67d56966d37 100644
--- a/source/blender/functions/FN_multi_function_network.h
+++ b/source/blender/functions/FN_multi_function_network.h
@@ -5,11 +5,13 @@
 
 #include "BLI_optional.h"
 #include "BLI_array_cxx.h"
+#include "BLI_set.h"
 
 namespace FN {
 
 using BLI::Array;
 using BLI::Optional;
+using BLI::Set;
 
 /* MFNetwork Builder
  ****************************************/
@@ -140,8 +142,8 @@ class MFNetworkBuilder : BLI::NonCopyable, BLI::NonMovable {
  public:
   ~MFNetworkBuilder();
 
-  std::string to_dot();
-  void to_dot__clipboard();
+  std::string to_dot(const Set<MFBuilderNode *> &marked_nodes = {});
+  void to_dot__clipboard(const Set<MFBuilderNode *> &marked_nodes = {});
 
   MFBuilderFunctionNode &add_function(const MultiFunction &function);
   MFBuilderDummyNode &add_dummy(StringRef name,
@@ -150,6 +152,7 @@ class MFNetworkBuilder : BLI::NonCopyable, BLI::NonMovable {
                                 ArrayRef<StringRef> input_names,
                                 ArrayRef<StringRef> output_names);
   void add_link(MFBuilderOutputSocket &from, MFBuilderInputSocket &to);
+  void remove_link(MFBuilderOutputSocket &from, MFBuilderInputSocket &to);
 
   ArrayRef<MFBuilderNode *> nodes_by_id() const
   {
@@ -182,6 +185,8 @@ class MFNetworkBuilder : BLI::NonCopyable, BLI::NonMovable {
   }
 };
 
+void optimize_multi_function_network(MFNetworkBuilder &network);
+
 /* Network
  ******************************************/
 
@@ -314,7 +319,7 @@ class MFNetwork : BLI::NonCopyable, BLI::NonMovable {
   Vector<MFOutputSocket *> m_output_sockets;
 
  public:
-  MFNetwork(std::unique_ptr<MFNetworkBuilder> builder);
+  MFNetwork(MFNetworkBuilder &builder);
   ~MFNetwork();
 
   const MFNode &node_by_id(uint id) const;
diff --git a/source/blender/functions/FN_multi_function_network_optimization.h b/source/blender/functions/FN_multi_function_network_optimization.h
new file mode 100644
index 00000000000..f2117f28032
--- /dev/null
+++ b/source/blender/functions/FN_multi_function_network_optimization.h
@@ -0,0 +1,16 @@
+#ifndef __FN_MULTI_FUNCTION_NETWORK_OPTIMIZATION_H__
+#define __FN_MULTI_FUNCTION_NETWORK_OPTIMIZATION_H__
+
+#include "FN_multi_function_network.h"
+
+#include "BLI_resource_collector.h"
+
+namespace FN {
+
+using BLI::ResourceCollector;
+
+void optimize_network__constant_folding(MFNetworkBuilder &network, ResourceCollector &resources);
+
+}  // namespace FN
+
+#endif /* __FN_MULTI_FUNCTION_NETWORK_OPTIMIZATION_H__ */
diff --git a/source/blender/functions/intern/multi_function_network.cc b/source/blender/functions/intern/multi_function_network.cc
index d28e8a4ab0b..d3e83dfb7c5 100644
--- a/source/blender/functions/intern/multi_function_network.cc
+++ b/source/blender/functions/intern/multi_function_network.cc
@@ -154,7 +154,15 @@ void MFNetworkBuilder::add_link(MFBuilderOutputSocket &from, MFBuilderInputSocke
   to.m_origin = &from;
 }
 
-std::string MFNetworkBuilder::to_dot()
+void MFNetworkBuilder::remove_link(MFBuilderOutputSocket &from, MFBuilderInputSocket &to)
+{
+  BLI_assert(from.m_targets.contains(&to));
+  BLI_assert(to.m_origin == &from);
+  from.m_targets.remove_first_occurrence_and_reorder(&to);
+  to.m_origin = nullptr;
+}
+
+std::string MFNetworkBuilder::to_dot(const Set<MFBuilderNode *> &marked_nodes)
 {
   using BLI::DotExport::Utils::NodeWithSocketsWrapper;
 
@@ -175,7 +183,10 @@ std::string MFNetworkBuilder::to_dot()
     }
 
     if (node->is_dummy()) {
-      dot_node.set_background_color("#AAAAFF");
+      dot_node.set_background_color("#EEEEFF");
+    }
+    if (marked_nodes.contains(node)) {
+      dot_node.set_background_color("#99EE99");
     }
 
     dot_nodes.add_new(node,
@@ -201,21 +212,21 @@ std::string MFNetworkBuilder::to_dot()
   return digraph.to_dot_string();
 }
 
-void MFNetworkBuilder::to_dot__clipboard()
+void MFNetworkBuilder::to_dot__clipboard(const Set<MFBuilderNode *> &marked_nodes)
 {
-  std::string dot = this->to_dot();
+  std::string dot = this->to_dot(marked_nodes);
   WM_clipboard_text_set(dot.c_str(), false);
 }
 
 /* Network
  ********************************************/
 
-MFNetwork::MFNetwork(std::unique_ptr<MFNetworkBuilder> builder)
+MFNetwork::MFNetwork(MFNetworkBuilder &builder)
 {
-  m_node_by_id = Array<MFNode *>(builder->nodes_by_id().size());
-  m_socket_by_id = Array<MFSocket *>(builder->sockets_by_id().size());
+  m_node_by_id = Array<MFNode *>(builder.nodes_by_id().size());
+  m_socket_by_id = Array<MFSocket *>(builder.sockets_by_id().size());
 
-  for (MFBuilderFunctionNode *builder_node : builder->function_nodes()) {
+  for (MFBuilderFunctionNode *builder_node : builder.function_nodes()) {
     MFFunctionNode &node = *m_allocator.construct<MFFunctionNode>().release();
 
     node.m_function = &builder_node->function();
@@ -254,7 +265,7 @@ MFNetwork::MFNetwork(std::unique_ptr<MFNetworkBuilder> builder)
     m_node_by_id[node.id()] = &node;
   }
 
-  for (MFBuilderDummyNode *builder_node : builder->dummy_nodes()) {
+  for (MFBuilderDummyNode *builder_node : builder.dummy_nodes()) {
     MFDummyNode &node = *m_allocator.construct<MFDummyNode>().release();
 
     node.m_id = builder_node->id();
@@ -292,14 +303,14 @@ MFNetwork::MFNetwork(std::unique_ptr<MFNetworkBuilder> builder)
     m_node_by_id[node.id()] = &node;
   }
 
-  for (MFBuilderInputSocket *builder_socket : builder->input_sockets()) {
+  for (MFBuilderInputSocket *builder_socket : builder.input_sockets()) {
     MFInputSocket &socket = m_socket_by_id[builder_socket->id()]->as_input();
     MFOutputSocket &origin = m_socket_by_id[builder_socket->origin()->id()]->as_output();
 
     socket.m_origin = &origin;
   }
 
-  for (MFBuilderOutputSocket *builder_socket : builder->output_sockets()) {
+  for (MFBuilderOutputSocket *builder_socket : builder.output_sockets()) {
     MFOutputSocket &socket = m_socket_by_id[builder_socket->id()]->as_output();
 
     for (MFBuilderInputSocket *builder_target : builder_socket->targets()) {
diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
new file mode 100644
index 00000000000..13f3ed0100e
--- /dev/null
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -0,0 +1,146 @@
+#include "FN_multi_function_network.h"
+#include "FN_multi_function_network_optimization.h"
+#include "FN_multi_functions.h"
+
+#include "BLI_stack_cxx.h"
+
+namespace FN {
+
+using BLI::Stack;
+
+static bool node_can_be_constant(MFBuilderNode &node)
+{
+  if (node.is_function()) {
+    const MultiFunction &fn = node.as_function().function();
+    return !fn.depends_on_context();
+  }
+  else {
+    return false;
+  }
+}
+
+void optimize_network__constant_folding(MFNetworkBuilder &network_builder,
+                                        ResourceCollector &resources)
+{
+  Array<bool> is_constant(network_builder.nodes_by_id().size(), true);
+
+  Stack<MFBuilderNode *> nodes_to_check = network_builder.nodes_by_id();
+
+  while (!nodes_to_check.is_empty()) {
+    MFBuilderNode &current_node = *nodes_to_check.pop();
+    bool &current_node_is_constant = is_constant[current_node.id()];
+
+    if (current_node_is_constant && !node_can_be_constant(current_node)) {
+      current_node_is_constant = false;
+    }
+
+    if (!current_node_is_constant) {
+      for (MFBuilderOutputSocket *output_socket : current_node.outputs()) {
+        for (MFBuilderInputSocket *target_socket : output_socket->targets()) {
+          MFBuilderNode &target_node = target_socket->n

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list