16 builder.
add(
"Parameter",
ParamType(param.type, param.variable->data_type()));
33constexpr int tot_variable_value_types = 6;
71 static constexpr ValueType
static_type = ValueType::GVVectorArray;
81 static constexpr ValueType
static_type = ValueType::GVectorArray;
93 static constexpr ValueType
static_type = ValueType::OneSingle;
108static_assert(std::is_trivially_destructible_v<VariableValue_GVArray>);
109static_assert(std::is_trivially_destructible_v<VariableValue_Span>);
110static_assert(std::is_trivially_destructible_v<VariableValue_GVVectorArray>);
111static_assert(std::is_trivially_destructible_v<VariableValue_GVectorArray>);
112static_assert(std::is_trivially_destructible_v<VariableValue_OneSingle>);
113static_assert(std::is_trivially_destructible_v<VariableValue_OneVector>);
127 static constexpr int min_alignment = 64;
136 std::array<Stack<VariableValue *>, tot_variable_value_types> variable_value_free_lists_;
146 static constexpr int small_value_max_size = 16;
147 static constexpr int small_value_max_alignment = 8;
156 return this->obtain<VariableValue_GVArray>(varray);
161 return this->obtain<VariableValue_GVVectorArray>(varray);
166 return this->obtain<VariableValue_Span>(buffer,
false);
171 void *buffer =
nullptr;
176 if (alignment > min_alignment) {
178 buffer = linear_allocator_.allocate(element_size *
size, alignment);
182 small_value_max_alignment) ?
183 &small_span_buffers_free_list_ :
184 span_buffers_free_lists_.lookup_ptr(element_size);
185 if (stack ==
nullptr || stack->
is_empty()) {
186 buffer = linear_allocator_.allocate(
187 std::max<int64_t>(element_size, small_value_max_size) *
size, min_alignment);
191 buffer = stack->
pop();
195 return this->obtain<VariableValue_Span>(buffer,
true);
200 return this->obtain<VariableValue_GVectorArray>(
data,
false);
206 return this->obtain<VariableValue_GVectorArray>(*vector_array,
true);
212 small_value_max_alignment);
213 Stack<void *> &stack = is_small ? small_single_value_free_list_ :
214 single_value_free_lists_.lookup_or_add_default(&type);
217 buffer = linear_allocator_.allocate(
218 std::max<int>(small_value_max_size, type.
size),
219 std::max<int>(small_value_max_alignment, type.
alignment));
222 buffer = stack.
pop();
224 return this->obtain<VariableValue_OneSingle>(buffer);
230 return this->obtain<VariableValue_OneVector>(*vector_array);
235 switch (value->
type) {
236 case ValueType::GVArray: {
239 case ValueType::Span: {
241 if (value_typed->owned) {
245 small_value_max_alignment) ?
246 small_span_buffers_free_list_ :
247 span_buffers_free_lists_.lookup_or_add_default(type.
size);
248 buffers.push(value_typed->data);
252 case ValueType::GVVectorArray: {
255 case ValueType::GVectorArray: {
257 if (value_typed->owned) {
258 delete &value_typed->data;
262 case ValueType::OneSingle: {
265 if (value_typed->is_initialized) {
269 small_value_max_alignment);
271 small_single_value_free_list_.push(value_typed->data);
274 single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data);
278 case ValueType::OneVector: {
280 delete &value_typed->
data;
290 template<
typename T,
typename... Args>
T *obtain(Args &&...args)
292 static_assert(std::is_base_of_v<VariableValue, T>);
295 void *buffer = linear_allocator_.
allocate(
sizeof(
T),
alignof(
T));
296 return new (buffer)
T(std::forward<Args>(args)...);
298 return new (stack.
pop())
T(std::forward<Args>(args)...);
328 case ValueType::GVArray:
330 case ValueType::Span:
332 case ValueType::GVVectorArray:
334 case ValueType::GVectorArray:
336 case ValueType::OneSingle:
338 case ValueType::OneVector:
363 case ValueType::GVArray: {
367 case ValueType::Span: {
370 params.add_readonly_single_input(span);
373 case ValueType::GVVectorArray: {
377 case ValueType::GVectorArray: {
381 case ValueType::OneSingle: {
385 params.add_readonly_single_input(gpointer);
388 case ValueType::OneVector: {
399 if (
value_ !=
nullptr &&
ELEM(
value_->type, ValueType::Span, ValueType::GVectorArray)) {
410 new_value = value_allocator.
obtain_Span(type, array_size);
417 if (
value_->type == ValueType::GVArray) {
420 full_mask, new_value->
data);
422 else if (
value_->type == ValueType::OneSingle) {
424 if (old_value_typed_->is_initialized) {
448 if (
value_->type == ValueType::GVVectorArray) {
452 else if (
value_->type == ValueType::OneVector) {
481 case ValueType::Span: {
484 params.add_single_mutable(span);
487 case ValueType::GVectorArray: {
491 case ValueType::GVArray:
492 case ValueType::GVVectorArray:
493 case ValueType::OneSingle:
494 case ValueType::OneVector: {
513 case ValueType::Span: {
516 params.add_uninitialized_single_output(span);
519 case ValueType::GVectorArray: {
523 case ValueType::GVArray:
524 case ValueType::GVVectorArray:
525 case ValueType::OneSingle:
526 case ValueType::OneVector: {
541 case ValueType::GVArray: {
545 case ValueType::GVVectorArray: {
549 case ValueType::OneSingle: {
556 case ValueType::OneVector: {
560 case ValueType::Span:
561 case ValueType::GVectorArray: {
571 if (value_ !=
nullptr &&
ELEM(
value_->type, ValueType::OneSingle, ValueType::OneVector)) {
580 if (
value_->type == ValueType::GVArray) {
585 else if (
value_->type == ValueType::Span) {
601 if (
value_->type == ValueType::GVVectorArray) {
606 else if (
value_->type == ValueType::GVectorArray) {
630 case ValueType::OneSingle: {
636 case ValueType::OneVector: {
640 case ValueType::GVArray:
641 case ValueType::Span:
642 case ValueType::GVVectorArray:
643 case ValueType::GVectorArray: {
660 case ValueType::OneSingle: {
663 params.add_uninitialized_single_output(
666 value_typed->is_initialized =
true;
669 case ValueType::OneVector: {
672 params.add_vector_output(value_typed->data);
675 case ValueType::GVArray:
676 case ValueType::Span:
677 case ValueType::GVVectorArray:
678 case ValueType::GVectorArray: {
704 case ValueType::GVArray: {
705 if (
mask.size() < full_mask.
size()) {
715 case ValueType::Span: {
720 case ValueType::GVVectorArray: {
721 if (
mask.size() < full_mask.
size()) {
731 case ValueType::GVectorArray: {
735 case ValueType::OneSingle: {
742 value_typed->is_initialized =
false;
746 case ValueType::OneVector: {
757 const bool should_self_destruct = new_tot_initialized == 0 &&
759 return should_self_destruct;
768 case ValueType::GVArray: {
773 case ValueType::Span: {
776 mask.min_array_size());
777 mask.foreach_index([&](
const int64_t i) { r_indices[span[
i]].append(
i); });
780 case ValueType::OneSingle: {
783 const bool condition = *
static_cast<const bool *
>(value_typed->data);
789 case ValueType::GVVectorArray:
790 case ValueType::GVectorArray:
791 case ValueType::OneVector: {
802 return static_cast<T *
>(
value_);
809 return static_cast<T *
>(
value_);
827 procedure_(procedure),
828 variable_states_(procedure.variables().
size()),
835 for (
const int variable_i : procedure_.variables().index_range()) {
837 if (
state.value_ !=
nullptr) {
838 const Variable *variable = procedure_.variables()[variable_i];
846 return value_allocator_;
858 for (
const int param_index :
fn.param_indices()) {
860 const Variable *variable = procedure.
params()[param_index].variable;
863 bool input_is_initialized,
864 void *caller_provided_storage =
nullptr) {
865 const int tot_initialized = input_is_initialized ? full_mask_.size() : 0;
867 VariableState &variable_state = variable_states_[variable_i];
869 variable_state.
value_ = value;
877 add_state(value_allocator_.obtain_GVArray(
data),
true);
882 add_state(value_allocator_.obtain_GVVectorArray(
data),
true);
887 add_state(value_allocator_.obtain_Span_not_owned(
data.data()),
false,
data.data());
892 add_state(value_allocator_.obtain_GVectorArray_not_owned(
data),
false, &
data);
897 add_state(value_allocator_.obtain_Span_not_owned(
data.data()),
true,
data.data());
902 add_state(value_allocator_.obtain_GVectorArray_not_owned(
data),
true, &
data);
964 VariableState &variable_state = variable_states_[variable_i];
965 return variable_state;
973 if (
mask.size() < full_mask.
size()) {
977 if (
state !=
nullptr &&
state->value_ !=
nullptr && !
state->is_one()) {
989 for (
const int param_index :
fn.param_indices()) {
991 if (variable ==
nullptr) {
992 r_param_variable_states[param_index] =
nullptr;
996 r_param_variable_states[param_index] = &variable_state;
1007 for (
const int param_index :
fn.param_indices()) {
1008 const ParamType param_type =
fn.param_type(param_index);
1009 VariableState *variable_state = param_variable_states[param_index];
1010 if (variable_state ==
nullptr) {
1011 params.add_ignored_single_output();
1025 for (
const int param_index :
fn.param_indices()) {
1026 const ParamType param_type =
fn.param_type(param_index);
1027 VariableState *variable_state = param_variable_states[param_index];
1028 if (variable_state ==
nullptr) {
1029 params.add_ignored_single_output();
1045 param_variable_states.
resize(
fn.param_amount());
1056 fn.call(one_mask,
params, context);
1084 return this->referenced_indices;
1095 return this->indices.
mask();
1098 operator bool()
const
1100 return this->instruction !=
nullptr;
1117 if (
mask.is_empty()) {
1122 next_instructions_.push({&instruction, std::move(new_indices)});
1132 new_indices.
memory = std::make_unique<IndexMaskMemory>();
1135 next_instructions_.push({&instruction, std::move(new_indices)});
1140 return next_instructions_.is_empty();
1146 return next_instructions_.
peek();
1151 next_instructions_.peek().instruction = &instruction;
1156 return next_instructions_.pop();
1175 while (!scheduler.
is_done()) {
1178 switch (instruction.
type()) {
1203 variable_states.
destruct(*variable, instr_info.
mask());
1223 const Variable *variable = procedure_.params()[param_index].variable;
#define BLI_assert_unreachable()
#define UNUSED_VARS_NDEBUG(...)
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void fill_construct_indices(const void *value, void *dst, const IndexMask &mask) const
void destruct_indices(void *ptr, const IndexMask &mask) const
void destruct(void *ptr) const
bool can_exist_in_buffer(const int64_t buffer_size, const int64_t buffer_alignment) const
void extend(int64_t index, const GVArray &values)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
void * allocate(const int64_t size, const int64_t alignment)
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
void push(const T &value)
void resize(const int64_t new_size)
Instruction * branch_false()
Instruction * branch_true()
Span< Variable * > params()
const MultiFunction & fn() const
const CPPType & vector_base_type() const
Category category() const
const CPPType & single_type() const
NextInstructionInfo pop()
const NextInstructionInfo & peek() const
void add_referenced_indices(const Instruction &instruction, const IndexMask &mask)
void add_owned_indices(const Instruction &instruction, Vector< int64_t > indices)
void update_instruction_pointer(const Instruction &instruction)
InstructionScheduler()=default
InstructionType type() const
void set_signature(const Signature *signature)
ParamType param_type(int param_index) const
IndexRange param_indices() const
virtual ExecutionHints get_execution_hints() const
const DataType & data_type() const
InterfaceType interface_type() const
ParamCategory category() const
void call(const IndexMask &mask, Params params, Context context) const override
ProcedureExecutor(const Procedure &procedure)
Span< ConstParameter > params() const
void add(ParamTag< Category, T >, const char *name)
VariableValue_GVectorArray * obtain_GVectorArray(const CPPType &type, int size)
VariableValue_GVectorArray * obtain_GVectorArray_not_owned(GVectorArray &data)
ValueAllocator(LinearAllocator<> &linear_allocator)
void release_value(VariableValue *value, const DataType &data_type)
VariableValue_OneSingle * obtain_OneSingle(const CPPType &type)
VariableValue_GVArray * obtain_GVArray(const GVArray &varray)
VariableValue_Span * obtain_Span(const CPPType &type, int size)
VariableValue_Span * obtain_Span_not_owned(void *buffer)
VariableValue_GVVectorArray * obtain_GVVectorArray(const GVVectorArray &varray)
VariableValue_OneVector * obtain_OneVector(const CPPType &type)
bool is_fully_initialized(const IndexMask &full_mask)
void indices_split(const IndexMask &mask, IndicesSplitVectors &r_indices)
void destruct_value(ValueAllocator &value_allocator, const DataType &data_type)
void ensure_is_mutable(const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
const T * value_as() const
void * caller_provided_storage_
void add_as_mutable(ParamsBuilder ¶ms, const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
void add_as_output(ParamsBuilder ¶ms, const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
void add_as_input__one(ParamsBuilder ¶ms, const DataType &data_type) const
void ensure_is_mutable__one(const DataType &data_type, ValueAllocator &value_allocator)
void add_as_input(ParamsBuilder ¶ms, const IndexMask &mask, const DataType &data_type) const
void add_as_output__one(ParamsBuilder ¶ms, const IndexMask &mask, const DataType &data_type, ValueAllocator &value_allocator)
bool destruct(const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
bool is_fully_uninitialized(const IndexMask &full_mask)
void add_as_mutable__one(ParamsBuilder ¶ms, const DataType &data_type, ValueAllocator &value_allocator)
VariableState & get_variable_state(const Variable &variable)
const IndexMask & full_mask() const
void destruct(const Variable &variable, const IndexMask &mask)
void add_initial_variable_states(const ProcedureExecutor &fn, const Procedure &procedure, Params ¶ms)
void add_as_param__one(VariableState &variable_state, ParamsBuilder ¶ms, const ParamType ¶m_type, const IndexMask &mask)
void add_as_param(VariableState &variable_state, ParamsBuilder ¶ms, const ParamType ¶m_type, const IndexMask &mask)
VariableStates(LinearAllocator<> &linear_allocator, const Procedure &procedure, const IndexMask &full_mask)
ValueAllocator & value_allocator()
int index_in_procedure() const
DataType data_type() const
int64_t min_array_size() const
void foreach_index(Fn &&fn) const
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
MultiFunction::ExecutionHints ExecutionHints
static bool evaluate_as_one(Span< VariableState * > param_variable_states, const IndexMask &mask, const IndexMask &full_mask)
static void gather_parameter_variable_states(const MultiFunction &fn, const CallInstruction &instruction, VariableStates &variable_states, MutableSpan< VariableState * > r_param_variable_states)
static void fill_params(const MultiFunction &fn, const IndexMask &mask, ParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
static void execute_call_instruction(const CallInstruction &instruction, const IndexMask &mask, VariableStates &variable_states, const Context &context)
static void fill_params__one(const MultiFunction &fn, const IndexMask &mask, ParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
std::array< Vector< int64_t >, 2 > IndicesSplitVectors
const IndexMask & mask() const
IndexMask referenced_indices
std::unique_ptr< IndexMaskMemory > memory
InstructionIndices indices
const Instruction * instruction
const IndexMask & mask() const
static constexpr ValueType static_type
VariableValue_GVArray(const GVArray &data)
const GVVectorArray & data
static constexpr ValueType static_type
VariableValue_GVVectorArray(const GVVectorArray &data)
static constexpr ValueType static_type
VariableValue_GVectorArray(GVectorArray &data, bool owned)
static constexpr ValueType static_type
VariableValue_OneSingle(void *data)
VariableValue_OneVector(GVectorArray &data)
static constexpr ValueType static_type
static constexpr ValueType static_type
VariableValue_Span(void *data, bool owned)
VariableValue(ValueType type)