wow there is something wrong, check debug mode!

dev-func-drop
Brett 2025-01-15 21:44:38 -05:00
parent 8594c44bae
commit 9eff9ea8ef
7 changed files with 93 additions and 65 deletions

View File

@ -27,7 +27,7 @@ macro(compile_options target_name)
sanitizers(${target_name}) sanitizers(${target_name})
endmacro() endmacro()
project(blt-gp VERSION 0.3.13) project(blt-gp VERSION 0.3.14)
include(CTest) include(CTest)

View File

@ -168,11 +168,11 @@ namespace blt::gp
const auto ptr = static_cast<char*>(allocate_bytes_for_size(aligned_size<NO_REF>())); const auto ptr = static_cast<char*>(allocate_bytes_for_size(aligned_size<NO_REF>()));
std::memcpy(ptr, &t, sizeof(NO_REF)); std::memcpy(ptr, &t, sizeof(NO_REF));
if constexpr (gp::detail::has_func_drop_ephemeral_v<T>) // if constexpr (gp::detail::has_func_drop_ephemeral_v<T>)
{ // {
const auto* ref_counter_ptr = new std::atomic_uint64_t(1); // NOLINT // const auto* ref_counter_ptr = new std::atomic_uint64_t(1); // NOLINT
std::memcpy(ptr + sizeof(NO_REF), &ref_counter_ptr, sizeof(std::atomic_uint64_t*)); // std::memcpy(ptr + sizeof(NO_REF), &ref_counter_ptr, sizeof(std::atomic_uint64_t*));
} // }
} }
template <typename T, typename NO_REF = NO_REF_T<T>> template <typename T, typename NO_REF = NO_REF_T<T>>

View File

@ -171,7 +171,7 @@ namespace blt::gp
public: public:
explicit tree_t(gp_program& program); explicit tree_t(gp_program& program);
tree_t(const tree_t& copy): func(copy.func) tree_t(const tree_t& copy): m_program(copy.m_program)
{ {
copy_fast(copy); copy_fast(copy);
} }
@ -180,6 +180,7 @@ namespace blt::gp
{ {
if (this == &copy) if (this == &copy)
return *this; return *this;
m_program = copy.m_program;
copy_fast(copy); copy_fast(copy);
return *this; return *this;
} }
@ -245,12 +246,14 @@ namespace blt::gp
void insert_operator(const op_container_t& container) void insert_operator(const op_container_t& container)
{ {
operations.emplace_back(container); operations.emplace_back(container);
handle_operator_inserted(operations.back());
} }
template <typename... Args> template <typename... Args>
void emplace_operator(Args&&... args) void emplace_operator(Args&&... args)
{ {
operations.emplace_back(std::forward<Args>(args)...); operations.emplace_back(std::forward<Args>(args)...);
handle_operator_inserted(operations.back());
} }
[[nodiscard]] tracked_vector<op_container_t>& get_operations() [[nodiscard]] tracked_vector<op_container_t>& get_operations()
@ -405,17 +408,26 @@ namespace blt::gp
} }
private: private:
void handle_operator_inserted(const op_container_t& op);
template <typename T, std::enable_if_t<!(std::is_pointer_v<T> || std::is_null_pointer_v<T>), bool> = true> template <typename T, std::enable_if_t<!(std::is_pointer_v<T> || std::is_null_pointer_v<T>), bool> = true>
[[nodiscard]] evaluation_context& evaluate(const T& context) const [[nodiscard]] evaluation_context& evaluate(const T& context) const
{ {
return (*func)(*this, const_cast<void*>(static_cast<const void*>(&context))); return evaluate(const_cast<void*>(static_cast<const void*>(&context)));
} }
[[nodiscard]] evaluation_context& evaluate() const [[nodiscard]] evaluation_context& evaluate() const
{ {
return (*func)(*this, nullptr); return evaluate(nullptr);
} }
[[nodiscard]] evaluation_context& evaluate(void* ptr) const;
tracked_vector<op_container_t> operations;
stack_allocator values;
gp_program* m_program;
protected:
template <typename Context, typename Operator> template <typename Context, typename Operator>
static void execute(void* context, stack_allocator& write_stack, stack_allocator& read_stack, Operator& operation) static void execute(void* context, stack_allocator& write_stack, stack_allocator& read_stack, Operator& operation)
{ {
@ -457,10 +469,6 @@ namespace blt::gp
{ {
call_jmp_table_internal<Context>(op, context, write_stack, read_stack, std::index_sequence_for<Operators...>(), operators...); call_jmp_table_internal<Context>(op, context, write_stack, read_stack, std::index_sequence_for<Operators...>(), operators...);
} }
tracked_vector<op_container_t> operations;
stack_allocator values;
detail::eval_func_t* func;
}; };
struct fitness_t struct fitness_t

View File

@ -69,10 +69,7 @@ namespace blt::gp
max_depth = std::max(max_depth, top.depth); max_depth = std::max(max_depth, top.depth);
if (args.program.is_operator_ephemeral(top.id)) if (args.program.is_operator_ephemeral(top.id))
{
info.func(nullptr, tree.get_values(), tree.get_values());
continue; continue;
}
for (const auto& child : info.argument_types) for (const auto& child : info.argument_types)
std::forward<Func>(perChild)(args.program, tree_generator, child, top.depth + 1); std::forward<Func>(perChild)(args.program, tree_generator, child, top.depth + 1);

View File

@ -352,8 +352,9 @@ namespace blt::gp
auto copy = c; auto copy = c;
try try
{ {
const auto& result = copy.evaluate(*static_cast<char*>(detail::debug::context_ptr)); // TODO a work around for the whole needing to access a now private function
blt::black_box(result); // const auto& result = copy.evaluate(*static_cast<char*>(detail::debug::context_ptr));
// blt::black_box(result);
} catch (...) } catch (...)
{ {
std::cout << "This occurred at point " << begin_point << " ending at (old) " << end_point << "\n"; std::cout << "This occurred at point " << begin_point << " ending at (old) " << end_point << "\n";

View File

@ -25,7 +25,7 @@
namespace blt::gp namespace blt::gp
{ {
// this one will copy previous bytes over // this one will copy previous bytes over
template<typename T> template <typename T>
blt::span<blt::u8> get_pointer_for_size(blt::size_t size) blt::span<blt::u8> get_pointer_for_size(blt::size_t size)
{ {
static blt::span<blt::u8> buffer{nullptr, 0}; static blt::span<blt::u8> buffer{nullptr, 0};
@ -36,7 +36,7 @@ namespace blt::gp
} }
return buffer; return buffer;
} }
std::ostream& create_indent(std::ostream& out, blt::size_t amount, bool pretty_print) std::ostream& create_indent(std::ostream& out, blt::size_t amount, bool pretty_print)
{ {
if (!pretty_print) if (!pretty_print)
@ -45,30 +45,30 @@ namespace blt::gp
out << '\t'; out << '\t';
return out; return out;
} }
std::string_view end_indent(bool pretty_print) std::string_view end_indent(bool pretty_print)
{ {
return pretty_print ? "\n" : ""; return pretty_print ? "\n" : "";
} }
std::string get_return_type(gp_program& program, type_id id, bool use_returns) std::string get_return_type(gp_program& program, type_id id, bool use_returns)
{ {
if (!use_returns) if (!use_returns)
return ""; return "";
return "(" + std::string(program.get_typesystem().get_type(id).name()) + ")"; return "(" + std::string(program.get_typesystem().get_type(id).name()) + ")";
} }
void tree_t::print(gp_program& program, std::ostream& out, bool print_literals, bool pretty_print, bool include_types) const void tree_t::print(gp_program& program, std::ostream& out, bool print_literals, bool pretty_print, bool include_types) const
{ {
std::stack<blt::size_t> arguments_left; std::stack<blt::size_t> arguments_left;
blt::size_t indent = 0; blt::size_t indent = 0;
stack_allocator reversed; stack_allocator reversed;
if (print_literals) if (print_literals)
{ {
// I hate this. // I hate this.
stack_allocator copy = values; stack_allocator copy = values;
// reverse the order of the stack // reverse the order of the stack
for (const auto& v : operations) for (const auto& v : operations)
{ {
@ -87,7 +87,8 @@ namespace blt::gp
indent++; indent++;
arguments_left.emplace(info.argc.argc); arguments_left.emplace(info.argc.argc);
out << name << return_type << end_indent(pretty_print); out << name << return_type << end_indent(pretty_print);
} else }
else
{ {
if (print_literals) if (print_literals)
{ {
@ -96,13 +97,15 @@ namespace blt::gp
{ {
program.get_print_func(v.id())(out, reversed); program.get_print_func(v.id())(out, reversed);
reversed.pop_bytes(v.type_size()); reversed.pop_bytes(v.type_size());
} else }
else
out << name; out << name;
out << return_type << end_indent(pretty_print); out << return_type << end_indent(pretty_print);
} else }
else
create_indent(out, indent, pretty_print) << name << return_type << end_indent(pretty_print); create_indent(out, indent, pretty_print) << name << return_type << end_indent(pretty_print);
} }
while (!arguments_left.empty()) while (!arguments_left.empty())
{ {
auto top = arguments_left.top(); auto top = arguments_left.top();
@ -112,7 +115,8 @@ namespace blt::gp
indent--; indent--;
create_indent(out, indent, pretty_print) << ")" << end_indent(pretty_print); create_indent(out, indent, pretty_print) << ")" << end_indent(pretty_print);
continue; continue;
} else }
else
{ {
if (!pretty_print) if (!pretty_print)
out << " "; out << " ";
@ -130,20 +134,21 @@ namespace blt::gp
indent--; indent--;
create_indent(out, indent, pretty_print) << ")" << end_indent(pretty_print); create_indent(out, indent, pretty_print) << ")" << end_indent(pretty_print);
continue; continue;
} else }
else
{ {
BLT_ERROR("Failed to print tree correctly!"); BLT_ERROR("Failed to print tree correctly!");
break; break;
} }
} }
out << '\n'; out << '\n';
} }
size_t tree_t::get_depth(gp_program& program) const size_t tree_t::get_depth(gp_program& program) const
{ {
size_t depth = 0; size_t depth = 0;
auto operations_stack = operations; auto operations_stack = operations;
thread_local tracked_vector<size_t> values_process; thread_local tracked_vector<size_t> values_process;
thread_local tracked_vector<size_t> value_stack; thread_local tracked_vector<size_t> value_stack;
@ -156,7 +161,7 @@ namespace blt::gp
if (op.is_value()) if (op.is_value())
value_stack.push_back(1); value_stack.push_back(1);
} }
while (!operations_stack.empty()) while (!operations_stack.empty())
{ {
auto operation = operations_stack.back(); auto operation = operations_stack.back();
@ -179,14 +184,14 @@ namespace blt::gp
value_stack.push_back(local_depth + 1); value_stack.push_back(local_depth + 1);
operations_stack.emplace_back(operation.type_size(), operation.id(), true, program.get_operator_flags(operation.id())); operations_stack.emplace_back(operation.type_size(), operation.id(), true, program.get_operator_flags(operation.id()));
} }
return depth; return depth;
} }
ptrdiff_t tree_t::find_endpoint(gp_program& program, ptrdiff_t start) const ptrdiff_t tree_t::find_endpoint(gp_program& program, ptrdiff_t start) const
{ {
i64 children_left = 0; i64 children_left = 0;
do do
{ {
const auto& type = program.get_operator_info(operations[start].id()); const auto& type = program.get_operator_info(operations[start].id());
@ -196,11 +201,12 @@ namespace blt::gp
if (type.argc.argc > 0) if (type.argc.argc > 0)
children_left += type.argc.argc; children_left += type.argc.argc;
start++; start++;
} while (children_left > 0); }
while (children_left > 0);
return start; return start;
} }
// this function doesn't work! // this function doesn't work!
ptrdiff_t tree_t::find_parent(gp_program& program, ptrdiff_t start) const ptrdiff_t tree_t::find_parent(gp_program& program, ptrdiff_t start) const
{ {
@ -216,22 +222,37 @@ namespace blt::gp
if (children_left <= 0) if (children_left <= 0)
break; break;
--start; --start;
} while (true); }
while (true);
return start; return start;
} }
void tree_t::handle_operator_inserted(const op_container_t& op)
{
if (m_program->is_operator_ephemeral(op.id()))
{
// Ephemeral values have corresponding insertions into the stack
m_program->get_operator_info(op.id()).func(nullptr, values, values);
}
}
evaluation_context& tree_t::evaluate(void* ptr) const
{
return m_program->get_eval_func()(*this, ptr);
}
bool tree_t::check(gp_program& program, void* context) const bool tree_t::check(gp_program& program, void* context) const
{ {
blt::size_t bytes_expected = 0; blt::size_t bytes_expected = 0;
auto bytes_size = values.size().total_used_bytes; const auto bytes_size = values.size().total_used_bytes;
for (const auto& op : get_operations()) for (const auto& op : get_operations())
{ {
if (op.is_value()) if (op.is_value())
bytes_expected += op.type_size(); bytes_expected += op.type_size();
} }
if (bytes_expected != bytes_size) if (bytes_expected != bytes_size)
{ {
BLT_WARN_STREAM << "Stack state: " << values.size() << "\n"; BLT_WARN_STREAM << "Stack state: " << values.size() << "\n";
@ -240,13 +261,13 @@ namespace blt::gp
BLT_WARN("Amount of bytes in stack doesn't match the number of bytes expected for the operations"); BLT_WARN("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
return false; return false;
} }
// copy the initial values // copy the initial values
evaluation_context results{}; evaluation_context results{};
auto value_stack = values; auto value_stack = values;
auto& values_process = results.values; auto& values_process = results.values;
blt::size_t total_produced = 0; blt::size_t total_produced = 0;
blt::size_t total_consumed = 0; blt::size_t total_consumed = 0;
@ -264,7 +285,7 @@ namespace blt::gp
program.get_operator_info(operation.id()).func(context, values_process, values_process); program.get_operator_info(operation.id()).func(context, values_process, values_process);
total_produced += program.get_typesystem().get_type(info.return_type).size(); total_produced += program.get_typesystem().get_type(info.return_type).size();
} }
const auto v1 = results.values.bytes_in_head(); const auto v1 = results.values.bytes_in_head();
const auto v2 = static_cast<ptrdiff_t>(operations.front().type_size()); const auto v2 = static_cast<ptrdiff_t>(operations.front().type_size());
if (v1 != v2) if (v1 != v2)
@ -277,7 +298,7 @@ namespace blt::gp
} }
return true; return true;
} }
void tree_t::find_child_extends(gp_program& program, tracked_vector<child_t>& vec, const size_t parent_node, const size_t argc) const void tree_t::find_child_extends(gp_program& program, tracked_vector<child_t>& vec, const size_t parent_node, const size_t argc) const
{ {
while (vec.size() < argc) while (vec.size() < argc)
@ -287,35 +308,36 @@ namespace blt::gp
if (current_point == 0) if (current_point == 0)
{ {
// first child. // first child.
prev = {static_cast<ptrdiff_t>(parent_node + 1), prev = {
find_endpoint(program, static_cast<ptrdiff_t>(parent_node + 1))}; static_cast<ptrdiff_t>(parent_node + 1),
find_endpoint(program, static_cast<ptrdiff_t>(parent_node + 1))
};
vec.push_back(prev); vec.push_back(prev);
continue; continue;
} else }
prev = vec[current_point - 1]; prev = vec[current_point - 1];
child_t next = {prev.end, find_endpoint(program, prev.end)}; child_t next = {prev.end, find_endpoint(program, prev.end)};
vec.push_back(next); vec.push_back(next);
} }
} }
tree_t::tree_t(gp_program& program): func(&program.get_eval_func()) tree_t::tree_t(gp_program& program): m_program(&program)
{ {
} }
void tree_t::clear(gp_program& program) void tree_t::clear(gp_program& program)
{ {
auto* f = &program.get_eval_func(); auto* f = &program;
if (f != func) if (&program != m_program)
func = f; m_program = f;
for (const auto& op : operations) for (const auto& op : operations)
{ {
if (op.has_ephemeral_drop()) if (op.has_ephemeral_drop())
{ {
// TODO:
} }
} }
operations.clear(); operations.clear();
values.reset(); values.reset();
} }
} }

View File

@ -47,7 +47,7 @@ struct drop_type
++ephemeral_construct; ++ephemeral_construct;
} }
void drop() void drop() const
{ {
if (!ephemeral) if (!ephemeral)
++normal_drop; ++normal_drop;