diff --git a/CMakeLists.txt b/CMakeLists.txt index d79074f..173245a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-6 VERSION 0.0.43) +project(image-gp-6 VERSION 0.0.44) include(FetchContent) diff --git a/include/float_operations.h b/include/float_operations.h index 9665ec6..98546e9 100644 --- a/include/float_operations.h +++ b/include/float_operations.h @@ -35,24 +35,19 @@ inline blt::gp::operation_t f_mul([](float a, float b) { inline blt::gp::operation_t f_pro_div([](float a, float b) { return b == 0.0f ? 0.0f : (a / b); }, "f_div"); -inline blt::gp::operation_t f_literal([]() { +inline auto f_literal = blt::gp::operation_t([]() { return program.get_random().get_float(0.0, 1.0); -}, "float_lit"); +}, "float_lit").set_ephemeral(); // used for blur size -inline blt::gp::operation_t i_literal([]() { +inline auto i_literal = blt::gp::operation_t([]() { return program.get_random().get_u64(u64_size_min, u64_size_max); -}, "int_lit"); +}, "int_lit").set_ephemeral(); template void create_float_operations(blt::gp::operator_builder& builder) { -// builder.add_operator(f_add); -// builder.add_operator(f_sub); -// builder.add_operator(f_mul); -// builder.add_operator(f_pro_div); - builder.add_operator(f_literal, true); - builder.add_operator(i_literal, true); + } #endif //IMAGE_GP_6_FLOAT_OPERATIONS_H diff --git a/include/image_operations.h b/include/image_operations.h index 01e609a..94ff7e1 100644 --- a/include/image_operations.h +++ b/include/image_operations.h @@ -224,14 +224,14 @@ inline blt::gp::operation_t hsv_to_rgb([](const full_image_t& a) { return img; }, "hsv"); -inline blt::gp::operation_t lit([]() { +inline auto lit = blt::gp::operation_t([]() { full_image_t img{}; auto bw = program.get_random().get_float(0.0f, 1.0f); for (auto& i : img.rgb_data) i = bw; return img; -}, "lit"); -inline blt::gp::operation_t vec([]() { +}, "lit").set_ephemeral(); +inline auto vec = blt::gp::operation_t([]() { full_image_t img{}; auto r = program.get_random().get_float(0.0f, 1.0f); auto g = program.get_random().get_float(0.0f, 1.0f); @@ -243,7 +243,7 @@ inline blt::gp::operation_t vec([]() { img.rgb_data[i * CHANNELS + 2] = b; } return img; -}, "vec"); +}, "vec").set_ephemeral(); inline blt::gp::operation_t random_val([]() { full_image_t img{}; for (auto& i : img.rgb_data) @@ -378,50 +378,9 @@ inline blt::gp::operation_t op_y_rgb([]() { template void create_image_operations(blt::gp::operator_builder& builder) { - builder.add_operator(perlin); - builder.add_operator(perlin_terminal); - builder.add_operator(perlin_warped); - builder.add_operator(add); - builder.add_operator(sub); - builder.add_operator(mul); - builder.add_operator(pro_div); - builder.add_operator(op_sin); - builder.add_operator(op_cos); - builder.add_operator(op_atan); - builder.add_operator(op_exp); - builder.add_operator(op_log); - builder.add_operator(op_abs); - builder.add_operator(op_round); - builder.add_operator(op_v_mod); - builder.add_operator(bitwise_and); - builder.add_operator(bitwise_or); - builder.add_operator(bitwise_invert); - builder.add_operator(bitwise_xor); - builder.add_operator(dissolve); - builder.add_operator(band_pass); - builder.add_operator(hsv_to_rgb); - builder.add_operator(gaussian_blur); - builder.add_operator(median_blur); - builder.add_operator(l_system); // idk when it got enabled but this works on 4.10 -#if CV_VERSION_MAJOR >= 4 && CV_VERSION_MINOR >= 10 - builder.add_operator(bilateral_filter); -#endif - builder.add_operator(high_pass); - - bool state = false; - builder.add_operator(lit, true); - builder.add_operator(vec, true); - builder.add_operator(random_val); - builder.add_operator(op_x_r, state); - builder.add_operator(op_x_g, state); - builder.add_operator(op_x_b, state); - builder.add_operator(op_x_rgb, state); - builder.add_operator(op_y_r, state); - builder.add_operator(op_y_g, state); - builder.add_operator(op_y_b, state); - builder.add_operator(op_y_rgb, state); + } #endif //IMAGE_GP_6_IMAGE_OPERATIONS_H diff --git a/lib/blt-gp b/lib/blt-gp index 766befd..e596678 160000 --- a/lib/blt-gp +++ b/lib/blt-gp @@ -1 +1 @@ -Subproject commit 766befd9495bb3b8ef399947801d6ea96b915779 +Subproject commit e5966789be45685ed73d0a152319c8da1793e53f diff --git a/src/custom_transformer.cpp b/src/custom_transformer.cpp index c6617dd..e9adc9e 100644 --- a/src/custom_transformer.cpp +++ b/src/custom_transformer.cpp @@ -23,6 +23,13 @@ namespace blt::gp { + inline tree_t& get_static_tree_tl(gp_program& program) + { + static thread_local tree_t new_tree{program}; + new_tree.clear(program); + return new_tree; + } + template static blt::u8* get_thread_pointer_for_size(blt::size_t bytes) { @@ -105,8 +112,9 @@ namespace blt::gp if (index < current_func_info.argument_types.size() && val.id != current_func_info.argument_types[index].id) { // TODO: new config? - auto tree = config.generator.get().generate( - {program, val.id, config.replacement_min_depth, config.replacement_max_depth}); + auto& tree = get_static_tree_tl(program); + config.generator.get().generate(tree, + {program, val.id, config.replacement_min_depth, config.replacement_max_depth}); auto& child = children_data[children_data.size() - 1 - index]; blt::size_t total_bytes_for = c.total_value_bytes(child.start, child.end); @@ -186,9 +194,10 @@ namespace blt::gp for (blt::ptrdiff_t i = static_cast(replacement_func_info.argc.argc) - 1; i >= current_func_info.argc.argc; i--) { - auto tree = config.generator.get().generate( - {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, - config.replacement_max_depth}); + auto& tree = get_static_tree_tl(program); + config.generator.get().generate(tree, + {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, + config.replacement_max_depth}); blt::size_t total_bytes_for = tree.total_value_bytes(); vals.copy_from(tree.get_values(), total_bytes_for); ops.insert(ops.begin() + static_cast(start_index), tree.get_operations().begin(), @@ -198,8 +207,8 @@ namespace blt::gp vals.copy_from(data, total_bytes_after); } // now finally update the type. - ops[c_node] = {replacement_func_info.function, program.get_typesystem().get_type(replacement_func_info.return_type).size(), - random_replacement, program.is_static(random_replacement)}; + ops[c_node] = {program.get_typesystem().get_type(replacement_func_info.return_type).size(), random_replacement, + program.is_static(random_replacement)}; } else { blt::size_t bytes_from_head = c.total_value_bytes(c_node + 1); @@ -229,9 +238,10 @@ namespace blt::gp id = program.get_random().select(terminals); } while (!program.is_static(id)); - stack_allocator stack; + static thread_local stack_allocator stack; + stack.reset(); - program.get_operator_info(id).function(nullptr, stack, stack, nullptr); + program.get_operator_info(id).func(nullptr, stack, stack); //auto adjustment = lit.get_function()(); auto& adjustment = stack.from(0); @@ -305,9 +315,10 @@ namespace blt::gp blt::size_t start_index = c_node; for (blt::ptrdiff_t i = new_argc - 1; i > static_cast(arg_position); i--) { - auto tree = config.generator.get().generate( - {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, - config.replacement_max_depth}); + auto& tree = get_static_tree_tl(program); + config.generator.get().generate(tree, + {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, + config.replacement_max_depth}); blt::size_t total_bytes_for = tree.total_value_bytes(); vals.copy_from(tree.get_values(), total_bytes_for); ops.insert(ops.begin() + static_cast(start_index), tree.get_operations().begin(), @@ -318,9 +329,10 @@ namespace blt::gp vals.copy_from(combined_ptr, for_bytes); for (blt::ptrdiff_t i = static_cast(arg_position) - 1; i >= 0; i--) { - auto tree = config.generator.get().generate( - {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, - config.replacement_max_depth}); + auto& tree = get_static_tree_tl(program); + config.generator.get().generate(tree, + {program, replacement_func_info.argument_types[i].id, config.replacement_min_depth, + config.replacement_max_depth}); blt::size_t total_bytes_for = tree.total_value_bytes(); vals.copy_from(tree.get_values(), total_bytes_for); ops.insert(ops.begin() + static_cast(start_index), tree.get_operations().begin(), @@ -330,7 +342,7 @@ namespace blt::gp vals.copy_from(combined_ptr + for_bytes, after_bytes); ops.insert(ops.begin() + static_cast(c_node), - {replacement_func_info.function, program.get_typesystem().get_type(replacement_func_info.return_type).size(), + {program.get_typesystem().get_type(replacement_func_info.return_type).size(), random_replacement, program.is_static(random_replacement)}); #if BLT_DEBUG_LEVEL >= 2 @@ -477,7 +489,7 @@ namespace blt::gp vals.copy_from(from_ptr, from_bytes); vals.copy_from(after_ptr, after_to_bytes); - static std::vector op_copy; + static thread_local std::vector op_copy; op_copy.clear(); op_copy.insert(op_copy.begin(), ops.begin() + from_child.start, ops.begin() + from_child.end); diff --git a/src/main.cpp b/src/main.cpp index 37c2bba..23e7b6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -259,7 +259,7 @@ constexpr auto create_fitness_function() cv::cvtColor(src, src_hsv, cv::COLOR_RGB2HSV); calcHist(&src_hsv, 1, channels, cv::Mat(), src_hist, 2, histSize, ranges, true, false); normalize(src_hist, src_hist, 0, 1, cv::NORM_MINMAX, -1, cv::Mat()); - + // auto total_hist = compareHist(hist_base, src_hist, cv::HISTCMP_BHATTACHARYYA); auto total_hist = compareHist(hist_base, src_hist, cv::HISTCMP_CORREL); @@ -286,9 +286,7 @@ void execute_generation() program.evaluate_fitness(); BLT_END_INTERVAL("Image Test", "Fitness"); BLT_START_INTERVAL("Image Test", "Gen"); - auto sel = blt::gp::select_tournament_t{}; -// auto sel = blt::gp::select_fitness_proportionate_t{}; - program.create_next_generation(sel, sel, sel); + program.create_next_generation(); BLT_END_INTERVAL("Image Test", "Gen"); BLT_TRACE("Move to next generation"); program.next_generation(); @@ -321,7 +319,9 @@ void run_gp() { BLT_DEBUG("Generate Initial Population"); static constexpr auto fitness_func = create_fitness_function(); - program.generate_population(type_system.get_type().id(), fitness_func, true); + auto sel = blt::gp::select_tournament_t{}; +// auto sel = blt::gp::select_fitness_proportionate_t{}; + program.generate_population(type_system.get_type().id(), fitness_func, sel, sel, sel); while (!program.should_thread_terminate()) { @@ -362,10 +362,20 @@ void init(const blt::gfx::window_data&) type_system.register_type(); blt::gp::operator_builder builder{type_system}; - create_image_operations(builder); - create_float_operations(builder); +#if CV_VERSION_MAJOR >= 4 && CV_VERSION_MINOR >= 10 + program.set_operations( + builder.build(perlin, perlin_terminal, perlin_warped, add, sub, mul, pro_div, op_sin, op_cos, op_atan, op_exp, op_log, op_abs, op_round, + op_v_mod, bitwise_and, bitwise_or, bitwise_invert, bitwise_xor, dissolve, band_pass, hsv_to_rgb, gaussian_blur, median_blur, + l_system, high_pass, bilateral_filter, lit, vec, random_val, op_x_r, op_x_g, op_x_b, op_x_rgb, op_y_r, op_y_g, op_y_b, + op_y_rgb, f_literal, i_literal)); +#else + program.set_operations( + builder.build(perlin, perlin_terminal, perlin_warped, add, sub, mul, pro_div, op_sin, op_cos, op_atan, op_exp, op_log, op_abs, op_round, + op_v_mod, bitwise_and, bitwise_or, bitwise_invert, bitwise_xor, dissolve, band_pass, hsv_to_rgb, gaussian_blur, median_blur, + l_system, high_pass, lit, vec, random_val, op_x_r, op_x_g, op_x_b, op_x_rgb, op_y_r, op_y_g, op_y_b, op_y_rgb, f_literal, + i_literal)); +#endif - program.set_operations(builder.build()); global_matrices.create_internals(); resources.load_resources();