From ce54f4855674059ef9124a27bff0741f97c75eec Mon Sep 17 00:00:00 2001 From: Mattias Fredriksson Date: Sat, 17 Sep 2022 22:12:02 -0500 Subject: BLI: Add generic utlity for gathering values with indices Add new functions to `array_utils` namespace called `gather(..)`. Versions of `GVArray::materialize_compressed_to_uninitialized(..)` with threading have been reimplemented locally in multiple geometry node contexts. The purpose of this patch is therefore to: * Assemble these implementations in a single file. * Provide a naming convention that is easier to recognize. Differential Revision: https://developer.blender.org/D15786 --- source/blender/blenlib/BLI_array_utils.hh | 75 ++++++++++++++++++++++++++++ source/blender/blenlib/intern/array_utils.cc | 13 ++++- 2 files changed, 87 insertions(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh index cf2f948b0b4..95b3bde10f4 100644 --- a/source/blender/blenlib/BLI_array_utils.hh +++ b/source/blender/blenlib/BLI_array_utils.hh @@ -6,6 +6,7 @@ #include "BLI_generic_virtual_array.hh" #include "BLI_index_mask.hh" #include "BLI_task.hh" +#include "BLI_virtual_array.hh" namespace blender::array_utils { @@ -25,6 +26,7 @@ inline void copy(const Span src, MutableSpan dst, const int64_t grain_size = 4096) { + BLI_assert(src.size() == dst.size()); threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) { for (const int64_t index : selection.slice(range)) { dst[index] = src[index]; @@ -32,4 +34,77 @@ inline void copy(const Span src, }); } +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +void gather(const GVArray &src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096); + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template +inline void gather(const VArray &src, + const IndexMask indices, + MutableSpan dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data()); + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template +inline void gather(const Span src, + const IndexMask indices, + MutableSpan dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template +inline void gather(const Span src, + const Span indices, + MutableSpan dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template +inline void gather(const VArray &src, + const Span indices, + MutableSpan dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + devirtualize_varray(src, [&](const auto &src) { + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); + }); +} + } // namespace blender::array_utils diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc index a0fc8810199..a837d6aceec 100644 --- a/source/blender/blenlib/intern/array_utils.cc +++ b/source/blender/blenlib/intern/array_utils.cc @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array_utils.hh" -#include "BLI_task.hh" namespace blender::array_utils { @@ -17,4 +16,16 @@ void copy(const GVArray &src, }); } +void gather(const GVArray &src, + const IndexMask indices, + GMutableSpan dst, + const int64_t grain_size) +{ + BLI_assert(src.type() == dst.type()); + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data()); + }); +} + } // namespace blender::array_utils -- cgit v1.2.3