From 7e33385bfba98b55507fad0aae0fc8820a2f08e0 Mon Sep 17 00:00:00 2001 From: Brett Date: Thu, 3 Apr 2025 15:14:13 -0400 Subject: [PATCH] hello silly --- .idea/vcs.xml | 5 ++- CMakeLists.txt | 2 +- include/gp_system.h | 2 ++ include/image_storage.h | 12 +++---- lib/blt | 2 +- lib/blt-gp | 2 +- src/gp_system.cpp | 78 +++++++++++++++++++++-------------------- src/image_storage.cpp | 22 +++++++++--- src/main.cpp | 16 ++++++--- 9 files changed, 82 insertions(+), 59 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index a96c79d..f1804a4 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -5,9 +5,6 @@ - - - @@ -17,6 +14,7 @@ + @@ -25,5 +23,6 @@ + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 964a41a..6c66d67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-2 VERSION 0.0.6) +project(image-gp-2 VERSION 0.0.7) 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 ddee68b..ff58e92 100644 --- a/include/gp_system.h +++ b/include/gp_system.h @@ -29,4 +29,6 @@ bool should_terminate(); image_storage_t& get_image(blt::size_t index); +void cleanup(); + #endif //GP_SYSTEM_H diff --git a/include/image_storage.h b/include/image_storage.h index 4cdb9ec..819026c 100644 --- a/include/image_storage.h +++ b/include/image_storage.h @@ -28,7 +28,7 @@ using image_pixel_t = float; constexpr blt::i32 IMAGE_DIMENSIONS = 256; -constexpr blt::i32 IMAGE_CHANNELS = 4; +constexpr blt::i32 IMAGE_CHANNELS = 1; constexpr blt::size_t IMAGE_SIZE = IMAGE_DIMENSIONS * IMAGE_DIMENSIONS; constexpr blt::size_t IMAGE_SIZE_CHANNELS = IMAGE_SIZE * IMAGE_CHANNELS; @@ -38,16 +38,16 @@ struct image_storage_t { std::array data; - static image_storage_t from_file(const std::string& path); + static std::array from_file(const std::string& path); - image_pixel_t& get(const blt::size_t x, const blt::size_t y, const blt::i32 c) + image_pixel_t& get(const blt::size_t x, const blt::size_t y) { - return data[(y * IMAGE_DIMENSIONS + x) * IMAGE_CHANNELS + c]; + return data[(y * IMAGE_DIMENSIONS + x) * IMAGE_CHANNELS]; } - [[nodiscard]] const image_pixel_t& get(const blt::size_t x, const blt::size_t y, const blt::i32 c) const + [[nodiscard]] const image_pixel_t& get(const blt::size_t x, const blt::size_t y) const { - return data[(y * IMAGE_DIMENSIONS + x) * IMAGE_CHANNELS + c]; + return data[(y * IMAGE_DIMENSIONS + x) * IMAGE_CHANNELS]; } }; diff --git a/lib/blt b/lib/blt index 284743c..729a16a 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 284743c683aebae3277f64a07cdd0deedf629039 +Subproject commit 729a16ab574e31bf1b44446a777e4ee834518c6e diff --git a/lib/blt-gp b/lib/blt-gp index a742164..0eea218 160000 --- a/lib/blt-gp +++ b/lib/blt-gp @@ -1 +1 @@ -Subproject commit a742164bedd31cac6d828032ee1a4a18c64d0cac +Subproject commit 0eea2189e37a372f7a012a07120ee0aed2b1646a diff --git a/src/gp_system.cpp b/src/gp_system.cpp index 7f13fdd..1ebb2e2 100644 --- a/src/gp_system.cpp +++ b/src/gp_system.cpp @@ -24,34 +24,28 @@ using namespace blt::gp; -gp_program program{ - []() { - return std::random_device()(); - } -}; +std::array programs; -std::vector images; -image_storage_t reference_image = image_storage_t::from_file("../silly.png"); +std::vector> images; +auto reference_image = image_storage_t::from_file("../silly.png"); +template 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); + + // 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) { for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y) { + images[index][(x * IMAGE_DIMENSIONS + y) * 3 + Channel] = data.get(x, y); + auto multiplier = (1 - std::abs((static_cast(x) / (static_cast(IMAGE_DIMENSIONS) / 2)) - 1)) + (1 - std::abs( (static_cast(y) / (static_cast(IMAGE_DIMENSIONS) / 2)) - 1)); - for (blt::size_t c = 0; c < IMAGE_CHANNELS; ++c) - { - 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); - const auto total = (diff_r + diff_g + diff_b) / 3; - fitness.raw_fitness += (total * total) * multiplier; - } + const auto diff = data.get(x, y) - reference_image[Channel].get(x, y); + fitness.raw_fitness += (diff * diff) * multiplier; } } fitness.raw_fitness /= static_cast(IMAGE_SIZE_CHANNELS); @@ -59,15 +53,14 @@ void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t inde fitness.adjusted_fitness = -fitness.standardized_fitness; } -void setup_operations() +void setup_operations(gp_program* program) { static operation_t op_image_x([]() { image_t ret; for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x) { for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y) - for (blt::i32 c = 0; c < IMAGE_CHANNELS; ++c) - ret.get_data().get(x, y, c) = static_cast(x) / static_cast(IMAGE_DIMENSIONS - 1); + ret.get_data().get(x, y) = static_cast(x) / static_cast(IMAGE_DIMENSIONS - 1); } return ret; }); @@ -76,8 +69,7 @@ void setup_operations() for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x) { for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y) - for (blt::i32 c = 0; c < IMAGE_CHANNELS; ++c) - ret.get_data().get(x, y, c) = static_cast(y) / static_cast(IMAGE_DIMENSIONS - 1); + ret.get_data().get(x, y) = static_cast(y) / static_cast(IMAGE_DIMENSIONS - 1); } return ret; }); @@ -86,8 +78,7 @@ void setup_operations() for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x) { for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y) - for (blt::i32 c = 0; c < IMAGE_CHANNELS; ++c) - ret.get_data().get(x, y, c) = static_cast(x + y) / static_cast((IMAGE_DIMENSIONS - 1) * (IMAGE_DIMENSIONS - 1)); + ret.get_data().get(x, y) = static_cast(x + y) / static_cast((IMAGE_DIMENSIONS - 1) * (IMAGE_DIMENSIONS - 1)); } return ret; }); @@ -95,9 +86,9 @@ void setup_operations() const auto blend = std::min(std::max(f, 0.0f), 1.0f); const auto beta = 1.0f - blend; image_t ret; - const cv::Mat src1{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC4, a.as_void()}; - const cv::Mat src2{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC4, b.as_void()}; - cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC4, ret.get_data().data.data()}; + const cv::Mat src1{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, a.as_void()}; + const cv::Mat src2{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, b.as_void()}; + 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"); @@ -117,14 +108,14 @@ void setup_operations() 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); + static auto lit = operation_t([program]() { + return program->get_random().get_float(-1.0f, 1.0f); }, "lit_float").set_ephemeral(); operator_builder builder{}; builder.build(make_add(), make_sub(), make_mul(), make_div(), op_image_x, op_image_y, op_image_xy, make_add(), make_sub(), make_mul(), make_prot_div(), op_sin, op_cos, op_exp, op_log, lit); - program.set_operations(builder.grab()); + program->set_operations(builder.grab()); } void setup_gp_system(const blt::size_t population_size) @@ -132,24 +123,30 @@ 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); + program = new gp_program{ + []() { + return std::random_device()(); + }, + config + }; + images.resize(population_size); setup_operations(); static auto sel = select_tournament_t{}; - program.generate_initial_population(program.get_typesystem().get_type().id()); - program.setup_generational_evaluation(fitness_func, sel, sel, sel); + program->generate_initial_population(program->get_typesystem().get_type().id()); + program->setup_generational_evaluation(fitness_func, sel, sel, sel); } void run_step() { - BLT_TRACE("------------\\{Begin Generation {}}------------", program.get_current_generation()); + BLT_TRACE("------------\\{Begin Generation {}}------------", program->get_current_generation()); BLT_TRACE("Creating next generation"); - program.create_next_generation(); + program->create_next_generation(); BLT_TRACE("Move to next generation"); - program.next_generation(); + program->next_generation(); BLT_TRACE("Evaluate Fitness"); - program.evaluate_fitness(); - const auto& stats = program.get_population_stats(); + 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)); @@ -158,10 +155,15 @@ void run_step() bool should_terminate() { - return program.should_terminate(); + return program->should_terminate(); } image_storage_t& get_image(blt::size_t index) { return images[index]; } + +void cleanup() +{ + delete program; +} diff --git a/src/image_storage.cpp b/src/image_storage.cpp index 6f013de..e148ddc 100644 --- a/src/image_storage.cpp +++ b/src/image_storage.cpp @@ -21,17 +21,31 @@ #include #include -image_storage_t image_storage_t::from_file(const std::string& path) +std::array image_storage_t::from_file(const std::string& path) { stbi_set_flip_vertically_on_load(true); int x, y, channels; auto* data = stbi_loadf(path.c_str(), &x, &y, &channels, 4); - image_storage_t storage{}; - stbir_resize_float_linear(data, x, y, 0, storage.data.data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, 0, STBIR_RGBA); + const auto resized = stbir_resize_float_linear(data, x, y, 0, nullptr, IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, 0, STBIR_RGBA); + + image_storage_t storage_r{}; + image_storage_t storage_g{}; + image_storage_t storage_b{}; + + for (blt::size_t i = 0; i < IMAGE_DIMENSIONS; ++i) + { + for (blt::size_t j = 0; j < IMAGE_DIMENSIONS; ++j) + { + storage_r.get(i, j) = resized[(i * IMAGE_DIMENSIONS + j) * 4]; + storage_g.get(i, j) = resized[(i * IMAGE_DIMENSIONS + j) * 4 + 1]; + storage_b.get(i, j) = resized[(i * IMAGE_DIMENSIONS + j) * 4 + 2]; + } + } stbi_image_free(data); - return storage; + stbi_image_free(resized); + return {storage_r, storage_g, storage_b}; } image_t operator/(const image_t& lhs, const image_t& rhs) diff --git a/src/main.cpp b/src/main.cpp index a0c93c7..431d2a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ std::thread run_gp() } else std::this_thread::sleep_for(std::chrono::milliseconds(10)); } + cleanup(); } }; } @@ -51,6 +52,8 @@ void init(const blt::gfx::window_data&) global_matrices.create_internals(); resources.load_resources(); renderer_2d.create(); + + setWindowSize(1400, 720); } void update(const blt::gfx::window_data& data) @@ -123,21 +126,24 @@ void update(const blt::gfx::window_data& data) 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 Blocks / Deallocated Blocks: (%ld / %ld) (%ld / %ld) (Total: %ld)", allocated_blocks, deallocated_blocks, - g_image_list.images.size(), allocated_blocks - deallocated_blocks, g_image_list.images.size() + (allocated_blocks - deallocated_blocks)); + g_image_list.images.size(), allocated_blocks - deallocated_blocks, + g_image_list.images.size() + (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++) + constexpr int images_x = 10; + constexpr int images_y = 6; + for (int i = 0; i < images_x; i++) { - for (int j = 0; j < 6; j++) + for (int j = 0; j < images_y; j++) { constexpr float padding_x = 32; constexpr float padding_y = 32; - constexpr float img_width = 128; - constexpr float img_height = 128; + const float img_width = (static_cast(data.width) - padding_x * 2 - padding_x * (images_x-1) - 256) / images_x; + const float img_height = (static_cast(data.height) - padding_y * 2 - padding_y * (images_y-1) - 32) / images_y; 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);