From f75710410ac8310a30331f7f16e04cf85d4929d0 Mon Sep 17 00:00:00 2001 From: Brett Date: Sat, 9 Mar 2024 18:32:31 -0500 Subject: [PATCH] test any, function calls and refs --- CMakeLists.txt | 2 +- libs/BLT | 2 +- tests/src/tests3.cpp | 619 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 619 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e30d9a8..f023f1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(lilfbtf5 VERSION 0.1.7) +project(lilfbtf5 VERSION 0.1.8) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/libs/BLT b/libs/BLT index 7e7e542..1dc08ca 160000 --- a/libs/BLT +++ b/libs/BLT @@ -1 +1 @@ -Subproject commit 7e7e542f51f75dbca6eb86f01abf8c5a2164f706 +Subproject commit 1dc08ca723dacc0ec685f0ba139a79629691544a diff --git a/tests/src/tests3.cpp b/tests/src/tests3.cpp index 28ec03f..8e57298 100644 --- a/tests/src/tests3.cpp +++ b/tests/src/tests3.cpp @@ -23,11 +23,117 @@ #include "blt/profiling/profiler_v2.h" #include #include +#include +#include namespace fb { using TYPE = double; + class func_base_t + { + private: + blt::size_t argc_ = 0; + std::function args)> func; + protected: + TYPE value = 0; + public: + explicit func_base_t(blt::size_t argc, std::function args)> func): + argc_(argc), func(std::move(func)) + {} + + [[nodiscard]] inline blt::size_t argc() const + { return argc_; } + + [[nodiscard]] inline TYPE getValue() const + { + return value; + } + + inline func_base_t setValue(TYPE val) + { + this->value = val; + return *this; + } + + inline void call(blt::span args) + { + func(*this, args); + }; + + ~func_base_t() = default; + }; + + class func_ref_base_t + { + private: + blt::size_t argc_ = 0; + std::function args)>& func; + protected: + TYPE value = 0; + public: + explicit func_ref_base_t(blt::size_t argc, std::function args)>& func): + argc_(argc), func(func) + {} + + [[nodiscard]] inline blt::size_t argc() const + { return argc_; } + + [[nodiscard]] inline TYPE getValue() const + { + return value; + } + + inline func_ref_base_t setValue(TYPE val) + { + this->value = val; + return *this; + } + + inline void call(blt::span args) + { + func(*this, args); + }; + + ~func_ref_base_t() = default; + }; + using func_ref_t = std::function)>; + + class func_ref_any_base_t + { + private: + blt::size_t argc_ = 0; + std::function args)>& func; + protected: + std::any value; + public: + explicit func_ref_any_base_t(blt::size_t argc, std::function args)>& func): + argc_(argc), func(func) + {} + + [[nodiscard]] inline blt::size_t argc() const + { return argc_; } + + [[nodiscard]] inline std::any getValue() const + { + return value; + } + + inline func_ref_any_base_t& setValue(std::any val) + { + this->value = std::move(val); + return *this; + } + + inline void call(blt::span args) + { + func(*this, args); + }; + + ~func_ref_any_base_t() = default; + }; + using func_ref_any_t = std::function)>; + class base_t { private: @@ -116,6 +222,40 @@ namespace fb blt::bump_allocator alloc; + inline func_ref_t add_function = [](func_ref_base_t& us, blt::span args) { + us.setValue(args[0] + args[1]); + }; + inline func_ref_t sub_function = [](func_ref_base_t& us, blt::span args) { + us.setValue(args[0] - args[1]); + }; + inline func_ref_t mul_function = [](func_ref_base_t& us, blt::span args) { + us.setValue(args[0] * args[1]); + }; + inline func_ref_t div_function = [](func_ref_base_t& us, blt::span args) { + if (args[1] == 0) + us.setValue(0); + else + us.setValue(args[0] / args[1]); + }; + inline func_ref_t value_function = [](auto&, auto) {}; + + inline func_ref_any_t add_function_any = [](func_ref_any_base_t& us, blt::span args) { + us.setValue(std::any_cast(args[0]) + std::any_cast(args[1])); + }; + inline func_ref_any_t sub_function_any = [](func_ref_any_base_t& us, blt::span args) { + us.setValue(std::any_cast(args[0]) - std::any_cast(args[1])); + }; + inline func_ref_any_t mul_function_any = [](func_ref_any_base_t& us, blt::span args) { + us.setValue(std::any_cast(args[0]) * std::any_cast(args[1])); + }; + inline func_ref_any_t div_function_any = [](func_ref_any_base_t& us, blt::span args) { + if (std::any_cast(args[1]) == 0) + us.setValue(0.0); + else + us.setValue(std::any_cast(args[0]) / std::any_cast(args[1])); + }; + inline func_ref_any_t value_function_any = [](auto&, auto) {}; + base_t* create_node_type(type_t i) { switch (i) @@ -136,6 +276,79 @@ namespace fb } } + func_base_t create_node_func_type(type_t i) + { + switch (i) + { + case type_t::ADD: + return func_base_t(2, [](func_base_t& us, blt::span args) { + us.setValue(args[0] + args[1]); + }); + case type_t::SUB: + return func_base_t(2, [](func_base_t& us, blt::span args) { + us.setValue(args[0] - args[1]); + }); + case type_t::MUL: + return func_base_t(2, [](func_base_t& us, blt::span args) { + us.setValue(args[0] * args[1]); + }); + case type_t::DIV: + return func_base_t(2, [](func_base_t& us, blt::span args) { + if (args[1] == 0) + us.setValue(0); + else + us.setValue(args[0] / args[1]); + }); + case type_t::VALUE: + return func_base_t(0, [](func_base_t&, blt::span) { + + }).setValue(random_value()); + default: + BLT_ERROR("Hey maybe something weird is going on here"); + return func_base_t{0, [](auto, auto) {}}; + } + } + + func_ref_base_t create_node_func_ref_type(type_t i) + { + switch (i) + { + case type_t::ADD: + return func_ref_base_t(2, add_function); + case type_t::SUB: + return func_ref_base_t(2, sub_function); + case type_t::MUL: + return func_ref_base_t(2, mul_function); + case type_t::DIV: + return func_ref_base_t(2, div_function); + case type_t::VALUE: + return func_ref_base_t(0, value_function).setValue(random_value()); + default: + BLT_ERROR("Hey maybe something weird is going on here"); + return func_ref_base_t(0, value_function); + } + } + + func_ref_any_base_t create_node_func_ref_any_type(type_t i) + { + switch (i) + { + case type_t::ADD: + return func_ref_any_base_t(2, add_function_any); + case type_t::SUB: + return func_ref_any_base_t(2, sub_function_any); + case type_t::MUL: + return func_ref_any_base_t(2, mul_function_any); + case type_t::DIV: + return func_ref_any_base_t(2, div_function_any); + case type_t::VALUE: + return func_ref_any_base_t(0, value_function_any).setValue(random_value()); + default: + BLT_ERROR("Hey maybe something weird is going on here"); + return func_ref_any_base_t(0, value_function_any); + } + } + class tree2 { private: @@ -381,6 +594,357 @@ namespace fb } }; + class tree4 + { + private: + struct node_t + { + func_base_t type; + node_t** children = nullptr; + + explicit node_t(type_t type): type(create_node_func_type(type)) + { + children = alloc.emplace_many(this->type.argc()); + for (blt::size_t i = 0; i < this->type.argc(); i++) + children[i] = nullptr; + } + + void evaluate() + { + if (type.argc() > 0) + { + TYPE v1 = children[0]->type.getValue(); + TYPE v2 = children[1]->type.getValue(); + TYPE d[2]{v1, v2}; + type.call(blt::span{d}); + } else + type.call({}); + } + + double evaluate_tree() + { + std::stack nodes; + std::stack node_stack; + + nodes.push(this); + + while (!nodes.empty()) + { + auto* top = nodes.top(); + node_stack.push(top); + nodes.pop(); + for (blt::size_t i = 0; i < top->type.argc(); i++) + nodes.push(top->children[i]); + } + + while (!node_stack.empty()) + { + node_stack.top()->evaluate(); + node_stack.pop(); + } + return type.getValue(); + } + + ~node_t() + { + for (blt::size_t i = 0; i < type.argc(); i++) + { + alloc.destroy(children[i]); + alloc.deallocate(children[i]); + } + alloc.deallocate(children); + } + }; + + node_t* root = nullptr; + public: + tree4() + {} + + void create(blt::u64 size) + { + root = alloc.template emplace(random_type()); + std::stack> stack; + stack.emplace(root, 0); + while (!stack.empty()) + { + auto top = stack.top(); + auto* node = top.first; + auto depth = top.second; + //BLT_WARN("gen type %ld with argc: %ld", node->type, node->argc); + stack.pop(); + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + for (blt::size_t i = 0; i < node->type.argc(); i++) + { + if (depth >= size) + { + node->children[i] = alloc.template emplace(type_t::VALUE); + //BLT_INFO("Skipping due to size, value %lf", node->children[i]->value); + continue; + } + if (choice()) + node->children[i] = alloc.template emplace(random_type()); + else + node->children[i] = alloc.template emplace(random_type_sub()); + //BLT_INFO("child %p to %p has type generated %ld with argc %d, value %lf", node->children[i], node, + // static_cast(node->children[i]->type), node->children[i]->argc, node->children[i]->value); + if (depth < size) + stack.emplace(node->children[i], depth + 1); + } + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + } +// BLT_INFO("We have %ld adds, %ld subs, %ld mul, %ld div, %ld val, == %ld", t1_add, t1_sub, t1_mul, t1_div, t1_val, +// t1_add + t1_sub + t1_mul + t1_val + t1_div); + } + + double evaluate() + { + return root->evaluate_tree(); + } + + ~tree4() + { + BLT_START_INTERVAL("Tree Destruction", "Inheritance Tree v3"); + alloc.destroy(root); + alloc.deallocate(root); + BLT_END_INTERVAL("Tree Destruction", "Inheritance Tree v3"); + } + }; + + class tree5 + { + private: + struct node_t + { + func_ref_base_t type; + node_t** children = nullptr; + + explicit node_t(type_t type): type(create_node_func_ref_type(type)) + { + children = alloc.emplace_many(this->type.argc()); + for (blt::size_t i = 0; i < this->type.argc(); i++) + children[i] = nullptr; + } + + void evaluate() + { + if (type.argc() > 0) + { + TYPE v1 = children[0]->type.getValue(); + TYPE v2 = children[1]->type.getValue(); + TYPE d[2]{v1, v2}; + type.call(blt::span{d}); + } else + type.call({}); + } + + double evaluate_tree() + { + std::stack nodes; + std::stack node_stack; + + nodes.push(this); + + while (!nodes.empty()) + { + auto* top = nodes.top(); + node_stack.push(top); + nodes.pop(); + for (blt::size_t i = 0; i < top->type.argc(); i++) + nodes.push(top->children[i]); + } + + while (!node_stack.empty()) + { + node_stack.top()->evaluate(); + node_stack.pop(); + } + return type.getValue(); + } + + ~node_t() + { + for (blt::size_t i = 0; i < type.argc(); i++) + { + alloc.destroy(children[i]); + alloc.deallocate(children[i]); + } + alloc.deallocate(children); + } + }; + + node_t* root = nullptr; + public: + tree5() + {} + + void create(blt::u64 size) + { + root = alloc.template emplace(random_type()); + std::stack> stack; + stack.emplace(root, 0); + while (!stack.empty()) + { + auto top = stack.top(); + auto* node = top.first; + auto depth = top.second; + //BLT_WARN("gen type %ld with argc: %ld", node->type, node->argc); + stack.pop(); + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + for (blt::size_t i = 0; i < node->type.argc(); i++) + { + if (depth >= size) + { + node->children[i] = alloc.template emplace(type_t::VALUE); + //BLT_INFO("Skipping due to size, value %lf", node->children[i]->value); + continue; + } + if (choice()) + node->children[i] = alloc.template emplace(random_type()); + else + node->children[i] = alloc.template emplace(random_type_sub()); + //BLT_INFO("child %p to %p has type generated %ld with argc %d, value %lf", node->children[i], node, + // static_cast(node->children[i]->type), node->children[i]->argc, node->children[i]->value); + if (depth < size) + stack.emplace(node->children[i], depth + 1); + } + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + } +// BLT_INFO("We have %ld adds, %ld subs, %ld mul, %ld div, %ld val, == %ld", t1_add, t1_sub, t1_mul, t1_div, t1_val, +// t1_add + t1_sub + t1_mul + t1_val + t1_div); + } + + double evaluate() + { + return root->evaluate_tree(); + } + + ~tree5() + { + BLT_START_INTERVAL("Tree Destruction", "Inheritance Tree v4"); + alloc.destroy(root); + alloc.deallocate(root); + BLT_END_INTERVAL("Tree Destruction", "Inheritance Tree v4"); + } + }; + + class tree6 + { + private: + struct node_t + { + func_ref_any_base_t type; + node_t** children = nullptr; + + explicit node_t(type_t type): type(create_node_func_ref_any_type(type)) + { + children = alloc.emplace_many(this->type.argc()); + for (blt::size_t i = 0; i < this->type.argc(); i++) + children[i] = nullptr; + } + + void evaluate() + { + if (type.argc() > 0) + { + std::any v1 = children[0]->type.getValue(); + std::any v2 = children[1]->type.getValue(); + std::any d[2]{v1, v2}; + type.call(blt::span{d}); + } else + type.call({}); + } + + double evaluate_tree() + { + std::stack nodes; + std::stack node_stack; + + nodes.push(this); + + while (!nodes.empty()) + { + auto* top = nodes.top(); + node_stack.push(top); + nodes.pop(); + for (blt::size_t i = 0; i < top->type.argc(); i++) + nodes.push(top->children[i]); + } + + while (!node_stack.empty()) + { + node_stack.top()->evaluate(); + node_stack.pop(); + } + return std::any_cast(type.getValue()); + } + + ~node_t() + { + for (blt::size_t i = 0; i < type.argc(); i++) + { + alloc.destroy(children[i]); + alloc.deallocate(children[i]); + } + alloc.deallocate(children); + } + }; + + node_t* root = nullptr; + public: + tree6() + {} + + void create(blt::u64 size) + { + root = alloc.template emplace(random_type()); + std::stack> stack; + stack.emplace(root, 0); + while (!stack.empty()) + { + auto top = stack.top(); + auto* node = top.first; + auto depth = top.second; + //BLT_WARN("gen type %ld with argc: %ld", node->type, node->argc); + stack.pop(); + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + for (blt::size_t i = 0; i < node->type.argc(); i++) + { + if (depth >= size) + { + node->children[i] = alloc.template emplace(type_t::VALUE); + //BLT_INFO("Skipping due to size, value %lf", node->children[i]->value); + continue; + } + if (choice()) + node->children[i] = alloc.template emplace(random_type()); + else + node->children[i] = alloc.template emplace(random_type_sub()); + //BLT_INFO("child %p to %p has type generated %ld with argc %d, value %lf", node->children[i], node, + // static_cast(node->children[i]->type), node->children[i]->argc, node->children[i]->value); + if (depth < size) + stack.emplace(node->children[i], depth + 1); + } + //BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n"; + } +// BLT_INFO("We have %ld adds, %ld subs, %ld mul, %ld div, %ld val, == %ld", t1_add, t1_sub, t1_mul, t1_div, t1_val, +// t1_add + t1_sub + t1_mul + t1_val + t1_div); + } + + double evaluate() + { + return root->evaluate_tree(); + } + + ~tree6() + { + BLT_START_INTERVAL("Tree Destruction", "Inheritance Tree v5"); + alloc.destroy(root); + alloc.deallocate(root); + BLT_END_INTERVAL("Tree Destruction", "Inheritance Tree v5"); + } + }; + void run() { constexpr auto size = 512; @@ -399,7 +963,7 @@ namespace fb void run2() { - constexpr auto size = 1; + constexpr auto size = 512; constexpr auto tree_size = 17; engine.reset(); tree3 love[size]; @@ -413,6 +977,54 @@ namespace fb BLT_END_INTERVAL("Tree Evaluation", "Inheritance Tree v2"); } + void run3() + { + constexpr auto size = 512; + constexpr auto tree_size = 17; + engine.reset(); + tree4 love[size]; + BLT_START_INTERVAL("Tree Construction", "Inheritance Tree v3"); + for (auto& i : love) + i.create(tree_size); + BLT_END_INTERVAL("Tree Construction", "Inheritance Tree v3"); + BLT_START_INTERVAL("Tree Evaluation", "Inheritance Tree v3"); + for (auto& i : love) + blt::black_box(i.evaluate()); + BLT_END_INTERVAL("Tree Evaluation", "Inheritance Tree v3"); + } + + void run4() + { + constexpr auto size = 512; + constexpr auto tree_size = 17; + engine.reset(); + tree5 love[size]; + BLT_START_INTERVAL("Tree Construction", "Inheritance Tree v4"); + for (auto& i : love) + i.create(tree_size); + BLT_END_INTERVAL("Tree Construction", "Inheritance Tree v4"); + BLT_START_INTERVAL("Tree Evaluation", "Inheritance Tree v4"); + for (auto& i : love) + blt::black_box(i.evaluate()); + BLT_END_INTERVAL("Tree Evaluation", "Inheritance Tree v4"); + } + + void run5() + { + constexpr auto size = 512; + constexpr auto tree_size = 17; + engine.reset(); + tree6 love[size]; + BLT_START_INTERVAL("Tree Construction", "Inheritance Tree v5"); + for (auto& i : love) + i.create(tree_size); + BLT_END_INTERVAL("Tree Construction", "Inheritance Tree v5"); + BLT_START_INTERVAL("Tree Evaluation", "Inheritance Tree v5"); + for (auto& i : love) + blt::black_box(i.evaluate()); + BLT_END_INTERVAL("Tree Evaluation", "Inheritance Tree v5"); + } + void test3() { auto cum = new blt::u8[512]; @@ -434,8 +1046,11 @@ namespace fb delete[] cum; - //run(); + run(); run2(); + run3(); + run4(); + run5(); // using testing = blt::size_t; // constexpr blt::size_t INT_SIZE = blt::BLT_2MB_SIZE * 8 / sizeof(testing);