Compare commits

..

No commits in common. "0a2a35165427a4fa7d7fabeba475de95e2e2289b" and "7511e2508b74f49a08f7cc462b470852400bac81" have entirely different histories.

11 changed files with 66 additions and 140 deletions

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.35)
include(CTest)
project(blt-gp VERSION 0.0.33)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
@ -38,38 +36,29 @@ if (${ENABLE_TSAN} MATCHES ON)
endif ()
if (${BUILD_EXAMPLES})
macro(blt_add_example name source)
project(blt-gp-example)
project(${name}-example)
add_executable(blt-gp-example examples/main.cpp examples/gp_test_2.cpp)
add_executable(${name}-example ${source})
target_link_libraries(blt-gp-example PUBLIC BLT blt-gp)
target_link_libraries(${name}-example PRIVATE BLT blt-gp)
target_compile_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_link_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_compile_options(blt-gp-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_link_options(blt-gp-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
if (${ENABLE_ADDRSAN} MATCHES ON)
target_compile_options(${name}-example PRIVATE -fsanitize=address)
target_link_options(${name}-example PRIVATE -fsanitize=address)
target_compile_options(blt-gp-example PRIVATE -fsanitize=address)
target_link_options(blt-gp-example PRIVATE -fsanitize=address)
endif ()
if (${ENABLE_UBSAN} MATCHES ON)
target_compile_options(${name}-example PRIVATE -fsanitize=undefined)
target_link_options(${name}-example PRIVATE -fsanitize=undefined)
target_compile_options(blt-gp-example PRIVATE -fsanitize=undefined)
target_link_options(blt-gp-example PRIVATE -fsanitize=undefined)
endif ()
if (${ENABLE_TSAN} MATCHES ON)
target_compile_options(${name}-example PRIVATE -fsanitize=thread)
target_link_options(${name}-example PRIVATE -fsanitize=thread)
target_compile_options(blt-gp-example PRIVATE -fsanitize=thread)
target_link_options(blt-gp-example PRIVATE -fsanitize=thread)
endif ()
add_test(NAME ${name}-test COMMAND ${name}-example)
project(blt-gp)
endmacro()
blt_add_example(blt-gp1 examples/main.cpp)
blt_add_example(blt-gp2 examples/gp_test_2.cpp)
endif ()

View File

@ -16,10 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/gp/program.h>
#include <blt/gp/generators.h>
#include <blt/gp/tree.h>
#include <blt/std/logging.h>
static constexpr long SEED = 41912;
@ -31,8 +27,7 @@ blt::gp::operation_t sub([](float a, float b) { return a - b; });
blt::gp::operation_t mul([](float a, float b) { return a * b; });
blt::gp::operation_t pro_div([](float a, float b) { return b == 0 ? 0.0f : a / b; });
blt::gp::operation_t lit([]() {
//static std::uniform_real_distribution<float> dist(-32000, 32000);
static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
static std::uniform_real_distribution<float> dist(-32000, 32000);
return dist(program.get_random());
});
@ -50,12 +45,5 @@ int main()
program.set_operations(std::move(silly));
blt::gp::grow_generator_t grow;
auto tree = grow.generate(blt::gp::generator_arguments{program, type_system.get_type<float>().id(), 3, 7});
auto value = tree.get_evaluation_value<float>(nullptr);
BLT_TRACE(value);
return 0;
}

View File

@ -270,7 +270,7 @@ void test()
}
std::cout << process.size() << std::endl;
std::cout << "Total Results: " << process.top() << std::endl;
std::cout << process.top() << std::endl;
}
@ -326,7 +326,7 @@ namespace blt::gp::detail
blt::gp::stack_allocator alloc;
int main()
int main_old()
{
constexpr blt::size_t MAX_ALIGNMENT = 8;
test();
@ -431,15 +431,15 @@ int main()
context hello{5, 10};
alloc.push(1.153f);
de[0](static_cast<void*>(&hello), alloc, alloc);
de[0](static_cast<void*>(&hello), alloc);
BLT_TRACE("first value: %f", alloc.pop<float>());
de[1](static_cast<void*>(&hello), alloc, alloc);
de[1](static_cast<void*>(&hello), 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);
de[2](static_cast<void*>(&hello), alloc);
BLT_TRACE("third value: %f", alloc.pop<float>());
//auto* pointer = static_cast<void*>(head->metadata.offset);

View File

@ -19,8 +19,6 @@
#ifndef BLT_GP_FWDECL_H
#define BLT_GP_FWDECL_H
#include <functional>
#include <blt/std/logging.h>
namespace blt::gp
{
@ -45,15 +43,9 @@ namespace blt::gp
class full_generator_t;
class stack_allocator;
namespace detail
{
class operator_storage_test;
// context*, read stack, write stack
using callable_t = std::function<void(void*, stack_allocator&, stack_allocator&)>;
// to, from
using transfer_t = std::function<void(stack_allocator&, stack_allocator&)>;
}
}

View File

@ -29,6 +29,8 @@ namespace blt::gp
{
namespace detail
{
using callable_t = std::function<void(void*, stack_allocator&)>;
template<typename T>
using remove_cv_ref = std::remove_cv_t<std::remove_reference_t<T>>;
@ -83,19 +85,19 @@ namespace blt::gp
template<typename Func, blt::u64... indices, typename... ExtraArgs>
inline static constexpr Return exec_sequence_to_indices(Func&& func, stack_allocator& allocator, std::integer_sequence<blt::u64, indices...>,
ExtraArgs&&... args)
ExtraArgs&& ... args)
{
// expands Args and indices, providing each argument with its index calculating the current argument byte offset
return std::forward<Func>(func)(std::forward<ExtraArgs>(args)..., allocator.from<Args>(getByteOffset<indices>())...);
}
template<typename Func, typename... ExtraArgs>
Return operator()(Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
Return operator()(Func&& func, stack_allocator& allocator, ExtraArgs&& ... args)
{
constexpr auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
Return ret = exec_sequence_to_indices(std::forward<Func>(func), read_allocator, seq, std::forward<ExtraArgs>(args)...);
read_allocator.call_destructors<Args...>();
read_allocator.pop_bytes((stack_allocator::aligned_size<Args>() + ...));
Return ret = exec_sequence_to_indices(std::forward<Func>(func), allocator, seq, std::forward<ExtraArgs>(args)...);
allocator.call_destructors<Args...>();
allocator.pop_bytes((stack_allocator::aligned_size<Args>() + ...));
return ret;
}
};
@ -123,18 +125,18 @@ namespace blt::gp
constexpr explicit operation_t(const Functor& functor): func(functor)
{}
[[nodiscard]] constexpr inline Return operator()(stack_allocator& read_allocator) const
[[nodiscard]] constexpr inline Return operator()(stack_allocator& allocator) const
{
if constexpr (sizeof...(Args) == 0)
{
return func();
} else
{
return call_with<Return, Args...>()(func, read_allocator);
return call_with<Return, Args...>()(func, allocator);
}
}
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& read_allocator) const
[[nodiscard]] constexpr inline Return operator()(void* context, stack_allocator& allocator) const
{
// should be an impossible state
if constexpr (sizeof...(Args) == 0)
@ -147,22 +149,22 @@ namespace blt::gp
return func(ctx_ref);
} else
{
return call_without_first<Return, Args...>()(func, read_allocator, ctx_ref);
return call_without_first<Return, Args...>()(func, allocator, ctx_ref);
}
}
template<typename Context>
[[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& values) {
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));
values.push(this->operator()(context, values));
} else
{
// first arg isn't context
write_allocator.push(this->operator()(read_allocator));
values.push(this->operator()(values));
}
};
}

View File

@ -63,6 +63,15 @@ namespace blt::gp
explicit gp_operations(type_system& system): system(system)
{}
template<typename T>
void add_non_context_argument(blt::gp::operator_id operator_id)
{
if constexpr (!std::is_same_v<Context, detail::remove_cv_ref<T>>)
{
argument_types[operator_id].push_back(system.get_type<T>());
}
}
template<typename Return, typename... Args>
gp_operations& add_operator(const operation_t<Return(Args...)>& op, bool is_static = false)
{
@ -87,24 +96,12 @@ namespace blt::gp
operator_argc[operator_id] = argc;
operators.push_back(op.template make_callable<Context>());
transfer_funcs.push_back([](stack_allocator& to, stack_allocator& from) {
to.push(from.pop<Return>());
});
if (is_static)
static_types.insert(operator_id);
return *this;
}
private:
template<typename T>
void add_non_context_argument(blt::gp::operator_id operator_id)
{
if constexpr (!std::is_same_v<Context, detail::remove_cv_ref<T>>)
{
argument_types[operator_id].push_back(system.get_type<T>());
}
}
type_system& system;
// indexed from return TYPE ID, returns index of operator
@ -115,7 +112,6 @@ namespace blt::gp
blt::expanding_buffer<argc_t> operator_argc;
blt::hashset_t<operator_id> static_types;
std::vector<detail::callable_t> operators;
std::vector<detail::transfer_t> transfer_funcs;
};
class gp_program
@ -198,11 +194,6 @@ namespace blt::gp
return operators[id];
}
inline detail::transfer_t& get_transfer_func(operator_id id)
{
return transfer_funcs[id];
}
inline bool is_static(operator_id id)
{
return static_types.contains(static_cast<blt::size_t>(id));
@ -217,7 +208,6 @@ namespace blt::gp
static_types = std::move(op.static_types);
operator_argc = std::move(op.operator_argc);
operators = std::move(op.operators);
transfer_funcs = std::move(op.transfer_funcs);
}
private:
@ -233,7 +223,6 @@ namespace blt::gp
blt::expanding_buffer<argc_t> operator_argc;
blt::hashset_t<operator_id> static_types;
std::vector<detail::callable_t> operators;
std::vector<detail::transfer_t> transfer_funcs;
};
}

View File

@ -20,7 +20,6 @@
#define BLT_GP_STACK_H
#include <blt/std/types.h>
#include <blt/std/logging.h>
#include <utility>
#include <stdexcept>
#include <cstdlib>
@ -111,16 +110,9 @@ namespace blt::gp
if (diff <= 0)
{
bytes -= head->used_bytes_in_block();
auto old = head;
head = head->metadata.prev;
free(old);
if (diff == 0)
break;
} else {
// otherwise update the offset pointer
} else // otherwise update the offset pointer
head->metadata.offset -= bytes;
break;
}
}
}
@ -151,9 +143,6 @@ namespace blt::gp
stack_allocator(const stack_allocator& copy)
{
if (copy.empty())
return;
head = nullptr;
block* list_itr = nullptr;
@ -169,8 +158,6 @@ namespace blt::gp
{
push_block(list_itr->metadata.size);
std::memcpy(head->buffer, list_itr->buffer, list_itr->storage_size());
head->metadata.size = list_itr->metadata.size;
head->metadata.offset = head->buffer + list_itr->used_bytes_in_block();
list_itr = list_itr->metadata.next;
}
}

View File

@ -32,13 +32,15 @@ namespace blt::gp
struct op_container_t
{
op_container_t(detail::callable_t& func, detail::transfer_t& transfer, bool is_value):
func(func), transfer(transfer), is_value(is_value)
op_container_t(detail::callable_t& func, u16 depth, bool isStatic, u16 argc, u8 argcContext):
func(func), depth(depth), is_static(isStatic), argc(argc), argc_context(argcContext)
{}
detail::callable_t& func;
detail::transfer_t& transfer;
bool is_value;
blt::u16 depth;
bool is_static: 1;
blt::u16 argc: 15;
blt::u8 argc_context;
};
class evaluation_context
@ -46,7 +48,7 @@ namespace blt::gp
friend class tree_t;
private:
explicit evaluation_context()
explicit evaluation_context(stack_allocator values): values(std::move(values))
{}
blt::gp::stack_allocator values;
@ -106,7 +108,7 @@ namespace blt::gp
}
/**
* Helper template for returning the result of evaluation (this calls it)
* Helper template for returning the result of evalutation (this calls it)
*/
template<typename T>
T get_evaluation_value(void* context)

@ -1 +1 @@
Subproject commit cdb91d800781d2c2a8ad3b9a829ca6d52abaa6ea
Subproject commit 2a34be2e7b452aa623b9043b7decf83c2e367cc7

View File

@ -17,7 +17,6 @@
*/
#include <blt/gp/generators.h>
#include <blt/gp/program.h>
#include <blt/std/logging.h>
#include <stack>
namespace blt::gp
@ -62,17 +61,16 @@ namespace blt::gp
tree.get_operations().emplace_back(
args.program.get_operation(top.id),
args.program.get_transfer_func(top.id),
//static_cast<blt::u16>(top.depth),
args.program.is_static(top.id)
//static_cast<blt::u16>(args.program.get_argc(top.id).argc),
//static_cast<blt::u8>(args.program.get_argc(top.id).argc_context)
static_cast<blt::u16>(top.depth),
args.program.is_static(top.id),
static_cast<blt::u16>(args.program.get_argc(top.id).argc),
static_cast<blt::u8>(args.program.get_argc(top.id).argc_context)
);
max_depth = std::max(max_depth, top.depth);
if (args.program.is_static(top.id))
{
args.program.get_operation(top.id)(nullptr, tree.get_values(), tree.get_values());
args.program.get_operation(top.id)(nullptr, tree.get_values());
continue;
}

View File

@ -16,38 +16,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/gp/tree.h>
#include <blt/gp/stack.h>
#include <blt/std/assert.h>
#include <blt/std/logging.h>
namespace blt::gp
{
inline auto empty_callable = detail::callable_t([](void*, stack_allocator&, stack_allocator&) { BLT_ABORT("This should never be called!"); });
evaluation_context tree_t::evaluate(void* context)
{
// copy the initial values
evaluation_context results{};
evaluation_context results {values};
auto value_stack = values;
auto& values_process = results.values;
auto operations_stack = operations;
auto& value_stack = results.values;
std::stack<op_container_t> operations_stack;
while (!operations_stack.empty())
{
auto operation = operations_stack.back();
// keep the last value in the stack on the process stack stored in the eval context, this way it can be accessed easily.
operations_stack.pop_back();
if (operation.is_value)
{
operation.transfer(values_process, value_stack);
continue;
}
operation.func(context, values_process, value_stack);
operations_stack.emplace_back(empty_callable, operation.transfer, true);
}
BLT_TRACE("Bytes Left: %ld | %ld", values_process.bytes_in_head(), value_stack.bytes_in_head());
return results;
}