[Bf-blender-cvs] [5816f755444] functions-experimental-refactor: initial automatic node vectorization

Jacques Lucke noreply at git.blender.org
Thu Oct 31 11:44:15 CET 2019


Commit: 5816f75544432fadc129469fb31d689ea5192ab6
Author: Jacques Lucke
Date:   Thu Oct 31 11:44:01 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rB5816f75544432fadc129469fb31d689ea5192ab6

initial automatic node vectorization

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

M	source/blender/blenkernel/BKE_generic_vector_array.h
M	source/blender/blenkernel/BKE_generic_virtual_list_list_ref.h
M	source/blender/blenkernel/BKE_generic_virtual_list_ref.h
M	source/blender/blenkernel/BKE_multi_functions.h
M	source/blender/blenkernel/intern/multi_functions.cc
M	source/blender/modifiers/intern/MOD_functiondeform_cxx.cc

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

diff --git a/source/blender/blenkernel/BKE_generic_vector_array.h b/source/blender/blenkernel/BKE_generic_vector_array.h
index 9d84d26ed0b..f4b25370a69 100644
--- a/source/blender/blenkernel/BKE_generic_vector_array.h
+++ b/source/blender/blenkernel/BKE_generic_vector_array.h
@@ -98,6 +98,16 @@ class GenericVectorArray : BLI::NonCopyable, BLI::NonMovable {
     }
   }
 
+  GenericMutableArrayRef allocate_single(uint index, uint size)
+  {
+    if (m_lengths[index] + size > m_capacities[index]) {
+      this->grow_single(index, m_lengths[index] + size);
+    }
+    void *allocation_start = POINTER_OFFSET(m_starts[index], m_element_size * m_lengths[index]);
+    m_lengths[index] += size;
+    return GenericMutableArrayRef(m_type, allocation_start, size);
+  }
+
   GenericArrayRef operator[](uint index) const
   {
     BLI_assert(index < m_array_size);
diff --git a/source/blender/blenkernel/BKE_generic_virtual_list_list_ref.h b/source/blender/blenkernel/BKE_generic_virtual_list_list_ref.h
index c000be2f9d3..745149cb1b0 100644
--- a/source/blender/blenkernel/BKE_generic_virtual_list_list_ref.h
+++ b/source/blender/blenkernel/BKE_generic_virtual_list_list_ref.h
@@ -98,6 +98,7 @@ class GenericVirtualListListRef {
   template<typename T> VirtualListListRef<T> as_typed_ref() const
   {
     BLI_assert(GET_TYPE<T>().is_same_or_generalization(*m_type));
+
     switch (m_category) {
       case Category::SingleArray:
         return VirtualListListRef<T>::FromSingleArray(
@@ -108,9 +109,32 @@ class GenericVirtualListListRef {
             ArrayRef<const T *>((const T **)m_data.full_array_list.starts, m_virtual_list_size),
             ArrayRef<uint>(m_data.full_array_list.real_array_sizes, m_virtual_list_size));
     }
+
     BLI_assert(false);
     return {};
   }
+
+  GenericVirtualListRef repeated_sublist(uint index, uint new_virtual_size) const
+  {
+    BLI_assert(index < m_virtual_list_size);
+
+    switch (m_category) {
+      case Category::SingleArray:
+        return GenericVirtualListRef::FromRepeatedArray(*m_type,
+                                                        m_data.single_array.data,
+                                                        m_data.single_array.real_array_size,
+                                                        new_virtual_size);
+      case Category::FullArrayList:
+        return GenericVirtualListRef::FromRepeatedArray(
+            *m_type,
+            m_data.full_array_list.starts[index],
+            m_data.full_array_list.real_array_sizes[index],
+            new_virtual_size);
+    }
+
+    BLI_assert(false);
+    return {*m_type};
+  }
 };
 
 }  // namespace BKE
diff --git a/source/blender/blenkernel/BKE_generic_virtual_list_ref.h b/source/blender/blenkernel/BKE_generic_virtual_list_ref.h
index 476621a2cf3..d9d92caeb1c 100644
--- a/source/blender/blenkernel/BKE_generic_virtual_list_ref.h
+++ b/source/blender/blenkernel/BKE_generic_virtual_list_ref.h
@@ -109,13 +109,18 @@ class GenericVirtualListRef {
                                                  uint real_size,
                                                  uint virtual_size)
   {
-    GenericVirtualListRef list;
-    list.m_virtual_size = virtual_size;
-    list.m_type = &type;
-    list.m_category = Category::RepeatedArray;
-    list.m_data.repeated_array.data = buffer;
-    list.m_data.repeated_array.real_size = real_size;
-    return list;
+    if (real_size < virtual_size) {
+      GenericVirtualListRef list;
+      list.m_virtual_size = virtual_size;
+      list.m_type = &type;
+      list.m_category = Category::RepeatedArray;
+      list.m_data.repeated_array.data = buffer;
+      list.m_data.repeated_array.real_size = real_size;
+      return list;
+    }
+    else {
+      return GenericVirtualListRef::FromFullArray(type, buffer, virtual_size);
+    }
   }
 
   uint size() const
@@ -126,6 +131,7 @@ class GenericVirtualListRef {
   const void *operator[](uint index) const
   {
     BLI_assert(index < m_virtual_size);
+
     switch (m_category) {
       case Category::Single:
         return m_data.single.data;
@@ -137,6 +143,7 @@ class GenericVirtualListRef {
         uint real_index = index % m_data.repeated_array.real_size;
         return POINTER_OFFSET(m_data.repeated_array.data, real_index * m_type->size());
     }
+
     BLI_assert(false);
     return m_data.single.data;
   }
@@ -144,6 +151,7 @@ class GenericVirtualListRef {
   template<typename T> VirtualListRef<T> as_typed_ref() const
   {
     BLI_assert(GET_TYPE<T>().is_same_or_generalization(*m_type));
+
     switch (m_category) {
       case Category::Single:
         return VirtualListRef<T>::FromSingle((const T *)m_data.single.data, m_virtual_size);
@@ -157,9 +165,15 @@ class GenericVirtualListRef {
                                                     m_data.repeated_array.real_size,
                                                     m_virtual_size);
     }
+
     BLI_assert(false);
     return {};
   }
+
+  GenericVirtualListRef repeated_element(uint index, uint new_virtual_size) const
+  {
+    return GenericVirtualListRef::FromSingle(*m_type, (*this)[index], new_virtual_size);
+  }
 };
 
 }  // namespace BKE
diff --git a/source/blender/blenkernel/BKE_multi_functions.h b/source/blender/blenkernel/BKE_multi_functions.h
index 27477a990a7..e31b43b278f 100644
--- a/source/blender/blenkernel/BKE_multi_functions.h
+++ b/source/blender/blenkernel/BKE_multi_functions.h
@@ -142,6 +142,18 @@ template<typename FromT, typename ToT> class MultiFunction_Convert : public Mult
   }
 };
 
+class MultiFunction_SimpleVectorize final : public MultiFunction {
+ private:
+  const MultiFunction &m_function;
+  Vector<bool> m_input_is_vectorized;
+  Vector<uint> m_vectorized_inputs;
+  Vector<uint> m_output_indices;
+
+ public:
+  MultiFunction_SimpleVectorize(const MultiFunction &function, ArrayRef<bool> input_is_vectorized);
+  void call(ArrayRef<uint> mask_indices, MFParams &params, MFContext &context) const override;
+};
+
 };  // namespace BKE
 
 #endif /* __BKE_MULTI_FUNCTIONS_H__ */
diff --git a/source/blender/blenkernel/intern/multi_functions.cc b/source/blender/blenkernel/intern/multi_functions.cc
index a5f205cce45..5e96600f3d0 100644
--- a/source/blender/blenkernel/intern/multi_functions.cc
+++ b/source/blender/blenkernel/intern/multi_functions.cc
@@ -311,4 +311,119 @@ void MultiFunction_ListLength::call(ArrayRef<uint> mask_indices,
   }
 }
 
+MultiFunction_SimpleVectorize::MultiFunction_SimpleVectorize(const MultiFunction &function,
+                                                             ArrayRef<bool> input_is_vectorized)
+    : m_function(function), m_input_is_vectorized(input_is_vectorized)
+{
+  BLI_assert(input_is_vectorized.contains(true));
+
+  MFSignatureBuilder signature;
+  ArrayRef<MFParamType> param_types = function.signature().param_types();
+
+  bool found_output_param = false;
+  UNUSED_VARS_NDEBUG(found_output_param);
+  for (uint param_index = 0; param_index < param_types.size(); param_index++) {
+    MFParamType param_type = param_types[param_index];
+    switch (param_type.category()) {
+      case MFParamType::None:
+      case MFParamType::ReadonlyVectorInput:
+      case MFParamType::VectorOutput:
+      case MFParamType::MutableVector: {
+        BLI_assert(false);
+        break;
+      }
+      case MFParamType::ReadonlySingleInput: {
+        BLI_assert(!found_output_param);
+        if (input_is_vectorized[param_index]) {
+          signature.readonly_vector_input("Input", param_type.type());
+          m_vectorized_inputs.append(param_index);
+        }
+        else {
+          signature.readonly_single_input("Input", param_type.type());
+        }
+        break;
+      }
+      case MFParamType::SingleOutput: {
+        signature.vector_output("Output", param_type.type());
+        m_output_indices.append(param_index);
+        found_output_param = true;
+        break;
+      }
+    }
+  }
+  this->set_signature(signature);
+}
+
+void MultiFunction_SimpleVectorize::call(ArrayRef<uint> mask_indices,
+                                         MFParams &params,
+                                         MFContext &context) const
+{
+  if (mask_indices.size() == 0) {
+    return;
+  }
+  uint array_size = mask_indices.last() + 1;
+
+  Vector<int> vectorization_lengths(array_size);
+  vectorization_lengths.fill_indices(mask_indices, -1);
+
+  for (uint param_index : m_vectorized_inputs) {
+    GenericVirtualListListRef values = params.readonly_vector_input(param_index, "Input");
+    for (uint i : mask_indices) {
+      if (vectorization_lengths[i] != 0) {
+        vectorization_lengths[i] = std::max<int>(vectorization_lengths[i], values[i].size());
+      }
+    }
+  }
+
+  Vector<GenericVectorArray *> output_vector_arrays;
+  for (uint param_index : m_output_indices) {
+    GenericVectorArray *vector_array = &params.vector_output(param_index, "Output");
+    output_vector_arrays.append(vector_array);
+  }
+
+  ArrayRef<MFParamType> param_types = m_function.signature().param_types();
+
+  for (uint index : mask_indices) {
+    uint length = vectorization_lengths[index];
+    MFParamsBuilder params_builder;
+    params_builder.start_new(m_function.signature(), length);
+
+    for (uint param_index = 0; param_index < param_types.size(); param_index++) {
+      MFParamType param_type = param_types[param_index];
+      switch (param_type.category()) {
+        case MFParamType::None:
+        case MFParamType::ReadonlyVectorInput:
+        case MFParamType::VectorOutput:
+        case MFParamType::MutableVector: {
+          BLI_assert(false);
+          break;
+        }
+        case MFParamType::ReadonlySingleInput: {
+          if (m_input_is_vectorized[param_index]) {
+            GenericVirtualListListRef input_list_list = params.readonly_vector_input(param_index,
+                                                                                     "Input");
+            GenericVirtualListRef repeated_input = input_list_list.repeated_sublist(index, length);
+            params_builder.add_readonly_single_input(repeated_input);
+          }
+          else {
+            GenericVirtualListRef input_list = params.readonly_single_input(param_index, "

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list