no idea where the leak is coming from
parent
7e33385bfb
commit
339046cc36
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
29
src/main.cpp
29
src/main.cpp
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue