almost have ephemeral drop working, probably missing an implicit copy

dev-func-drop
Brett 2025-01-17 15:35:15 -05:00
parent 87d0a46552
commit 0e5d8dfd25
6 changed files with 89 additions and 39 deletions

View File

@ -27,7 +27,7 @@ macro(compile_options target_name)
sanitizers(${target_name})
endmacro()
project(blt-gp VERSION 0.3.18)
project(blt-gp VERSION 0.3.19)
include(CTest)

View File

@ -88,7 +88,7 @@ namespace blt::gp
{
const auto bytes = detail::aligned_size(sizeof(NO_REF_T<T>));
if constexpr (blt::gp::detail::has_func_drop_v<T>)
return bytes + sizeof(std::atomic_uint64_t*);
return bytes + detail::aligned_size(sizeof(std::atomic_uint64_t*));
return bytes;
}
@ -168,11 +168,10 @@ namespace blt::gp
const auto ptr = static_cast<char*>(allocate_bytes_for_size(aligned_size<NO_REF>()));
std::memcpy(ptr, &t, sizeof(NO_REF));
// if constexpr (gp::detail::has_func_drop_ephemeral_v<T>)
// {
// const auto* ref_counter_ptr = new std::atomic_uint64_t(1); // NOLINT
// std::memcpy(ptr + sizeof(NO_REF), &ref_counter_ptr, sizeof(std::atomic_uint64_t*));
// }
if constexpr (gp::detail::has_func_drop_v<T>)
{
new(ptr + sizeof(NO_REF)) mem::pointer_storage<std::atomic_uint64_t>{nullptr};
}
}
template <typename T, typename NO_REF = NO_REF_T<T>>
@ -207,6 +206,30 @@ namespace blt::gp
return *reinterpret_cast<NO_REF*>(from(aligned_size<NO_REF>() + bytes));
}
[[nodiscard]] mem::pointer_storage<std::atomic_uint64_t>& access_pointer(const size_t bytes, const size_t type_size) const
{
const auto type_ref = from(bytes);
return *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - detail::aligned_size(
sizeof(std::atomic_uint64_t*)))));
}
[[nodiscard]] mem::pointer_storage<std::atomic_uint64_t>& access_pointer_forward(const size_t bytes, const size_t type_size) const
{
const auto type_ref = data_ + bytes;
return *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - detail::aligned_size(
sizeof(std::atomic_uint64_t*)))));
}
template <typename T>
[[nodiscard]] mem::pointer_storage<std::atomic_uint64_t>& access_pointer(const size_t bytes) const
{
auto& type_ref = from<T>(bytes);
return *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(reinterpret_cast<char*>(&type_ref) + detail::aligned_size(sizeof(T))));
}
void pop_bytes(const size_t bytes)
{
#if BLT_DEBUG_LEVEL > 0

View File

@ -213,44 +213,61 @@ namespace blt::gp
auto copy_it = copy.operations.begin();
auto op_it = operations.begin();
size_t total_op_bytes = 0;
size_t total_copy_bytes = 0;
for (; op_it != operations.end(); ++op_it)
{
if (op_it->get_flags().is_ephemeral())
{
if (op_it->has_ephemeral_drop())
{
}
}
if (copy_it == copy.operations.end())
break;
*op_it = *copy_it;
if (op_it->get_flags().is_ephemeral())
if (op_it->is_value())
{
if (copy_it->has_ephemeral_drop())
if (op_it->get_flags().is_ephemeral() && op_it->has_ephemeral_drop())
{
// BLT_TRACE("%lu %lu %lu", total_op_bytes, values.bytes_in_head(), values.bytes_in_head() - total_op_bytes);
auto& ptr = values.access_pointer_forward(total_op_bytes, op_it->type_size());
--*ptr;
// if (*ptr == 0)
// delete *ptr;
}
total_op_bytes += op_it->type_size();
}
*op_it = *copy_it;
if (copy_it->is_value())
{
if (copy_it->get_flags().is_ephemeral() && copy_it->has_ephemeral_drop())
{
auto& ptr = copy.values.access_pointer_forward(total_copy_bytes, copy_it->type_size());
++*ptr;
}
total_copy_bytes += copy_it->type_size();
}
++copy_it;
}
const auto op_it_cpy = op_it;
for (; op_it != operations.end(); ++op_it)
{
if (op_it->get_flags().is_ephemeral())
if (op_it->is_value())
{
if (op_it->has_ephemeral_drop())
if (op_it->get_flags().is_ephemeral() && op_it->has_ephemeral_drop())
{
auto& ptr = values.access_pointer_forward(total_op_bytes, op_it->type_size());
--*ptr;
}
total_op_bytes += op_it->type_size();
}
}
operations.erase(op_it_cpy, operations.end());
for (; copy_it != copy.operations.end(); ++copy_it)
{
if (copy_it->get_flags().is_ephemeral())
if (copy_it->is_value())
{
if (copy_it->has_ephemeral_drop())
if (copy_it->get_flags().is_ephemeral() && copy_it->has_ephemeral_drop())
{
auto& ptr = copy.values.access_pointer_forward(total_copy_bytes, copy_it->type_size());
++*ptr;
}
total_copy_bytes += copy_it->type_size();
}
operations.emplace_back(*copy_it);
}
@ -457,6 +474,11 @@ namespace blt::gp
};
}
~tree_t()
{
clear(*m_program);
}
private:
void handle_operator_inserted(const op_container_t& op);

@ -1 +1 @@
Subproject commit 1aa7f12c0f0b6d910d4baef51bb530a819663a3d
Subproject commit 74c1010118c3ae13f27499f564ce477b23ae0b0a

View File

@ -278,6 +278,12 @@ namespace blt::gp
{
// Ephemeral values have corresponding insertions into the stack
m_program->get_operator_info(op.id()).func(nullptr, values, values);
if (m_program->operator_has_ephemeral_drop(op.id()))
{
auto& ptr = values.access_pointer(op.type_size(), op.type_size());
ptr = new std::atomic_uint64_t(1);
ptr.bit(0, true);
}
}
}
@ -372,11 +378,23 @@ namespace blt::gp
auto* f = &program;
if (&program != m_program)
m_program = f;
for (const auto& op : operations)
size_t total_bytes = 0;
for (const auto& op : iterate(operations))
{
if (op.has_ephemeral_drop())
if (op.is_value())
{
// TODO:
if (op.get_flags().is_ephemeral() && op.has_ephemeral_drop())
{
auto& ptr = values.access_pointer_forward(total_bytes, op.type_size());
--*ptr;
BLT_TRACE(ptr->load());
if (*ptr == 0)
{
// BLT_TRACE("Deleting pointers!");
delete ptr.get();
}
}
total_bytes += op.type_size();
}
}
operations.clear();

View File

@ -76,7 +76,7 @@ prog_config_t config = prog_config_t()
.set_reproduction_chance(0.1)
.set_max_generations(50)
.set_pop_size(50)
.set_thread_count(0);
.set_thread_count(1);
example::symbolic_regression_t regression{691ul, config};
@ -123,19 +123,6 @@ bool fitness_function(const tree_t& current_tree, fitness_t& fitness, size_t)
int main()
{
int silly = 53;
int* silly_ptr = &silly;
blt::mem::print_bytes(std::cout, silly_ptr);
for (blt::size_t i = 49; i < 64; i++)
{
silly_ptr = reinterpret_cast<int*>(reinterpret_cast<std::uintptr_t>(silly_ptr) | 1ul << i);
}
blt::mem::print_bytes(std::cout, silly_ptr);
return 0;
operator_builder<context> builder{};
builder.build(add, sub, mul, pro_div, op_sin, op_cos, op_exp, op_log, lit, op_x);
regression.get_program().set_operations(builder.grab());