getting a random segfault. was present before this commit. adding tracked_alloactor to vectors

shared
Brett 2024-08-29 19:47:35 -04:00
parent 5f1a80c062
commit cc76f2791a
13 changed files with 311 additions and 167 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.1.33) project(blt-gp VERSION 0.1.34)
include(CTest) include(CTest)

View File

@ -1302,7 +1302,7 @@
,"0x4845DA0: memalign (in /usr/libexec/valgrind/vgpreload_dhat-amd64-linux.so)" ,"0x4845DA0: memalign (in /usr/libexec/valgrind/vgpreload_dhat-amd64-linux.so)"
,"0x129674: std::_Function_handler<void (void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&), blt::gp::operation_t<lit::{lambda()#1}, float ()>::make_callable<context>() const::{lambda(void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&)#1}>::_M_invoke(std::_Any_data const&, void*&&, blt::gp::stack_allocator&, blt::gp::stack_allocator&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x129674: std::_Function_handler<void (void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&), blt::gp::operation_t<lit::{lambda()#1}, float ()>::make_callable<context>() const::{lambda(void*, blt::gp::stack_allocator&, blt::gp::stack_allocator&)#1}>::_M_invoke(std::_Any_data const&, void*&&, blt::gp::stack_allocator&, blt::gp::stack_allocator&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x158664: blt::gp::tree_t blt::gp::create_tree<blt::gp::grow_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}>(blt::gp::grow_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}&&, blt::gp::generator_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x158664: blt::gp::tree_t blt::gp::create_tree<blt::gp::grow_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}>(blt::gp::grow_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}&&, blt::gp::generator_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x15D0C0: void std::vector<blt::gp::individual, std::allocator<blt::gp::individual> >::_M_realloc_insert<blt::gp::tree_t>(__gnu_cxx::__normal_iterator<blt::gp::individual*, std::vector<blt::gp::individual, std::allocator<blt::gp::individual> > >, blt::gp::tree_t&&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x15D0C0: void std::vector<blt::gp::individual_t, std::allocator<blt::gp::individual_t> >::_M_realloc_insert<blt::gp::tree_t>(__gnu_cxx::__normal_iterator<blt::gp::individual_t*, std::vector<blt::gp::individual_t, std::allocator<blt::gp::individual_t> > >, blt::gp::tree_t&&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x15CCFA: blt::gp::ramped_half_initializer_t::generate(blt::gp::initializer_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x15CCFA: blt::gp::ramped_half_initializer_t::generate(blt::gp::initializer_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x15A9F0: blt::gp::tree_t blt::gp::create_tree<blt::gp::full_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}>(blt::gp::full_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}&&, blt::gp::generator_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x15A9F0: blt::gp::tree_t blt::gp::create_tree<blt::gp::full_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}>(blt::gp::full_generator_t::generate(blt::gp::generator_arguments const&)::{lambda(blt::gp::gp_program&, std::stack<blt::gp::stack, std::deque<blt::gp::stack, std::allocator<blt::gp::stack> > >&, blt::gp::type_id, unsigned long)#1}&&, blt::gp::generator_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x15C977: blt::gp::ramped_half_initializer_t::generate(blt::gp::initializer_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x15C977: blt::gp::ramped_half_initializer_t::generate(blt::gp::initializer_arguments const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
@ -1330,7 +1330,7 @@
,"0x1548AB: blt::gp::crossover_t::apply(blt::gp::gp_program&, blt::gp::tree_t const&, blt::gp::tree_t const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x1548AB: blt::gp::crossover_t::apply(blt::gp::gp_program&, blt::gp::tree_t const&, blt::gp::tree_t const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x1549A7: blt::gp::crossover_t::apply(blt::gp::gp_program&, blt::gp::tree_t const&, blt::gp::tree_t const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x1549A7: blt::gp::crossover_t::apply(blt::gp::gp_program&, blt::gp::tree_t const&, blt::gp::tree_t const&) (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127C77: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127C77: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x1268EF: blt::gp::individual& std::vector<blt::gp::individual, std::allocator<blt::gp::individual> >::emplace_back<blt::gp::individual>(blt::gp::individual&&) [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x1268EF: blt::gp::individual_t& std::vector<blt::gp::individual_t, std::allocator<blt::gp::individual_t> >::emplace_back<blt::gp::individual_t>(blt::gp::individual_t&&) [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127DDE: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127DDE: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127F26: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127F26: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127FE6: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127FE6: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
@ -1366,7 +1366,7 @@
,"0x1247AC: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x1247AC: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x12497D: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x12497D: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x124A4A: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x124A4A: main (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x126AFC: blt::gp::individual& std::vector<blt::gp::individual, std::allocator<blt::gp::individual> >::emplace_back<blt::gp::tree_t>(blt::gp::tree_t&&) [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x126AFC: blt::gp::individual_t& std::vector<blt::gp::individual_t, std::allocator<blt::gp::individual_t> >::emplace_back<blt::gp::tree_t>(blt::gp::tree_t&&) [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127AE9: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127AE9: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127E76: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127E76: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"
,"0x127EAF: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)" ,"0x127EAF: blt::gp::default_next_pop_creator<blt::gp::select_tournament_t, blt::gp::select_tournament_t, blt::gp::select_tournament_t>::{lambda(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&)#1}::operator()(blt::gp::selector_args&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&, blt::gp::select_tournament_t&&) const [clone .isra.0] (in /home/brett/Documents/code/c++/blt-gp/cmake-build-release/blt-SR-playground-example)"

View File

@ -199,7 +199,7 @@ struct test_results_t
} }
}; };
test_results_t test_individual(blt::gp::individual& i) test_results_t test_individual(blt::gp::individual_t& i)
{ {
test_results_t results; test_results_t results;
@ -307,7 +307,7 @@ int main(int argc, const char** argv)
BLT_END_INTERVAL("Rice Classification", "Main"); BLT_END_INTERVAL("Rice Classification", "Main");
std::vector<std::pair<test_results_t, blt::gp::individual*>> results; std::vector<std::pair<test_results_t, blt::gp::individual_t*>> results;
for (auto& i : program.get_current_pop().get_individuals()) for (auto& i : program.get_current_pop().get_individuals())
results.emplace_back(test_individual(i), &i); results.emplace_back(test_individual(i), &i);
std::sort(results.begin(), results.end(), [](const auto& a, const auto& b) { std::sort(results.begin(), results.end(), [](const auto& a, const auto& b) {

View File

@ -22,16 +22,22 @@
#include <functional> #include <functional>
#include <blt/std/logging.h> #include <blt/std/logging.h>
#include <blt/std/types.h> #include <blt/std/types.h>
#include <blt/gp/stats.h>
#include <ostream> #include <ostream>
#include <optional> #include <cstdlib>
namespace blt::gp namespace blt::gp
{ {
inline allocation_tracker_t tracker;
class gp_program; class gp_program;
class type; class type;
struct operator_id;
struct type_id;
class type_provider; class type_provider;
struct op_container_t; struct op_container_t;
@ -40,6 +46,8 @@ namespace blt::gp
class tree_t; class tree_t;
struct individual_t;
class population_t; class population_t;
class tree_generator_t; class tree_generator_t;
@ -50,6 +58,112 @@ namespace blt::gp
class stack_allocator; class stack_allocator;
template<typename T>
class tracked_allocator_t;
template<typename T>
using tracked_vector = std::vector<T, tracked_allocator_t<T>>;
// using operation_vector_t = tracked_vector<op_container_t>;
// using individual_vector_t = tracked_vector<individual_t, tracked_allocator_t<individual_t>>;
// using tree_vector_t = tracked_vector<tree_t>;
class aligned_allocator
{
public:
void* allocate(blt::size_t bytes) // NOLINT
{
#ifdef BLT_TRACK_ALLOCATIONS
tracker.allocate(bytes);
#endif
return std::aligned_alloc(8, bytes);
}
void deallocate(void* ptr, blt::size_t bytes) // NOLINT
{
if (ptr == nullptr)
return;
#ifdef BLT_TRACK_ALLOCATIONS
tracker.deallocate(bytes);
#else
(void) bytes;
#endif
std::free(ptr);
}
};
template<typename T>
class tracked_allocator_t
{
public:
using value_type = T;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using void_pointer = void*;
using const_void_pointer = const void*;
using difference_type = blt::ptrdiff_t;
using size_type = blt::size_t;
template<class U>
struct rebind
{
typedef tracked_allocator_t<U> other;
};
pointer allocate(size_type n)
{
#ifdef BLT_TRACK_ALLOCATIONS
tracker.allocate(n * sizeof(T));
#endif
return static_cast<pointer>(std::malloc(n * sizeof(T)));
}
pointer allocate(size_type n, const_void_pointer)
{
return allocate(n);
}
void deallocate(pointer p, size_type n)
{
#ifdef BLT_TRACK_ALLOCATIONS
tracker.deallocate(n * sizeof(T));
#else
(void) n;
#endif
std::free(p);
}
template<class U, class... Args>
void construct(U* p, Args&& ... args)
{
new(p) T(args...);
}
template<class U>
void destroy(U* p)
{
p->~T();
}
[[nodiscard]] size_type max_size() const noexcept
{
return std::numeric_limits<size_type>::max();
}
};
template<class T1, class T2>
inline static bool operator==(const tracked_allocator_t<T1>& lhs, const tracked_allocator_t<T2>& rhs) noexcept
{
return &lhs == &rhs;
}
template<class T1, class T2>
inline static bool operator!=(const tracked_allocator_t<T1>& lhs, const tracked_allocator_t<T2>& rhs) noexcept
{
return &lhs != &rhs;
}
namespace detail namespace detail
{ {
class operator_storage_test; class operator_storage_test;
@ -66,6 +180,9 @@ namespace blt::gp
}; };
using destroy_func_t = std::function<void(destroy_t, stack_allocator&)>; using destroy_func_t = std::function<void(destroy_t, stack_allocator&)>;
using const_op_iter_t = tracked_vector<op_container_t>::const_iterator;
using op_iter_t = tracked_vector<op_container_t>::iterator;
} }
} }

View File

@ -409,7 +409,7 @@ namespace blt::gp
} }
if (thread_helper.next_gen_left > 0) if (thread_helper.next_gen_left > 0)
{ {
static thread_local std::vector<tree_t> new_children; static thread_local tracked_vector<tree_t> new_children;
new_children.clear(); new_children.clear();
auto args = get_selector_args(new_children); auto args = get_selector_args(new_children);
@ -486,7 +486,7 @@ namespace blt::gp
} }
if (thread_helper.next_gen_left > 0) if (thread_helper.next_gen_left > 0)
{ {
static thread_local std::vector<tree_t> new_children; static thread_local tracked_vector<tree_t> new_children;
new_children.clear(); new_children.clear();
auto args = get_selector_args(new_children); auto args = get_selector_args(new_children);
if (id == 0) if (id == 0)
@ -593,8 +593,8 @@ namespace blt::gp
template<blt::size_t size> template<blt::size_t size>
auto get_best_individuals() auto get_best_individuals()
{ {
return convert_array<std::array<std::reference_wrapper<individual>, size>>(get_best_indexes<size>(), return convert_array<std::array<std::reference_wrapper<individual_t>, size>>(get_best_indexes<size>(),
[this](auto&& arr, blt::size_t index) -> individual& { [this](auto&& arr, blt::size_t index) -> individual_t& {
return current_pop.get_individuals()[arr[index]]; return current_pop.get_individuals()[arr[index]];
}, },
std::make_integer_sequence<blt::size_t, size>()); std::make_integer_sequence<blt::size_t, size>());
@ -751,7 +751,7 @@ namespace blt::gp
// 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(blt::size_t)>*> thread_execution_service = nullptr;
inline selector_args get_selector_args(std::vector<tree_t>& next_pop_trees) inline selector_args get_selector_args(tracked_vector<tree_t>& next_pop_trees)
{ {
return {*this, next_pop_trees, current_pop, current_stats, config, get_random()}; return {*this, next_pop_trees, current_pop, current_stats, config, get_random()};
} }

View File

@ -32,7 +32,7 @@ namespace blt::gp
struct selector_args struct selector_args
{ {
gp_program& program; gp_program& program;
std::vector<tree_t>& next_pop; tracked_vector<tree_t>& next_pop;
population_t& current_pop; population_t& current_pop;
population_stats& current_stats; population_stats& current_stats;
prog_config_t& config; prog_config_t& config;
@ -44,7 +44,8 @@ namespace blt::gp
if (config.elites > 0) if (config.elites > 0)
{ {
std::vector<std::pair<std::size_t, double>> values; static thread_local tracked_vector<std::pair<std::size_t, double>> values;
values.clear();
for (blt::size_t i = 0; i < config.elites; i++) for (blt::size_t i = 0; i < config.elites; i++)
values.emplace_back(i, current_pop.get_individuals()[i].fitness.adjusted_fitness); values.emplace_back(i, current_pop.get_individuals()[i].fitness.adjusted_fitness);
@ -178,7 +179,7 @@ namespace blt::gp
explicit select_tournament_t(blt::size_t selection_size = 3): selection_size(selection_size) explicit select_tournament_t(blt::size_t selection_size = 3): selection_size(selection_size)
{ {
if (selection_size == 0) if (selection_size == 0)
BLT_ABORT("Unable to select with this size. Must select at least 1 individual!"); BLT_ABORT("Unable to select with this size. Must select at least 1 individual_t!");
} }
tree_t& select(gp_program& program, population_t& pop, population_stats& stats) final; tree_t& select(gp_program& program, population_t& pop, population_stats& stats) final;

View File

@ -27,6 +27,7 @@
#include <blt/std/ranges.h> #include <blt/std/ranges.h>
#include <blt/std/meta.h> #include <blt/std/meta.h>
#include <blt/gp/fwdecl.h> #include <blt/gp/fwdecl.h>
#include <blt/gp/stats.h>
#include <utility> #include <utility>
#include <stdexcept> #include <stdexcept>
#include <cstdlib> #include <cstdlib>
@ -37,141 +38,11 @@
namespace blt::gp namespace blt::gp
{ {
namespace detail namespace detail
{ {
BLT_META_MAKE_FUNCTION_CHECK(drop); BLT_META_MAKE_FUNCTION_CHECK(drop);
} }
class allocation_tracker_t
{
public:
struct allocation_data_t
{
blt::u64 start_allocations = 0;
blt::u64 start_deallocations = 0;
blt::u64 start_allocated_bytes = 0;
blt::u64 start_deallocated_bytes = 0;
blt::u64 end_allocations = 0;
blt::u64 end_deallocations = 0;
blt::u64 end_allocated_bytes = 0;
blt::u64 end_deallocated_bytes = 0;
[[nodiscard]] blt::u64 getAllocationDifference() const
{
return end_allocations - start_allocations;
}
[[nodiscard]] blt::u64 getDeallocationDifference() const
{
return end_deallocations - start_deallocations;
}
[[nodiscard]] blt::u64 getAllocatedByteDifference() const
{
return end_allocated_bytes - start_allocated_bytes;
}
[[nodiscard]] blt::u64 getDeallocatedByteDifference() const
{
return end_deallocated_bytes - start_deallocated_bytes;
}
};
void allocate(blt::size_t bytes)
{
allocations++;
allocated_bytes += bytes;
}
void deallocate(blt::size_t bytes)
{
deallocations++;
deallocated_bytes += bytes;
}
[[nodiscard]] blt::u64 getAllocations() const
{
return allocations;
}
[[nodiscard]] blt::u64 getDeallocations() const
{
return deallocations;
}
[[nodiscard]] blt::u64 getAllocatedBytes() const
{
return allocated_bytes;
}
[[nodiscard]] blt::u64 getDeallocatedBytes() const
{
return deallocated_bytes;
}
[[nodiscard]] blt::u64 getAllocationDifference() const
{
return std::abs(static_cast<blt::i64>(getAllocations()) - static_cast<blt::i64>(getDeallocations()));
}
[[nodiscard]] blt::u64 getCurrentlyAllocatedBytes() const
{
return getAllocatedBytes() - getDeallocatedBytes();
}
[[nodiscard]] allocation_data_t start_measurement() const
{
allocation_data_t data{};
data.start_allocations = allocations;
data.start_deallocations = deallocations;
data.start_allocated_bytes = allocated_bytes;
data.start_deallocated_bytes = deallocated_bytes;
return data;
}
void stop_measurement(allocation_data_t& data) const
{
data.end_allocations = allocations;
data.end_deallocations = deallocations;
data.end_allocated_bytes = allocated_bytes;
data.end_deallocated_bytes = deallocated_bytes;
}
private:
std::atomic_uint64_t allocations = 0;
std::atomic_uint64_t deallocations = 0;
std::atomic_uint64_t allocated_bytes = 0;
std::atomic_uint64_t deallocated_bytes = 0;
};
inline allocation_tracker_t tracker;
class aligned_allocator
{
public:
void* allocate(blt::size_t bytes) // NOLINT
{
#ifdef BLT_TRACK_ALLOCATIONS
tracker.allocate(bytes);
#endif
return std::aligned_alloc(8, bytes);
}
void deallocate(void* ptr, blt::size_t bytes) // NOLINT
{
if (ptr == nullptr)
return;
#ifdef BLT_TRACK_ALLOCATIONS
tracker.deallocate(bytes);
#else
(void) bytes;
#endif
std::free(ptr);
}
};
class stack_allocator class stack_allocator
{ {
constexpr static blt::size_t PAGE_SIZE = 0x100; constexpr static blt::size_t PAGE_SIZE = 0x100;

134
include/blt/gp/stats.h Normal file
View File

@ -0,0 +1,134 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_GP_STATS_H
#define BLT_GP_STATS_H
#include <blt/std/types.h>
#include <atomic>
#include <cmath>
namespace blt::gp
{
class allocation_tracker_t
{
public:
struct allocation_data_t
{
blt::u64 start_allocations = 0;
blt::u64 start_deallocations = 0;
blt::u64 start_allocated_bytes = 0;
blt::u64 start_deallocated_bytes = 0;
blt::u64 end_allocations = 0;
blt::u64 end_deallocations = 0;
blt::u64 end_allocated_bytes = 0;
blt::u64 end_deallocated_bytes = 0;
[[nodiscard]] blt::u64 getAllocationDifference() const
{
return end_allocations - start_allocations;
}
[[nodiscard]] blt::u64 getDeallocationDifference() const
{
return end_deallocations - start_deallocations;
}
[[nodiscard]] blt::u64 getAllocatedByteDifference() const
{
return end_allocated_bytes - start_allocated_bytes;
}
[[nodiscard]] blt::u64 getDeallocatedByteDifference() const
{
return end_deallocated_bytes - start_deallocated_bytes;
}
};
void allocate(blt::size_t bytes)
{
allocations++;
allocated_bytes += bytes;
}
void deallocate(blt::size_t bytes)
{
deallocations++;
deallocated_bytes += bytes;
}
[[nodiscard]] blt::u64 getAllocations() const
{
return allocations;
}
[[nodiscard]] blt::u64 getDeallocations() const
{
return deallocations;
}
[[nodiscard]] blt::u64 getAllocatedBytes() const
{
return allocated_bytes;
}
[[nodiscard]] blt::u64 getDeallocatedBytes() const
{
return deallocated_bytes;
}
[[nodiscard]] blt::u64 getAllocationDifference() const
{
return std::abs(static_cast<blt::i64>(getAllocations()) - static_cast<blt::i64>(getDeallocations()));
}
[[nodiscard]] blt::u64 getCurrentlyAllocatedBytes() const
{
return getAllocatedBytes() - getDeallocatedBytes();
}
[[nodiscard]] allocation_data_t start_measurement() const
{
allocation_data_t data{};
data.start_allocations = allocations;
data.start_deallocations = deallocations;
data.start_allocated_bytes = allocated_bytes;
data.start_deallocated_bytes = deallocated_bytes;
return data;
}
void stop_measurement(allocation_data_t& data) const
{
data.end_allocations = allocations;
data.end_deallocations = deallocations;
data.end_allocated_bytes = allocated_bytes;
data.end_deallocated_bytes = deallocated_bytes;
}
private:
std::atomic_uint64_t allocations = 0;
std::atomic_uint64_t deallocations = 0;
std::atomic_uint64_t allocated_bytes = 0;
std::atomic_uint64_t deallocated_bytes = 0;
};
}
#endif //BLT_GP_STATS_H

View File

@ -29,8 +29,6 @@ namespace blt::gp
{ {
namespace detail namespace detail
{ {
using op_iter = std::vector<blt::gp::op_container_t>::iterator;
template<typename T> template<typename T>
inline static constexpr double sum(const T& array) inline static constexpr double sum(const T& array)
{ {

View File

@ -53,7 +53,6 @@ namespace blt::gp
class tree_t class tree_t
{ {
using iter_type = std::vector<op_container_t>::const_iterator;
public: public:
explicit tree_t(gp_program& program); explicit tree_t(gp_program& program);
@ -66,12 +65,12 @@ namespace blt::gp
blt::ptrdiff_t end; blt::ptrdiff_t end;
}; };
[[nodiscard]] inline std::vector<op_container_t>& get_operations() [[nodiscard]] inline tracked_vector<op_container_t>& get_operations()
{ {
return operations; return operations;
} }
[[nodiscard]] inline const std::vector<op_container_t>& get_operations() const [[nodiscard]] inline const tracked_vector<op_container_t>& get_operations() const
{ {
return operations; return operations;
} }
@ -133,7 +132,7 @@ namespace blt::gp
blt::ptrdiff_t find_parent(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) // valid for [begin, end)
static blt::size_t total_value_bytes(iter_type begin, iter_type end) static blt::size_t total_value_bytes(detail::const_op_iter_t begin, detail::const_op_iter_t end)
{ {
blt::size_t total = 0; blt::size_t total = 0;
for (auto it = begin; it != end; it++) for (auto it = begin; it != end; it++)
@ -161,7 +160,7 @@ namespace blt::gp
} }
private: private:
std::vector<op_container_t> operations; tracked_vector<op_container_t> operations;
blt::gp::stack_allocator values; blt::gp::stack_allocator values;
detail::eval_func_t* func; detail::eval_func_t* func;
}; };
@ -174,26 +173,26 @@ namespace blt::gp
blt::i64 hits = 0; blt::i64 hits = 0;
}; };
struct individual struct individual_t
{ {
tree_t tree; tree_t tree;
fitness_t fitness; fitness_t fitness;
individual() = default; individual_t() = delete;
explicit individual(tree_t&& tree): tree(std::move(tree)) explicit individual_t(tree_t&& tree): tree(std::move(tree))
{} {}
explicit individual(const tree_t& tree): tree(tree) explicit individual_t(const tree_t& tree): tree(tree)
{} {}
individual(const individual&) = default; individual_t(const individual_t&) = default;
individual(individual&&) = default; individual_t(individual_t&&) = default;
individual& operator=(const individual&) = delete; individual_t& operator=(const individual_t&) = delete;
individual& operator=(individual&&) = default; individual_t& operator=(individual_t&&) = default;
}; };
struct population_stats struct population_stats
@ -220,7 +219,7 @@ namespace blt::gp
class population_tree_iterator class population_tree_iterator
{ {
public: public:
population_tree_iterator(std::vector<individual>& ind, blt::size_t pos): ind(ind), pos(pos) population_tree_iterator(tracked_vector<individual_t>& ind, blt::size_t pos): ind(ind), pos(pos)
{} {}
auto begin() auto begin()
@ -265,11 +264,11 @@ namespace blt::gp
} }
private: private:
std::vector<individual>& ind; tracked_vector<individual_t>& ind;
blt::size_t pos; blt::size_t pos;
}; };
std::vector<individual>& get_individuals() tracked_vector<individual_t>& get_individuals()
{ {
return individuals; return individuals;
} }
@ -315,7 +314,7 @@ namespace blt::gp
population_t& operator=(population_t&&) = default; population_t& operator=(population_t&&) = default;
private: private:
std::vector<individual> individuals; tracked_vector<individual_t> individuals;
}; };
} }

View File

@ -86,7 +86,7 @@ namespace blt::gp
return ref.tree; return ref.tree;
} }
} }
BLT_WARN("Unable to find individual with fitness proportionate. This should not be a possible code path! (%lf)", choice); BLT_WARN("Unable to find individual_t with fitness proportionate. This should not be a possible code path! (%lf)", choice);
return pop.get_individuals()[0].tree; return pop.get_individuals()[0].tree;
//BLT_ABORT("Unable to find individual"); //BLT_ABORT("Unable to find individual");
} }

24
src/stats.cpp Normal file
View File

@ -0,0 +1,24 @@
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/gp/stats.h>
#include <blt/std/logging.h>
namespace blt::gp
{
}

View File

@ -36,7 +36,7 @@ namespace blt::gp
return new_tree; return new_tree;
} }
inline blt::size_t accumulate_type_sizes(detail::op_iter begin, detail::op_iter end) inline blt::size_t accumulate_type_sizes(detail::op_iter_t begin, detail::op_iter_t end)
{ {
blt::size_t total = 0; blt::size_t total = 0;
for (auto it = begin; it != end; ++it) for (auto it = begin; it != end; ++it)