[Bf-blender-cvs] [594596d5aa2] devirtualizer: initial devirtualizer

Jacques Lucke noreply at git.blender.org
Sun Apr 10 16:00:24 CEST 2022


Commit: 594596d5aa2912f616a63946c30493b8a156c0bc
Author: Jacques Lucke
Date:   Sun Apr 10 13:03:28 2022 +0200
Branches: devirtualizer
https://developer.blender.org/rB594596d5aa2912f616a63946c30493b8a156c0bc

initial devirtualizer

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

A	source/blender/blenlib/BLI_virtual_array_devirtualize.hh
M	source/blender/blenlib/tests/BLI_virtual_array_test.cc

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

diff --git a/source/blender/blenlib/BLI_virtual_array_devirtualize.hh b/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
new file mode 100644
index 00000000000..36369211bfb
--- /dev/null
+++ b/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <tuple>
+
+#include "BLI_virtual_array.hh"
+
+namespace blender {
+
+struct SingleInputTagBase {
+};
+template<typename T> struct SingleInputTag : public SingleInputTagBase {
+};
+struct SingleOutputTagBase {
+};
+template<typename T> struct SingleOutputTag : public SingleOutputTagBase {
+};
+
+template<typename T> struct ParamType {
+};
+
+template<typename T> struct ParamType<SingleInputTag<T>> {
+  using type = VArray<T>;
+};
+
+template<typename T> struct ParamType<SingleOutputTag<T>> {
+  using type = MutableSpan<T>;
+};
+
+template<typename Fn, typename... Args> class ArrayDevirtualizer {
+ private:
+  using TagsTuple = std::tuple<Args...>;
+
+  Fn fn_;
+  IndexMask mask_;
+  std::tuple<const typename ParamType<Args>::type *...> params_;
+
+  std::array<bool, sizeof...(Args)> varray_is_span_;
+  std::array<bool, sizeof...(Args)> varray_is_single_;
+
+ public:
+  ArrayDevirtualizer(Fn fn, const IndexMask *mask, const typename ParamType<Args>::type *...params)
+      : fn_(std::move(fn)), mask_(*mask), params_{params...}
+  {
+    this->init(std::make_index_sequence<sizeof...(Args)>{});
+  }
+
+  void execute_fallback()
+  {
+    this->execute_fallback_impl(std::make_index_sequence<sizeof...(Args)>{});
+  }
+
+ private:
+  template<size_t... I> void init(std::index_sequence<I...> /* indices */)
+  {
+    varray_is_span_.fill(false);
+    varray_is_single_.fill(false);
+    (this->init_param<I>(), ...);
+  }
+
+  template<size_t I> void init_param()
+  {
+    using ParamTag = std::tuple_element_t<I, TagsTuple>;
+    if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
+      const typename ParamType<ParamTag>::type *varray = std::get<I>(params_);
+      varray_is_span_[I] = varray->is_span();
+      varray_is_single_[I] = varray->is_single();
+    }
+  }
+
+  template<size_t... I> void execute_fallback_impl(std::index_sequence<I...> /* indices */)
+  {
+    fn_(mask_, mask_, *std::get<I>(params_)...);
+  }
+};
+
+}  // namespace blender
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index 90c7f1078a5..714e5e82860 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -5,6 +5,7 @@
 #include "BLI_vector.hh"
 #include "BLI_vector_set.hh"
 #include "BLI_virtual_array.hh"
+#include "BLI_virtual_array_devirtualize.hh"
 #include "testing/testing.h"
 
 namespace blender::tests {
@@ -222,4 +223,30 @@ TEST(virtual_array, MaterializeCompressed)
   }
 }
 
+TEST(virtual_array, Devirtualize)
+{
+  auto fn = [](auto in_indices, auto out_indices, auto in1, auto in2, MutableSpan<int> out1) {
+    for (const int64_t i : IndexRange(in_indices.size())) {
+      const int64_t in_i = in_indices[i];
+      const int64_t out_i = out_indices[i];
+      out1[out_i] = in1[in_i] + in2[in_i];
+    }
+  };
+
+  IndexMask mask(IndexRange(10));
+  VArray<int> in1 = VArray<int>::ForSingle(3, 10);
+  VArray<int> in2 = VArray<int>::ForSingle(5, 10);
+  std::array<int, 10> out1_array;
+  MutableSpan<int> out1 = out1_array;
+  out1.fill(-1);
+
+  ArrayDevirtualizer<decltype(fn), SingleInputTag<int>, SingleInputTag<int>, SingleOutputTag<int>>
+      devirtualizer{fn, &mask, &in1, &in2, &out1};
+
+  devirtualizer.execute_fallback();
+
+  EXPECT_EQ(out1[0], 8);
+  EXPECT_EQ(out1[1], 8);
+}
+
 }  // namespace blender::tests



More information about the Bf-blender-cvs mailing list