[Bf-blender-cvs] [38531114f7b] functions: initial support for defaults when using auto vectorization

Jacques Lucke noreply at git.blender.org
Mon May 13 10:16:55 CEST 2019


Commit: 38531114f7b41dc0fdcde47cedd83377ac802886
Author: Jacques Lucke
Date:   Sun May 12 20:04:16 2019 +0200
Branches: functions
https://developer.blender.org/rB38531114f7b41dc0fdcde47cedd83377ac802886

initial support for defaults when using auto vectorization

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

M	source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
M	source/blender/functions/functions/auto_vectorization.cpp
M	source/blender/functions/functions/auto_vectorization.hpp
M	source/blender/functions/functions/scalar_math.cpp
M	source/blender/functions/functions/scalar_math.hpp
M	source/blender/functions/functions/simple_conversions.cpp
M	source/blender/functions/functions/vectors.cpp
M	source/blender/functions/functions/vectors.hpp

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

diff --git a/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp b/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
index 1ca931a3645..9831840d68c 100644
--- a/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
@@ -13,25 +13,35 @@ namespace DataFlowNodes {
 
 using namespace Types;
 
+struct AutoVectorizedInput {
+  const char *prop_name;
+  SharedFunction &default_value_builder;
+};
+
 static SharedFunction get_vectorized_function(SharedFunction &original_fn,
                                               PointerRNA &node_rna,
-                                              SmallVector<const char *> vectorize_prop_names)
+                                              ArrayRef<AutoVectorizedInput> auto_vectorized_inputs)
 {
-  BLI_assert(original_fn->signature().inputs().size() == vectorize_prop_names.size());
+  BLI_assert(original_fn->signature().inputs().size() == auto_vectorized_inputs.size());
 
   SmallVector<bool> vectorized_inputs;
-  for (const char *prop_name : vectorize_prop_names) {
+  SmallVector<SharedFunction> used_default_value_builders;
+  for (auto &input : auto_vectorized_inputs) {
     char state[5];
-    BLI_assert(RNA_string_length(&node_rna, prop_name) == strlen("BASE"));
-    RNA_string_get(&node_rna, prop_name, state);
+    BLI_assert(RNA_string_length(&node_rna, input.prop_name) == strlen("BASE"));
+    RNA_string_get(&node_rna, input.prop_name, state);
     BLI_assert(STREQ(state, "BASE") || STREQ(state, "LIST"));
 
     bool is_vectorized = STREQ(state, "LIST");
     vectorized_inputs.append(is_vectorized);
+    if (is_vectorized) {
+      used_default_value_builders.append(input.default_value_builder);
+    }
   }
 
   if (vectorized_inputs.contains(true)) {
-    return Functions::to_vectorized_function(original_fn, vectorized_inputs);
+    return Functions::to_vectorized_function(
+        original_fn, vectorized_inputs, used_default_value_builders);
   }
   else {
     return original_fn;
@@ -74,12 +84,17 @@ static void INSERT_float_math(BTreeGraphBuilder &builder, bNode *bnode)
   uint input_amount = original_fn->signature().inputs().size();
 
   if (input_amount == 1) {
-    SharedFunction fn = get_vectorized_function(original_fn, rna, {"use_list__a"});
+    SharedFunction fn = get_vectorized_function(
+        original_fn, rna, {{"use_list__a", Functions::GET_FN_output_float_0()}});
     builder.insert_matching_function(fn, bnode);
   }
   else {
     BLI_assert(input_amount == 2);
-    SharedFunction fn = get_vectorized_function(original_fn, rna, {"use_list__a", "use_list__b"});
+    SharedFunction fn = get_vectorized_function(
+        original_fn,
+        rna,
+        {{"use_list__a", Functions::GET_FN_output_float_0()},
+         {"use_list__b", Functions::GET_FN_output_float_0()}});
     builder.insert_matching_function(fn, bnode);
   }
 }
@@ -101,7 +116,10 @@ static void INSERT_vector_math(BTreeGraphBuilder &builder, bNode *bnode)
   int operation = RNA_enum_get(&rna, "operation");
 
   SharedFunction fn = get_vectorized_function(
-      get_vector_math_function(operation), rna, {"use_list__a", "use_list__b"});
+      get_vector_math_function(operation),
+      rna,
+      {{"use_list__a", Functions::GET_FN_output_float_0()},
+       {"use_list__b", Functions::GET_FN_output_float_0()}});
   builder.insert_matching_function(fn, bnode);
 }
 
@@ -212,7 +230,11 @@ static void INSERT_combine_vector(BTreeGraphBuilder &builder, bNode *bnode)
 {
   PointerRNA rna = builder.get_rna(bnode);
   SharedFunction fn = get_vectorized_function(
-      Functions::GET_FN_combine_vector(), rna, {"use_list__x", "use_list__y", "use_list__z"});
+      Functions::GET_FN_combine_vector(),
+      rna,
+      {{"use_list__x", Functions::GET_FN_output_float_1()},
+       {"use_list__y", Functions::GET_FN_output_float_0()},
+       {"use_list__z", Functions::GET_FN_output_float_0()}});
   builder.insert_matching_function(fn, bnode);
 }
 
@@ -220,7 +242,9 @@ static void INSERT_separate_vector(BTreeGraphBuilder &builder, bNode *bnode)
 {
   PointerRNA rna = builder.get_rna(bnode);
   SharedFunction fn = get_vectorized_function(
-      Functions::GET_FN_separate_vector(), rna, {"use_list__vector"});
+      Functions::GET_FN_separate_vector(),
+      rna,
+      {{"use_list__vector", Functions::GET_FN_output_float_0()}});
   builder.insert_matching_function(fn, bnode);
 }
 
diff --git a/source/blender/functions/functions/auto_vectorization.cpp b/source/blender/functions/functions/auto_vectorization.cpp
index 9aa8b4e20ad..0339a3cab1c 100644
--- a/source/blender/functions/functions/auto_vectorization.cpp
+++ b/source/blender/functions/functions/auto_vectorization.cpp
@@ -22,6 +22,7 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
  private:
   SharedFunction m_main;
   SmallVector<bool> m_input_is_list;
+  SmallVector<SharedFunction> m_empty_list_value_builders;
 
   struct InputInfo {
     bool is_list;
@@ -43,8 +44,12 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
   SmallVector<OutputInfo> m_output_info;
 
  public:
-  AutoVectorizationGen(SharedFunction main, const SmallVector<bool> &input_is_list)
-      : m_main(main), m_input_is_list(input_is_list)
+  AutoVectorizationGen(SharedFunction main,
+                       ArrayRef<bool> input_is_list,
+                       ArrayRef<SharedFunction> empty_list_value_builders)
+      : m_main(main),
+        m_input_is_list(input_is_list.to_small_vector()),
+        m_empty_list_value_builders(empty_list_value_builders.to_small_vector())
   {
     BLI_assert(input_is_list.contains(true));
     for (uint i = 0; i < main->signature().inputs().size(); i++) {
@@ -85,7 +90,7 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
     llvm::Value *iteration = loop.current_iteration();
 
     LLVMValues main_inputs = this->prepare_main_function_inputs(
-        body_builder, interface, input_data_pointers, input_list_lengths, iteration);
+        body_builder, interface, settings, input_data_pointers, input_list_lengths, iteration);
 
     LLVMValues main_outputs(m_output_info.size());
     CodeInterface main_interface(
@@ -171,6 +176,7 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
 
   LLVMValues prepare_main_function_inputs(CodeBuilder &builder,
                                           CodeInterface &interface,
+                                          const BuildIRSettings &settings,
                                           const LLVMValues &input_data_pointers,
                                           const LLVMValues &input_list_lengths,
                                           llvm::Value *iteration) const
@@ -189,9 +195,16 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
         CodeBuilder &else_builder = ifthenelse.else_builder();
 
         /* Use default value when list has no elements. */
-        then_builder.CreateAssertFalse("cannot handle empty lists yet");
-        llvm::Value *default_value = then_builder.getUndef(
-            type_info->get_type(then_builder.getContext()));
+        SharedFunction &default_builder = m_empty_list_value_builders[list_input_index];
+        auto *default_builder_body = default_builder->body<LLVMBuildIRBody>();
+        LLVMValues default_builder_inputs(0);
+        LLVMValues default_builder_outputs(1);
+        CodeInterface default_builder_interface(default_builder_inputs,
+                                                default_builder_outputs,
+                                                interface.context_ptr(),
+                                                interface.function_ir_cache());
+        default_builder_body->build_ir(builder, default_builder_interface, settings);
+        llvm::Value *default_value = default_builder_outputs[0];
 
         /* Load value from list. */
         llvm::Value *current_index = else_builder.CreateURem(iteration, list_length);
@@ -387,24 +400,16 @@ class AutoVectorization : public TupleCallBody {
   }
 };
 
-static bool any_true(const SmallVector<bool> &list)
-{
-  for (bool value : list) {
-    if (value) {
-      return true;
-    }
-  }
-  return false;
-}
-
 SharedFunction to_vectorized_function(SharedFunction &original_fn,
-                                      const SmallVector<bool> &vectorize_input)
+                                      ArrayRef<bool> vectorized_inputs_mask,
+                                      ArrayRef<SharedFunction> empty_list_value_builders)
 {
   uint input_amount = original_fn->signature().inputs().size();
   uint output_amount = original_fn->signature().outputs().size();
 
-  BLI_assert(vectorize_input.size() == input_amount);
-  BLI_assert(any_true(vectorize_input));
+  BLI_assert(vectorized_inputs_mask.size() == input_amount);
+  BLI_assert(vectorized_inputs_mask.contains(true));
+  BLI_assert(empty_list_value_builders.size() == vectorized_inputs_mask.count(true));
 
   if (!original_fn->has_body<TupleCallBody>()) {
     if (original_fn->has_body<LLVMBuildIRBody>()) {
@@ -418,7 +423,7 @@ SharedFunction to_vectorized_function(SharedFunction &original_fn,
   InputParameters inputs;
   for (uint i = 0; i < input_amount; i++) {
     auto original_parameter = original_fn->signature().inputs()[i];
-    if (vectorize_input[i]) {
+    if (vectorized_inputs_mask[i]) {
       SharedType &list_type = get_list_type(original_parameter.type());
       inputs.append(InputParameter(original_parameter.name() + " (List)", list_type));
     }
@@ -436,8 +441,9 @@ SharedFunction to_vectorized_function(SharedFunction &original_fn,
 
   std::string name = original_fn->name() + " (Vectorized)";
   auto fn = SharedFunction::New(name, Signature(inputs, outputs));
-  // fn->add_body<AutoVectorization>(original_fn, vectorize_input);
-  fn->add_body<AutoVectorizationGen>(original_fn, vectorize_input);
+  // fn->add_body<AutoVectorization>(original_fn, vectorized_inputs_mask);
+  fn->add_body<AutoVectorizationGen>(
+      original_fn, vectorized_inputs_mask, empty_list_value_builders);
   return fn;
 }
 
diff --git a/source/blender/functions/functions/auto_vectorization.hpp b/source/blender/functions/function

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list