diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea1ffe..58ec75b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ macro(compile_options target_name) sanitizers(${target_name}) endmacro() -project(blt-gp VERSION 0.3.29) +project(blt-gp VERSION 0.3.30) include(CTest) diff --git a/include/blt/gp/program.h b/include/blt/gp/program.h index dc51e50..84092f8 100644 --- a/include/blt/gp/program.h +++ b/include/blt/gp/program.h @@ -766,25 +766,27 @@ namespace blt::gp { if (get_random().choice(selection_probabilities.crossover_chance)) { - thread_local tree_t tree{*this}; - tree.clear(*this); - auto ptr = c2; - if (ptr == nullptr) - ptr = &tree; + // if (c2 == nullptr) + // return 0; + // auto ptr = c2; + // if (ptr == nullptr) + // ptr = &tree_t::get_thread_local(*this); #ifdef BLT_TRACK_ALLOCATIONS auto state = tracker.start_measurement_thread_local(); #endif const tree_t* p1; const tree_t* p2; size_t runs = 0; - // double parent_val = 0; + tree_t tree{*this}; do { + // BLT_TRACE("%lu %p %p", runs, &c1, &tree); p1 = &crossover.select(*this, current_pop); p2 = &crossover.select(*this, current_pop); c1.copy_fast(*p1); - ptr->copy_fast(*p2); + tree.copy_fast(*p2); + // ptr->copy_fast(*p2); if (++runs >= config.crossover.get().get_config().max_crossover_iterations) return 0; @@ -792,7 +794,7 @@ namespace blt::gp crossover_calls.value(1); #endif } - while (!config.crossover.get().apply(*this, *p1, *p2, c1, *ptr)); + while (!config.crossover.get().apply(*this, *p1, *p2, c1, tree)); #ifdef BLT_TRACK_ALLOCATIONS tracker.stop_measurement_thread_local(state); crossover_calls.call(); @@ -802,8 +804,10 @@ namespace blt::gp crossover_allocations.set_value(std::max(crossover_allocations.get_value(), state.getAllocatedByteDifference())); } #endif - if (c2 == nullptr) - tree.clear(*this); + // if (c2 == nullptr) + // tree_t::get_thread_local(*this); + if (c2 != nullptr) + *c2 = tree; return 2; } if (get_random().choice(selection_probabilities.mutation_chance)) diff --git a/include/blt/gp/tree.h b/include/blt/gp/tree.h index 9922f86..2d10a1e 100644 --- a/include/blt/gp/tree.h +++ b/include/blt/gp/tree.h @@ -613,6 +613,8 @@ namespace blt::gp clear(*m_program); } + static tree_t& get_thread_local(gp_program& program); + private: void handle_operator_inserted(const op_container_t& op); diff --git a/src/tree.cpp b/src/tree.cpp index 128f718..3f768bc 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -365,15 +365,15 @@ namespace blt::gp values.copy_from(copy_ptr_c1 + c1_subtree_bytes, c1_stack_after_bytes); // now swap the operators - auto insert_point_c1 = c1_subtree_begin_itr - 1; - auto insert_point_c2 = c2_subtree_begin_itr - 1; + // auto insert_point_c1 = c1_subtree_begin_itr - 1; + // auto insert_point_c2 = c2_subtree_begin_itr - 1; // invalidates [begin, end()) so the insert points should be fine - operations.erase(c1_subtree_begin_itr, c1_subtree_end_itr); - other_tree.operations.erase(c2_subtree_begin_itr, c2_subtree_end_itr); + auto insert_point_c1 = operations.erase(c1_subtree_begin_itr, c1_subtree_end_itr); + auto insert_point_c2 = other_tree.operations.erase(c2_subtree_begin_itr, c2_subtree_end_itr); - operations.insert(++insert_point_c1, c2_subtree_operators.begin(), c2_subtree_operators.end()); - other_tree.operations.insert(++insert_point_c2, c1_subtree_operators.begin(), c1_subtree_operators.end()); + operations.insert(insert_point_c1, c2_subtree_operators.begin(), c2_subtree_operators.end()); + other_tree.operations.insert(insert_point_c2, c1_subtree_operators.begin(), c1_subtree_operators.end()); } void tree_t::replace_subtree(const subtree_point_t point, const ptrdiff_t extent, tree_t& other_tree) @@ -498,6 +498,13 @@ namespace blt::gp return start; } + tree_t& tree_t::get_thread_local(gp_program& program) + { + thread_local tree_t tree{program}; + tree.clear(program); + return tree; + } + void tree_t::handle_operator_inserted(const op_container_t& op) { if (m_program->is_operator_ephemeral(op.id()))