working on fixing memorys
parent
44571f5402
commit
f7d28d7a65
|
@ -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)
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
2
lib/blt
2
lib/blt
|
@ -1 +1 @@
|
|||
Subproject commit 4c462dff38a982bc5dc5212337af160bc018cce1
|
||||
Subproject commit 2e6abb8013a622771330c17f0d938db5f672f12b
|
|
@ -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.");
|
||||
}
|
||||
|
|
32
src/tree.cpp
32
src/tree.cpp
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue