hello silly

main
Brett 2025-04-03 15:14:13 -04:00
parent 93bde73a8a
commit 7e33385bfb
9 changed files with 82 additions and 59 deletions

View File

@ -5,9 +5,6 @@
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src/subprojects/dlg" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/imgui-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/freetype-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/freetype-src/subprojects/dlg" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/imgui-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src/subprojects/dlg" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/imgui-src" vcs="Git" />
@ -17,6 +14,7 @@
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src/subprojects/dlg" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/imgui-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/FastNoise2" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/blt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/blt-gp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/blt-gp/lib/blt" vcs="Git" />
@ -25,5 +23,6 @@
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/blt/libraries/parallel-hashmap" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/stb" vcs="Git" />
</component>
</project>

View File

@ -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)

View File

@ -29,4 +29,6 @@ bool should_terminate();
image_storage_t& get_image(blt::size_t index);
void cleanup();
#endif //GP_SYSTEM_H

View File

@ -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<image_pixel_t, IMAGE_SIZE_CHANNELS> data;
static image_storage_t from_file(const std::string& path);
static std::array<image_storage_t, 3> 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];
}
};

@ -1 +1 @@
Subproject commit 284743c683aebae3277f64a07cdd0deedf629039
Subproject commit 729a16ab574e31bf1b44446a777e4ee834518c6e

@ -1 +1 @@
Subproject commit a742164bedd31cac6d828032ee1a4a18c64d0cac
Subproject commit 0eea2189e37a372f7a012a07120ee0aed2b1646a

View File

@ -24,34 +24,28 @@
using namespace blt::gp;
gp_program program{
[]() {
return std::random_device()();
}
};
std::array<gp_program*, 3> programs;
std::vector<image_storage_t> images;
image_storage_t reference_image = image_storage_t::from_file("../silly.png");
std::vector<std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3>> images;
auto reference_image = image_storage_t::from_file("../silly.png");
template <size_t Channel>
void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t index)
{
auto image = tree.get_evaluation_ref<image_t>();
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<float>(x) / (static_cast<float>(IMAGE_DIMENSIONS) / 2)) - 1)) + (1 - std::abs(
(static_cast<float>(y) / (static_cast<float>(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<float>(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<float>(x) / static_cast<float>(IMAGE_DIMENSIONS - 1);
ret.get_data().get(x, y) = static_cast<float>(x) / static_cast<float>(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<float>(y) / static_cast<float>(IMAGE_DIMENSIONS - 1);
ret.get_data().get(x, y) = static_cast<float>(y) / static_cast<float>(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<float>(x + y) / static_cast<float>((IMAGE_DIMENSIONS - 1) * (IMAGE_DIMENSIONS - 1));
ret.get_data().get(x, y) = static_cast<float>(x + y) / static_cast<float>((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<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);
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<image_t>().id());
program.setup_generational_evaluation(fitness_func, sel, sel, sel);
program->generate_initial_population(program->get_typesystem().get_type<image_t>().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;
}

View File

@ -21,17 +21,31 @@
#include <blt/iterator/zip.h>
#include <blt/math/vectors.h>
image_storage_t image_storage_t::from_file(const std::string& path)
std::array<image_storage_t, 3> 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)

View File

@ -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<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);