[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 ¤t_node = *nodes_to_check.pop();
+ bool ¤t_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