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})
endmacro()
project(blt-gp VERSION 0.3.13)
project(blt-gp VERSION 0.3.14)
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>()));
std::memcpy(ptr, &t, sizeof(NO_REF));
if constexpr (gp::detail::has_func_drop_ephemeral_v<T>)
{
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*));
}
// if constexpr (gp::detail::has_func_drop_ephemeral_v<T>)
// {
// 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*));
// }
}
template <typename T, typename NO_REF = NO_REF_T<T>>

View File

@ -171,7 +171,7 @@ namespace blt::gp
public:
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);
}
@ -180,6 +180,7 @@ namespace blt::gp
{
if (this == &copy)
return *this;
m_program = copy.m_program;
copy_fast(copy);
return *this;
}
@ -245,12 +246,14 @@ namespace blt::gp
void insert_operator(const op_container_t& container)
{
operations.emplace_back(container);
handle_operator_inserted(operations.back());
}
template <typename... Args>
void emplace_operator(Args&&... args)
{
operations.emplace_back(std::forward<Args>(args)...);
handle_operator_inserted(operations.back());
}
[[nodiscard]] tracked_vector<op_container_t>& get_operations()
@ -405,17 +408,26 @@ namespace blt::gp
}
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>
[[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
{
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>
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...);
}
tracked_vector<op_container_t> operations;
stack_allocator values;
detail::eval_func_t* func;
};
struct fitness_t

View File

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

View File

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

View File

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

View File

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