5#include "testing/testing.h"
14TEST(multi_function_procedure, ConstantOutput)
29 auto [var1] = builder.
add_call<1>(constant_fn);
30 auto [var2] = builder.
add_call<1>(add_fn, {var1, var1});
35 EXPECT_TRUE(procedure.validate());
46 executor.
call(
mask, params, context);
52TEST(multi_function_procedure, SimpleTest)
62 auto add_fn = mf::build::SI2_SO<int, int, int>(
"add", [](
int a,
int b) {
return a +
b; });
63 auto add_10_fn = mf::build::SM<int>(
"add_10", [](
int &a) { a += 10; });
70 auto [var3] = builder.
add_call<1>(add_fn, {var1, var2});
71 auto [var4] = builder.
add_call<1>(add_fn, {var2, var3});
77 EXPECT_TRUE(procedure.validate());
92 executor.
call(
mask, params, context);
99TEST(multi_function_procedure, BranchTest)
113 auto add_10_fn =
build::SM<int>(
"add_10", [](
int &a) { a += 10; });
114 auto add_100_fn =
build::SM<int>(
"add_100", [](
int &a) { a += 100; });
124 branch.branch_true.add_call(add_100_fn, {var1});
126 builder.
add_call(add_10_fn, {var1});
130 EXPECT_TRUE(procedure.validate());
137 Array<bool> values_cond = {
true,
false,
true,
true,
false};
143 procedure_fn.
call(
mask, params, context);
152TEST(multi_function_procedure, EvaluateOne)
160 int tot_evaluations = 0;
161 const auto add_10_fn = mf::build::SI1_SO<int, int>(
"add_10", [&](
int a) {
170 auto [var2] = builder.
add_call<1>(add_10_fn, {var1});
181 params.add_readonly_single_input_value(1);
185 procedure_fn.
call(
mask, params, context);
196TEST(multi_function_procedure, SimpleLoop)
215 auto greater_or_equal_fn = mf::build::SI2_SO<int, int, bool>(
216 "greater or equal", [](
int a,
int b) {
return a >=
b; });
217 auto double_fn =
build::SM<int>(
"double", [](
int &a) { a *= 2; });
218 auto add_1000_fn =
build::SM<int>(
"add 1000", [](
int &a) { a += 1000; });
225 auto [var_out] = builder.
add_call<1>(const_1_fn);
226 var_out->set_name(
"out");
227 auto [var_index] = builder.
add_call<1>(const_0_fn);
228 var_index->set_name(
"index");
231 auto [var_condition] = builder.
add_call<1>(greater_or_equal_fn, {var_index, var_count});
232 var_condition->set_name(
"condition");
238 builder.
add_call(double_fn, {var_out});
239 builder.
add_call(add_1_fn, {var_index});
242 builder.
add_call(add_1000_fn, {var_out});
247 EXPECT_TRUE(procedure.validate());
257 params.add_readonly_single_input(counts.
as_span());
261 procedure_fn.
call(
mask, params, context);
270TEST(multi_function_procedure, Vectors)
294 builder.
add_call(extend_fn, {var_v1, var_v2});
295 auto [var_constant] = builder.
add_call<1>(constant_5_fn);
296 builder.
add_call(append_fn, {var_v2, var_constant});
298 builder.
add_call(extend_fn, {var_v2, var_v1});
299 auto [var_len] = builder.
add_call<1>(sum_elements_fn, {var_v2});
300 auto [var_v3] = builder.
add_call<1>(create_range_fn, {var_len});
317 v2.append(0, &value_10);
318 v2.append(4, &value_10);
320 params.add_readonly_vector_input(v1.
as_span());
321 params.add_vector_mutable(
v2);
322 params.add_vector_output(v3);
325 procedure_fn.
call(
mask, params, context);
340TEST(multi_function_procedure, BufferReuse)
358 auto [var_b] = builder.
add_call<1>(add_10_fn, {var_a});
360 auto [var_c] = builder.
add_call<1>(add_10_fn, {var_b});
362 auto [var_d] = builder.
add_call<1>(add_10_fn, {var_c});
364 auto [var_e] = builder.
add_call<1>(add_10_fn, {var_d});
366 auto [var_out] = builder.
add_call<1>(add_10_fn, {var_e});
371 EXPECT_TRUE(procedure.validate());
386 procedure_fn.
call(
mask, params, context);
395TEST(multi_function_procedure, OutputBufferReplaced)
400 const int output_value = 42;
415 mf::ParamsBuilder params(procedure_fn, &
mask);
416 params.add_uninitialized_single_output(
output.as_mutable_span());
418 mf::ContextBuilder context;
419 procedure_fn.
call(
mask, params, context);
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
static const CPPType & get()
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
constexpr IndexRange()=default
static DataType ForVector(const CPPType &type)
static DataType ForSingle(const CPPType &type)
static ParamType ForMutableVector(const CPPType &base_type)
void add_single_mutable(GMutableSpan ref, StringRef expected_name="")
void add_uninitialized_single_output(T *value, StringRef expected_name="")
void add_readonly_single_input(const T *value, StringRef expected_name="")
void add_readonly_single_input_value(T value, StringRef expected_name="")
void add_output_parameter(Variable &variable)
void add_loop_continue(Loop &loop)
Variable & add_single_mutable_parameter(std::string name="")
ReturnInstruction & add_return()
void add_destruct(Variable &variable)
Variable & add_input_parameter(DataType data_type, std::string name="")
void add_loop_break(Loop &loop)
void set_cursor_after_loop(Loop &loop)
Vector< Variable * > add_call(const MultiFunction &fn, Span< Variable * > input_and_mutable_variables={})
Variable & add_single_input_parameter(std::string name="")
void add_parameter(ParamType::InterfaceType interface_type, Variable &variable)
Branch add_branch(Variable &condition)
CallInstruction & add_call_with_all_variables(const MultiFunction &fn, Span< Variable * > param_variables)
void set_cursor_after_branch(Branch &branch)
void call(const IndexMask &mask, Params params, Context context) const override
Variable & new_variable(DataType data_type, std::string name="")
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
auto SI1_SO(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 SI2_SO(const char *name, const ElementFn element_fn, const ExecPreset exec_preset=exec_presets::Materialized())
TEST(multi_function_procedure, ConstantOutput)
ProcedureBuilder branch_false
ProcedureBuilder branch_true