silly
parent
366928fe56
commit
966d64d239
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(blt-gp VERSION 0.0.137)
|
project(blt-gp VERSION 0.0.138)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ macro(blt_add_project name source type)
|
||||||
|
|
||||||
# set (passRegex "Pass" "Passed" "PASS" "PASSED")
|
# set (passRegex "Pass" "Passed" "PASS" "PASSED")
|
||||||
# set (failRegex "WARN" "FAIL" "ERROR" "FATAL")
|
# set (failRegex "WARN" "FAIL" "ERROR" "FATAL")
|
||||||
set (failRegex "\[WARN\]" "FAIL" "ERROR" "FATAL" "exception")
|
set (failRegex "\\[WARN\\]" "FAIL" "ERROR" "FATAL" "exception")
|
||||||
|
|
||||||
# set_property (TEST ${name} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}")
|
# set_property (TEST ${name} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}")
|
||||||
set_property (TEST ${name} PROPERTY FAIL_REGULAR_EXPRESSION "${failRegex}")
|
set_property (TEST ${name} PROPERTY FAIL_REGULAR_EXPRESSION "${failRegex}")
|
||||||
|
|
|
@ -52,13 +52,22 @@ namespace blt::gp
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
// requires operator[](bit_index), push_back, clear
|
||||||
|
using bitmask_t = std::vector<bool>;
|
||||||
|
|
||||||
class operator_storage_test;
|
class operator_storage_test;
|
||||||
// context*, read stack, write stack
|
// context*, read stack, write stack
|
||||||
using callable_t = std::function<void(void*, stack_allocator&, stack_allocator&)>;
|
using callable_t = std::function<void(void*, stack_allocator&, stack_allocator&, bitmask_t*)>;
|
||||||
// to, from
|
|
||||||
using transfer_t = std::function<void(std::optional<std::reference_wrapper<stack_allocator>>, stack_allocator&)>;
|
|
||||||
// debug function,
|
// debug function,
|
||||||
using print_func_t = std::function<void(std::ostream&, stack_allocator&)>;
|
using print_func_t = std::function<void(std::ostream&, stack_allocator&)>;
|
||||||
|
|
||||||
|
enum class destroy_t
|
||||||
|
{
|
||||||
|
ARGS,
|
||||||
|
RETURN
|
||||||
|
};
|
||||||
|
|
||||||
|
using destroy_func_t = std::function<void(destroy_t, bitmask_t* mask, stack_allocator&)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,16 +102,16 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename context = void, typename... NoCtxArgs>
|
template<typename context = void, typename... NoCtxArgs>
|
||||||
void call_destructors_without_first(stack_allocator& read_allocator)
|
void call_destructors_without_first(stack_allocator& read_allocator, detail::bitmask_t* mask)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(NoCtxArgs) > 0)
|
if constexpr (sizeof...(NoCtxArgs) > 0)
|
||||||
{
|
{
|
||||||
read_allocator.call_destructors<detail::remove_cv_ref<NoCtxArgs>...>();
|
read_allocator.call_destructors<detail::remove_cv_ref<NoCtxArgs>...>(mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func, typename... ExtraArgs>
|
template<typename Func, typename... ExtraArgs>
|
||||||
Return operator()(bool, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
Return operator()(bool has_context, detail::bitmask_t* mask, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
||||||
{
|
{
|
||||||
constexpr auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
constexpr auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||||
#if BLT_DEBUG_LEVEL > 0
|
#if BLT_DEBUG_LEVEL > 0
|
||||||
|
@ -119,10 +119,10 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
Return ret = exec_sequence_to_indices(std::forward<Func>(func), read_allocator, seq, std::forward<ExtraArgs>(args)...);
|
Return ret = exec_sequence_to_indices(std::forward<Func>(func), read_allocator, seq, std::forward<ExtraArgs>(args)...);
|
||||||
/*if (has_context)
|
if (has_context)
|
||||||
call_destructors_without_first<Args...>(read_allocator);
|
call_destructors_without_first<Args...>(read_allocator, mask);
|
||||||
else
|
else
|
||||||
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>();*/
|
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>(mask);
|
||||||
read_allocator.pop_bytes((stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() + ...));
|
read_allocator.pop_bytes((stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() + ...));
|
||||||
return ret;
|
return ret;
|
||||||
#if BLT_DEBUG_LEVEL > 0
|
#if BLT_DEBUG_LEVEL > 0
|
||||||
|
@ -158,18 +158,18 @@ namespace blt::gp
|
||||||
constexpr explicit operation_t(const Functor& functor, std::optional<std::string_view> name = {}): func(functor), name(name)
|
constexpr explicit operation_t(const Functor& functor, std::optional<std::string_view> name = {}): func(functor), name(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
[[nodiscard]] constexpr inline Return operator()(stack_allocator& read_allocator) const
|
[[nodiscard]] constexpr inline Return operator()(stack_allocator& read_allocator, detail::bitmask_t* mask) const
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(Args) == 0)
|
if constexpr (sizeof...(Args) == 0)
|
||||||
{
|
{
|
||||||
return func();
|
return func();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return call_with<Return, Args...>()(false, func, read_allocator);
|
return call_with<Return, Args...>()(false, mask, func, read_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& read_allocator) const
|
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& read_allocator, detail::bitmask_t* mask) const
|
||||||
{
|
{
|
||||||
// should be an impossible state
|
// should be an impossible state
|
||||||
if constexpr (sizeof...(Args) == 0)
|
if constexpr (sizeof...(Args) == 0)
|
||||||
|
@ -182,22 +182,22 @@ namespace blt::gp
|
||||||
return func(ctx_ref);
|
return func(ctx_ref);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return call_without_first<Return, Args...>()(true, func, read_allocator, ctx_ref);
|
return call_without_first<Return, Args...>()(true, mask, func, read_allocator, ctx_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
[[nodiscard]] detail::callable_t make_callable() const
|
[[nodiscard]] detail::callable_t make_callable() const
|
||||||
{
|
{
|
||||||
return [this](void* context, stack_allocator& read_allocator, stack_allocator& write_allocator) {
|
return [this](void* context, stack_allocator& read_allocator, stack_allocator& write_allocator, detail::bitmask_t* mask) {
|
||||||
if constexpr (detail::is_same_v<Context, detail::remove_cv_ref<typename detail::first_arg<Args...>::type>>)
|
if constexpr (detail::is_same_v<Context, detail::remove_cv_ref<typename detail::first_arg<Args...>::type>>)
|
||||||
{
|
{
|
||||||
// first arg is context
|
// first arg is context
|
||||||
write_allocator.push(this->operator()(context, read_allocator));
|
write_allocator.push(this->operator()(context, read_allocator, mask));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// first arg isn't context
|
// first arg isn't context
|
||||||
write_allocator.push(this->operator()(read_allocator));
|
write_allocator.push(this->operator()(read_allocator, mask));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ namespace blt::gp
|
||||||
blt::hashset_t<operator_id> static_types;
|
blt::hashset_t<operator_id> static_types;
|
||||||
std::vector<operator_info> operators;
|
std::vector<operator_info> operators;
|
||||||
std::vector<detail::print_func_t> print_funcs;
|
std::vector<detail::print_func_t> print_funcs;
|
||||||
|
std::vector<detail::destroy_func_t> destroy_funcs;
|
||||||
std::vector<std::optional<std::string_view>> names;
|
std::vector<std::optional<std::string_view>> names;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,13 +136,24 @@ namespace blt::gp
|
||||||
storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) {
|
storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) {
|
||||||
if constexpr (blt::meta::is_streamable_v<Return>)
|
if constexpr (blt::meta::is_streamable_v<Return>)
|
||||||
{
|
{
|
||||||
out << stack.pop<Return>();
|
out << stack.from<Return>(0);
|
||||||
(void) (op); // remove warning
|
(void) (op); // remove warning
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
out << "[Printing Value on '" << (op.get_name() ? *op.get_name() : "") << "' Not Supported!]";
|
out << "[Printing Value on '" << (op.get_name() ? *op.get_name() : "") << "' Not Supported!]";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
storage.destroy_funcs.push_back([](detail::destroy_t type, detail::bitmask_t* mask, stack_allocator& alloc) {
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case detail::destroy_t::ARGS:
|
||||||
|
alloc.call_destructors<Args...>(mask);
|
||||||
|
break;
|
||||||
|
case detail::destroy_t::RETURN:
|
||||||
|
alloc.from<detail::remove_cv_ref<Return>>(0).drop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
storage.names.push_back(op.get_name());
|
storage.names.push_back(op.get_name());
|
||||||
if (is_static)
|
if (is_static)
|
||||||
storage.static_types.insert(operator_id);
|
storage.static_types.insert(operator_id);
|
||||||
|
@ -374,6 +386,8 @@ namespace blt::gp
|
||||||
void reset_program(type_id root_type, bool eval_fitness_now = true)
|
void reset_program(type_id root_type, bool eval_fitness_now = true)
|
||||||
{
|
{
|
||||||
current_generation = 0;
|
current_generation = 0;
|
||||||
|
for (auto& pop : current_pop)
|
||||||
|
pop.tree.drop(*this);
|
||||||
current_pop = config.pop_initializer.get().generate(
|
current_pop = config.pop_initializer.get().generate(
|
||||||
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
|
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
|
||||||
if (eval_fitness_now)
|
if (eval_fitness_now)
|
||||||
|
@ -484,6 +498,11 @@ namespace blt::gp
|
||||||
return storage.print_funcs[id];
|
return storage.print_funcs[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline detail::destroy_func_t& get_destroy_func(operator_id id)
|
||||||
|
{
|
||||||
|
return storage.destroy_funcs[id];
|
||||||
|
}
|
||||||
|
|
||||||
inline std::optional<std::string_view> get_name(operator_id id)
|
inline std::optional<std::string_view> get_name(operator_id id)
|
||||||
{
|
{
|
||||||
return storage.names[id];
|
return storage.names[id];
|
||||||
|
@ -521,6 +540,12 @@ namespace blt::gp
|
||||||
|
|
||||||
~gp_program()
|
~gp_program()
|
||||||
{
|
{
|
||||||
|
std::cout << ("Destroying Program!") << std::endl;
|
||||||
|
for (auto& pop : current_pop.get_individuals())
|
||||||
|
{
|
||||||
|
pop.tree.drop(*this);
|
||||||
|
pop = {};
|
||||||
|
}
|
||||||
thread_helper.lifetime_over = true;
|
thread_helper.lifetime_over = true;
|
||||||
thread_helper.barrier.notify_all();
|
thread_helper.barrier.notify_all();
|
||||||
thread_helper.thread_function_condition.notify_all();
|
thread_helper.thread_function_condition.notify_all();
|
||||||
|
|
|
@ -234,7 +234,7 @@ namespace blt::gp
|
||||||
NO_REF_T t = *reinterpret_cast<NO_REF_T*>(head->metadata.offset - TYPE_SIZE);
|
NO_REF_T t = *reinterpret_cast<NO_REF_T*>(head->metadata.offset - TYPE_SIZE);
|
||||||
// call destructor
|
// call destructor
|
||||||
if constexpr (detail::has_func_drop_v<T>)
|
if constexpr (detail::has_func_drop_v<T>)
|
||||||
call_drop<NO_REF_T>(0);
|
call_drop<NO_REF_T>(0, 0, nullptr);
|
||||||
// move offset back
|
// move offset back
|
||||||
head->metadata.offset -= TYPE_SIZE;
|
head->metadata.offset -= TYPE_SIZE;
|
||||||
// moving back allows us to allocate with other data, if there is room.
|
// moving back allows us to allocate with other data, if there is room.
|
||||||
|
@ -347,11 +347,22 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
void call_destructors()
|
void call_destructors(detail::bitmask_t* mask)
|
||||||
{
|
{
|
||||||
|
if constexpr (sizeof...(Args) > 0) {
|
||||||
blt::size_t offset = (stack_allocator::aligned_size<NO_REF_T<Args>>() + ...) -
|
blt::size_t offset = (stack_allocator::aligned_size<NO_REF_T<Args>>() + ...) -
|
||||||
stack_allocator::aligned_size<NO_REF_T<typename blt::meta::arg_helper<Args...>::First>>();
|
stack_allocator::aligned_size<NO_REF_T<typename blt::meta::arg_helper<Args...>::First>>();
|
||||||
((call_drop<Args>(offset), offset -= stack_allocator::aligned_size<NO_REF_T<Args>>()), ...);
|
blt::size_t index = 0;
|
||||||
|
if (mask != nullptr)
|
||||||
|
index = mask->size() - sizeof...(Args);
|
||||||
|
((call_drop<Args>(offset, index, mask), offset -= stack_allocator::aligned_size<NO_REF_T<Args>>(), ++index), ...);
|
||||||
|
if (mask != nullptr)
|
||||||
|
{
|
||||||
|
auto& mask_r = *mask;
|
||||||
|
for (blt::size_t i = 0; i < sizeof...(Args); i++)
|
||||||
|
mask_r.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool empty() const noexcept
|
[[nodiscard]] bool empty() const noexcept
|
||||||
|
@ -552,10 +563,16 @@ namespace blt::gp
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void call_drop(blt::size_t offset)
|
inline void call_drop(blt::size_t offset, blt::size_t index, detail::bitmask_t* mask)
|
||||||
{
|
{
|
||||||
if constexpr (detail::has_func_drop_v<T>)
|
if constexpr (detail::has_func_drop_v<T>)
|
||||||
{
|
{
|
||||||
|
if (mask != nullptr)
|
||||||
|
{
|
||||||
|
auto& mask_r = *mask;
|
||||||
|
if (!mask_r[index])
|
||||||
|
return;
|
||||||
|
}
|
||||||
from<NO_REF_T<T>>(offset).drop();
|
from<NO_REF_T<T>>(offset).drop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,31 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
using iter_type = std::vector<op_container_t>::const_iterator;
|
using iter_type = std::vector<op_container_t>::const_iterator;
|
||||||
public:
|
public:
|
||||||
|
tree_t(): reference_counter(new std::atomic_int64_t(1))
|
||||||
|
{}
|
||||||
|
|
||||||
|
tree_t(const tree_t& copy): operations(copy.operations), values(copy.values), reference_counter(copy.reference_counter)
|
||||||
|
{
|
||||||
|
reference_counter->operator++();
|
||||||
|
}
|
||||||
|
|
||||||
|
tree_t(tree_t&& move) noexcept:
|
||||||
|
operations(std::move(move.operations)), values(std::move(move.values)), reference_counter(move.reference_counter)
|
||||||
|
{
|
||||||
|
move.reference_counter = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree_t& operator=(const tree_t& copy) = delete;
|
||||||
|
|
||||||
|
tree_t& operator=(tree_t&& move) noexcept
|
||||||
|
{
|
||||||
|
operations = std::exchange(operations, std::move(move.operations));
|
||||||
|
values = std::exchange(values, std::move(move.values));
|
||||||
|
reference_counter = std::exchange(reference_counter, move.reference_counter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] inline std::vector<op_container_t>& get_operations()
|
[[nodiscard]] inline std::vector<op_container_t>& get_operations()
|
||||||
{
|
{
|
||||||
return operations;
|
return operations;
|
||||||
|
@ -147,9 +172,21 @@ namespace blt::gp
|
||||||
return total_value_bytes(operations.begin(), operations.end());
|
return total_value_bytes(operations.begin(), operations.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drop(gp_program& program);
|
||||||
|
|
||||||
|
~tree_t()
|
||||||
|
{
|
||||||
|
if (reference_counter == nullptr)
|
||||||
|
return;
|
||||||
|
reference_counter->operator--();
|
||||||
|
if (*reference_counter == 0)
|
||||||
|
delete reference_counter;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<op_container_t> operations;
|
std::vector<op_container_t> operations;
|
||||||
blt::gp::stack_allocator values;
|
blt::gp::stack_allocator values;
|
||||||
|
std::atomic_int64_t* reference_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fitness_t
|
struct fitness_t
|
||||||
|
|
2
lib/blt
2
lib/blt
|
@ -1 +1 @@
|
||||||
Subproject commit 92300bc6a29927f5354d516df76ad40be7fca868
|
Subproject commit 644f42684320edc95f9fd5fc3b203bda3c4e6633
|
|
@ -71,7 +71,7 @@ namespace blt::gp
|
||||||
|
|
||||||
if (args.program.is_static(top.id))
|
if (args.program.is_static(top.id))
|
||||||
{
|
{
|
||||||
info.function(nullptr, tree.get_values(), tree.get_values());
|
info.function(nullptr, tree.get_values(), tree.get_values(), nullptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
49
src/tree.cpp
49
src/tree.cpp
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
namespace blt::gp
|
namespace blt::gp
|
||||||
{
|
{
|
||||||
inline auto empty_callable = detail::callable_t([](void*, stack_allocator&, stack_allocator&) { BLT_ABORT("This should never be called!"); });
|
inline auto empty_callable = detail::callable_t(
|
||||||
|
[](void*, stack_allocator&, stack_allocator&, detail::bitmask_t*) { BLT_ABORT("This should never be called!"); });
|
||||||
|
|
||||||
evaluation_context tree_t::evaluate(void* context) const
|
evaluation_context tree_t::evaluate(void* context) const
|
||||||
{
|
{
|
||||||
|
@ -47,15 +48,19 @@ namespace blt::gp
|
||||||
|
|
||||||
auto value_stack = values;
|
auto value_stack = values;
|
||||||
auto& values_process = results.values;
|
auto& values_process = results.values;
|
||||||
|
static thread_local detail::bitmask_t bitfield;
|
||||||
|
bitfield.clear();
|
||||||
|
|
||||||
for (const auto& operation : blt::reverse_iterate(operations.begin(), operations.end()))
|
for (const auto& operation : blt::reverse_iterate(operations.begin(), operations.end()))
|
||||||
{
|
{
|
||||||
if (operation.is_value)
|
if (operation.is_value)
|
||||||
{
|
{
|
||||||
value_stack.transfer_bytes(values_process, operation.type_size);
|
value_stack.transfer_bytes(values_process, operation.type_size);
|
||||||
|
bitfield.push_back(false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
operation.func(context, values_process, values_process);
|
operation.func(context, values_process, values_process, &bitfield);
|
||||||
|
bitfield.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
@ -222,6 +227,8 @@ namespace blt::gp
|
||||||
|
|
||||||
bool tree_t::check(gp_program& program, void* context) const
|
bool tree_t::check(gp_program& program, void* context) const
|
||||||
{
|
{
|
||||||
|
static thread_local detail::bitmask_t bitfield;
|
||||||
|
bitfield.clear();
|
||||||
blt::size_t bytes_expected = 0;
|
blt::size_t bytes_expected = 0;
|
||||||
auto bytes_size = values.size().total_used_bytes;
|
auto bytes_size = values.size().total_used_bytes;
|
||||||
|
|
||||||
|
@ -255,12 +262,14 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
value_stack.transfer_bytes(values_process, operation.type_size);
|
value_stack.transfer_bytes(values_process, operation.type_size);
|
||||||
total_produced += stack_allocator::aligned_size(operation.type_size);
|
total_produced += stack_allocator::aligned_size(operation.type_size);
|
||||||
|
bitfield.push_back(false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto& info = program.get_operator_info(operation.id);
|
auto& info = program.get_operator_info(operation.id);
|
||||||
for (auto& arg : info.argument_types)
|
for (auto& arg : info.argument_types)
|
||||||
total_consumed += stack_allocator::aligned_size(program.get_typesystem().get_type(arg).size());
|
total_consumed += stack_allocator::aligned_size(program.get_typesystem().get_type(arg).size());
|
||||||
operation.func(context, values_process, values_process);
|
operation.func(context, values_process, values_process, &bitfield);
|
||||||
|
bitfield.push_back(true);
|
||||||
total_produced += stack_allocator::aligned_size(program.get_typesystem().get_type(info.return_type).size());
|
total_produced += stack_allocator::aligned_size(program.get_typesystem().get_type(info.return_type).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,4 +285,38 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tree_t::drop(gp_program& program)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
if (values.empty())
|
||||||
|
return;
|
||||||
|
std::cout << "---- NEW TREE ---- References " << *reference_counter << " ----" << std::endl;
|
||||||
|
if (reference_counter->load() > 1)
|
||||||
|
return;
|
||||||
|
static blt::hashset_t<blt::size_t> sets;
|
||||||
|
while (!operations.empty())
|
||||||
|
{
|
||||||
|
auto operation = operations.back();
|
||||||
|
if (operation.is_value)
|
||||||
|
{
|
||||||
|
struct hello
|
||||||
|
{
|
||||||
|
float* f;
|
||||||
|
blt::size_t i;
|
||||||
|
};
|
||||||
|
auto h = values.from<hello>(0);
|
||||||
|
if (sets.find(h.i) != sets.end())
|
||||||
|
std::cout << "HEY ASSHOLE Duplicate Value " << h.i << std::endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Destroying Value " << h.i << std::endl;
|
||||||
|
sets.insert(h.i);
|
||||||
|
}
|
||||||
|
program.get_destroy_func(operation.id)(detail::destroy_t::RETURN, nullptr, values);
|
||||||
|
values.pop_bytes(static_cast<blt::ptrdiff_t>(stack_allocator::aligned_size(operation.type_size)));
|
||||||
|
}
|
||||||
|
operations.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -53,41 +53,47 @@ class move_float
|
||||||
move_float(): f(new float()), assignment(++last_value)
|
move_float(): f(new float()), assignment(++last_value)
|
||||||
{
|
{
|
||||||
constructions++;
|
constructions++;
|
||||||
BLT_TRACE("Value %ld Default Constructed", assignment);
|
//BLT_TRACE("Value %ld Default Constructed", assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit move_float(float f): f(new float(f)), assignment(++last_value)
|
explicit move_float(float f): f(new float(f)), assignment(++last_value)
|
||||||
{
|
{
|
||||||
constructions++;
|
constructions++;
|
||||||
BLT_TRACE("Value %ld Constructed", assignment);
|
//BLT_TRACE("Value %ld Constructed", assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator float() const
|
explicit operator float() const
|
||||||
{
|
{
|
||||||
BLT_TRACE("Using value %ld", assignment);
|
//BLT_TRACE("Using value %ld", assignment);
|
||||||
return *f;
|
return *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] float get() const
|
[[nodiscard]] float get() const
|
||||||
{
|
{
|
||||||
BLT_TRACE("Using value %ld", assignment);
|
//BLT_TRACE("Using value %ld", assignment);
|
||||||
return *f;
|
return *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float operator*() const
|
float operator*() const
|
||||||
{
|
{
|
||||||
BLT_TRACE("Using value %ld", assignment);
|
//BLT_TRACE("Using value %ld", assignment);
|
||||||
return *f;
|
return *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drop() // NOLINT
|
void drop() // NOLINT
|
||||||
{
|
{
|
||||||
BLT_TRACE("Drop Called On %ld", assignment);
|
//BLT_TRACE("Drop Called On %ld", assignment);
|
||||||
delete f;
|
delete f;
|
||||||
f = nullptr;
|
f = nullptr;
|
||||||
destructions++;
|
destructions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& stream, const move_float& e)
|
||||||
|
{
|
||||||
|
stream << *e;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float* f = nullptr;
|
float* f = nullptr;
|
||||||
blt::size_t assignment;
|
blt::size_t assignment;
|
||||||
|
@ -106,13 +112,13 @@ std::array<context, 200> fitness_cases;
|
||||||
blt::gp::prog_config_t config = blt::gp::prog_config_t()
|
blt::gp::prog_config_t config = blt::gp::prog_config_t()
|
||||||
.set_initial_min_tree_size(2)
|
.set_initial_min_tree_size(2)
|
||||||
.set_initial_max_tree_size(6)
|
.set_initial_max_tree_size(6)
|
||||||
.set_elite_count(2)
|
.set_elite_count(0)
|
||||||
.set_crossover_chance(0.9)
|
.set_crossover_chance(0.9)
|
||||||
.set_mutation_chance(0.1)
|
.set_mutation_chance(0.1)
|
||||||
.set_reproduction_chance(0)
|
.set_reproduction_chance(0)
|
||||||
.set_max_generations(1)
|
.set_max_generations(5)
|
||||||
.set_pop_size(1)
|
.set_pop_size(500)
|
||||||
.set_thread_count(1);
|
.set_thread_count(0);
|
||||||
|
|
||||||
blt::gp::type_provider type_system;
|
blt::gp::type_provider type_system;
|
||||||
blt::gp::gp_program program{type_system, SEED, config};
|
blt::gp::gp_program program{type_system, SEED, config};
|
||||||
|
@ -137,7 +143,10 @@ constexpr auto fitness_function = [](blt::gp::tree_t& current_tree, blt::gp::fit
|
||||||
constexpr double value_cutoff = 1.e15;
|
constexpr double value_cutoff = 1.e15;
|
||||||
for (auto& fitness_case : fitness_cases)
|
for (auto& fitness_case : fitness_cases)
|
||||||
{
|
{
|
||||||
auto diff = std::abs(fitness_case.y - *current_tree.get_evaluation_value<move_float>(&fitness_case));
|
auto ctx = current_tree.evaluate(&fitness_case);
|
||||||
|
auto diff = std::abs(fitness_case.y - *current_tree.get_evaluation_ref<move_float>(ctx));
|
||||||
|
// this will call the drop function.
|
||||||
|
current_tree.get_evaluation_value<move_float>(ctx);
|
||||||
if (diff < value_cutoff)
|
if (diff < value_cutoff)
|
||||||
{
|
{
|
||||||
fitness.raw_fitness += diff;
|
fitness.raw_fitness += diff;
|
||||||
|
@ -211,7 +220,7 @@ int main()
|
||||||
|
|
||||||
BLT_END_INTERVAL("Symbolic Regression", "Main");
|
BLT_END_INTERVAL("Symbolic Regression", "Main");
|
||||||
|
|
||||||
auto best = program.get_best_individuals<3>();
|
auto best = program.get_best_individuals<1>();
|
||||||
|
|
||||||
BLT_INFO("Best approximations:");
|
BLT_INFO("Best approximations:");
|
||||||
for (auto& i_ref : best)
|
for (auto& i_ref : best)
|
||||||
|
|
|
@ -63,7 +63,7 @@ blt::gp::op_container_t make_container(blt::gp::operator_id id)
|
||||||
|
|
||||||
blt::gp::op_container_t make_value(const blt::gp::type& id)
|
blt::gp::op_container_t make_value(const blt::gp::type& id)
|
||||||
{
|
{
|
||||||
static blt::gp::detail::callable_t empty([](void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&) {});
|
static blt::gp::detail::callable_t empty([](void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&, blt::gp::detail::bitmask_t*) {});
|
||||||
return {empty, id.size(), 0, true};
|
return {empty, id.size(), 0, true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ int main()
|
||||||
return f + g;
|
return f + g;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::cout << silly_op(alloc) << std::endl;
|
std::cout << silly_op(alloc, nullptr) << std::endl;
|
||||||
|
|
||||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||||
|
|
||||||
|
@ -456,15 +456,15 @@ int main()
|
||||||
context hello{5, 10};
|
context hello{5, 10};
|
||||||
|
|
||||||
alloc.push(1.153f);
|
alloc.push(1.153f);
|
||||||
de[0](static_cast<void*>(&hello), alloc, alloc);
|
de[0](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||||
BLT_TRACE("first value: %f", alloc.pop<float>());
|
BLT_TRACE("first value: %f", alloc.pop<float>());
|
||||||
|
|
||||||
de[1](static_cast<void*>(&hello), alloc, alloc);
|
de[1](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||||
BLT_TRACE("second value: %f", alloc.pop<float>());
|
BLT_TRACE("second value: %f", alloc.pop<float>());
|
||||||
|
|
||||||
alloc.push(1.0f);
|
alloc.push(1.0f);
|
||||||
alloc.push(52.213f);
|
alloc.push(52.213f);
|
||||||
de[2](static_cast<void*>(&hello), alloc, alloc);
|
de[2](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||||
BLT_TRACE("third value: %f", alloc.pop<float>());
|
BLT_TRACE("third value: %f", alloc.pop<float>());
|
||||||
|
|
||||||
//auto* pointer = static_cast<void*>(head->metadata.offset);
|
//auto* pointer = static_cast<void*>(head->metadata.offset);
|
||||||
|
@ -482,7 +482,7 @@ int main()
|
||||||
|
|
||||||
//blt::span<void*, 3> spv{arr};
|
//blt::span<void*, 3> spv{arr};
|
||||||
|
|
||||||
std::cout << silly_op.operator()(alloc) << std::endl;
|
std::cout << silly_op.operator()(alloc, nullptr) << std::endl;
|
||||||
|
|
||||||
std::cout << "Hello World!" << std::endl;
|
std::cout << "Hello World!" << std::endl;
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ void test_basic()
|
||||||
stack.push(50.0f);
|
stack.push(50.0f);
|
||||||
stack.push(10.0f);
|
stack.push(10.0f);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<float>();
|
auto val = stack.pop<float>();
|
||||||
RUN_TEST(val != 60.000000f, stack, "Basic 2 Test Passed", "Basic 2 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(val != 60.000000f, stack, "Basic 2 Test Passed", "Basic 2 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -317,7 +317,7 @@ void test_basic()
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
||||||
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<float>();
|
auto val = stack.pop<float>();
|
||||||
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>>();
|
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>>();
|
||||||
|
@ -338,7 +338,7 @@ void test_mixed()
|
||||||
stack.push(false);
|
stack.push(false);
|
||||||
|
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<float>();
|
auto val = stack.pop<float>();
|
||||||
RUN_TEST(val != 50.000000f, stack, "Mixed 4 Test Passed", "Mixed 4 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(val != 50.000000f, stack, "Mixed 4 Test Passed", "Mixed 4 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -356,7 +356,7 @@ void test_mixed()
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
||||||
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<float>();
|
auto val = stack.pop<float>();
|
||||||
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>>();
|
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(float)>>();
|
||||||
|
@ -376,7 +376,7 @@ void test_large_256()
|
||||||
stack.push(69.420f);
|
stack.push(69.420f);
|
||||||
|
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_256>();
|
auto val = stack.pop<large_256>();
|
||||||
RUN_TEST(!compare(val, base_256), stack, "Large 256 3 Test Passed", "Large 256 3 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(!compare(val, base_256), stack, "Large 256 3 Test Passed", "Large 256 3 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -393,7 +393,7 @@ void test_large_256()
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
||||||
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_256>();
|
auto val = stack.pop<large_256>();
|
||||||
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(large_256)>>();
|
stack.pop<std::array<blt::u8, blt::gp::stack_allocator::page_size_no_block() - sizeof(large_256)>>();
|
||||||
|
@ -412,7 +412,7 @@ void test_large_4096()
|
||||||
stack.push(33.0f);
|
stack.push(33.0f);
|
||||||
stack.push(true);
|
stack.push(true);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_4096>();
|
auto val = stack.pop<large_4096>();
|
||||||
RUN_TEST(!compare(val, base_4096), stack, "Large 4096 3 Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(!compare(val, base_4096), stack, "Large 4096 3 Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -428,7 +428,7 @@ void test_large_4096()
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
||||||
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_4096>();
|
auto val = stack.pop<large_4096>();
|
||||||
RUN_TEST(!compare(val, base_4096), stack, "Large 4096 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(!compare(val, base_4096), stack, "Large 4096 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -446,7 +446,7 @@ void test_large_18290()
|
||||||
stack.push(-2543.0f);
|
stack.push(-2543.0f);
|
||||||
stack.push(true);
|
stack.push(true);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_18290>();
|
auto val = stack.pop<large_18290>();
|
||||||
RUN_TEST(!compare(val, base_18290), stack, "Large 18290 3 Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(!compare(val, base_18290), stack, "Large 18290 3 Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
@ -463,7 +463,7 @@ void test_large_18290()
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
BLT_ASSERT(size.blocks > 1 && "Stack doesn't have more than one block!");
|
||||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_18290>();
|
auto val = stack.pop<large_18290>();
|
||||||
stack.pop<std::array<blt::u8, 20480 - 18290 - blt::gp::stack_allocator::block_size()>>();
|
stack.pop<std::array<blt::u8, 20480 - 18290 - blt::gp::stack_allocator::block_size()>>();
|
||||||
|
@ -479,12 +479,12 @@ void test_large_18290()
|
||||||
stack.push(true);
|
stack.push(true);
|
||||||
auto size = stack.size();
|
auto size = stack.size();
|
||||||
BLT_TRACE_STREAM << size << "\n";
|
BLT_TRACE_STREAM << size << "\n";
|
||||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
stack.push(-2543.0f);
|
stack.push(-2543.0f);
|
||||||
stack.push(true);
|
stack.push(true);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||||
auto val = stack.pop<large_18290>();
|
auto val = stack.pop<large_18290>();
|
||||||
RUN_TEST(!compare(val, base_18290), stack, "Large 18290 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
RUN_TEST(!compare(val, base_18290), stack, "Large 18290 3 Boundary Test Passed", "Large 4096 3 Test Failed. Unexpected value produced '%lf'", val);
|
||||||
|
|
Loading…
Reference in New Issue