Compare commits

..

No commits in common. "f7f63f6f84635daa8c51c9abfd9ef86cff4b350b" and "e6ec71da1daf4e6e22216dc8713356cc934405d2" have entirely different histories.

11 changed files with 104 additions and 179 deletions

5
.gitignore vendored
View File

@ -6,8 +6,3 @@ out/
./out/ ./out/
massif.* massif.*
callgrind.* callgrind.*
*.out.*
<<<<<<< HEAD
heaptrack.*
=======
>>>>>>> refs/remotes/origin/main

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.75) project(blt-gp VERSION 0.0.70)
include(CTest) include(CTest)
@ -11,9 +11,6 @@ option(DEBUG_LEVEL "Enable debug features which prints extra information to the
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_subdirectory(lib/blt) add_subdirectory(lib/blt)
include_directories(include/) include_directories(include/)
@ -24,7 +21,7 @@ add_library(blt-gp ${PROJECT_BUILD_FILES})
target_compile_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comment) target_compile_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comment)
target_link_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comment) target_link_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comment)
target_link_libraries(blt-gp PRIVATE BLT Threads::Threads) target_link_libraries(blt-gp PRIVATE BLT)
target_compile_definitions(blt-gp PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) target_compile_definitions(blt-gp PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL})
if (${ENABLE_ADDRSAN} MATCHES ON) if (${ENABLE_ADDRSAN} MATCHES ON)
@ -49,7 +46,7 @@ if (${BUILD_EXAMPLES})
add_executable(${name}-example ${source}) add_executable(${name}-example ${source})
target_link_libraries(${name}-example PRIVATE BLT blt-gp Threads::Threads) target_link_libraries(${name}-example PRIVATE BLT blt-gp)
target_compile_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) target_compile_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_link_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) target_link_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)

View File

@ -83,9 +83,7 @@ float example_function(float x)
int main() int main()
{ {
BLT_INFO("Starting BLT-GP Symbolic Regression Example");
BLT_START_INTERVAL("Symbolic Regression", "Main"); BLT_START_INTERVAL("Symbolic Regression", "Main");
BLT_DEBUG("Setup Fitness cases");
for (auto& fitness_case : fitness_cases) for (auto& fitness_case : fitness_cases)
{ {
constexpr float range = 10; constexpr float range = 10;
@ -95,7 +93,6 @@ int main()
fitness_case = {x, y}; fitness_case = {x, y};
} }
BLT_DEBUG("Setup Types and Operators");
type_system.register_type<float>(); type_system.register_type<float>();
blt::gp::operator_builder<context> builder{type_system}; blt::gp::operator_builder<context> builder{type_system};
@ -113,24 +110,17 @@ int main()
program.set_operations(builder.build()); program.set_operations(builder.build());
BLT_DEBUG("Generate Initial Population");
program.generate_population(type_system.get_type<float>().id(), fitness_function); program.generate_population(type_system.get_type<float>().id(), fitness_function);
BLT_DEBUG("Begin Generation Loop");
while (!program.should_terminate()) while (!program.should_terminate())
{ {
BLT_TRACE("------------{Begin Generation %ld}------------", program.get_current_generation());
BLT_START_INTERVAL("Symbolic Regression", "Gen"); BLT_START_INTERVAL("Symbolic Regression", "Gen");
program.create_next_generation(blt::gp::select_tournament_t{}, blt::gp::select_tournament_t{}, blt::gp::select_tournament_t{}); program.create_next_generation(blt::gp::select_tournament_t{}, blt::gp::select_tournament_t{}, blt::gp::select_tournament_t{});
BLT_END_INTERVAL("Symbolic Regression", "Gen"); BLT_END_INTERVAL("Symbolic Regression", "Gen");
BLT_TRACE("Move to next generation");
BLT_START_INTERVAL("Symbolic Regression", "Fitness"); BLT_START_INTERVAL("Symbolic Regression", "Fitness");
program.next_generation(); program.next_generation();
BLT_TRACE("Evaluate Fitness");
program.evaluate_fitness(); program.evaluate_fitness();
BLT_END_INTERVAL("Symbolic Regression", "Fitness"); BLT_END_INTERVAL("Symbolic Regression", "Fitness");
BLT_TRACE("----------------------------------------------");
std::cout << std::endl;
} }
BLT_END_INTERVAL("Symbolic Regression", "Main"); BLT_END_INTERVAL("Symbolic Regression", "Main");

View File

@ -131,8 +131,6 @@ namespace blt::gp
prog_config_t& set_thread_count(blt::size_t t) prog_config_t& set_thread_count(blt::size_t t)
{ {
if (t == 0)
t = std::thread::hardware_concurrency();
threads = t; threads = t;
//evaluation_size = (population_size / threads) / 2; //evaluation_size = (population_size / threads) / 2;
return *this; return *this;

View File

@ -33,8 +33,6 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <atomic> #include <atomic>
#include <condition_variable>
#include <stdexcept>
#include <blt/std/ranges.h> #include <blt/std/ranges.h>
#include <blt/std/hashmap.h> #include <blt/std/hashmap.h>
@ -54,79 +52,6 @@
namespace blt::gp namespace blt::gp
{ {
namespace detail
{
// Author: Kirk Saunders (ks825016@ohio.edu)
// Description: Simple implementation of a thread barrier
// using C++ condition variables.
// Date: 2/17/2020
// https://github.com/kirksaunders/barrier/blob/master/barrier.hpp
class barrier
{
public:
// Construct barrier for use with num threads.
explicit barrier(std::atomic_bool& exit_cond, std::size_t num)
: num_threads(num),
wait_count(0),
instance(0),
mut(),
cv(),
exit_cond(exit_cond)
{
if (num == 0)
{
throw std::invalid_argument("Barrier thread count cannot be 0");
}
}
// disable copying of barrier
barrier(const barrier&) = delete;
barrier& operator=(const barrier&) = delete;
// This function blocks the calling thread until
// all threads (specified by num_threads) have
// called it. Blocking is achieved using a
// call to condition_variable.wait().
void wait()
{
std::unique_lock<std::mutex> lock(mut); // acquire lock
std::size_t inst = instance; // store current instance for comparison
// in predicate
if (++wait_count == num_threads)
{ // all threads reached barrier
wait_count = 0; // reset wait_count
instance++; // increment instance for next use of barrier and to
// pass condition variable predicate
cv.notify_all();
} else
{ // not all threads have reached barrier
cv.wait(lock, [this, &inst]() { return (instance != inst || exit_cond); });
// NOTE: The predicate lambda here protects against spurious
// wakeups of the thread. As long as this->instance is
// equal to inst, the thread will not wake.
// this->instance will only increment when all threads
// have reached the barrier and are ready to be unblocked.
}
}
void notify_all()
{
cv.notify_all();
}
private:
std::size_t num_threads; // number of threads using barrier
std::size_t wait_count; // counter to keep track of waiting threads
std::size_t instance; // counter to keep track of barrier use count
std::mutex mut; // mutex used to protect resources
std::condition_variable cv; // condition variable used to block threads
std::atomic_bool& exit_cond; // used to signal we should exit
};
}
struct argc_t struct argc_t
{ {
blt::u32 argc = 0; blt::u32 argc = 0;
@ -149,7 +74,7 @@ namespace blt::gp
// function to call this operator // function to call this operator
detail::callable_t function; detail::callable_t function;
// function used to transfer values between stacks // function used to transfer values between stacks
//detail::transfer_t transfer; detail::transfer_t transfer;
}; };
struct operator_storage struct operator_storage
@ -200,24 +125,24 @@ namespace blt::gp
BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!"); BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!");
info.function = op.template make_callable<Context>(); info.function = op.template make_callable<Context>();
// info.transfer = [](std::optional<std::reference_wrapper<stack_allocator>> to, stack_allocator& from) { info.transfer = [](std::optional<std::reference_wrapper<stack_allocator>> to, stack_allocator& from) {
//#if BLT_DEBUG_LEVEL >= 3 #if BLT_DEBUG_LEVEL >= 3
// auto value = from.pop<Return>(); auto value = from.pop<Return>();
// //BLT_TRACE_STREAM << value << "\n"; //BLT_TRACE_STREAM << value << "\n";
// if (to){ if (to){
// to->get().push(value); to->get().push(value);
// } }
//#else #else
// if (to) if (to)
// { {
// to->get().push(from.pop<Return>()); to->get().push(from.pop<Return>());
// } else } else
// { {
// from.pop<Return>(); from.pop<Return>();
// } }
//#endif #endif
//
// }; };
storage.operators.push_back(info); storage.operators.push_back(info);
storage.print_funcs.push_back([](std::ostream& out, stack_allocator& stack) { storage.print_funcs.push_back([](std::ostream& out, stack_allocator& stack) {
out << stack.pop<Return>(); out << stack.pop<Return>();
@ -360,8 +285,7 @@ namespace blt::gp
{*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 (config.threads == 1) if (config.threads == 1)
{ {
BLT_INFO("Starting with single thread variant!"); thread_execution_service = new std::function([this, &fitness_function]() {
thread_execution_service = new std::function([this, &fitness_function](blt::size_t) {
for (const auto& ind : blt::enumerate(current_pop.get_individuals())) for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
{ {
fitness_function(ind.second.tree, ind.second.fitness, ind.first); fitness_function(ind.second.tree, ind.second.fitness, ind.first);
@ -376,24 +300,23 @@ namespace blt::gp
}); });
} else } else
{ {
BLT_INFO("Starting thread execution service!"); thread_execution_service = new std::function([this, &fitness_function]() {
std::scoped_lock lock(thread_helper.thread_function_control);
thread_execution_service = new std::function([this, &fitness_function](blt::size_t) {
thread_helper.barrier.wait();
if (thread_helper.evaluation_left > 0) if (thread_helper.evaluation_left > 0)
{ {
thread_helper.threads_left.fetch_add(1, std::memory_order::memory_order_relaxed);
while (thread_helper.evaluation_left > 0) while (thread_helper.evaluation_left > 0)
{ {
blt::size_t size = 0; blt::size_t size = 0;
blt::size_t begin = 0; blt::size_t begin = 0;
blt::size_t end = thread_helper.evaluation_left.load(std::memory_order_relaxed); blt::size_t end = thread_helper.evaluation_left.load(std::memory_order_acquire);
do do
{ {
size = std::min(end, config.evaluation_size); size = std::min(end, config.evaluation_size);
begin = end - size; begin = end - size;
} while (!thread_helper.evaluation_left.compare_exchange_weak(end, end - size, } while (!thread_helper.evaluation_left.compare_exchange_weak(end, end - size,
std::memory_order::memory_order_relaxed, std::memory_order::memory_order_release,
std::memory_order::memory_order_relaxed)); std::memory_order::memory_order_acquire));
for (blt::size_t i = begin; i < end; i++) for (blt::size_t i = begin; i < end; i++)
{ {
auto& ind = current_pop.get_individuals()[i]; auto& ind = current_pop.get_individuals()[i];
@ -403,22 +326,22 @@ namespace blt::gp
auto old_best = current_stats.best_fitness.load(std::memory_order_relaxed); auto old_best = current_stats.best_fitness.load(std::memory_order_relaxed);
while (ind.fitness.adjusted_fitness > old_best && while (ind.fitness.adjusted_fitness > old_best &&
!current_stats.best_fitness.compare_exchange_weak(old_best, ind.fitness.adjusted_fitness, !current_stats.best_fitness.compare_exchange_weak(old_best, ind.fitness.adjusted_fitness,
std::memory_order_relaxed, std::memory_order_relaxed)); std::memory_order_release, std::memory_order_relaxed));
auto old_worst = current_stats.worst_fitness.load(std::memory_order_relaxed); auto old_worst = current_stats.worst_fitness.load(std::memory_order_relaxed);
while (ind.fitness.adjusted_fitness < old_worst && while (ind.fitness.adjusted_fitness < old_worst &&
!current_stats.worst_fitness.compare_exchange_weak(old_worst, ind.fitness.adjusted_fitness, !current_stats.worst_fitness.compare_exchange_weak(old_worst, ind.fitness.adjusted_fitness,
std::memory_order_relaxed, std::memory_order_relaxed)); std::memory_order_release, std::memory_order_relaxed));
auto old_overall = current_stats.overall_fitness.load(std::memory_order_relaxed); auto old_overall = current_stats.overall_fitness.load(std::memory_order_relaxed);
while (!current_stats.overall_fitness.compare_exchange_weak(old_overall, while (!current_stats.overall_fitness.compare_exchange_weak(old_overall,
ind.fitness.adjusted_fitness + old_overall, ind.fitness.adjusted_fitness + old_overall,
std::memory_order_relaxed, std::memory_order_release,
std::memory_order_relaxed)); std::memory_order_relaxed));
} }
} }
thread_helper.threads_left.fetch_sub(1, std::memory_order::memory_order_relaxed);
} }
thread_helper.barrier.wait();
}); });
} }
evaluate_fitness_internal(); evaluate_fitness_internal();
@ -559,7 +482,6 @@ namespace blt::gp
~gp_program() ~gp_program()
{ {
thread_helper.lifetime_over = true; thread_helper.lifetime_over = true;
thread_helper.barrier.notify_all();
for (auto& thread : thread_helper.threads) for (auto& thread : thread_helper.threads)
{ {
if (thread->joinable()) if (thread->joinable())
@ -585,18 +507,15 @@ namespace blt::gp
struct concurrency_storage struct concurrency_storage
{ {
std::vector<std::unique_ptr<std::thread>> threads; std::vector<std::unique_ptr<std::thread>> threads;
std::mutex thread_function_control; //std::mutex evaluation_control;
std::atomic_uint64_t evaluation_left = 0; std::atomic_uint64_t evaluation_left = 0;
std::atomic_int64_t threads_left = 0;
std::atomic_bool lifetime_over = false; std::atomic_bool lifetime_over = false;
detail::barrier barrier; } thread_helper;
explicit concurrency_storage(blt::size_t threads): barrier(lifetime_over, threads)
{}
} thread_helper{config.threads};
// for convenience, shouldn't decrease performance too much // for convenience, shouldn't decrease performance too much
std::atomic<std::function<void(blt::size_t)>*> thread_execution_service = nullptr; std::atomic<std::function<void()>*> thread_execution_service = nullptr;
inline selector_args get_selector_args() inline selector_args get_selector_args()
{ {
@ -615,11 +534,52 @@ namespace blt::gp
void evaluate_fitness_internal() void evaluate_fitness_internal()
{ {
current_stats.clear(); current_stats.clear();
if (config.threads != 1) if (config.threads == 1)
thread_helper.evaluation_left.store(current_pop.get_individuals().size(), std::memory_order_release); {
(*thread_execution_service)(0); (*thread_execution_service)();
} else
{
{
//std::scoped_lock lock(thread_helper.evaluation_control);
thread_helper.evaluation_left.store(current_pop.get_individuals().size(), std::memory_order_release);
}
//std::cout << "Func" << std::endl;
while (thread_execution_service == nullptr)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
//std::cout << "Wait" << std::endl;
(*thread_execution_service)();
//std::cout << "FINSIHED WAITING!!!!!!!! " << thread_helper.threads_left << std::endl;
while (thread_helper.threads_left > 0)
{
//std::cout << thread_helper.threads_left << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
//std::cout << "Finished" << std::endl;
}
current_stats.average_fitness = current_stats.overall_fitness / static_cast<double>(config.population_size); current_stats.average_fitness = current_stats.overall_fitness / static_cast<double>(config.population_size);
/*current_stats = {};
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
{
fitness_function(ind.second.tree, ind.second.fitness, ind.first);
if (ind.second.fitness.adjusted_fitness > current_stats.best_fitness)
{
current_stats.best_fitness = ind.second.fitness.adjusted_fitness;
current_stats.best_individual = &ind.second;
}
if (ind.second.fitness.adjusted_fitness < current_stats.worst_fitness)
{
current_stats.worst_fitness = ind.second.fitness.adjusted_fitness;
current_stats.worst_individual = &ind.second;
}
current_stats.overall_fitness += ind.second.fitness.adjusted_fitness;
}
current_stats.average_fitness = current_stats.overall_fitness / static_cast<double>(config.population_size);*/
} }
}; };

View File

@ -399,10 +399,7 @@ namespace blt::gp
auto old = head; auto old = head;
head = head->metadata.prev; head = head->metadata.prev;
if (head == nullptr) if (head == nullptr)
{
head = old; head = old;
head->reset();
}
//free_chain(old); //free_chain(old);
// required to prevent silly memory :3 // required to prevent silly memory :3
// if (head != nullptr) // if (head != nullptr)

View File

@ -34,16 +34,12 @@ namespace blt::gp
struct op_container_t struct op_container_t
{ {
// op_container_t(detail::callable_t& func, detail::transfer_t& transfer, operator_id id, bool is_value): op_container_t(detail::callable_t& func, detail::transfer_t& transfer, operator_id id, bool is_value):
// func(func), transfer(transfer), id(id), is_value(is_value) func(func), transfer(transfer), id(id), is_value(is_value)
// {}
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)
{} {}
std::reference_wrapper<detail::callable_t> func; std::reference_wrapper<detail::callable_t> func;
blt::size_t type_size; std::reference_wrapper<detail::transfer_t> transfer;
//std::reference_wrapper<detail::transfer_t> transfer;
operator_id id; operator_id id;
bool is_value; bool is_value;
}; };

View File

@ -64,7 +64,7 @@ namespace blt::gp
tree.get_operations().emplace_back( tree.get_operations().emplace_back(
info.function, info.function,
args.program.get_typesystem().get_type(info.return_type).size(), info.transfer,
top.id, top.id,
args.program.is_static(top.id)); args.program.is_static(top.id));
max_depth = std::max(max_depth, top.depth); max_depth = std::max(max_depth, top.depth);

View File

@ -57,19 +57,11 @@ namespace blt::gp
// main thread is thread0 // main thread is thread0
for (blt::size_t i = 1; i < config.threads; i++) for (blt::size_t i = 1; i < config.threads; i++)
{ {
thread_helper.threads.emplace_back(new std::thread([i, this]() { thread_helper.threads.emplace_back(new std::thread([this]() {
std::function<void(blt::size_t)>* execution_function = nullptr;
while (!should_thread_terminate()) while (!should_thread_terminate())
{ {
if (execution_function == nullptr) if (thread_execution_service != nullptr)
{ (*thread_execution_service)();
std::scoped_lock lock(thread_helper.thread_function_control);
if (thread_execution_service != nullptr)
execution_function = thread_execution_service.load(std::memory_order_acquire);
std::cout.flush();
}
if (execution_function != nullptr)
(*execution_function)(i);
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
})); }));

View File

@ -169,7 +169,7 @@ namespace blt::gp
for (auto it = c1_ops.end() - 1; it != crossover_point_end_itr - 1; it--) for (auto it = c1_ops.end() - 1; it != crossover_point_end_itr - 1; it--)
{ {
if (it->is_value) if (it->is_value)
c1_stack_init.transfer_bytes(c1_stack_after_copy, it->type_size); it->transfer(c1_stack_after_copy, c1_stack_init);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -179,7 +179,7 @@ namespace blt::gp
for (auto it = crossover_point_end_itr - 1; it != crossover_point_begin_itr - 1; it--) for (auto it = crossover_point_end_itr - 1; it != crossover_point_begin_itr - 1; it--)
{ {
if (it->is_value) if (it->is_value)
c1_stack_init.transfer_bytes(c1_stack_for_copy, it->type_size); it->transfer(c1_stack_for_copy, c1_stack_init);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -189,7 +189,7 @@ namespace blt::gp
for (auto it = c2_ops.end() - 1; it != found_point_end_itr - 1; it--) for (auto it = c2_ops.end() - 1; it != found_point_end_itr - 1; it--)
{ {
if (it->is_value) if (it->is_value)
c2_stack_init.transfer_bytes(c2_stack_after_copy, it->type_size); it->transfer(c2_stack_after_copy, c2_stack_init);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -198,7 +198,7 @@ namespace blt::gp
for (auto it = found_point_end_itr - 1; it != found_point_begin_itr - 1; it--) for (auto it = found_point_end_itr - 1; it != found_point_begin_itr - 1; it--)
{ {
if (it->is_value) if (it->is_value)
c2_stack_init.transfer_bytes(c2_stack_for_copy, it->type_size); it->transfer(c2_stack_for_copy, c2_stack_init);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -208,7 +208,7 @@ namespace blt::gp
for (auto it = found_point_begin_itr; it != found_point_end_itr; it++) for (auto it = found_point_begin_itr; it != found_point_end_itr; it++)
{ {
if (it->is_value) if (it->is_value)
c2_stack_for_copy.transfer_bytes(c1.get_values(), it->type_size); it->transfer(c1.get_values(), c2_stack_for_copy);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -217,7 +217,7 @@ namespace blt::gp
for (auto it = crossover_point_begin_itr; it != crossover_point_end_itr; it++) for (auto it = crossover_point_begin_itr; it != crossover_point_end_itr; it++)
{ {
if (it->is_value) if (it->is_value)
c1_stack_for_copy.transfer_bytes(c2.get_values(), it->type_size); it->transfer(c2.get_values(), c1_stack_for_copy);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -227,7 +227,7 @@ namespace blt::gp
for (auto it = crossover_point_end_itr; it != c1_ops.end(); it++) for (auto it = crossover_point_end_itr; it != c1_ops.end(); it++)
{ {
if (it->is_value) if (it->is_value)
c1_stack_after_copy.transfer_bytes(c1.get_values(), it->type_size); it->transfer(c1.get_values(), c1_stack_after_copy);
} }
#if BLT_DEBUG_LEVEL > 1 #if BLT_DEBUG_LEVEL > 1
@ -236,7 +236,7 @@ namespace blt::gp
for (auto it = found_point_end_itr; it != c2_ops.end(); it++) for (auto it = found_point_end_itr; it != c2_ops.end(); it++)
{ {
if (it->is_value) if (it->is_value)
c2_stack_after_copy.transfer_bytes(c2.get_values(), it->type_size); it->transfer(c2.get_values(), c2_stack_after_copy);
} }
// now swap the operators // now swap the operators
@ -288,7 +288,7 @@ namespace blt::gp
{ {
if (it->is_value) if (it->is_value)
{ {
vals.transfer_bytes(after_stack, it->type_size); it->transfer(after_stack, vals);
//after_ops.push_back(*it); //after_ops.push_back(*it);
} }
} }
@ -296,7 +296,7 @@ namespace blt::gp
for (auto it = end_p - 1; it != begin_p - 1; it--) for (auto it = end_p - 1; it != begin_p - 1; it--)
{ {
if (it->is_value) if (it->is_value)
vals.pop_bytes(static_cast<blt::ptrdiff_t>(it->type_size)); it->transfer(std::optional<std::reference_wrapper<stack_allocator>>{}, vals);
} }
auto before = begin_p - 1; auto before = begin_p - 1;
@ -313,7 +313,7 @@ namespace blt::gp
for (const auto& op : new_ops) for (const auto& op : new_ops)
{ {
if (op.is_value) if (op.is_value)
new_vals.transfer_bytes(vals, op.type_size); op.transfer(vals, new_vals);
} }
auto new_end_point = point + new_ops.size(); auto new_end_point = point + new_ops.size();
@ -322,7 +322,7 @@ namespace blt::gp
for (auto it = new_end_p; it != ops.end(); it++) for (auto it = new_end_p; it != ops.end(); it++)
{ {
if (it->is_value) if (it->is_value)
after_stack.transfer_bytes(vals, it->type_size); it->transfer(vals, after_stack);
} }
return c; return c;

View File

@ -42,11 +42,11 @@ namespace blt::gp
operations_stack.pop_back(); operations_stack.pop_back();
if (operation.is_value) if (operation.is_value)
{ {
value_stack.transfer_bytes(values_process, operation.type_size); operation.transfer(values_process, value_stack);
continue; continue;
} }
operation.func(context, values_process, value_stack); operation.func(context, values_process, value_stack);
operations_stack.emplace_back(empty_callable, operation.type_size, operation.id, true); operations_stack.emplace_back(empty_callable, operation.transfer, operation.id, true);
} }
return results; return results;
@ -88,7 +88,7 @@ namespace blt::gp
for (const auto& v : operations) for (const auto& v : operations)
{ {
if (v.is_value) if (v.is_value)
copy.transfer_bytes(reversed, v.type_size); v.transfer(reversed, copy);
} }
} }
for (const auto& v : operations) for (const auto& v : operations)
@ -187,7 +187,7 @@ namespace blt::gp
values_process.pop_back(); values_process.pop_back();
} }
value_stack.push_back(local_depth + 1); value_stack.push_back(local_depth + 1);
operations_stack.emplace_back(empty_callable, operation.type_size, operation.id, true); operations_stack.emplace_back(empty_callable, operation.transfer, operation.id, true);
} }
return depth; return depth;