hopefully fix evaluation order

thread
Brett 2024-08-03 19:51:38 -04:00
parent be90039a5a
commit ec71055078
9 changed files with 119 additions and 59 deletions

View File

@ -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)

View File

@ -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<detail::remove_cv_ref<Args>>() : 0)), ...);
((offset += (current_index++ < index ? stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() : 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<blt::u64, indices...>,
ExtraArgs&& ... args)
{
//blt::size_t arg_size = (stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() + ...);
//BLT_TRACE(arg_size);
// expands Args and indices, providing each argument with its index calculating the current argument byte offset
return std::forward<Func>(func)(std::forward<ExtraArgs>(args)...,
allocator.from<detail::remove_cv_ref<Args>>(getByteOffset<indices>())...);
@ -174,6 +177,7 @@ namespace blt::gp
return name;
}
operator_id id = -1;
private:
function_t func;
std::optional<std::string_view> name;

View File

@ -40,6 +40,7 @@
#include <blt/std/hashmap.h>
#include <blt/std/types.h>
#include <blt/std/utility.h>
#include <blt/std/meta.h>
#include <blt/std/memory.h>
#include <blt/std/thread.h>
#include <blt/gp/fwdecl.h>
@ -105,10 +106,11 @@ namespace blt::gp
{}
template<typename ArgType, typename Return, typename... Args>
operator_builder& add_operator(const operation_t<ArgType, Return(Args...)>& op, bool is_static = false)
operator_builder& add_operator(operation_t<ArgType, Return(Args...)>& op, bool is_static = false)
{
auto return_type_id = system.get_type<Return>().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<Context>();
// info.transfer = [](std::optional<std::reference_wrapper<stack_allocator>> to, stack_allocator& from) {
//#if BLT_DEBUG_LEVEL >= 3
// auto value = from.pop<Return>();
// //BLT_TRACE_STREAM << value << "\n";
// if (to){
// to->get().push(value);
// }
//#else
// if (to)
// {
// to->get().push(from.pop<Return>());
// } else
// {
// from.pop<Return>();
// }
//#endif
//
// };
storage.operators.push_back(info);
storage.print_funcs.push_back([](std::ostream& out, stack_allocator& stack) {
storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) {
if constexpr (blt::meta::is_streamable_v<Return>) {
out << stack.pop<Return>();
(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)

View File

@ -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<blt::ptrdiff_t>(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<NO_REF_T*>(blk->metadata.offset - remaining_bytes);
}

View File

@ -26,7 +26,6 @@
#include <blt/std/memory.h>
#include <blt/gp/fwdecl.h>
#include <blt/gp/stack.h>
#include <blt/gp/operations.h>
#include <random>
namespace blt::gp

@ -1 +1 @@
Subproject commit fb17ff16c0e10193454921af0d27d1f5afd4ddd6
Subproject commit befd5e0ca1135c467f194d1d0e5691d301f93a34

View File

@ -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);
}

View File

@ -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<blt::u8>(a) && ref < static_cast<blt::u8>(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<float>()));
tree.get_operations().push_back(make_value(type_system.get_type<float>()));
tree.get_values().push(50.0f);
tree.get_values().push(120.0f);
tree.get_values().push(50.0f);
auto val = tree.get_evaluation_value<float>(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<float>()));
ops.push_back(make_value(type_system.get_type<float>()));
ops.push_back(make_value(type_system.get_type<float>()));
vals.push(50.0f);
vals.push(120.0f);
vals.push(5555.0f);
auto val = tree.get_evaluation_value<large_18290>(nullptr);
blt::black_box(val);
}
int main()
{
for (auto& v : base.data)
v = static_cast<blt::u8>(blt::random::murmur_random64c(691, std::numeric_limits<blt::u8>::min(), std::numeric_limits<blt::u8>::max()));
type_system.register_type<float>();
type_system.register_type<bool>();
type_system.register_type<large_18290>();
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(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();
}

View File

@ -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<typename T, typename Class, blt::size_t size>
static inline auto constexpr array_size(const T(Class::*)[size])
{
return size;
}
template<typename T, typename U>
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<blt::gp::detail::empty_t>()(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<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>{});
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<blt::gp::detail::empty_t>()(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<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>{});
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<blt::gp::detail::empty_t>()(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<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(large_256)>{});
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<blt::gp::detail::empty_t>()(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<blt::gp::detail::empty_t>()(nullptr, stack, stack);
BLT_TRACE_STREAM << stack.size() << "\n";
auto val = stack.pop<large_4096>();
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<blt::gp::detail::empty_t>()(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<blt::u8, 20480 - 18290 - blt::gp::stack_allocator::block_size()>());
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<blt::gp::detail::empty_t>()(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<blt::gp::detail::empty_t>()(nullptr, stack, stack);
BLT_TRACE_STREAM << stack.size() << "\n";