BLI: refactor IndexMask for better performance and memory usage #104629

Merged
Jacques Lucke merged 254 commits from JacquesLucke/blender:index-mask-refactor into main 2023-05-24 18:11:47 +02:00
7 changed files with 48 additions and 48 deletions
Showing only changes of commit 9048ff9362 - Show all commits

View File

@ -56,9 +56,9 @@ template<typename T> void copy_assign_compressed_cb(const void *src, void *dst,
const T *src_ = static_cast<const T *>(src);
T *dst_ = static_cast<T *>(dst);
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst_[i] = src_[best_mask[i]];
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
dst_[i] = src_[mask_segment[i]];
}
});
}
@ -79,9 +79,9 @@ template<typename T> void copy_construct_compressed_cb(const void *src, void *ds
const T *src_ = static_cast<const T *>(src);
T *dst_ = static_cast<T *>(dst);
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst_ + i) T(src_[best_mask[i]]);
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
new (dst_ + i) T(src_[mask_segment[i]]);
}
});
}

View File

@ -52,16 +52,16 @@ inline void interpolate_to_masked(const Span<T> src,
BLI_assert(indices.size() == dst_mask.size());
const int last_src_index = src.size() - 1;
dst_mask.to_best_mask_type([&](auto dst_mask) {
for (const int i : IndexRange(dst_mask.size())) {
dst_mask.foreach_span_or_range([&](auto dst_mask_segment) {
for (const int i : IndexRange(dst_mask_segment.size())) {
const int prev_index = indices[i];
const float factor = factors[i];
const bool is_cyclic_case = prev_index == last_src_index;
if (is_cyclic_case) {
dst[dst_mask[i]] = math::interpolate(src.last(), src.first(), factor);
dst[dst_mask_segment[i]] = math::interpolate(src.last(), src.first(), factor);
}
else {
dst[dst_mask[i]] = math::interpolate(src[prev_index], src[prev_index + 1], factor);
dst[dst_mask_segment[i]] = math::interpolate(src[prev_index], src[prev_index + 1], factor);
}
}
});

View File

@ -127,9 +127,9 @@ template<typename T> class VArrayImpl {
*/
virtual void materialize_compressed(IndexMask mask, T *dst) const
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = this->get(best_mask[i]);
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
dst[i] = this->get(mask_segment[i]);
}
});
}
@ -139,9 +139,9 @@ template<typename T> class VArrayImpl {
*/
virtual void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(this->get(best_mask[i]));
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
new (dst + i) T(this->get(mask_segment[i]));
}
});
}
@ -241,18 +241,18 @@ template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
void materialize_compressed(IndexMask mask, T *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = data_[best_mask[i]];
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
dst[i] = data_[mask_segment[i]];
}
});
}
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(data_[best_mask[i]]);
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
new (dst + i) T(data_[mask_segment[i]]);
}
});
}
@ -383,18 +383,18 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
void materialize_compressed(IndexMask mask, T *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = get_func_(best_mask[i]);
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
dst[i] = get_func_(mask_segment[i]);
}
});
}
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(get_func_(best_mask[i]));
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
new (dst + i) T(get_func_(mask_segment[i]));
}
});
}
@ -446,18 +446,18 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
void materialize_compressed(IndexMask mask, ElemT *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = GetFunc(data_[best_mask[i]]);
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
dst[i] = GetFunc(data_[mask_segment[i]]);
}
});
}
void materialize_compressed_to_uninitialized(IndexMask mask, ElemT *dst) const override
{
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) ElemT(GetFunc(data_[best_mask[i]]));
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
new (dst + i) ElemT(GetFunc(data_[mask_segment[i]]));
}
});
}

View File

@ -671,8 +671,8 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
void call(IndexMask mask, Params params, Context /*context*/) const override
{
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
mask.to_best_mask_type([&](const auto &mask) {
for (const int64_t i : mask) {
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : mask_segment) {
new (&output[i]) T(value_);
}
});

View File

@ -80,11 +80,11 @@ class SeparateRGBAFunction : public mf::MultiFunction {
}
devirtualize_varray(colors, [&](auto colors) {
mask.to_best_mask_type([&](auto mask) {
mask.foreach_span_or_range([&](const auto mask_segment) {
const int used_outputs_num = used_outputs.size();
const int *used_outputs_data = used_outputs.data();
for (const int64_t i : mask) {
for (const int64_t i : mask_segment) {
const ColorGeometry4f &color = colors[i];
for (const int out_i : IndexRange(used_outputs_num)) {
const int channel = used_outputs_data[out_i];

View File

@ -137,8 +137,8 @@ static void sample_indices_and_lengths(const Span<float> accumulated_lengths,
const float total_length = accumulated_lengths.last();
length_parameterize::SampleSegmentHint hint;
mask.to_best_mask_type([&](const auto mask) {
for (const int64_t i : mask) {
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : mask_segment) {
const float sample_length = length_mode == GEO_NODE_CURVE_SAMPLE_FACTOR ?
sample_lengths[i] * total_length :
sample_lengths[i];
@ -171,9 +171,9 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
switch (length_mode) {
case GEO_NODE_CURVE_SAMPLE_FACTOR:
mask.to_best_mask_type([&](const auto mask) {
for (const int64_t i : IndexRange(mask.size())) {
const float length = sample_lengths[mask[i]] * total_length;
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
const float length = sample_lengths[mask_segment[i]] * total_length;
length_parameterize::sample_at_length(accumulated_lengths,
std::clamp(length, 0.0f, total_length),
r_segment_indices[i],
@ -183,9 +183,9 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
});
break;
case GEO_NODE_CURVE_SAMPLE_LENGTH:
mask.to_best_mask_type([&](const auto mask) {
for (const int64_t i : IndexRange(mask.size())) {
const float length = sample_lengths[mask[i]];
mask.foreach_span_or_range([&](const auto mask_segment) {
for (const int64_t i : IndexRange(mask_segment.size())) {
const float length = sample_lengths[mask_segment[i]];
length_parameterize::sample_at_length(accumulated_lengths,
std::clamp(length, 0.0f, total_length),
r_segment_indices[i],

View File

@ -63,11 +63,11 @@ class MF_SeparateXYZ : public mf::MultiFunction {
}
devirtualize_varray(vectors, [&](auto vectors) {
mask.to_best_mask_type([&](auto mask) {
mask.foreach_span_or_range([&](const auto mask_segment) {
const int used_outputs_num = used_outputs.size();
const int *used_outputs_data = used_outputs.data();
for (const int64_t i : mask) {
for (const int64_t i : mask_segment) {
const float3 &vector = vectors[i];
for (const int out_i : IndexRange(used_outputs_num)) {
const int coordinate = used_outputs_data[out_i];