[Bf-blender-cvs] [0264b27c5e0] devirtualizer: progress
Jacques Lucke
noreply at git.blender.org
Sun Apr 10 16:00:25 CEST 2022
Commit: 0264b27c5e033b868665368a8b617ca39611784f
Author: Jacques Lucke
Date: Sun Apr 10 14:27:52 2022 +0200
Branches: devirtualizer
https://developer.blender.org/rB0264b27c5e033b868665368a8b617ca39611784f
progress
===================================================================
M 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
index 26dd99b029a..8c1213e3c0b 100644
--- a/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
+++ b/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
@@ -30,10 +30,11 @@ template<typename T> struct ParamType<SingleOutputTag<T>> {
using type = MutableSpan<T>;
};
-enum class DevirtualizeMode {
- None,
- Span,
- Single,
+struct DevirtualizeNone {
+};
+struct DevirtualizeSpan {
+};
+struct DevirtualizeSingle {
};
template<typename Fn, typename... Args> class ArrayDevirtualizer {
@@ -47,6 +48,8 @@ template<typename Fn, typename... Args> class ArrayDevirtualizer {
std::array<bool, sizeof...(Args)> varray_is_span_;
std::array<bool, sizeof...(Args)> varray_is_single_;
+ bool executed_ = false;
+
public:
ArrayDevirtualizer(Fn fn, const IndexMask *mask, const typename ParamType<Args>::type *...params)
: fn_(std::move(fn)), mask_(*mask), params_{params...}
@@ -54,12 +57,57 @@ template<typename Fn, typename... Args> class ArrayDevirtualizer {
this->init(std::make_index_sequence<sizeof...(Args)>{});
}
- void execute_fallback()
+ bool execute_fallback()
{
+ BLI_assert(!executed_);
this->execute_fallback_impl(std::make_index_sequence<sizeof...(Args)>{});
+ return true;
+ }
+
+ bool try_execute_devirtualized()
+ {
+ BLI_assert(!executed_);
+ return this->try_execute_devirtualized_impl();
}
private:
+ template<typename... Mode> bool try_execute_devirtualized_impl()
+ {
+ if constexpr (sizeof...(Mode) == sizeof...(Args)) {
+ this->try_execute_devirtualized_impl_call(std::tuple<Mode...>(),
+ std::make_index_sequence<sizeof...(Args)>());
+ return true;
+ }
+ else {
+ constexpr size_t I = sizeof...(Mode);
+ using ParamTag = std::tuple_element_t<I, TagsTuple>;
+ if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
+ if (varray_is_single_[I]) {
+ return this->try_execute_devirtualized_impl<Mode..., DevirtualizeSingle>();
+ }
+ else if (varray_is_span_[I]) {
+ return this->try_execute_devirtualized_impl<Mode..., DevirtualizeSpan>();
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ return this->try_execute_devirtualized_impl<Mode..., DevirtualizeNone>();
+ }
+ }
+ }
+
+ template<typename... Mode, size_t... I>
+ void try_execute_devirtualized_impl_call(std::tuple<Mode...> /* modes */,
+ std::index_sequence<I...> /* indices */)
+ {
+ fn_(mask_,
+ mask_,
+ this->get_execute_param<I, std::tuple_element_t<I, std::tuple<Mode...>>>()...);
+ executed_ = true;
+ }
+
template<size_t... I> void init(std::index_sequence<I...> /* indices */)
{
varray_is_span_.fill(false);
@@ -79,24 +127,23 @@ template<typename Fn, typename... Args> class ArrayDevirtualizer {
template<size_t... I> void execute_fallback_impl(std::index_sequence<I...> /* indices */)
{
- fn_(mask_, mask_, this->get_execute_param<I, DevirtualizeMode::None>()...);
+ fn_(mask_, mask_, this->get_execute_param<I, DevirtualizeNone>()...);
+ executed_ = true;
}
- template<size_t I, DevirtualizeMode mode> auto get_execute_param()
+ template<size_t I, typename Mode> auto get_execute_param()
{
using ParamTag = std::tuple_element_t<I, TagsTuple>;
if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
using T = typename ParamTag::BaseType;
- static_assert(
- ELEM(mode, DevirtualizeMode::None, DevirtualizeMode::Single, DevirtualizeMode::Span));
const VArray<T> *varray = std::get<I>(params_);
- if constexpr (mode == DevirtualizeMode::None) {
+ if constexpr (std::is_same_v<Mode, DevirtualizeNone>) {
return *varray;
}
- else if constexpr (mode == DevirtualizeMode::Single) {
+ else if constexpr (std::is_same_v<Mode, DevirtualizeSingle>) {
return SingleAsSpan(*varray);
}
- else if constexpr (mode == DevirtualizeMode::Span) {
+ else if constexpr (std::is_same_v<Mode, DevirtualizeSpan>) {
return varray->get_internal_span();
}
}
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index b5851d5c5b3..91df8b06540 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -223,19 +223,31 @@ TEST(virtual_array, MaterializeCompressed)
}
}
-TEST(virtual_array, Devirtualize)
-{
- auto fn = [](auto in_indices, auto out_indices, auto in1, auto in2, int *__restrict out1) {
+struct MyOperator {
+ template<typename InIndices, typename OutIndices, typename In1Array, typename In2Array>
+ void operator()(InIndices in_indices,
+ OutIndices out_indices,
+ In1Array in1,
+ In2Array in2,
+ int *__restrict 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];
}
- };
+ }
+};
+
+TEST(virtual_array, Devirtualize)
+{
+ MyOperator fn;
IndexMask mask(IndexRange(10));
VArray<int> in1 = VArray<int>::ForSingle(3, 10);
- VArray<int> in2 = VArray<int>::ForSingle(5, 10);
+ // VArray<int> in2 = VArray<int>::ForSingle(5, 10);
+ VArray<int> in2 = VArray<int>::ForContainer(Array<int>(10, 5));
+ // VArray<int> in2 = VArray<int>::ForFunc(10, [](int64_t i) { return (int)i; });
std::array<int, 10> out1_array;
MutableSpan<int> out1 = out1_array;
out1.fill(-1);
@@ -243,7 +255,7 @@ TEST(virtual_array, Devirtualize)
ArrayDevirtualizer<decltype(fn), SingleInputTag<int>, SingleInputTag<int>, SingleOutputTag<int>>
devirtualizer{fn, &mask, &in1, &in2, &out1};
- devirtualizer.execute_fallback();
+ devirtualizer.try_execute_devirtualized();
EXPECT_EQ(out1[0], 8);
EXPECT_EQ(out1[1], 8);
More information about the Bf-blender-cvs
mailing list