Compare commits
8 Commits
914995fc82
...
bd230f075f
Author | SHA1 | Date |
---|---|---|
Brett | bd230f075f | |
Brett | 7aaad70132 | |
Brett | 46ceaf49dd | |
Brett | 3d82f69370 | |
Brett | 24f702b35e | |
Brett | 17a2805ef1 | |
Brett | 82b8c82768 | |
Brett | 52732bc1a1 |
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(blt-gp VERSION 0.1.12)
|
||||
project(blt-gp VERSION 0.1.19)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ blt::gp::prog_config_t config = blt::gp::prog_config_t()
|
|||
.set_mutation_chance(0.1)
|
||||
.set_reproduction_chance(0)
|
||||
.set_max_generations(50)
|
||||
.set_pop_size(500)
|
||||
.set_pop_size(5000)
|
||||
.set_thread_count(0);
|
||||
|
||||
blt::gp::type_provider type_system;
|
||||
|
@ -56,9 +56,10 @@ blt::gp::operation_t op_cos([](float a) { return std::cos(a); }, "cos");
|
|||
blt::gp::operation_t op_exp([](float a) { return std::exp(a); }, "exp");
|
||||
blt::gp::operation_t op_log([](float a) { return a == 0.0f ? 0.0f : std::log(a); }, "log");
|
||||
|
||||
blt::gp::operation_t lit([]() {
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
return program.get_random().get_float(-320.0f, 320.0f);
|
||||
}, "lit");
|
||||
}, "lit").set_ephemeral();
|
||||
|
||||
blt::gp::operation_t op_x([](const context& context) {
|
||||
return context.x;
|
||||
}, "x");
|
||||
|
@ -104,19 +105,7 @@ int main()
|
|||
type_system.register_type<float>();
|
||||
|
||||
blt::gp::operator_builder<context> builder{type_system};
|
||||
builder.add_operator(add);
|
||||
builder.add_operator(sub);
|
||||
builder.add_operator(mul);
|
||||
builder.add_operator(pro_div);
|
||||
builder.add_operator(op_sin);
|
||||
builder.add_operator(op_cos);
|
||||
builder.add_operator(op_exp);
|
||||
builder.add_operator(op_log);
|
||||
|
||||
builder.add_operator(lit, true);
|
||||
builder.add_operator(op_x);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(add, sub, mul, pro_div, op_sin, op_cos, op_exp, op_log, lit, op_x));
|
||||
|
||||
BLT_DEBUG("Generate Initial Population");
|
||||
auto sel = blt::gp::select_fitness_proportionate_t{};
|
||||
|
|
|
@ -52,12 +52,10 @@ namespace blt::gp
|
|||
|
||||
namespace detail
|
||||
{
|
||||
// requires operator[](bit_index), push_back, clear
|
||||
using bitmask_t = std::vector<bool>;
|
||||
|
||||
class operator_storage_test;
|
||||
// context*, read stack, write stack
|
||||
using callable_t = std::function<void(void*, stack_allocator&, stack_allocator&, bitmask_t*)>;
|
||||
using operator_func_t = std::function<void(void*, stack_allocator&, stack_allocator&)>;
|
||||
using eval_func_t = std::function<evaluation_context(const tree_t& tree, void* context)>;
|
||||
// debug function,
|
||||
using print_func_t = std::function<void(std::ostream&, stack_allocator&)>;
|
||||
|
||||
|
@ -67,7 +65,7 @@ namespace blt::gp
|
|||
RETURN
|
||||
};
|
||||
|
||||
using destroy_func_t = std::function<void(destroy_t, bitmask_t* mask, stack_allocator&)>;
|
||||
using destroy_func_t = std::function<void(destroy_t, stack_allocator&)>;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -102,16 +102,16 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
template<typename context = void, typename... NoCtxArgs>
|
||||
void call_destructors_without_first(stack_allocator& read_allocator, detail::bitmask_t* mask)
|
||||
void call_destructors_without_first(stack_allocator& read_allocator)
|
||||
{
|
||||
if constexpr (sizeof...(NoCtxArgs) > 0)
|
||||
{
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<NoCtxArgs>...>(mask);
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<NoCtxArgs>...>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func, typename... ExtraArgs>
|
||||
Return operator()(bool has_context, detail::bitmask_t* mask, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
||||
Return operator()(bool has_context, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
||||
{
|
||||
constexpr auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
|
@ -120,9 +120,9 @@ namespace blt::gp
|
|||
#endif
|
||||
Return ret = exec_sequence_to_indices(std::forward<Func>(func), read_allocator, seq, std::forward<ExtraArgs>(args)...);
|
||||
if (has_context)
|
||||
call_destructors_without_first<Args...>(read_allocator, mask);
|
||||
call_destructors_without_first<Args...>(read_allocator);
|
||||
else
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>(mask);
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>();
|
||||
read_allocator.pop_bytes((stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() + ...));
|
||||
return ret;
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
|
@ -144,11 +144,12 @@ namespace blt::gp
|
|||
template<typename, typename>
|
||||
class operation_t;
|
||||
|
||||
template<typename ArgType, typename Return, typename... Args>
|
||||
class operation_t<ArgType, Return(Args...)>
|
||||
template<typename RawFunction, typename Return, typename... Args>
|
||||
class operation_t<RawFunction, Return(Args...)>
|
||||
{
|
||||
public:
|
||||
using function_t = ArgType;
|
||||
using function_t = RawFunction;
|
||||
using First_Arg = typename blt::meta::arg_helper<Args...>::First;
|
||||
|
||||
constexpr operation_t(const operation_t& copy) = default;
|
||||
|
||||
|
@ -158,18 +159,18 @@ namespace blt::gp
|
|||
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, detail::bitmask_t* mask) const
|
||||
[[nodiscard]] constexpr inline Return operator()(stack_allocator& read_allocator) const
|
||||
{
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
{
|
||||
return func();
|
||||
} else
|
||||
{
|
||||
return call_with<Return, Args...>()(false, mask, func, read_allocator);
|
||||
return call_with<Return, Args...>()(false, func, read_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& read_allocator, detail::bitmask_t* mask) const
|
||||
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& read_allocator) const
|
||||
{
|
||||
// should be an impossible state
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
|
@ -182,22 +183,22 @@ namespace blt::gp
|
|||
return func(ctx_ref);
|
||||
} else
|
||||
{
|
||||
return call_without_first<Return, Args...>()(true, mask, func, read_allocator, ctx_ref);
|
||||
return call_without_first<Return, Args...>()(true, func, read_allocator, ctx_ref);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Context>
|
||||
[[nodiscard]] detail::callable_t make_callable() const
|
||||
[[nodiscard]] detail::operator_func_t make_callable() const
|
||||
{
|
||||
return [this](void* context, stack_allocator& read_allocator, stack_allocator& write_allocator, detail::bitmask_t* mask) {
|
||||
return [this](void* context, stack_allocator& read_allocator, stack_allocator& write_allocator) {
|
||||
if constexpr (detail::is_same_v<Context, detail::remove_cv_ref<typename detail::first_arg<Args...>::type>>)
|
||||
{
|
||||
// first arg is context
|
||||
write_allocator.push(this->operator()(context, read_allocator, mask));
|
||||
write_allocator.push(this->operator()(context, read_allocator));
|
||||
} else
|
||||
{
|
||||
// first arg isn't context
|
||||
write_allocator.push(this->operator()(read_allocator, mask));
|
||||
write_allocator.push(this->operator()(read_allocator));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -212,38 +213,42 @@ namespace blt::gp
|
|||
return func;
|
||||
}
|
||||
|
||||
inline auto set_ephemeral()
|
||||
{
|
||||
is_ephemeral_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool is_ephemeral()
|
||||
{
|
||||
return is_ephemeral_;
|
||||
}
|
||||
|
||||
operator_id id = -1;
|
||||
private:
|
||||
function_t func;
|
||||
std::optional<std::string_view> name;
|
||||
bool is_ephemeral_ = false;
|
||||
};
|
||||
|
||||
template<typename ArgType, typename Return, typename Class, typename... Args>
|
||||
class operation_t<ArgType, Return (Class::*)(Args...) const> : public operation_t<ArgType, Return(Args...)>
|
||||
template<typename RawFunction, typename Return, typename Class, typename... Args>
|
||||
class operation_t<RawFunction, Return (Class::*)(Args...) const> : public operation_t<RawFunction, Return(Args...)>
|
||||
{
|
||||
public:
|
||||
using operation_t<ArgType, Return(Args...)>::operation_t;
|
||||
using operation_t<RawFunction, Return(Args...)>::operation_t;
|
||||
};
|
||||
|
||||
template<typename Lambda>
|
||||
operation_t(Lambda)
|
||||
->
|
||||
operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
operation_t(Lambda) -> operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
operation_t(Return(*)
|
||||
(Args...)) ->
|
||||
operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
operation_t(Return(*)(Args...)) -> operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
|
||||
template<typename Lambda>
|
||||
operation_t(Lambda, std::optional<std::string_view>
|
||||
) ->
|
||||
operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
operation_t(Lambda, std::optional<std::string_view>) -> operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
operation_t(Return(*)
|
||||
(Args...), std::optional<std::string_view>) ->
|
||||
operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
operation_t(Return(*)(Args...), std::optional<std::string_view>) -> operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
}
|
||||
|
||||
#endif //BLT_GP_OPERATIONS_H
|
||||
|
|
|
@ -75,10 +75,8 @@ namespace blt::gp
|
|||
type_id return_type;
|
||||
// number of arguments for this operator
|
||||
argc_t argc;
|
||||
// function to call this operator
|
||||
detail::callable_t function;
|
||||
// function used to transfer values between stacks
|
||||
//detail::transfer_t transfer;
|
||||
// per operator function callable (slow)
|
||||
detail::operator_func_t func;
|
||||
};
|
||||
|
||||
struct operator_storage
|
||||
|
@ -93,6 +91,8 @@ namespace blt::gp
|
|||
std::vector<detail::print_func_t> print_funcs;
|
||||
std::vector<detail::destroy_func_t> destroy_funcs;
|
||||
std::vector<std::optional<std::string_view>> names;
|
||||
|
||||
detail::eval_func_t eval_func;
|
||||
};
|
||||
|
||||
template<typename Context = detail::empty_t>
|
||||
|
@ -106,65 +106,38 @@ namespace blt::gp
|
|||
explicit operator_builder(type_provider& system): system(system)
|
||||
{}
|
||||
|
||||
template<typename ArgType, typename Return, typename... Args>
|
||||
operator_builder& add_operator(operation_t<ArgType, Return(Args...)>& op, bool is_static = false)
|
||||
template<typename... Operators>
|
||||
operator_storage& build(Operators& ... operators)
|
||||
{
|
||||
auto return_type_id = system.get_type<Return>().id();
|
||||
auto operator_id = blt::gp::operator_id(storage.operators.size());
|
||||
op.id = operator_id;
|
||||
std::vector<blt::size_t> sizes;
|
||||
(sizes.push_back(add_operator(operators)), ...);
|
||||
blt::size_t largest = 0;
|
||||
for (auto v : sizes)
|
||||
largest = std::max(v, largest);
|
||||
|
||||
operator_info info;
|
||||
storage.eval_func = [&operators..., largest](const tree_t& tree, void* context) {
|
||||
const auto& ops = tree.get_operations();
|
||||
const auto& vals = tree.get_values();
|
||||
|
||||
if constexpr (sizeof...(Args) > 0)
|
||||
evaluation_context results{};
|
||||
results.values.reserve(largest);
|
||||
|
||||
blt::size_t total_so_far = 0;
|
||||
|
||||
for (const auto& operation : blt::reverse_iterate(ops.begin(), ops.end()))
|
||||
{
|
||||
(add_non_context_argument<detail::remove_cv_ref<Args>>(info.argument_types), ...);
|
||||
if (operation.is_value)
|
||||
{
|
||||
total_so_far += stack_allocator::aligned_size(operation.type_size);
|
||||
results.values.copy_from(vals.from(total_so_far), stack_allocator::aligned_size(operation.type_size));
|
||||
continue;
|
||||
}
|
||||
call_jmp_table(operation.id, context, results.values, results.values, operators...);
|
||||
}
|
||||
|
||||
info.argc.argc_context = info.argc.argc = sizeof...(Args);
|
||||
info.return_type = system.get_type<Return>().id();
|
||||
return results;
|
||||
};
|
||||
|
||||
((std::is_same_v<detail::remove_cv_ref<Args>, Context> ? info.argc.argc -= 1 : (blt::size_t) nullptr), ...);
|
||||
|
||||
auto& operator_list = info.argc.argc == 0 ? storage.terminals : storage.non_terminals;
|
||||
operator_list[return_type_id].push_back(operator_id);
|
||||
|
||||
BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!");
|
||||
|
||||
info.function = op.template make_callable<Context>();
|
||||
|
||||
storage.operators.push_back(info);
|
||||
storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) {
|
||||
if constexpr (blt::meta::is_streamable_v<Return>)
|
||||
{
|
||||
out << stack.from<Return>(0);
|
||||
(void) (op); // remove warning
|
||||
} else
|
||||
{
|
||||
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:
|
||||
if constexpr (detail::has_func_drop_v<remove_cvref_t<Return>>)
|
||||
{
|
||||
alloc.from<detail::remove_cv_ref<Return>>(0).drop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
storage.names.push_back(op.get_name());
|
||||
if (is_static)
|
||||
storage.static_types.insert(operator_id);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator_storage& build()
|
||||
{
|
||||
blt::hashset_t<type_id> has_terminals;
|
||||
|
||||
for (const auto& v : blt::enumerate(storage.terminals))
|
||||
|
@ -232,6 +205,65 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
private:
|
||||
template<typename RawFunction, typename Return, typename... Args>
|
||||
auto add_operator(operation_t<RawFunction, Return(Args...)>& op)
|
||||
{
|
||||
auto total_size_required = stack_allocator::aligned_size(sizeof(Return));
|
||||
((total_size_required += stack_allocator::aligned_size(sizeof(Args))), ...);
|
||||
|
||||
auto return_type_id = system.get_type<Return>().id();
|
||||
auto operator_id = blt::gp::operator_id(storage.operators.size());
|
||||
op.id = operator_id;
|
||||
|
||||
operator_info info;
|
||||
|
||||
if constexpr (sizeof...(Args) > 0)
|
||||
{
|
||||
(add_non_context_argument<detail::remove_cv_ref<Args>>(info.argument_types), ...);
|
||||
}
|
||||
|
||||
info.argc.argc_context = info.argc.argc = sizeof...(Args);
|
||||
info.return_type = return_type_id;
|
||||
info.func = op.template make_callable<Context>();
|
||||
|
||||
((std::is_same_v<detail::remove_cv_ref<Args>, Context> ? info.argc.argc -= 1 : (blt::size_t) nullptr), ...);
|
||||
|
||||
auto& operator_list = info.argc.argc == 0 ? storage.terminals : storage.non_terminals;
|
||||
operator_list[return_type_id].push_back(operator_id);
|
||||
|
||||
BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!");
|
||||
|
||||
storage.operators.push_back(info);
|
||||
storage.print_funcs.push_back([&op](std::ostream& out, stack_allocator& stack) {
|
||||
if constexpr (blt::meta::is_streamable_v<Return>)
|
||||
{
|
||||
out << stack.from<Return>(0);
|
||||
(void) (op); // remove warning
|
||||
} else
|
||||
{
|
||||
out << "[Printing Value on '" << (op.get_name() ? *op.get_name() : "") << "' Not Supported!]";
|
||||
}
|
||||
});
|
||||
storage.destroy_funcs.push_back([](detail::destroy_t type, stack_allocator& alloc) {
|
||||
switch (type)
|
||||
{
|
||||
case detail::destroy_t::ARGS:
|
||||
alloc.call_destructors<Args...>();
|
||||
break;
|
||||
case detail::destroy_t::RETURN:
|
||||
if constexpr (detail::has_func_drop_v<remove_cvref_t<Return>>)
|
||||
{
|
||||
alloc.from<detail::remove_cv_ref<Return>>(0).drop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
storage.names.push_back(op.get_name());
|
||||
if (op.is_ephemeral())
|
||||
storage.static_types.insert(operator_id);
|
||||
return total_size_required;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add_non_context_argument(decltype(operator_info::argument_types)& types)
|
||||
{
|
||||
|
@ -241,6 +273,47 @@ namespace blt::gp
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Operator>
|
||||
static inline void execute(void* context, stack_allocator& write_stack, stack_allocator& read_stack, Operator& operation)
|
||||
{
|
||||
if constexpr (std::is_same_v<detail::remove_cv_ref<typename Operator::First_Arg>, Context>)
|
||||
{
|
||||
write_stack.push(operation(context, read_stack));
|
||||
} else
|
||||
{
|
||||
write_stack.push(operation(read_stack));
|
||||
}
|
||||
}
|
||||
|
||||
template<blt::size_t id, typename Operator>
|
||||
static inline bool call(blt::size_t op, void* context, stack_allocator& write_stack, stack_allocator& read_stack, Operator& operation)
|
||||
{
|
||||
if (id == op)
|
||||
{
|
||||
execute(context, write_stack, read_stack, operation);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename... Operators, size_t... operator_ids>
|
||||
static inline void call_jmp_table_internal(size_t op, void* context, stack_allocator& write_stack, stack_allocator& read_stack,
|
||||
std::integer_sequence<size_t, operator_ids...>, Operators&... operators)
|
||||
{
|
||||
if (op >= sizeof...(operator_ids))
|
||||
{
|
||||
BLT_UNREACHABLE;
|
||||
}
|
||||
(call<operator_ids>(op, context, write_stack, read_stack, operators) && ...);
|
||||
}
|
||||
|
||||
template<typename... Operators>
|
||||
static inline void call_jmp_table(size_t op, void* context, stack_allocator& write_stack, stack_allocator& read_stack,
|
||||
Operators& ... operators)
|
||||
{
|
||||
call_jmp_table_internal(op, context, write_stack, read_stack, std::index_sequence_for<Operators...>(), operators...);
|
||||
}
|
||||
|
||||
type_provider& system;
|
||||
operator_storage storage;
|
||||
};
|
||||
|
@ -460,8 +533,6 @@ namespace blt::gp
|
|||
void reset_program(type_id root_type, bool eval_fitness_now = true)
|
||||
{
|
||||
current_generation = 0;
|
||||
for (auto& pop : current_pop)
|
||||
pop.tree.drop(*this);
|
||||
current_pop = config.pop_initializer.get().generate(
|
||||
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
|
||||
if (eval_fitness_now)
|
||||
|
@ -470,7 +541,6 @@ namespace blt::gp
|
|||
|
||||
void next_generation()
|
||||
{
|
||||
current_pop.drop(*this);
|
||||
current_pop = std::move(next_pop);
|
||||
current_generation++;
|
||||
}
|
||||
|
@ -603,6 +673,11 @@ namespace blt::gp
|
|||
storage = std::move(op);
|
||||
}
|
||||
|
||||
inline detail::eval_func_t& get_eval_func()
|
||||
{
|
||||
return storage.eval_func;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline auto get_current_generation() const
|
||||
{
|
||||
return current_generation.load();
|
||||
|
@ -615,7 +690,6 @@ namespace blt::gp
|
|||
|
||||
~gp_program()
|
||||
{
|
||||
current_pop.drop(*this);
|
||||
thread_helper.lifetime_over = true;
|
||||
thread_helper.barrier.notify_all();
|
||||
thread_helper.thread_function_condition.notify_all();
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace blt::gp
|
|||
using Allocator = aligned_allocator;
|
||||
public:
|
||||
static Allocator& get_allocator();
|
||||
|
||||
struct size_data_t
|
||||
{
|
||||
blt::size_t total_size_bytes = 0;
|
||||
|
@ -130,7 +131,7 @@ namespace blt::gp
|
|||
if (stack.empty())
|
||||
return;
|
||||
if (size_ < stack.bytes_stored + bytes_stored)
|
||||
expand(stack.bytes_stored + bytes_stored);
|
||||
expand(stack.bytes_stored + size_);
|
||||
std::memcpy(data_ + bytes_stored, stack.data_, stack.bytes_stored);
|
||||
bytes_stored += stack.bytes_stored;
|
||||
}
|
||||
|
@ -140,7 +141,7 @@ namespace blt::gp
|
|||
if (bytes == 0)
|
||||
return;
|
||||
if (size_ < bytes + bytes_stored)
|
||||
expand(bytes + bytes_stored);
|
||||
expand(bytes + size_);
|
||||
std::memcpy(data_ + bytes_stored, stack.data_ + (stack.bytes_stored - bytes), bytes);
|
||||
bytes_stored += bytes;
|
||||
}
|
||||
|
@ -150,7 +151,7 @@ namespace blt::gp
|
|||
if (bytes == 0 || data == nullptr)
|
||||
return;
|
||||
if (size_ < bytes + bytes_stored)
|
||||
expand(bytes + bytes_stored);
|
||||
expand(bytes + size_);
|
||||
std::memcpy(data_ + bytes_stored, data, bytes);
|
||||
bytes_stored += bytes;
|
||||
}
|
||||
|
@ -185,18 +186,22 @@ namespace blt::gp
|
|||
return *reinterpret_cast<T*>(data_ + bytes_stored);
|
||||
}
|
||||
|
||||
[[nodiscard]] blt::u8* from(blt::size_t bytes) const
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
if (bytes_stored < bytes)
|
||||
BLT_ABORT(("Not enough bytes in stack to reference " + std::to_string(bytes) + " bytes requested but " + std::to_string(bytes) +
|
||||
" bytes stored!").c_str());
|
||||
#endif
|
||||
return data_ + (bytes_stored - bytes);
|
||||
}
|
||||
|
||||
template<typename T, typename NO_REF = NO_REF_T<T>>
|
||||
T& from(blt::size_t bytes)
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<NO_REF> && "Type must be bitwise copyable!");
|
||||
static_assert(alignof(NO_REF) <= MAX_ALIGNMENT && "Type alignment must not be greater than the max alignment!");
|
||||
auto size = aligned_size(sizeof(NO_REF)) + bytes;
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
if (bytes_stored < size)
|
||||
BLT_ABORT(("Not enough bytes in stack to reference " + std::to_string(size) + " bytes requested but " + std::to_string(bytes) +
|
||||
" bytes stored!").c_str());
|
||||
#endif
|
||||
return *reinterpret_cast<NO_REF*>(data_ + bytes_stored - size);
|
||||
return *reinterpret_cast<NO_REF*>(from(aligned_size(sizeof(NO_REF)) + bytes));
|
||||
}
|
||||
|
||||
void pop_bytes(blt::size_t bytes)
|
||||
|
@ -222,22 +227,13 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
template<typename... Args>
|
||||
void call_destructors(detail::bitmask_t* mask)
|
||||
void call_destructors()
|
||||
{
|
||||
if constexpr (sizeof...(Args) > 0)
|
||||
{
|
||||
blt::size_t offset = (stack_allocator::aligned_size(sizeof(NO_REF_T<Args>)) + ...) -
|
||||
stack_allocator::aligned_size(sizeof(NO_REF_T<typename blt::meta::arg_helper<Args...>::First>));
|
||||
blt::size_t index = 0;
|
||||
if (mask != nullptr)
|
||||
index = mask->size() - sizeof...(Args);
|
||||
((call_drop<Args>(offset, index, mask), offset -= stack_allocator::aligned_size(sizeof(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();
|
||||
}
|
||||
((call_drop<Args>(offset), offset -= stack_allocator::aligned_size(sizeof(NO_REF_T<Args>))), ...);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,15 +263,19 @@ namespace blt::gp
|
|||
return data;
|
||||
}
|
||||
|
||||
void reserve(blt::size_t bytes)
|
||||
{
|
||||
if (bytes > size_)
|
||||
expand(bytes);
|
||||
}
|
||||
|
||||
private:
|
||||
void expand(blt::size_t bytes)
|
||||
{
|
||||
bytes = to_nearest_page_size(bytes);
|
||||
// auto new_data = static_cast<blt::u8*>(std::malloc(bytes));
|
||||
auto new_data = static_cast<blt::u8*>(get_allocator().allocate(bytes));
|
||||
if (bytes_stored > 0)
|
||||
std::memcpy(new_data, data_, bytes_stored);
|
||||
// std::free(data_);
|
||||
get_allocator().deallocate(data_, size_);
|
||||
data_ = new_data;
|
||||
size_ = bytes;
|
||||
|
@ -298,30 +298,24 @@ namespace blt::gp
|
|||
|
||||
void* allocate_bytes_for_size(blt::size_t bytes)
|
||||
{
|
||||
auto aligned_ptr = get_aligned_pointer(bytes);
|
||||
auto used_bytes = aligned_size(bytes);
|
||||
auto aligned_ptr = get_aligned_pointer(used_bytes);
|
||||
if (aligned_ptr == nullptr)
|
||||
{
|
||||
expand(size_ + bytes);
|
||||
aligned_ptr = get_aligned_pointer(bytes);
|
||||
expand(size_ + used_bytes);
|
||||
aligned_ptr = get_aligned_pointer(used_bytes);
|
||||
}
|
||||
if (aligned_ptr == nullptr)
|
||||
throw std::bad_alloc();
|
||||
auto used_bytes = aligned_size(bytes);
|
||||
bytes_stored += used_bytes;
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void call_drop(blt::size_t offset, blt::size_t index, detail::bitmask_t* mask)
|
||||
inline void call_drop(blt::size_t offset)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,11 +34,10 @@ namespace blt::gp
|
|||
|
||||
struct op_container_t
|
||||
{
|
||||
op_container_t(detail::callable_t& func, blt::size_t type_size, operator_id id, bool is_value):
|
||||
func(func), type_size(type_size), id(id), is_value(is_value)
|
||||
op_container_t(blt::size_t type_size, operator_id id, bool is_value):
|
||||
type_size(type_size), id(id), is_value(is_value)
|
||||
{}
|
||||
|
||||
std::reference_wrapper<detail::callable_t> func;
|
||||
blt::size_t type_size;
|
||||
operator_id id;
|
||||
bool is_value;
|
||||
|
@ -46,11 +45,8 @@ namespace blt::gp
|
|||
|
||||
class evaluation_context
|
||||
{
|
||||
friend class tree_t;
|
||||
|
||||
private:
|
||||
explicit evaluation_context()
|
||||
{}
|
||||
public:
|
||||
explicit evaluation_context() = default;
|
||||
|
||||
blt::gp::stack_allocator values;
|
||||
};
|
||||
|
@ -59,6 +55,8 @@ namespace blt::gp
|
|||
{
|
||||
using iter_type = std::vector<op_container_t>::const_iterator;
|
||||
public:
|
||||
explicit tree_t(gp_program& program);
|
||||
|
||||
struct child_t
|
||||
{
|
||||
blt::ptrdiff_t start;
|
||||
|
@ -86,7 +84,10 @@ namespace blt::gp
|
|||
return values;
|
||||
}
|
||||
|
||||
evaluation_context evaluate(void* context) const;
|
||||
evaluation_context evaluate(void* context) const
|
||||
{
|
||||
return (*func)(*this, context);
|
||||
}
|
||||
|
||||
blt::size_t get_depth(gp_program& program);
|
||||
|
||||
|
@ -124,7 +125,9 @@ namespace blt::gp
|
|||
bool check(gp_program& program, void* context) const;
|
||||
|
||||
void find_child_extends(gp_program& program, std::vector<child_t>& vec, blt::size_t parent_node, blt::size_t argc) const;
|
||||
|
||||
blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, blt::ptrdiff_t start) const;
|
||||
|
||||
blt::ptrdiff_t find_parent(blt::gp::gp_program& program, blt::ptrdiff_t start) const;
|
||||
|
||||
// valid for [begin, end)
|
||||
|
@ -155,11 +158,10 @@ namespace blt::gp
|
|||
return total_value_bytes(operations.begin(), operations.end());
|
||||
}
|
||||
|
||||
void drop(gp_program& program);
|
||||
private:
|
||||
std::vector<op_container_t> operations;
|
||||
blt::gp::stack_allocator values;
|
||||
std::atomic_int64_t* reference_counter;
|
||||
detail::eval_func_t* func;
|
||||
};
|
||||
|
||||
struct fitness_t
|
||||
|
@ -310,7 +312,6 @@ namespace blt::gp
|
|||
|
||||
population_t& operator=(population_t&&) = default;
|
||||
|
||||
void drop(gp_program& program);
|
||||
private:
|
||||
std::vector<individual> individuals;
|
||||
};
|
||||
|
|
2
lib/blt
2
lib/blt
|
@ -1 +1 @@
|
|||
Subproject commit 78710a12cca9ecf7f92394ddf66ed5e2c0301484
|
||||
Subproject commit 9ce6c89ce0145902d31515194a707a9aca948121
|
|
@ -53,7 +53,7 @@ namespace blt::gp
|
|||
{
|
||||
std::stack<stack> tree_generator = get_initial_stack(args.program, args.root_type);
|
||||
blt::size_t max_depth = 0;
|
||||
tree_t tree;
|
||||
tree_t tree{args.program};
|
||||
|
||||
while (!tree_generator.empty())
|
||||
{
|
||||
|
@ -63,7 +63,6 @@ namespace blt::gp
|
|||
auto& info = args.program.get_operator_info(top.id);
|
||||
|
||||
tree.get_operations().emplace_back(
|
||||
info.function,
|
||||
args.program.get_typesystem().get_type(info.return_type).size(),
|
||||
top.id,
|
||||
args.program.is_static(top.id));
|
||||
|
@ -71,7 +70,7 @@ namespace blt::gp
|
|||
|
||||
if (args.program.is_static(top.id))
|
||||
{
|
||||
info.function(nullptr, tree.get_values(), tree.get_values(), nullptr);
|
||||
info.func(nullptr, tree.get_values(), tree.get_values());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -457,8 +457,8 @@ namespace blt::gp
|
|||
vals.copy_from(data, total_bytes_after);
|
||||
}
|
||||
// now finally update the type.
|
||||
ops[c_node] = {replacement_func_info.function, program.get_typesystem().get_type(replacement_func_info.return_type).size(),
|
||||
random_replacement, program.is_static(random_replacement)};
|
||||
ops[c_node] = {program.get_typesystem().get_type(replacement_func_info.return_type).size(), random_replacement,
|
||||
program.is_static(random_replacement)};
|
||||
}
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
if (!c.check(program, nullptr))
|
||||
|
@ -543,7 +543,7 @@ namespace blt::gp
|
|||
vals.copy_from(combined_ptr + for_bytes, after_bytes);
|
||||
|
||||
ops.insert(ops.begin() + static_cast<blt::ptrdiff_t>(c_node),
|
||||
{replacement_func_info.function, program.get_typesystem().get_type(replacement_func_info.return_type).size(),
|
||||
{program.get_typesystem().get_type(replacement_func_info.return_type).size(),
|
||||
random_replacement, program.is_static(random_replacement)});
|
||||
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
|
|
121
src/tree.cpp
121
src/tree.cpp
|
@ -37,48 +37,6 @@ namespace blt::gp
|
|||
return buffer;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
blt::size_t expected_bytes = 0;
|
||||
blt::size_t found_bytes = values.size().total_used_bytes;
|
||||
for (const auto& op : operations)
|
||||
{
|
||||
if (op.is_value)
|
||||
expected_bytes += stack_allocator::aligned_size(op.type_size);
|
||||
}
|
||||
if (expected_bytes != found_bytes)
|
||||
{
|
||||
BLT_WARN("Bytes found %ld vs bytes expected %ld", found_bytes, expected_bytes);
|
||||
BLT_ABORT("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
|
||||
}
|
||||
#endif
|
||||
// copy the initial values
|
||||
evaluation_context results{};
|
||||
|
||||
auto value_stack = 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()))
|
||||
{
|
||||
if (operation.is_value)
|
||||
{
|
||||
value_stack.transfer_bytes(values_process, operation.type_size);
|
||||
bitfield.push_back(false);
|
||||
continue;
|
||||
}
|
||||
operation.func(context, values_process, values_process, &bitfield);
|
||||
bitfield.push_back(true);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::ostream& create_indent(std::ostream& out, blt::size_t amount, bool pretty_print)
|
||||
{
|
||||
if (!pretty_print)
|
||||
|
@ -135,8 +93,10 @@ namespace blt::gp
|
|||
{
|
||||
create_indent(out, indent, pretty_print);
|
||||
if (program.is_static(v.id))
|
||||
{
|
||||
program.get_print_func(v.id)(out, reversed);
|
||||
else
|
||||
reversed.pop_bytes(stack_allocator::aligned_size(v.type_size));
|
||||
} else
|
||||
out << name;
|
||||
out << return_type << end_indent(pretty_print);
|
||||
} else
|
||||
|
@ -214,7 +174,7 @@ namespace blt::gp
|
|||
values_process.pop_back();
|
||||
}
|
||||
value_stack.push_back(local_depth + 1);
|
||||
operations_stack.emplace_back(empty_callable, operation.type_size, operation.id, true);
|
||||
operations_stack.emplace_back(operation.type_size, operation.id, true);
|
||||
}
|
||||
|
||||
return depth;
|
||||
|
@ -260,8 +220,6 @@ namespace blt::gp
|
|||
|
||||
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;
|
||||
auto bytes_size = values.size().total_used_bytes;
|
||||
|
||||
|
@ -289,22 +247,22 @@ namespace blt::gp
|
|||
blt::size_t total_produced = 0;
|
||||
blt::size_t total_consumed = 0;
|
||||
|
||||
for (const auto& operation : blt::reverse_iterate(operations.begin(), operations.end()))
|
||||
{
|
||||
if (operation.is_value)
|
||||
{
|
||||
value_stack.transfer_bytes(values_process, operation.type_size);
|
||||
total_produced += stack_allocator::aligned_size(operation.type_size);
|
||||
bitfield.push_back(false);
|
||||
continue;
|
||||
}
|
||||
auto& info = program.get_operator_info(operation.id);
|
||||
for (auto& arg : info.argument_types)
|
||||
total_consumed += stack_allocator::aligned_size(program.get_typesystem().get_type(arg).size());
|
||||
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());
|
||||
}
|
||||
// for (const auto& operation : blt::reverse_iterate(operations.begin(), operations.end()))
|
||||
// {
|
||||
// if (operation.is_value)
|
||||
// {
|
||||
// value_stack.transfer_bytes(values_process, operation.type_size);
|
||||
// total_produced += stack_allocator::aligned_size(operation.type_size);
|
||||
// bitfield.push_back(false);
|
||||
// continue;
|
||||
// }
|
||||
// auto& info = program.get_operator_info(operation.id);
|
||||
// for (auto& arg : info.argument_types)
|
||||
// total_consumed += stack_allocator::aligned_size(program.get_typesystem().get_type(arg).size());
|
||||
// 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());
|
||||
// }
|
||||
|
||||
auto v1 = results.values.bytes_in_head();
|
||||
auto v2 = static_cast<blt::ptrdiff_t>(stack_allocator::aligned_size(operations.front().type_size));
|
||||
|
@ -319,40 +277,6 @@ namespace blt::gp
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void tree_t::find_child_extends(gp_program& program, std::vector<child_t>& vec, blt::size_t parent_node, blt::size_t argc) const
|
||||
{
|
||||
while (vec.size() < argc)
|
||||
|
@ -373,9 +297,8 @@ namespace blt::gp
|
|||
}
|
||||
}
|
||||
|
||||
void population_t::drop(gp_program& program)
|
||||
tree_t::tree_t(gp_program& program): func(&program.get_eval_func())
|
||||
{
|
||||
for (auto& pop : get_individuals())
|
||||
pop.tree.drop(program);
|
||||
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
perf stat -d -d -d -r 30 -e branches,branch-misses,cache-misses,cache-references,cycles,instructions,alignment-faults,cgroup-switches,faults,duration_time,user_time,system_time,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-prefetches,L1-icache-loads,L1-icache-load-misses,dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses,l2_request_g1.all_no_prefetch,page-faults,page-faults:u,page-faults:k ./cmake-build-release/blt-symbolic-regression-example
|
||||
perf stat -d -d -d -r 50 -e branches,branch-misses,cache-misses,cache-references,cycles,instructions,alignment-faults,cgroup-switches,faults,duration_time,user_time,system_time,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-prefetches,L1-icache-loads,L1-icache-load-misses,dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses,l2_request_g1.all_no_prefetch,page-faults,page-faults:u,page-faults:k ./cmake-build-release/blt-symbolic-regression-example
|
||||
|
|
|
@ -1 +1 @@
|
|||
perf stat -d -d -d -r 30 -e branches,branch-misses,cache-misses,cache-references,cycles,instructions,alignment-faults,cgroup-switches,faults,duration_time,user_time,system_time,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-prefetches,L1-icache-loads,L1-icache-load-misses,dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses,l2_request_g1.all_no_prefetch,page-faults,page-faults:u,page-faults:k ./cmake-build-release-clang/blt-SR-playground-example
|
||||
perf stat -d -d -d -r 50 -e branches,branch-misses,cache-misses,cache-references,cycles,instructions,alignment-faults,cgroup-switches,faults,duration_time,user_time,system_time,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-prefetches,L1-icache-loads,L1-icache-load-misses,dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses,l2_request_g1.all_no_prefetch,page-faults,page-faults:u,page-faults:k ./cmake-build-release-clang/blt-symbolic-regression-example
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
perf stat -d -d -d -r 50 -e branches,branch-misses,cache-misses,cache-references,cycles,instructions,alignment-faults,cgroup-switches,faults,duration_time,user_time,system_time,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-prefetches,L1-icache-loads,L1-icache-load-misses,dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses,l2_request_g1.all_no_prefetch,page-faults,page-faults:u,page-faults:k ./cmake-build-minsizerel-clang/blt-symbolic-regression-example
|
|
@ -58,13 +58,12 @@ blt::gp::gp_program program{type_system, SEED};
|
|||
blt::gp::op_container_t make_container(blt::gp::operator_id id)
|
||||
{
|
||||
auto& info = program.get_operator_info(id);
|
||||
return {info.function, type_system.get_type(info.return_type).size(), id, false};
|
||||
return {type_system.get_type(info.return_type).size(), id, false};
|
||||
}
|
||||
|
||||
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&, blt::gp::detail::bitmask_t*) {});
|
||||
return {empty, id.size(), 0, true};
|
||||
return {id.size(), 0, true};
|
||||
}
|
||||
|
||||
blt::gp::operation_t add([](float a, float b) {
|
||||
|
@ -105,7 +104,7 @@ blt::gp::operation_t large_literal([]() {
|
|||
void basic_tree()
|
||||
{
|
||||
BLT_INFO("Testing if we can get a basic tree going.");
|
||||
blt::gp::tree_t tree;
|
||||
blt::gp::tree_t tree{program};
|
||||
|
||||
tree.get_operations().push_back(make_container(sub.id));
|
||||
tree.get_operations().push_back(make_value(type_system.get_type<float>()));
|
||||
|
@ -120,7 +119,7 @@ void basic_tree()
|
|||
|
||||
void large_cross_type_tree()
|
||||
{
|
||||
blt::gp::tree_t tree;
|
||||
blt::gp::tree_t tree{program};
|
||||
auto& ops = tree.get_operations();
|
||||
auto& vals = tree.get_values();
|
||||
|
||||
|
@ -149,16 +148,7 @@ int main()
|
|||
type_system.register_type<large_18290>();
|
||||
|
||||
blt::gp::operator_builder builder{type_system};
|
||||
|
||||
builder.add_operator(f_literal); // 0
|
||||
builder.add_operator(b_literal); // 1
|
||||
builder.add_operator(add); // 2
|
||||
builder.add_operator(basic_2t); // 3
|
||||
builder.add_operator(sub); // 4
|
||||
builder.add_operator(large_literal); // 5
|
||||
builder.add_operator(cross_large_type); // 6
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(f_literal, b_literal, add, basic_2t, sub, large_literal, cross_large_type));
|
||||
|
||||
basic_tree();
|
||||
large_cross_type_tree();
|
||||
|
|
|
@ -319,9 +319,9 @@ namespace blt::gp::detail
|
|||
explicit operator_storage_test(blt::gp::operator_builder<context>& ops): ops(ops)
|
||||
{}
|
||||
|
||||
inline blt::gp::detail::callable_t& operator[](blt::size_t index)
|
||||
inline blt::gp::detail::operator_func_t& operator[](blt::size_t index)
|
||||
{
|
||||
return ops.storage.operators[index].function;
|
||||
return ops.storage.operators[index].func;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -424,7 +424,7 @@ int main()
|
|||
return f + g;
|
||||
});
|
||||
|
||||
std::cout << silly_op(alloc, nullptr) << std::endl;
|
||||
std::cout << silly_op(alloc) << std::endl;
|
||||
|
||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||
|
||||
|
@ -447,24 +447,21 @@ int main()
|
|||
//BLT_TRACE(blt::type_string<blt::gp::detail::remove_cv_ref<decltype(silly_op_3)::first::type>>());
|
||||
//BLT_TRACE("Same types? %s", (std::is_same_v<context, blt::gp::detail::remove_cv_ref<decltype(silly_op_3)::first::type>>) ? "true" : "false");
|
||||
|
||||
ops.add_operator(silly_op_3);
|
||||
ops.add_operator(silly_op_4);
|
||||
ops.add_operator(silly_op_2);
|
||||
|
||||
ops.build(silly_op_3, silly_op_4, silly_op_2);
|
||||
blt::gp::detail::operator_storage_test de(ops);
|
||||
|
||||
context hello{5, 10};
|
||||
|
||||
alloc.push(1.153f);
|
||||
de[0](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||
de[0](static_cast<void*>(&hello), alloc, alloc);
|
||||
BLT_TRACE("first value: %f", alloc.pop<float>());
|
||||
|
||||
de[1](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||
de[1](static_cast<void*>(&hello), alloc, alloc);
|
||||
BLT_TRACE("second value: %f", alloc.pop<float>());
|
||||
|
||||
alloc.push(1.0f);
|
||||
alloc.push(52.213f);
|
||||
de[2](static_cast<void*>(&hello), alloc, alloc, nullptr);
|
||||
de[2](static_cast<void*>(&hello), alloc, alloc);
|
||||
BLT_TRACE("third value: %f", alloc.pop<float>());
|
||||
|
||||
//auto* pointer = static_cast<void*>(head->metadata.offset);
|
||||
|
@ -482,7 +479,7 @@ int main()
|
|||
|
||||
//blt::span<void*, 3> spv{arr};
|
||||
|
||||
std::cout << silly_op.operator()(alloc, nullptr) << std::endl;
|
||||
std::cout << silly_op.operator()(alloc) << std::endl;
|
||||
|
||||
std::cout << "Hello World!" << std::endl;
|
||||
|
||||
|
|
|
@ -32,18 +32,21 @@ blt::gp::operation_t add([](float a, float b) {
|
|||
});
|
||||
blt::gp::operation_t sub([](float a, float b) {
|
||||
BLT_TRACE("a: %f - b: %f = %f", a, b, a - b);
|
||||
return a - b; });
|
||||
return a - b;
|
||||
});
|
||||
blt::gp::operation_t mul([](float a, float b) {
|
||||
BLT_TRACE("a: %f * b: %f = %f", a, b, a * b);
|
||||
return a * b; });
|
||||
return a * b;
|
||||
});
|
||||
blt::gp::operation_t pro_div([](float a, float b) {
|
||||
BLT_TRACE("a: %f / b: %f = %f", a, b, (b == 0 ? 0.0f : a / b));
|
||||
return b == 0 ? 0.0f : a / b; });
|
||||
blt::gp::operation_t lit([]() {
|
||||
return b == 0 ? 0.0f : a / b;
|
||||
});
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
});
|
||||
}).set_ephemeral();
|
||||
|
||||
/**
|
||||
* This is a test using a type with blt::gp
|
||||
|
@ -53,13 +56,8 @@ int main()
|
|||
type_system.register_type<float>();
|
||||
|
||||
blt::gp::operator_builder silly{type_system};
|
||||
silly.add_operator(add);
|
||||
silly.add_operator(sub);
|
||||
silly.add_operator(mul);
|
||||
silly.add_operator(pro_div);
|
||||
silly.add_operator(lit, true);
|
||||
|
||||
program.set_operations(silly.build());
|
||||
program.set_operations(silly.build(add, sub, mul, pro_div, lit));
|
||||
|
||||
blt::gp::grow_generator_t grow;
|
||||
auto tree = grow.generate(blt::gp::generator_arguments{program, type_system.get_type<float>().id(), 3, 7});
|
||||
|
|
|
@ -40,11 +40,11 @@ blt::gp::operation_t op_or([](bool a, bool b) {return a || b; });
|
|||
blt::gp::operation_t op_xor([](bool a, bool b) {return static_cast<bool>(a ^ b); });
|
||||
blt::gp::operation_t op_not([](bool b) {return !b; });
|
||||
|
||||
blt::gp::operation_t lit([]() {
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.f);
|
||||
});
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
}).set_ephemeral();
|
||||
|
||||
/**
|
||||
* This is a test using multiple types with blt::gp
|
||||
|
@ -55,24 +55,7 @@ int main()
|
|||
type_system.register_type<bool>();
|
||||
|
||||
blt::gp::operator_builder silly{type_system};
|
||||
silly.add_operator(add);
|
||||
silly.add_operator(sub);
|
||||
silly.add_operator(mul);
|
||||
silly.add_operator(pro_div);
|
||||
|
||||
silly.add_operator(op_if);
|
||||
silly.add_operator(eq_f);
|
||||
silly.add_operator(eq_b);
|
||||
silly.add_operator(lt);
|
||||
silly.add_operator(gt);
|
||||
silly.add_operator(op_and);
|
||||
silly.add_operator(op_or);
|
||||
silly.add_operator(op_xor);
|
||||
silly.add_operator(op_not);
|
||||
|
||||
silly.add_operator(lit, true);
|
||||
|
||||
program.set_operations(silly.build());
|
||||
program.set_operations(silly.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit));
|
||||
|
||||
blt::gp::grow_generator_t grow;
|
||||
auto tree = grow.generate(blt::gp::generator_arguments{program, type_system.get_type<float>().id(), 3, 7});
|
||||
|
|
|
@ -40,11 +40,11 @@ blt::gp::operation_t op_or([](bool a, bool b) { return a || b; });
|
|||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); });
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; });
|
||||
|
||||
blt::gp::operation_t lit([]() {
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
});
|
||||
}).set_ephemeral();
|
||||
|
||||
/**
|
||||
* This is a test using multiple types with blt::gp
|
||||
|
@ -55,24 +55,7 @@ int main()
|
|||
type_system.register_type<bool>();
|
||||
|
||||
blt::gp::operator_builder builder{type_system};
|
||||
builder.add_operator(add);
|
||||
builder.add_operator(sub);
|
||||
builder.add_operator(mul);
|
||||
builder.add_operator(pro_div);
|
||||
|
||||
builder.add_operator(op_if);
|
||||
builder.add_operator(eq_f);
|
||||
builder.add_operator(eq_b);
|
||||
builder.add_operator(lt);
|
||||
builder.add_operator(gt);
|
||||
builder.add_operator(op_and);
|
||||
builder.add_operator(op_or);
|
||||
builder.add_operator(op_xor);
|
||||
builder.add_operator(op_not);
|
||||
|
||||
builder.add_operator(lit, true);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit));
|
||||
|
||||
blt::gp::ramped_half_initializer_t pop_init;
|
||||
|
||||
|
|
|
@ -61,11 +61,11 @@ blt::gp::operation_t op_or([](bool a, bool b) { return a || b; }, "or"); // 10
|
|||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); }, "xor"); // 11
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; }, "not"); // 12
|
||||
|
||||
blt::gp::operation_t lit([]() { // 13
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.f);
|
||||
}, "lit");
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
}).set_ephemeral();
|
||||
|
||||
/**
|
||||
* This is a test using multiple types with blt::gp
|
||||
|
@ -76,24 +76,7 @@ int main()
|
|||
type_system.register_type<bool>();
|
||||
|
||||
blt::gp::operator_builder builder{type_system};
|
||||
builder.add_operator(add);
|
||||
builder.add_operator(sub);
|
||||
builder.add_operator(mul);
|
||||
builder.add_operator(pro_div);
|
||||
|
||||
builder.add_operator(op_if);
|
||||
builder.add_operator(eq_f);
|
||||
builder.add_operator(eq_b);
|
||||
builder.add_operator(lt);
|
||||
builder.add_operator(gt);
|
||||
builder.add_operator(op_and);
|
||||
builder.add_operator(op_or);
|
||||
builder.add_operator(op_xor);
|
||||
builder.add_operator(op_not);
|
||||
|
||||
builder.add_operator(lit, true);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit));
|
||||
|
||||
blt::gp::ramped_half_initializer_t pop_init;
|
||||
|
||||
|
|
|
@ -59,11 +59,11 @@ blt::gp::operation_t op_or([](bool a, bool b) { return a || b; }, "or"); // 10
|
|||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); }, "xor"); // 11
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; }, "not"); // 12
|
||||
|
||||
blt::gp::operation_t lit([]() { // 13
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
}, "lit");
|
||||
}).set_ephemeral();
|
||||
|
||||
/**
|
||||
* This is a test using multiple types with blt::gp
|
||||
|
@ -74,24 +74,7 @@ int main()
|
|||
type_system.register_type<bool>();
|
||||
|
||||
blt::gp::operator_builder builder{type_system};
|
||||
builder.add_operator(add);
|
||||
builder.add_operator(sub);
|
||||
builder.add_operator(mul);
|
||||
builder.add_operator(pro_div);
|
||||
|
||||
builder.add_operator(op_if);
|
||||
builder.add_operator(eq_f);
|
||||
builder.add_operator(eq_b);
|
||||
builder.add_operator(lt);
|
||||
builder.add_operator(gt);
|
||||
builder.add_operator(op_and);
|
||||
builder.add_operator(op_or);
|
||||
builder.add_operator(op_xor);
|
||||
builder.add_operator(op_not);
|
||||
|
||||
builder.add_operator(lit, true);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit));
|
||||
|
||||
blt::gp::ramped_half_initializer_t pop_init;
|
||||
|
||||
|
|
|
@ -42,11 +42,11 @@ blt::gp::operation_t op_or([](bool a, bool b) { return a || b; }, "or"); // 10
|
|||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); }, "xor"); // 11
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; }, "not"); // 12
|
||||
|
||||
blt::gp::operation_t lit([]() { // 13
|
||||
auto lit = blt::gp::operation_t([]() {
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
// static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return program.get_random().get_float(0.0f, 10.0f);
|
||||
}, "lit");
|
||||
}).set_ephemeral();
|
||||
|
||||
void print_best()
|
||||
{
|
||||
|
@ -90,24 +90,7 @@ int main()
|
|||
type_system.register_type<bool>();
|
||||
|
||||
blt::gp::operator_builder builder{type_system};
|
||||
builder.add_operator(add);
|
||||
builder.add_operator(sub);
|
||||
builder.add_operator(mul);
|
||||
builder.add_operator(pro_div);
|
||||
|
||||
builder.add_operator(op_if);
|
||||
builder.add_operator(eq_f);
|
||||
builder.add_operator(eq_b);
|
||||
builder.add_operator(lt);
|
||||
builder.add_operator(gt);
|
||||
builder.add_operator(op_and);
|
||||
builder.add_operator(op_or);
|
||||
builder.add_operator(op_xor);
|
||||
builder.add_operator(op_not);
|
||||
|
||||
builder.add_operator(lit, true);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit));
|
||||
|
||||
auto sel = blt::gp::select_tournament_t{};
|
||||
program.generate_population(type_system.get_type<float>().id(), fitness_function, sel, sel, sel);
|
||||
|
|
|
@ -72,13 +72,13 @@ blt::gp::operation_t basic_sub([](float a, float b, bool choice) {
|
|||
}
|
||||
}, "sub");
|
||||
|
||||
blt::gp::operation_t basic_lit_f([]() {
|
||||
auto basic_lit_f= blt::gp::operation_t([]() {
|
||||
return b_rand.choice() ? 5.0f : 10.0f;
|
||||
});
|
||||
}).set_ephemeral();
|
||||
|
||||
blt::gp::operation_t basic_lit_b([]() {
|
||||
auto basic_lit_b = blt::gp::operation_t([]() {
|
||||
return false;
|
||||
});
|
||||
}).set_ephemeral();
|
||||
|
||||
void basic_test()
|
||||
{
|
||||
|
@ -86,11 +86,7 @@ void basic_test()
|
|||
|
||||
blt::gp::operator_builder<context> builder{type_system};
|
||||
|
||||
builder.add_operator(basic_sub);
|
||||
builder.add_operator(basic_lit_f, true);
|
||||
builder.add_operator(basic_lit_b, true);
|
||||
|
||||
program.set_operations(builder.build());
|
||||
program.set_operations(builder.build(basic_sub, basic_lit_f, basic_lit_b));
|
||||
|
||||
blt::gp::grow_generator_t gen;
|
||||
blt::gp::generator_arguments args{program, type_system.get_type<float>().id(), 1, 1};
|
||||
|
|
|
@ -302,7 +302,7 @@ void test_basic()
|
|||
stack.push(50.0f);
|
||||
stack.push(10.0f);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<float>();
|
||||
RUN_TEST(val != 60.000000f, stack, "Basic 2 Test Passed", "Basic 2 Test Failed. Unexpected value produced '%lf'", val);
|
||||
|
@ -318,7 +318,7 @@ void test_basic()
|
|||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
//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, nullptr);
|
||||
basic_2.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<float>();
|
||||
stack.pop<std::array<blt::u8, 4096 - sizeof(float)>>();
|
||||
|
@ -339,7 +339,7 @@ void test_mixed()
|
|||
stack.push(false);
|
||||
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<float>();
|
||||
RUN_TEST(val != 50.000000f, stack, "Mixed 4 Test Passed", "Mixed 4 Test Failed. Unexpected value produced '%lf'", val);
|
||||
|
@ -357,7 +357,7 @@ void test_mixed()
|
|||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
// 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, nullptr);
|
||||
basic_mixed_4.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<float>();
|
||||
stack.pop<std::array<blt::u8, 4096 - sizeof(float)>>();
|
||||
|
@ -377,7 +377,7 @@ void test_large_256()
|
|||
stack.push(69.420f);
|
||||
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
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);
|
||||
|
@ -394,7 +394,7 @@ void test_large_256()
|
|||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
// 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, nullptr);
|
||||
large_256_basic_3.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<large_256>();
|
||||
stack.pop<std::array<blt::u8, 4096 - sizeof(large_256)>>();
|
||||
|
@ -413,7 +413,7 @@ void test_large_4096()
|
|||
stack.push(33.0f);
|
||||
stack.push(true);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
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);
|
||||
|
@ -429,7 +429,7 @@ void test_large_4096()
|
|||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
// 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, nullptr);
|
||||
large_4096_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
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);
|
||||
|
@ -447,7 +447,7 @@ void test_large_18290()
|
|||
stack.push(-2543.0f);
|
||||
stack.push(true);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
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);
|
||||
|
@ -464,7 +464,7 @@ void test_large_18290()
|
|||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
// 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, nullptr);
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
auto val = stack.pop<large_18290>();
|
||||
stack.pop<std::array<blt::u8, 20480 - 18290 - 32>>();
|
||||
|
@ -480,12 +480,12 @@ void test_large_18290()
|
|||
stack.push(true);
|
||||
auto size = stack.size();
|
||||
BLT_TRACE_STREAM << size << "\n";
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
stack.push(-2543.0f);
|
||||
stack.push(true);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack, nullptr);
|
||||
large_18290_basic_3b.make_callable<blt::gp::detail::empty_t>()(nullptr, stack, stack);
|
||||
BLT_TRACE_STREAM << stack.size() << "\n";
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue