no idea where the leak is coming from

main
Brett 2025-04-04 02:06:21 -04:00
parent 7e33385bfb
commit 339046cc36
5 changed files with 120 additions and 40 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25)
project(image-gp-2 VERSION 0.0.7)
project(image-gp-2 VERSION 0.0.8)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)

View File

@ -27,7 +27,7 @@ void run_step();
bool should_terminate();
image_storage_t& get_image(blt::size_t index);
std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3>& get_image(blt::size_t index);
void cleanup();

View File

@ -68,10 +68,11 @@ struct image_cleaner_t
};
inline image_cleaner_t g_image_list;
inline std::atomic_uint64_t g_image_counter = 0;
struct image_t
{
image_t()
image_t(): id(++g_image_counter)
{
image_storage_t* front = nullptr;
{
@ -87,8 +88,14 @@ struct image_t
else
data = new image_storage_t;
++g_allocated_blocks;
BLT_TRACE("Allocated {}!", id);
}
image_t(const image_t& other) = default;
image_t& operator=(const image_t& other) = default;
void drop()
{
{
@ -97,6 +104,7 @@ struct image_t
}
data = nullptr;
++g_deallocated_blocks;
BLT_TRACE("Deallocated {}!", id);
}
[[nodiscard]] void* as_void_const() const
@ -129,6 +137,7 @@ struct image_t
private:
image_storage_t* data;
blt::size_t id;
};
#endif //IMAGE_STORAGE_H

View File

@ -53,6 +53,7 @@ void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t inde
fitness.adjusted_fitness = -fitness.standardized_fitness;
}
template <typename T>
void setup_operations(gp_program* program)
{
static operation_t op_image_x([]() {
@ -73,15 +74,13 @@ void setup_operations(gp_program* program)
}
return ret;
});
static operation_t op_image_xy([]() {
static auto op_image_ephemeral = operation_t([program]() {
image_t ret;
for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x)
{
for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y)
ret.get_data().get(x, y) = static_cast<float>(x + y) / static_cast<float>((IMAGE_DIMENSIONS - 1) * (IMAGE_DIMENSIONS - 1));
}
const auto value = program->get_random().get_float();
for (auto& v : ret.get_data().data)
v = value;
return ret;
});
}).set_ephemeral();
static operation_t op_image_blend([](const image_t& a, const image_t& b, const float f) {
const auto blend = std::min(std::max(f, 0.0f), 1.0f);
const auto beta = 1.0f - blend;
@ -91,7 +90,32 @@ void setup_operations(gp_program* program)
cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, ret.get_data().data.data()};
addWeighted(src1, blend, src2, beta, 0.0, dst);
return ret;
}, "blend");
}, "blend_image");
static operation_t op_image_sin([](const image_t& a) {
image_t ret;
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
ret.get_data().data[i] = std::sin(v);
return ret;
}, "sin_image");
static operation_t op_image_cos([](const image_t& a) {
image_t ret;
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
ret.get_data().data[i] = std::cos(v);
return ret;
}, "cos_image");
static operation_t op_image_log([](const image_t& a) {
image_t ret;
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
{
if (blt::f_equal(v, 0))
ret.get_data().data[i] = 0;
else if (v < 0)
ret.get_data().data[i] = -std::log(-v);
else
ret.get_data().data[i] = std::log(v);
}
return ret;
}, "sin_image");
static operation_t op_sin([](const float a) {
return std::sin(a);
}, "sin_float");
@ -113,57 +137,85 @@ void setup_operations(gp_program* program)
}, "lit_float").set_ephemeral();
operator_builder builder{};
builder.build(make_add<image_t>(), make_sub<image_t>(), make_mul<image_t>(), make_div<image_t>(), op_image_x, op_image_y, op_image_xy,
make_add<float>(), make_sub<float>(), make_mul<float>(), make_prot_div<float>(), op_sin, op_cos, op_exp, op_log, lit);
builder.build(make_add<image_t>(), make_sub<image_t>(), make_mul<image_t>(), make_div<image_t>(), op_image_x, op_image_y, op_image_sin,
op_image_cos, op_image_log, make_add<float>(), make_sub<float>(), make_mul<float>(), make_prot_div<float>(),
op_sin, op_cos, op_exp, op_log, lit);
program->set_operations(builder.grab());
}
void setup_gp_system(const blt::size_t population_size)
{
prog_config_t config{};
config.population_size = population_size;
config.elites = 2;
program = new gp_program{
[]() {
return std::random_device()();
},
config
};
config.set_pop_size(1);
config.set_elite_count(0);
config.set_thread_count(0);
// config.set_crossover_chance(0);
// config.set_mutation_chance(0);
// config.set_reproduction_chance(0);
const auto rand = std::random_device()();
BLT_INFO("Random Seed: {}", rand);
for (auto& program : programs)
{
program = new gp_program{rand, config};
}
setup_operations<struct p1>(programs[0]);
setup_operations<struct p2>(programs[1]);
setup_operations<struct p3>(programs[2]);
images.resize(population_size);
setup_operations();
static auto sel = select_tournament_t{};
program->generate_initial_population(program->get_typesystem().get_type<image_t>().id());
program->setup_generational_evaluation(fitness_func, sel, sel, sel);
for (const auto program : programs)
program->generate_initial_population(program->get_typesystem().get_type<image_t>().id());
programs[0]->setup_generational_evaluation(fitness_func<0>, sel, sel, sel);
programs[1]->setup_generational_evaluation(fitness_func<1>, sel, sel, sel);
programs[2]->setup_generational_evaluation(fitness_func<2>, sel, sel, sel);
}
void run_step()
{
BLT_TRACE("------------\\{Begin Generation {}}------------", program->get_current_generation());
BLT_TRACE("------------\\{Begin Generation {}}------------", programs[0]->get_current_generation());
BLT_TRACE("Creating next generation");
program->create_next_generation();
for (const auto program : programs)
program->create_next_generation();
BLT_TRACE("Move to next generation");
program->next_generation();
for (const auto program : programs)
program->next_generation();
BLT_TRACE("Evaluate Fitness");
program->evaluate_fitness();
const auto& stats = program->get_population_stats();
BLT_TRACE("Avg Fit: {:0.6f}, Best Fit: {:0.6f}, Worst Fit: {:0.6f}, Overall Fit: {:0.6f}", stats.average_fitness.load(std::memory_order_relaxed),
stats.best_fitness.load(std::memory_order_relaxed), stats.worst_fitness.load(std::memory_order_relaxed),
stats.overall_fitness.load(std::memory_order_relaxed));
for (const auto program : programs)
program->evaluate_fitness();
for (const auto [i, program] : blt::enumerate(programs))
{
const auto& stats = program->get_population_stats();
if (i == 0)
BLT_TRACE("Channel Red");
else if (i == 1)
BLT_TRACE("Channel Green");
else
BLT_TRACE("Channel Blue");
BLT_TRACE("\tAvg Fit: {:0.6f}, Best Fit: {:0.6f}, Worst Fit: {:0.6f}, Overall Fit: {:0.6f}",
stats.average_fitness.load(std::memory_order_relaxed), stats.best_fitness.load(std::memory_order_relaxed),
stats.worst_fitness.load(std::memory_order_relaxed), stats.overall_fitness.load(std::memory_order_relaxed));
}
BLT_TRACE("----------------------------------------------");
}
bool should_terminate()
{
return program->should_terminate();
return programs[0]->should_terminate() || programs[1]->should_terminate() || programs[2]->should_terminate();
}
image_storage_t& get_image(blt::size_t index)
std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3>& get_image(const blt::size_t index)
{
return images[index];
}
void cleanup()
{
delete program;
for (const auto program : programs)
delete program;
}

View File

@ -70,7 +70,7 @@ void update(const blt::gfx::window_data& data)
ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y));
ImGui::Begin("MainWindow", nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoBringToFrontOnFocus);
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoBackground);
// Create the tab bar
if (ImGui::BeginTabBar("MainTabs"))
@ -132,7 +132,26 @@ void update(const blt::gfx::window_data& data)
ImGui::End();
for (blt::size_t i = 0; i < population_size; i++)
gl_images[i]->upload(get_image(i).data.data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGBA, GL_FLOAT);
{
auto& image = get_image(i);
float min = std::numeric_limits<float>::max();
float max = std::numeric_limits<float>::min();
for (auto& pixel : image)
{
if (std::isnan(pixel) || std::isinf(pixel))
pixel = 0;
if (pixel > max)
max = pixel;
if (pixel < min)
min = pixel;
}
for (auto& pixel : image)
pixel = (pixel - min) / (max - min);
gl_images[i]->upload(get_image(i).data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGB, GL_FLOAT);
}
constexpr int images_x = 10;
constexpr int images_y = 6;
@ -142,12 +161,12 @@ void update(const blt::gfx::window_data& data)
{
constexpr float padding_x = 32;
constexpr float padding_y = 32;
const float img_width = (static_cast<float>(data.width) - padding_x * 2 - padding_x * (images_x-1) - 256) / images_x;
const float img_height = (static_cast<float>(data.height) - padding_y * 2 - padding_y * (images_y-1) - 32) / images_y;
const float img_width = (static_cast<float>(data.width) - padding_x * 2 - padding_x * (images_x - 1) - 256) / images_x;
const float img_height = (static_cast<float>(data.height) - padding_y * 2 - padding_y * (images_y - 1) - 32) / images_y;
const float x = 256 + static_cast<float>(i) * img_width + padding_x * static_cast<float>(i) + img_width;
const float y = static_cast<float>(data.height) - (16 + static_cast<float>(j) * img_height + padding_y * static_cast<float>(j) +
img_height);
renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{x, y, img_width, img_height}, std::to_string(i * j));
renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{x, y, img_width, img_height}, std::to_string(i * images_y + j));
}
}