62 template<
typename... ParamTags,
typename... LoadedParams,
size_t...
I>
64 std::index_sequence<I...> ,
65 const std::tuple<LoadedParams...> &loaded_params)
const
67 return std::make_tuple([&]() {
71 const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
78 T *
ptr = std::get<I>(loaded_params);
94 template<
typename... ParamTags,
typename... LoadedParams,
size_t...
I>
96 std::index_sequence<I...> ,
97 const std::tuple<LoadedParams...> &loaded_params)
const
99 return std::make_tuple([&]() {
104 constexpr bool UseSpan =
ValueSequence<size_t, Indices...>::template contains<I>();
105 const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
112 T *
ptr = std::get<I>(loaded_params);
128template<
typename MaskT,
typename... Args,
typename... ParamTags,
size_t...
I,
typename ElementFn>
131#if (defined(__GNUC__) && !defined(__clang__))
132[[gnu::optimize(
"-funroll-loops")]] [[gnu::optimize(
"O3")]]
135 std::index_sequence<I...> ,
136 ElementFn element_fn,
140 Args &&__restrict... args)
142 if constexpr (std::is_same_v<std::decay_t<MaskT>,
IndexRange>) {
147 element_fn(args[
i]...);
152 element_fn(args[
i]...);
172template<
typename... ParamTags,
typename ElementFn,
typename... Chunks>
173#if (defined(__GNUC__) && !defined(__clang__))
174[[gnu::optimize(
"-funroll-loops")]] [[gnu::optimize(
"O3")]]
177 const ElementFn element_fn,
179 Chunks &&__restrict... chunks)
182 element_fn(chunks[
i]...);
191template<
typename... ParamTags,
size_t...
I,
typename ElementFn,
typename... LoadedParams>
193 std::index_sequence<I...> ,
194 const ElementFn element_fn,
196 const std::tuple<LoadedParams...> &loaded_params)
203 static constexpr int64_t MaxChunkSize = 64;
205 const int64_t tmp_buffer_size = std::min(mask_size, MaxChunkSize);
208 std::tuple<TypedBuffer<typename ParamTags::base_type, MaxChunkSize>...> temporary_buffers;
211 std::tuple<MaterializeArgInfo<ParamTags>...> args_info;
221 const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
226 const T &in_single = *
static_cast<const T *
>(common_info.
data);
227 T *tmp_buffer = std::get<I>(temporary_buffers).ptr();
246 for (
int64_t chunk_start = 0; chunk_start < mask_size; chunk_start += MaxChunkSize) {
247 const int64_t chunk_end = std::min<int64_t>(chunk_start + MaxChunkSize, mask_size);
248 const int64_t chunk_size = chunk_end - chunk_start;
250 const int64_t mask_start = sliced_mask[0];
255 if (!sliced_mask_is_range) {
262 T *tmp_buffer = std::get<I>(temporary_buffers).ptr();
263 T *param_buffer = std::get<I>(loaded_params);
265 new (tmp_buffer +
i)
T(std::move(param_buffer[sliced_mask[
i]]));
272 const IndexMask *current_segment_mask =
nullptr;
283 T *tmp_buffer = std::get<I>(temporary_buffers);
287 return const_cast<const T *
>(tmp_buffer);
295 const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
296 if (current_segment_mask ==
nullptr) {
297 current_segment_mask = &index_mask_from_segment.
update(
298 {segment_offset, sliced_mask.
base_span()});
306 return const_cast<const T *
>(tmp_buffer);
313 if (sliced_mask_is_range) {
315 T *param_buffer = std::get<I>(loaded_params);
316 return param_buffer + mask_start;
325 if (!sliced_mask_is_range) {
335 T *tmp_buffer = std::get<I>(temporary_buffers).ptr();
336 T *param_buffer = std::get<I>(loaded_params);
338 new (param_buffer + sliced_mask[
i])
T(std::move(tmp_buffer[
i]));
339 std::destroy_at(tmp_buffer +
i);
355 T *tmp_buffer = std::get<I>(temporary_buffers).ptr();
372 T *tmp_buffer = std::get<I>(temporary_buffers).ptr();
380template<
typename ElementFn,
typename ExecPreset,
typename... ParamTags,
size_t...
I>
382 const ExecPreset exec_preset,
386 std::index_sequence<I...> )
391 const auto loaded_params = std::make_tuple([&]() {
397 return params.readonly_single_input(
I).get_implementation();
400 return static_cast<T *
>(
params.uninitialized_single_output(
I).
data());
403 return static_cast<T *
>(
params.single_mutable(
I).
data());
408 bool executed_devirtualized =
false;
409 if constexpr (ExecPreset::use_devirtualization) {
412 mask.to_spans_and_ranges<16>();
414 const auto devirtualizers = exec_preset.create_devirtualizers(
417 devirtualizers, [&](
auto &&...args) {
418 for (
const std::variant<IndexRange, IndexMaskSegment> &segment : mask_segments) {
419 if (std::holds_alternative<IndexRange>(segment)) {
420 const auto segment_range = std::get<IndexRange>(segment);
422 std::index_sequence<I...>(),
425 std::forward<
decltype(args)>(args)...);
428 const auto segment_indices = std::get<IndexMaskSegment>(segment);
430 std::index_sequence<I...>(),
433 std::forward<
decltype(args)>(args)...);
444 if (!executed_devirtualized) {
450 std::index_sequence<I...>(),
465 const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
472 T *
ptr = std::get<I>(loaded_params);
487template<
typename ElementFn,
typename ExecPreset,
typename... ParamTags>
489 const ExecPreset exec_preset,
498 std::make_index_sequence<
sizeof...(ParamTags)>());
512 : call_fn_(std::move(call_fn))
516 ([&] { builder.
add(ParamTags(),
""); }(), ...);
526template<
typename Out,
typename... In,
typename ElementFn,
typename ExecPreset>
528 const ElementFn element_fn,
529 const ExecPreset exec_preset,
535 [element_fn](
const In &...
in, Out &
out) {
new (&
out) Out(element_fn(
in...)); },
541template<
typename Out1,
typename Out2,
typename... In,
typename ElementFn,
typename ExecPreset>
543 const ElementFn element_fn,
544 const ExecPreset exec_preset,
557template<
typename In1,
562 const ElementFn element_fn,
570template<
typename In1,
576 const ElementFn element_fn,
584template<
typename In1,
591 const ElementFn element_fn,
599template<
typename In1,
607 const ElementFn element_fn,
615template<
typename In1,
624 const ElementFn element_fn,
632template<
typename In1,
642 const ElementFn element_fn,
650template<
typename In1,
662 const ElementFn element_fn,
666 name, element_fn, exec_preset,
TypeSequence<In1, In2, In3, In4, In5, In6, In7, In8>());
670template<
typename Mut1,
typename ElementFn,
typename ExecPreset = exec_presets::AllSpanOrSingle>
672 const ElementFn element_fn,
677 element_fn, exec_preset, param_tags);
682template<
typename In1,
688 const ElementFn element_fn,
696template<
typename In1,
703 const ElementFn element_fn,
711template<
typename In1,
719 const ElementFn element_fn,
727template<
typename In1,
736 const ElementFn element_fn,
744template<
typename In1,
754 const ElementFn element_fn,
762template<
typename In1,
769 const ElementFn element_fn,
777 element_fn, exec_preset, param_tags);
782template<
typename In1,
790 const ElementFn element_fn,
799 element_fn, exec_preset, param_tags);
873 if (other1 !=
nullptr) {
874 return value_ == other1->value_;
878 if (other2 !=
nullptr) {
880 if (type == other2->type_) {
881 return type.
is_equal_or_false(
static_cast<const void *
>(&value_), other2->value_);
BMesh const char void * data
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static const CPPType & get()
bool is_equal_or_false(const void *a, const void *b) const
virtual void materialize_compressed(const IndexMask &mask, void *dst, bool dst_is_uninitialized) const
virtual CommonVArrayInfo common_info() const
VArray< T > typed() const
Span< BaseT > base_span() const
CustomMF_Constant(U &&value)
bool equals(const MultiFunction &other) const override
uint64_t hash() const override
void call(const IndexMask &mask, Params params, Context) const override
CustomMF_DefaultOutput(Span< DataType > input_types, Span< DataType > output_types)
void call(const IndexMask &mask, Params params, Context context) const override
void call(const IndexMask &mask, Params params, Context context) const override
CustomMF_GenericConstantArray(GSpan array)
CustomMF_GenericConstant(const CPPType &type, const void *value, bool make_value_copy)
uint64_t hash() const override
~CustomMF_GenericConstant() override
bool equals(const MultiFunction &other) const override
friend class CustomMF_Constant
void call(const IndexMask &mask, Params params, Context context) const override
CustomMF_GenericCopy(DataType data_type)
void call(const IndexMask &mask, Params params, Context context) const override
StringRefNull name() const
void set_signature(const Signature *signature)
void add(ParamTag< Category, T >, const char *name)
void single_output(const char *name, const ParamFlag flag=ParamFlag::None)
CustomMF(const char *name, CallFn call_fn, TypeSequence< ParamTags... >)
void call(const IndexMask &mask, Params params, Context) const override
const IndexMask & update(IndexMaskSegment segment)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
auto build_multi_function_with_n_inputs_two_outputs(const char *name, const ElementFn element_fn, const ExecPreset exec_preset, TypeSequence< In... >)
auto build_multi_function_with_n_inputs_one_output(const char *name, const ElementFn element_fn, const ExecPreset exec_preset, TypeSequence< In... >)
void execute_element_fn_as_multi_function(const ElementFn element_fn, const ExecPreset exec_preset, const IndexMask &mask, Params params, TypeSequence< ParamTags... >, std::index_sequence< I... >)
auto build_multi_function_call_from_element_fn(const ElementFn element_fn, const ExecPreset exec_preset, TypeSequence< ParamTags... >)
void execute_array(TypeSequence< ParamTags... >, std::index_sequence< I... >, ElementFn element_fn, MaskT mask, Args &&__restrict... args)
void execute_materialized_impl(TypeSequence< ParamTags... >, const ElementFn element_fn, const int64_t size, Chunks &&__restrict... chunks)
void execute_materialized(TypeSequence< ParamTags... >, std::index_sequence< I... >, const ElementFn element_fn, const IndexMaskSegment mask, const std::tuple< LoadedParams... > &loaded_params)
auto SI1_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI3_SO2(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI5_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI4_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI1_SO2(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SM(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::AllSpanOrSingle())
auto SI3_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI4_SO2(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI2_SO2(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI1_SO3(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI1_SO4(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI6_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI2_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI5_SO2(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
auto SI8_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
bool non_empty_is_range(const Span< T > indices)
uint64_t get_default_hash(const T &v, const Args &...args)
bool call_with_devirtualized_parameters(const std::tuple< Devirtualizers... > &devis, const Fn &fn)
void uninitialized_fill_n(T *dst, int64_t n, const T &value)
void destruct_n(T *ptr, int64_t n)
static constexpr ParamCategory category
const ParamTag::base_type * internal_span_data
static constexpr FallbackMode fallback_mode
auto create_devirtualizers(TypeSequence< ParamTags... >, std::index_sequence< I... >, const std::tuple< LoadedParams... > &loaded_params) const
static constexpr bool use_devirtualization
static constexpr FallbackMode fallback_mode
static constexpr bool use_devirtualization
static constexpr bool use_devirtualization
static constexpr FallbackMode fallback_mode
auto create_devirtualizers(TypeSequence< ParamTags... >, std::index_sequence< I... >, const std::tuple< LoadedParams... > &loaded_params) const
static constexpr FallbackMode fallback_mode
static constexpr bool use_devirtualization