From ec710550781362f28d4279b8eeba1d8a00337854 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 3 Aug 2024 19:51:38 -0400 Subject: [PATCH] hopefully fix evaluation order --- CMakeLists.txt | 2 +- include/blt/gp/operations.h | 8 +++-- include/blt/gp/program.h | 32 +++++++----------- include/blt/gp/stack.h | 3 ++ include/blt/gp/typesystem.h | 1 - lib/blt | 2 +- src/tree.cpp | 3 ++ tests/evaluation_tests.cpp | 66 ++++++++++++++++++++++++++++++++----- tests/stack_tests.cpp | 61 ++++++++++++++++++++-------------- 9 files changed, 119 insertions(+), 59 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53b3ef3..6930724 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.110) +project(blt-gp VERSION 0.0.111) include(CTest) diff --git a/include/blt/gp/operations.h b/include/blt/gp/operations.h index b7e1106..c52451f 100644 --- a/include/blt/gp/operations.h +++ b/include/blt/gp/operations.h @@ -78,7 +78,8 @@ namespace blt::gp { blt::size_t offset = 0; blt::size_t current_index = 0; - ((offset += (current_index++ > index ? stack_allocator::aligned_size>() : 0)), ...); + ((offset += (current_index++ < index ? stack_allocator::aligned_size>() : 0)), ...); + //BLT_INFO("offset %ld for index %ld", offset, index); return offset; } @@ -86,6 +87,8 @@ namespace blt::gp inline static constexpr Return exec_sequence_to_indices(Func&& func, stack_allocator& allocator, std::integer_sequence, ExtraArgs&& ... args) { + //blt::size_t arg_size = (stack_allocator::aligned_size>() + ...); + //BLT_TRACE(arg_size); // expands Args and indices, providing each argument with its index calculating the current argument byte offset return std::forward(func)(std::forward(args)..., allocator.from>(getByteOffset())...); @@ -173,7 +176,8 @@ namespace blt::gp { return name; } - + + operator_id id = -1; private: function_t func; std::optional name; diff --git a/include/blt/gp/program.h b/include/blt/gp/program.h index 377b0ef..7759238 100644 --- a/include/blt/gp/program.h +++ b/include/blt/gp/program.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -105,10 +106,11 @@ namespace blt::gp {} template - operator_builder& add_operator(const operation_t& op, bool is_static = false) + operator_builder& add_operator(operation_t& op, bool is_static = false) { auto return_type_id = system.get_type().id(); auto operator_id = blt::gp::operator_id(storage.operators.size()); + op.id = operator_id; operator_info info; @@ -128,27 +130,15 @@ namespace blt::gp BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!"); info.function = op.template make_callable(); -// info.transfer = [](std::optional> to, stack_allocator& from) { -//#if BLT_DEBUG_LEVEL >= 3 -// auto value = from.pop(); -// //BLT_TRACE_STREAM << value << "\n"; -// if (to){ -// to->get().push(value); -// } -//#else -// if (to) -// { -// to->get().push(from.pop()); -// } else -// { -// from.pop(); -// } -//#endif -// -// }; + storage.operators.push_back(info); - storage.print_funcs.push_back([](std::ostream& out, stack_allocator& stack) { - out << stack.pop(); + storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) { + if constexpr (blt::meta::is_streamable_v) { + out << stack.pop(); + (void)(op); // remove warning + } else { + out << "[Printing Value on '" << (op.get_name() ? *op.get_name() : "") << "' Not Supported!]"; + } }); storage.names.push_back(op.get_name()); if (is_static) diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index a0ed959..667691c 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -151,8 +151,11 @@ namespace blt::gp if (blk == nullptr) throw std::runtime_error("Some nonsense is going on. This function already smells"); if (blk->used_bytes_in_block() < static_cast(TYPE_SIZE)) + { + BLT_WARN_STREAM << size() << "\n"; throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( blk->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(NO_REF_T))).c_str()); + } return *reinterpret_cast(blk->metadata.offset - remaining_bytes); } diff --git a/include/blt/gp/typesystem.h b/include/blt/gp/typesystem.h index b549fa0..5a7f974 100644 --- a/include/blt/gp/typesystem.h +++ b/include/blt/gp/typesystem.h @@ -26,7 +26,6 @@ #include #include #include -#include #include namespace blt::gp diff --git a/lib/blt b/lib/blt index fb17ff1..befd5e0 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit fb17ff16c0e10193454921af0d27d1f5afd4ddd6 +Subproject commit befd5e0ca1135c467f194d1d0e5691d301f93a34 diff --git a/src/tree.cpp b/src/tree.cpp index 90c5a14..d1e7672 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -56,9 +56,12 @@ namespace blt::gp operations_stack.pop_back(); if (operation.is_value) { + //BLT_DEBUG("Processed Value %ld with size %ld", operation.id, stack_allocator::aligned_size(operation.type_size)); value_stack.transfer_bytes(values_process, operation.type_size); continue; } + //BLT_DEBUG("Processed function %ld with size %ld", operation.id, stack_allocator::aligned_size(operation.type_size)); + //BLT_TRACE("Stack info: %ld %ld", values_process.size().total_used_bytes, value_stack.size().total_used_bytes); operation.func(context, values_process, value_stack); operations_stack.emplace_back(empty_callable, operation.type_size, operation.id, true); } diff --git a/tests/evaluation_tests.cpp b/tests/evaluation_tests.cpp index 32bbedf..78bd155 100644 --- a/tests/evaluation_tests.cpp +++ b/tests/evaluation_tests.cpp @@ -50,6 +50,8 @@ struct large_18290 blt::u8 data[18290]; }; +large_18290 base{}; + blt::gp::type_provider type_system; blt::gp::gp_program program{type_system, SEED}; @@ -65,14 +67,29 @@ blt::gp::op_container_t make_value(const blt::gp::type& id) return {empty, id.size(), 0, true}; } -blt::gp::operation_t basic_2([](float a, float b) { +blt::gp::operation_t add([](float a, float b) { return a + b; }); +blt::gp::operation_t sub([](float a, float b) { + return a - b; +}); + blt::gp::operation_t basic_2t([](float a, bool b) { return b ? a : 0.0f; }); +blt::gp::operation_t cross_large_type([](const large_18290& input, const float a, const float b) { + BLT_TRACE("%f, %f", a, b); + large_18290 output{}; + for (const auto& [index, ref] : blt::enumerate(input.data)) + { + if (ref > static_cast(a) && ref < static_cast(b)) + output.data[index] = ref; + } + return output; +}); + blt::gp::operation_t f_literal([]() { return 0.0f; }); @@ -81,35 +98,68 @@ blt::gp::operation_t b_literal([]() { return false; }); +blt::gp::operation_t large_literal([]() { + return base; +}); + void basic_tree() { BLT_INFO("Testing if we can get a basic tree going."); blt::gp::tree_t tree; - tree.get_operations().push_back(make_container(2)); + tree.get_operations().push_back(make_container(sub.id)); tree.get_operations().push_back(make_value(type_system.get_type())); tree.get_operations().push_back(make_value(type_system.get_type())); - tree.get_values().push(50.0f); tree.get_values().push(120.0f); + tree.get_values().push(50.0f); auto val = tree.get_evaluation_value(nullptr); BLT_TRACE(val); - BLT_ASSERT(val == (50 + 120)); + BLT_ASSERT(val == (120 - 50)); +} + +void large_cross_type_tree() +{ + blt::gp::tree_t tree; + auto& ops = tree.get_operations(); + auto& vals = tree.get_values(); + + ops.push_back(make_container(cross_large_type.id)); + ops.push_back(make_container(large_literal.id)); + ops.push_back(make_container(sub.id)); + ops.push_back(make_value(type_system.get_type())); + ops.push_back(make_value(type_system.get_type())); + ops.push_back(make_value(type_system.get_type())); + + vals.push(50.0f); + vals.push(120.0f); + vals.push(5555.0f); + + auto val = tree.get_evaluation_value(nullptr); + blt::black_box(val); } int main() { + for (auto& v : base.data) + v = static_cast(blt::random::murmur_random64c(691, std::numeric_limits::min(), std::numeric_limits::max())); + type_system.register_type(); type_system.register_type(); + type_system.register_type(); blt::gp::operator_builder builder{type_system}; - builder.add_operator(f_literal); // 0 - builder.add_operator(b_literal); // 1 - builder.add_operator(basic_2); // 2 - builder.add_operator(basic_2t); // 3 + builder.add_operator(f_literal); // 0 + builder.add_operator(b_literal); // 1 + builder.add_operator(add); // 2 + builder.add_operator(basic_2t); // 3 + builder.add_operator(sub); // 4 + builder.add_operator(large_literal); // 5 + builder.add_operator(cross_large_type); // 6 program.set_operations(builder.build()); basic_tree(); + large_cross_type_tree(); } \ No newline at end of file diff --git a/tests/stack_tests.cpp b/tests/stack_tests.cpp index f4a1673..d931826 100644 --- a/tests/stack_tests.cpp +++ b/tests/stack_tests.cpp @@ -33,7 +33,7 @@ struct log_box ~log_box() { - for (auto& c : text) + for (auto& _ : text) logger << '-'; logger << '\n'; } @@ -51,9 +51,18 @@ T make_data(T t, Func&& func) return t; } +template +static inline auto constexpr array_size(const T(Class::*)[size]) +{ + return size; +} + template blt::ptrdiff_t compare(const T& t, const U& u) { + constexpr auto ts = array_size(&T::data); + constexpr auto us = array_size(&U::data); + BLT_ASSERT_MSG(ts == us, ("Array sizes don't match! " + std::to_string(ts) + " vs " + std::to_string(us)).c_str()); for (const auto& [index, v] : blt::enumerate(t.data)) { if (u.data[index] != v) @@ -289,8 +298,8 @@ void test_basic() BLT_INFO("Testing basic with stack"); { blt::gp::stack_allocator stack; - stack.push(50.0f); stack.push(10.0f); + stack.push(50.0f); BLT_TRACE_STREAM << stack.size() << "\n"; basic_2.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; @@ -303,8 +312,8 @@ void test_basic() { blt::gp::stack_allocator stack; stack.push(std::array{}); - stack.push(50.0f); stack.push(10.0f); + stack.push(50.0f); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!"); @@ -323,10 +332,11 @@ void test_mixed() BLT_INFO("Testing mixed with stack"); { blt::gp::stack_allocator stack; - stack.push(50.0f); - stack.push(10.0f); - stack.push(true); stack.push(false); + stack.push(true); + stack.push(10.0f); + stack.push(50.0f); + BLT_TRACE_STREAM << stack.size() << "\n"; basic_mixed_4.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; @@ -339,10 +349,10 @@ void test_mixed() { blt::gp::stack_allocator stack; stack.push(std::array{}); - stack.push(50.0f); - stack.push(10.0f); - stack.push(true); stack.push(false); + stack.push(true); + stack.push(10.0f); + stack.push(50.0f); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!"); @@ -361,9 +371,10 @@ void test_large_256() BLT_INFO("Testing large 256 with stack"); { blt::gp::stack_allocator stack; - stack.push(base_256); - stack.push(691.0f); stack.push(69.420f); + stack.push(691.0f); + stack.push(base_256); + BLT_TRACE_STREAM << stack.size() << "\n"; large_256_basic_3.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; @@ -376,9 +387,9 @@ void test_large_256() { blt::gp::stack_allocator stack; stack.push(std::array{}); - stack.push(base_256); - stack.push(691.0f); stack.push(69.420f); + stack.push(691.0f); + stack.push(base_256); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!"); @@ -397,9 +408,9 @@ void test_large_4096() BLT_INFO("Testing large 4096 with stack"); { blt::gp::stack_allocator stack; - stack.push(base_4096); - stack.push(33.0f); stack.push(true); + stack.push(33.0f); + stack.push(base_4096); BLT_TRACE_STREAM << stack.size() << "\n"; large_4096_basic_3b.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; @@ -411,16 +422,16 @@ void test_large_4096() BLT_INFO("Testing large 4096 with stack over boundary"); { blt::gp::stack_allocator stack; - stack.push(base_4096); - stack.push(33.0f); stack.push(true); + stack.push(33.0f); + stack.push(base_4096); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!"); large_4096_basic_3b.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; auto val = stack.pop(); - RUN_TEST(!compare(val, base_256), stack, "Large 4096 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val); + RUN_TEST(!compare(val, base_4096), stack, "Large 4096 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val); BLT_TRACE_STREAM << stack.size() << "\n"; BLT_ASSERT(stack.empty() && "Stack was not empty after evaluation over stack boundary"); } @@ -431,9 +442,9 @@ void test_large_18290() BLT_INFO("Testing large 18290 with stack"); { blt::gp::stack_allocator stack; - stack.push(base_18290); - stack.push(-2543.0f); stack.push(true); + stack.push(-2543.0f); + stack.push(base_18290); BLT_TRACE_STREAM << stack.size() << "\n"; large_18290_basic_3b.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; @@ -446,9 +457,9 @@ void test_large_18290() { blt::gp::stack_allocator stack; stack.push(std::array()); - stack.push(base_18290); - stack.push(-2543.0f); stack.push(true); + stack.push(-2543.0f); + stack.push(base_18290); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!"); @@ -463,15 +474,15 @@ void test_large_18290() BLT_INFO("Testing large 18290 with stack over multiple boundaries"); { blt::gp::stack_allocator stack; - stack.push(base_18290); + stack.push(true); stack.push(-2543.0f); stack.push(true); + stack.push(-2543.0f); + stack.push(base_18290); auto size = stack.size(); BLT_TRACE_STREAM << size << "\n"; large_18290_basic_3b.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n"; - stack.push(-2543.0f); - stack.push(true); BLT_TRACE_STREAM << stack.size() << "\n"; large_18290_basic_3b.make_callable()(nullptr, stack, stack); BLT_TRACE_STREAM << stack.size() << "\n";