working on fixing memorys

dev-func-drop
Brett 2025-01-16 15:24:58 -05:00
parent 44571f5402
commit f7d28d7a65
7 changed files with 143 additions and 96 deletions

View File

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

View File

@ -164,7 +164,7 @@ namespace blt::gp::example
{
auto& i = i_ref.get();
BLT_DEBUG("Fitness: %lf, stand: %lf, raw: %lf", i.fitness.adjusted_fitness, i.fitness.standardized_fitness, i.fitness.raw_fitness);
i.tree.print(program, std::cout);
i.tree.print(std::cout);
std::cout << "\n";
}

View File

@ -27,9 +27,6 @@
#include <utility>
#include <stack>
#include <ostream>
#include <atomic>
#include <bits/locale_facets_nonio.h>
namespace blt::gp
{
@ -182,7 +179,9 @@ namespace blt::gp
type_id type;
};
explicit tree_t(gp_program& program);
explicit tree_t(gp_program& program): m_program(&program)
{
}
tree_t(const tree_t& copy): m_program(copy.m_program)
{
@ -216,27 +215,45 @@ namespace blt::gp
for (; op_it != operations.end(); ++op_it)
{
if (op_it->has_ephemeral_drop())
if (op_it->get_flags().is_ephemeral())
{
if (op_it->has_ephemeral_drop())
{
}
}
if (copy_it == copy.operations.end())
break;
*op_it = *copy_it;
if (copy_it->has_ephemeral_drop())
if (op_it->get_flags().is_ephemeral())
{
if (copy_it->has_ephemeral_drop())
{
}
}
++copy_it;
}
const auto op_it_cpy = op_it;
for (; op_it != operations.end(); ++op_it)
{
if (op_it->has_ephemeral_drop())
if (op_it->get_flags().is_ephemeral())
{
if (op_it->has_ephemeral_drop())
{
}
}
}
operations.erase(op_it_cpy, operations.end());
for (; copy_it != copy.operations.end(); ++copy_it)
{
if (copy_it->get_flags().is_ephemeral())
{
if (copy_it->has_ephemeral_drop())
{
}
}
operations.emplace_back(*copy_it);
}
values.reserve(copy.values.stored());
values.reset();
@ -284,16 +301,40 @@ namespace blt::gp
size_t get_depth(gp_program& program) const;
subtree_point_t select_subtree(double terminal_chance = 0.1) const;
std::optional<subtree_point_t> select_subtree(type_id type, u32 max_tries = 5, double terminal_chance = 0.1) const;
subtree_point_t select_subtree_traverse(double terminal_chance = 0.1, double depth_multiplier = 0.6) const;
std::optional<subtree_point_t> select_subtree_traverse(type_id type, u32 max_tries = 5, double terminal_chance = 0.1,
double depth_multiplier = 0.6) const;
/**
* Selects a random index inside this tree's operations stack
* @param terminal_chance if we select a terminal this is the chance we will actually pick it, otherwise continue the loop.
*/
[[nodiscard]] subtree_point_t select_subtree(double terminal_chance = 0.1) const;
/**
* Selects a random index inside the tree's operations stack, with a limit on the max number of times we will attempt to select this point.
* @param type type to find
* @param max_tries maximum number of times we are allowed to select a tree without finding a corresponding type.
* @param terminal_chance if we select a terminal this is the chance that we will actually pick it
*/
[[nodiscard]] std::optional<subtree_point_t> select_subtree(type_id type, u32 max_tries = 5, double terminal_chance = 0.1) const;
/**
* Select an index by traversing through the tree structure
* @param terminal_chance if we select a terminal this is the chance that we will actually pick it.
* @param depth_multiplier this controls how the depth contributes to the chance to exit.
* By default, a depth of 3.5 will have a 50% chance of returning the current index.
*/
[[nodiscard]] subtree_point_t select_subtree_traverse(double terminal_chance = 0.1, double depth_multiplier = 0.6) const;
/**
* SSelect an index by traversing through the tree structure, with a limit on the max number of times we will attempt to select this point.
* @param type type to find
* @param max_tries maximum number of times we are allowed to select a tree without finding a corresponding type.
* @param terminal_chance if we select a terminal this is the chance that we will actually pick it
* @param depth_multiplier this controls how the depth contributes to the chance to exit.
* By default, a depth of 3.5 will have a 50% chance of returning the current index.
*/
[[nodiscard]] std::optional<subtree_point_t> select_subtree_traverse(type_id type, u32 max_tries = 5, double terminal_chance = 0.1,
double depth_multiplier = 0.6) const;
/**
* User function for evaluating this tree using a context reference. This function should only be used if the tree is expecting the context value
* This function returns a copy of your value, if it is too large for the stack, or you otherwise need a reference, please use the corresponding
* get_evaluation_ref function!
* User function for evaluating this tree using a context reference. This function should only be used if the tree is expecting the context value
* This function returns a copy of your value, if it is too large for the stack, or you otherwise need a reference, please use the corresponding
* get_evaluation_ref function!
*/
template <typename T, typename Context>
T get_evaluation_value(const Context& context) const
@ -350,10 +391,10 @@ namespace blt::gp
return evaluation_ref<T>{val, ctx};
}
void print(gp_program& program, std::ostream& output, bool print_literals = true, bool pretty_indent = false,
void print(std::ostream& output, bool print_literals = true, bool pretty_indent = false,
bool include_types = false) const;
bool check(gp_program& program, void* context) const;
bool check(void* context) const;
void find_child_extends(tracked_vector<child_t>& vec, blt::size_t parent_node, blt::size_t argc) const;

@ -1 +1 @@
Subproject commit 4c462dff38a982bc5dc5212337af160bc018cce1
Subproject commit 2e6abb8013a622771330c17f0d938db5f672f12b

View File

@ -146,7 +146,7 @@ namespace blt::gp
break;
default:
#if BLT_DEBUG_LEVEL > 0
BLT_ABORT("This place should be unreachable!");
BLT_ABORT("This place should be unreachable!");
#else
BLT_UNREACHABLE;
#endif
@ -156,13 +156,15 @@ namespace blt::gp
blt::size_t c1_found_bytes = c1.get_values().size().total_used_bytes;
blt::size_t c2_found_bytes = c2.get_values().size().total_used_bytes;
blt::size_t c1_expected_bytes = std::accumulate(c1.get_operations().begin(), c1.get_operations().end(), 0ul,
[](const auto& v1, const auto& v2) {
[](const auto& v1, const auto& v2)
{
if (v2.is_value())
return v1 + v2.type_size();
return v1;
});
blt::size_t c2_expected_bytes = std::accumulate(c2.get_operations().begin(), c2.get_operations().end(), 0ul,
[](const auto& v1, const auto& v2) {
[](const auto& v1, const auto& v2)
{
if (v2.is_value())
return v1 + v2.type_size();
return v1;
@ -331,48 +333,50 @@ namespace blt::gp
// this will check to make sure that the tree is in a correct and executable state. it requires that the evaluation is context free!
#if BLT_DEBUG_LEVEL >= 2
// BLT_ASSERT(new_vals_r.empty());
//BLT_ASSERT(stack_after.empty());
blt::size_t bytes_expected = 0;
auto bytes_size = vals_r.size().total_used_bytes;
//BLT_ASSERT(stack_after.empty());
blt::size_t bytes_expected = 0;
auto bytes_size = vals_r.size().total_used_bytes;
for (const auto& op : c.get_operations())
{
if (op.is_value())
bytes_expected += op.type_size();
}
for (const auto& op : c.get_operations())
{
if (op.is_value())
bytes_expected += op.type_size();
}
if (bytes_expected != bytes_size)
{
BLT_WARN_STREAM << "Stack state: " << vals_r.size() << "\n";
BLT_WARN("Child tree bytes %ld vs expected %ld, difference: %ld", bytes_size, bytes_expected,
static_cast<blt::ptrdiff_t>(bytes_expected) - static_cast<blt::ptrdiff_t>(bytes_size));
BLT_TRACE("Total bytes after: %ld", total_bytes_after);
BLT_ABORT("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
}
auto copy = c;
try
{
if (!copy.check(program, detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
// 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";
std::cout << "our root type is " << ops_r[begin_point].id() << " with size " << ops_r[begin_point].type_size()
<< "\n";
std::cout << "now Named: " << (program.get_name(ops_r[begin_point].id()) ? *program.get_name(ops_r[begin_point].id()) : "Unnamed") << "\n";
std::cout << "Was named: " << (program.get_name(begin_operator_id) ? *program.get_name(begin_operator_id) : "Unnamed") << "\n";
//std::cout << "Parent:" << std::endl;
//p.print(program, std::cout, false, true);
std::cout << "Child:" << std::endl;
c.print(program, std::cout, false, true);
std::cout << std::endl;
c.print(program, std::cout, true, true);
std::cout << std::endl;
throw std::exception();
}
if (bytes_expected != bytes_size)
{
BLT_WARN_STREAM << "Stack state: " << vals_r.size() << "\n";
BLT_WARN("Child tree bytes %ld vs expected %ld, difference: %ld", bytes_size, bytes_expected,
static_cast<blt::ptrdiff_t>(bytes_expected) - static_cast<blt::ptrdiff_t>(bytes_size));
BLT_TRACE("Total bytes after: %ld", total_bytes_after);
BLT_ABORT("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
}
auto copy = c;
try
{
if (!copy.check(detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
// 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";
std::cout << "our root type is " << ops_r[begin_point].id() << " with size " << ops_r[begin_point].type_size()
<< "\n";
std::cout << "now Named: " << (program.get_name(ops_r[begin_point].id()) ? *program.get_name(ops_r[begin_point].id()) : "Unnamed") <<
"\n";
std::cout << "Was named: " << (program.get_name(begin_operator_id) ? *program.get_name(begin_operator_id) : "Unnamed") << "\n";
//std::cout << "Parent:" << std::endl;
//p.print(program, std::cout, false, true);
std::cout << "Child:" << std::endl;
c.print(std::cout, false, true);
std::cout << std::endl;
c.print(std::cout, true, true);
std::cout << std::endl;
throw std::exception();
}
#endif
return begin_point + new_ops_r.size();
}
@ -485,7 +489,8 @@ namespace blt::gp
blt::size_t found_bytes = vals.size().total_used_bytes;
blt::size_t expected_bytes = std::accumulate(ops.begin(),
ops.end(), 0ul,
[](const auto& v1, const auto& v2) {
[](const auto& v1, const auto& v2)
{
if (v2.is_value())
return v1 + v2.type_size();
return v1;
@ -550,12 +555,12 @@ namespace blt::gp
};
}
#if BLT_DEBUG_LEVEL >= 2
if (!c.check(program, detail::debug::context_ptr))
if (!c.check(detail::debug::context_ptr))
{
std::cout << "Parent: " << std::endl;
c_copy.print(program, std::cout, false, true);
c_copy.print(std::cout, false, true);
std::cout << "Child Values:" << std::endl;
c.print(program, std::cout, true, true);
c.print(std::cout, true, true);
std::cout << std::endl;
BLT_ABORT("Tree Check Failed.");
}
@ -647,14 +652,14 @@ namespace blt::gp
});
#if BLT_DEBUG_LEVEL >= 2
if (!c.check(program, detail::debug::context_ptr))
if (!c.check(detail::debug::context_ptr))
{
std::cout << "Parent: " << std::endl;
p.print(program, std::cout, false, true);
p.print(std::cout, false, true);
std::cout << "Child:" << std::endl;
c.print(program, std::cout, false, true);
c.print(std::cout, false, true);
std::cout << "Child Values:" << std::endl;
c.print(program, std::cout, true, true);
c.print(std::cout, true, true);
std::cout << std::endl;
BLT_ABORT("Tree Check Failed.");
}
@ -710,12 +715,12 @@ namespace blt::gp
vals.copy_from(storage_ptr, for_bytes + after_bytes);
#if BLT_DEBUG_LEVEL >= 2
if (!c.check(program, detail::debug::context_ptr))
if (!c.check(detail::debug::context_ptr))
{
std::cout << "Parent: " << std::endl;
p.print(program, std::cout, false, true);
p.print(std::cout, false, true);
std::cout << "Child Values:" << std::endl;
c.print(program, std::cout, true, true);
c.print(std::cout, true, true);
std::cout << std::endl;
BLT_ABORT("Tree Check Failed.");
}
@ -802,7 +807,7 @@ namespace blt::gp
case mutation_operator::END:
default:
#if BLT_DEBUG_LEVEL > 1
BLT_ABORT("You shouldn't be able to get here!");
BLT_ABORT("You shouldn't be able to get here!");
#else
BLT_UNREACHABLE;
#endif
@ -810,12 +815,12 @@ namespace blt::gp
}
#if BLT_DEBUG_LEVEL >= 2
if (!c.check(program, detail::debug::context_ptr))
if (!c.check(detail::debug::context_ptr))
{
std::cout << "Parent: " << std::endl;
p.print(program, std::cout, false, true);
p.print(std::cout, false, true);
std::cout << "Child Values:" << std::endl;
c.print(program, std::cout, true, true);
c.print(std::cout, true, true);
std::cout << std::endl;
BLT_ABORT("Tree Check Failed.");
}

View File

@ -58,7 +58,7 @@ namespace blt::gp
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(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;
@ -78,9 +78,9 @@ namespace blt::gp
}
for (const auto& v : operations)
{
auto info = program.get_operator_info(v.id());
const auto name = program.get_name(v.id()) ? program.get_name(v.id()).value() : "NULL";
auto return_type = get_return_type(program, info.return_type, include_types);
auto info = m_program->get_operator_info(v.id());
const auto name = m_program->get_name(v.id()) ? m_program->get_name(v.id()).value() : "NULL";
auto return_type = get_return_type(*m_program, info.return_type, include_types);
if (info.argc.argc > 0)
{
create_indent(out, indent, pretty_print) << "(";
@ -93,9 +93,9 @@ namespace blt::gp
if (print_literals)
{
create_indent(out, indent, pretty_print);
if (program.is_operator_ephemeral(v.id()))
if (m_program->is_operator_ephemeral(v.id()))
{
program.get_print_func(v.id())(out, reversed);
m_program->get_print_func(v.id())(out, reversed);
reversed.pop_bytes(v.type_size());
}
else
@ -286,7 +286,7 @@ namespace blt::gp
return m_program->get_eval_func()(*this, ptr);
}
bool tree_t::check(gp_program& program, void* context) const
bool tree_t::check(void* context) const
{
blt::size_t bytes_expected = 0;
const auto bytes_size = values.size().total_used_bytes;
@ -312,8 +312,8 @@ namespace blt::gp
auto value_stack = values;
auto& values_process = results.values;
blt::size_t total_produced = 0;
blt::size_t total_consumed = 0;
size_t total_produced = 0;
size_t total_consumed = 0;
for (const auto& operation : iterate(operations).rev())
{
@ -323,17 +323,17 @@ namespace blt::gp
total_produced += operation.type_size();
continue;
}
auto& info = program.get_operator_info(operation.id());
auto& info = m_program->get_operator_info(operation.id());
for (auto& arg : info.argument_types)
total_consumed += program.get_typesystem().get_type(arg).size();
program.get_operator_info(operation.id()).func(context, values_process, values_process);
total_produced += program.get_typesystem().get_type(info.return_type).size();
total_consumed += m_program->get_typesystem().get_type(arg).size();
m_program->get_operator_info(operation.id()).func(context, values_process, values_process);
total_produced += m_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());
program.get_destroy_func(operations.front().id())(detail::destroy_t::RETURN, results.values);
m_program->get_destroy_func(operations.front().id())(detail::destroy_t::RETURN, results.values);
if (v1 != v2)
{
const auto vd = std::abs(v1 - v2);
@ -367,10 +367,6 @@ namespace blt::gp
}
}
tree_t::tree_t(gp_program& program): m_program(&program)
{
}
void tree_t::clear(gp_program& program)
{
auto* f = &program;

View File

@ -127,6 +127,11 @@ bool fitness_function(const tree_t& current_tree, fitness_t& fitness, size_t)
int main()
{
int hello = 32;
int* silly = &hello;
blt::mem::print_bytes(std::cout, silly);
return 0;
operator_builder<context> builder{};
builder.build(add, sub, mul, pro_div, op_sin, op_cos, op_exp, op_log, lit, op_x);
regression.get_program().set_operations(builder.grab());