From 0cb0bdc672d20e2b32b93952b08589b3e6c33ed4 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Wed, 2 Apr 2025 21:19:22 -0400 Subject: [PATCH] silly code --- CMakeLists.txt | 2 +- include/gp_system.h | 3 + include/image_storage.h | 22 ++++++- lib/blt-gp | 2 +- src/gp_system.cpp | 24 ++++++-- src/image_storage.cpp | 4 +- src/main.cpp | 129 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 171 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47bfb39..2df0ff5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-2 VERSION 0.0.4) +project(image-gp-2 VERSION 0.0.5) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/gp_system.h b/include/gp_system.h index 5a7a834..ddee68b 100644 --- a/include/gp_system.h +++ b/include/gp_system.h @@ -18,6 +18,7 @@ #ifndef GP_SYSTEM_H #define GP_SYSTEM_H +#include #include void setup_gp_system(blt::size_t population_size); @@ -26,4 +27,6 @@ void run_step(); bool should_terminate(); +image_storage_t& get_image(blt::size_t index); + #endif //GP_SYSTEM_H diff --git a/include/image_storage.h b/include/image_storage.h index d262795..57a600f 100644 --- a/include/image_storage.h +++ b/include/image_storage.h @@ -22,6 +22,7 @@ #include #include #include +#include #include using image_pixel_t = float; @@ -49,12 +50,28 @@ struct image_storage_t } }; +inline std::atomic_uint64_t g_allocated_nodes = 0; +inline std::atomic_uint64_t g_deallocated_nodes = 0; + struct atomic_node_t { + explicit atomic_node_t(image_storage_t* data): data(data) + { + ++g_allocated_nodes; + } + std::atomic next = nullptr; image_storage_t* data = nullptr; + + ~atomic_node_t() + { + ++g_deallocated_nodes; + } }; +inline std::atomic_uint64_t g_allocated_blocks = 0; +inline std::atomic_uint64_t g_deallocated_blocks = 0; + class atomic_list_t { public: @@ -106,14 +123,15 @@ struct image_t delete front; } else data = new image_storage_t; + ++g_allocated_blocks; } void drop() { - const auto node = new atomic_node_t(); // NOLINT - node->data = data; + const auto node = new atomic_node_t(data); // NOLINT data = nullptr; g_image_list.push_back(node); + ++g_deallocated_blocks; } [[nodiscard]] void* as_void_const() const diff --git a/lib/blt-gp b/lib/blt-gp index abb4cc2..a742164 160000 --- a/lib/blt-gp +++ b/lib/blt-gp @@ -1 +1 @@ -Subproject commit abb4cc26a4ab2f739e18bdc6dd52bbce24a1b0d5 +Subproject commit a742164bedd31cac6d828032ee1a4a18c64d0cac diff --git a/src/gp_system.cpp b/src/gp_system.cpp index 8d4e31e..7f13fdd 100644 --- a/src/gp_system.cpp +++ b/src/gp_system.cpp @@ -30,11 +30,13 @@ gp_program program{ } }; +std::vector images; image_storage_t reference_image = image_storage_t::from_file("../silly.png"); -void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t) +void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t index) { auto image = tree.get_evaluation_ref(); + std::memcpy(images[index].data.data(), image->get_data().data.data(), IMAGE_SIZE_BYTES); auto& data = image->get_data(); for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x) { @@ -47,13 +49,14 @@ void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t) const auto diff_r = data.get(x, y, 0) - reference_image.get(x, y, 0); const auto diff_g = data.get(x, y, 1) - reference_image.get(x, y, 1); const auto diff_b = data.get(x, y, 2) - reference_image.get(x, y, 2); - fitness.raw_fitness += diff_r * diff_r * multiplier + diff_g * diff_g * multiplier + diff_b * diff_b * multiplier; + const auto total = (diff_r + diff_g + diff_b) / 3; + fitness.raw_fitness += (total * total) * multiplier; } } } - fitness.raw_fitness /= static_cast(IMAGE_DIMENSIONS * IMAGE_DIMENSIONS); + fitness.raw_fitness /= static_cast(IMAGE_SIZE_CHANNELS); fitness.standardized_fitness = fitness.raw_fitness; - fitness.adjusted_fitness = fitness.standardized_fitness; + fitness.adjusted_fitness = -fitness.standardized_fitness; } void setup_operations() @@ -108,7 +111,11 @@ void setup_operations() return std::exp(a); }, "exp_float"); static operation_t op_log([](const float a) { - return a <= 0.0f ? 0.0f : std::log(a); + if (blt::f_equal(a, 0)) + return 0.0f; + if (a < 0) + return -std::log(-a); + return std::log(a); }, "log_float"); static auto lit = operation_t([]() { return program.get_random().get_float(-1.0f, 1.0f); @@ -124,7 +131,9 @@ void setup_gp_system(const blt::size_t population_size) { prog_config_t config{}; config.population_size = population_size; + config.elites = 2; program.set_config(config); + images.resize(population_size); setup_operations(); static auto sel = select_tournament_t{}; program.generate_initial_population(program.get_typesystem().get_type().id()); @@ -151,3 +160,8 @@ bool should_terminate() { return program.should_terminate(); } + +image_storage_t& get_image(blt::size_t index) +{ + return images[index]; +} diff --git a/src/image_storage.cpp b/src/image_storage.cpp index 3c535d4..6f013de 100644 --- a/src/image_storage.cpp +++ b/src/image_storage.cpp @@ -16,8 +16,6 @@ * along with this program. If not, see . */ #include -#define STB_IMAGE_IMPLEMENTATION -#define STB_IMAGE_RESIZE_IMPLEMENTATION #include #include #include @@ -32,7 +30,7 @@ image_storage_t image_storage_t::from_file(const std::string& path) image_storage_t storage{}; stbir_resize_float_linear(data, x, y, 0, storage.data.data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, 0, STBIR_RGBA); - STBI_FREE(data); + stbi_image_free(data); return storage; } diff --git a/src/main.cpp b/src/main.cpp index 40fc78a..75f4477 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,18 +5,49 @@ #include "blt/gfx/renderer/batch_2d_renderer.h" #include "blt/gfx/renderer/camera.h" #include +#include blt::gfx::matrix_state_manager global_matrices; blt::gfx::resource_manager resources; blt::gfx::batch_renderer_2d renderer_2d(resources, global_matrices); blt::gfx::first_person_camera camera; +std::vector gl_images; +blt::size_t population_size = 64; + +namespace im = ImGui; + +std::atomic_bool run_generation = false; +std::atomic_bool should_exit = false; + +std::thread run_gp() +{ + return std::thread{ + []() { + setup_gp_system(population_size); + while (!should_terminate() && !should_exit) + { + if (run_generation) + { + run_step(); + run_generation = false; + } else + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + }; +} + void init(const blt::gfx::window_data&) { using namespace blt::gfx; - setup_gp_system(64); - + for (blt::size_t i = 0; i < population_size; i++) + { + auto texture = new texture_gl2D(IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGBA8); + gl_images.push_back(texture); + resources.set(std::to_string(i), texture); + } global_matrices.create_internals(); resources.load_resources(); renderer_2d.create(); @@ -30,11 +61,100 @@ void update(const blt::gfx::window_data& data) camera.update_view(global_matrices); global_matrices.update(); + im::ShowDemoWindow(); + + ImGui::SetNextWindowPos(ImVec2(0, 0)); + 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); + + // Create the tab bar + if (ImGui::BeginTabBar("MainTabs")) + { + // 1. Run GP tab + if (ImGui::BeginTabItem("Run GP")) + { + // Left child - fixed width (250px) + ImGui::BeginChild("ControlPanel", ImVec2(250, 0), true); + { + ImGui::Text("Control Panel"); + ImGui::Separator(); + if (ImGui::Button("Run Step")) + { + BLT_TRACE("Running step"); + run_generation = true; + } + } + ImGui::EndChild(); + + // Right child - take the remaining space + ImGui::SameLine(); + // ImGui::BeginChild("MainContent", ImVec2(0, 0), false, ImGuiWindowFlags_NoBackground); + {} + // ImGui::EndChild(); + + ImGui::EndTabItem(); + } + + // 2. Explore Trees tab + if (ImGui::BeginTabItem("Explore Trees")) + { + ImGui::Text("Here you can explore trees."); + // Additional UI for exploring trees + ImGui::EndTabItem(); + } + + // 3. Statistics tab + if (ImGui::BeginTabItem("Statistics")) + { + ImGui::Text("Here you can view statistics."); + // Additional UI for statistical data + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::End(); // MainWindow + + if (ImGui::Begin("Debug")) + { + const auto allocated_nodes = g_allocated_nodes.load(std::memory_order_relaxed); + const auto deallocated_nodes = g_deallocated_nodes.load(std::memory_order_relaxed); + const auto allocated_blocks = g_allocated_blocks.load(std::memory_order_relaxed); + const auto deallocated_blocks = g_deallocated_blocks.load(std::memory_order_relaxed); + ImGui::Text("Allocated Nodes / Deallocated Nodes: (%ld / %ld) (%lf%% / %ld)", allocated_nodes, deallocated_nodes, + (static_cast(deallocated_nodes) / static_cast(allocated_nodes)) * 100.0, allocated_nodes - deallocated_nodes); + ImGui::Text("Allocated Blocks / Deallocated Blocks: (%ld / %ld) (%lf%% / %ld)", allocated_blocks, deallocated_blocks, + (static_cast(deallocated_blocks) / static_cast(allocated_blocks)) * 100.0, allocated_blocks - deallocated_blocks); + } + 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); + + for (int i = 0; i < 10; i++) + { + for (int j = 0; j < 6; j++) + { + constexpr float padding_x = 32; + constexpr float padding_y = 32; + constexpr float img_width = 128; + constexpr float img_height = 128; + const float x = 256 + static_cast(i) * img_width + padding_x * static_cast(i) + img_width; + const float y = static_cast(data.height) - (16 + static_cast(j) * img_height + padding_y * static_cast(j) + + img_height); + renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{x, y, img_width, img_height}, std::to_string(i * j)); + } + } + renderer_2d.render(data.width, data.height); } void destroy(const blt::gfx::window_data&) { + gl_images.clear(); global_matrices.cleanup(); resources.cleanup(); renderer_2d.cleanup(); @@ -43,5 +163,8 @@ void destroy(const blt::gfx::window_data&) int main() { + auto run_gp_thread = run_gp(); blt::gfx::init(blt::gfx::window_data{"Image GP", init, update, destroy}.setSyncInterval(1)); -} \ No newline at end of file + should_exit = true; + run_gp_thread.join(); +}