Brett 2025-04-18 15:47:46 -04:00
parent 487f771377
commit b634ea7268
3 changed files with 29 additions and 19 deletions

View File

@ -27,7 +27,7 @@ macro(compile_options target_name)
sanitizers(${target_name}) sanitizers(${target_name})
endmacro() endmacro()
project(blt-gp VERSION 0.5.11) project(blt-gp VERSION 0.5.12)
include(CTest) include(CTest)

View File

@ -58,8 +58,8 @@ namespace blt::gp
{ {
struct argc_t struct argc_t
{ {
blt::u32 argc = 0; u32 argc = 0;
blt::u32 argc_context = 0; u32 argc_context = 0;
[[nodiscard]] bool is_terminal() const [[nodiscard]] bool is_terminal() const
{ {
@ -81,8 +81,8 @@ namespace blt::gp
struct operator_metadata_t struct operator_metadata_t
{ {
blt::size_t arg_size_bytes = 0; size_t arg_size_bytes = 0;
blt::size_t return_size_bytes = 0; size_t return_size_bytes = 0;
argc_t argc{}; argc_t argc{};
}; };
@ -106,12 +106,15 @@ namespace blt::gp
type_provider system; type_provider system;
}; };
using serializer_error_t = std::variant<>;
template <typename Context = detail::empty_t> template <typename Context = detail::empty_t>
class operator_builder class operator_builder
{ {
friend class gp_program; friend class gp_program;
friend class blt::gp::detail::operator_storage_test; friend class detail::operator_storage_test;
public: public:
explicit operator_builder() = default; explicit operator_builder() = default;
@ -833,9 +836,9 @@ namespace blt::gp
void save_state(fs::writer_t& writer); void save_state(fs::writer_t& writer);
void load_generation(fs::reader_t& reader); bool load_generation(fs::reader_t& reader);
void load_state(fs::reader_t& reader); std::optional<serializer_error_t> load_state(fs::reader_t& reader);
private: private:
template <typename FitnessFunc> template <typename FitnessFunc>

View File

@ -18,6 +18,9 @@
#include <blt/gp/program.h> #include <blt/gp/program.h>
#include <iostream> #include <iostream>
#define BLT_ASSERT_RET(expr, ret) if (!(expr)) { return ret; }
#define BLT_ASSERT_RET(expr) if (!(expr)) { return false; }
namespace blt::gp namespace blt::gp
{ {
// default static references for mutation, crossover, and initializer // default static references for mutation, crossover, and initializer
@ -69,10 +72,10 @@ namespace blt::gp
} }
} }
void gp_program::load_generation(fs::reader_t& reader) bool gp_program::load_generation(fs::reader_t& reader)
{ {
size_t individuals; size_t individuals;
reader.read(&individuals, sizeof(individuals)); BLT_ASSERT_RET(reader.read(&individuals, sizeof(individuals)) == sizeof(individuals));
if (current_pop.get_individuals().size() != individuals) if (current_pop.get_individuals().size() != individuals)
{ {
for (size_t i = current_pop.get_individuals().size(); i < individuals; i++) for (size_t i = current_pop.get_individuals().size(); i < individuals; i++)
@ -80,10 +83,11 @@ namespace blt::gp
} }
for (auto& individual : current_pop.get_individuals()) for (auto& individual : current_pop.get_individuals())
{ {
reader.read(&individual.fitness, sizeof(individual.fitness)); BLT_ASSERT_RET(reader.read(&individual.fitness, sizeof(individual.fitness)) == sizeof(individual.fitness));
individual.tree.clear(*this); individual.tree.clear(*this);
individual.tree.from_file(reader); individual.tree.from_file(reader);
} }
return true;
} }
void write_stat(fs::writer_t& writer, const population_stats& stat) void write_stat(fs::writer_t& writer, const population_stats& stat)
@ -102,17 +106,18 @@ namespace blt::gp
writer.write(&fitness, sizeof(fitness)); writer.write(&fitness, sizeof(fitness));
} }
void load_stat(fs::reader_t& reader, population_stats& stat) bool load_stat(fs::reader_t& reader, population_stats& stat)
{ {
BLT_ASSERT(reader.read(&stat.overall_fitness, sizeof(stat.overall_fitness)) == sizeof(stat.overall_fitness)); BLT_ASSERT_RET(reader.read(&stat.overall_fitness, sizeof(stat.overall_fitness)) == sizeof(stat.overall_fitness));
BLT_ASSERT(reader.read(&stat.average_fitness, sizeof(stat.average_fitness)) == sizeof(stat.average_fitness)); BLT_ASSERT_RET(reader.read(&stat.average_fitness, sizeof(stat.average_fitness)) == sizeof(stat.average_fitness));
BLT_ASSERT(reader.read(&stat.best_fitness, sizeof(stat.best_fitness)) == sizeof(stat.best_fitness)); BLT_ASSERT_RET(reader.read(&stat.best_fitness, sizeof(stat.best_fitness)) == sizeof(stat.best_fitness));
BLT_ASSERT(reader.read(&stat.worst_fitness, sizeof(stat.worst_fitness)) == sizeof(stat.worst_fitness)); BLT_ASSERT_RET(reader.read(&stat.worst_fitness, sizeof(stat.worst_fitness)) == sizeof(stat.worst_fitness));
size_t fitness_count; size_t fitness_count;
BLT_ASSERT(reader.read(&fitness_count, sizeof(fitness_count)) == sizeof(size_t)); BLT_ASSERT_RET(reader.read(&fitness_count, sizeof(fitness_count)) == sizeof(size_t));
stat.normalized_fitness.resize(fitness_count); stat.normalized_fitness.resize(fitness_count);
for (auto& fitness : stat.normalized_fitness) for (auto& fitness : stat.normalized_fitness)
BLT_ASSERT(reader.read(&fitness, sizeof(fitness)) == sizeof(fitness)); BLT_ASSERT_RET(reader.read(&fitness, sizeof(fitness)) == sizeof(fitness));
return true;
} }
void gp_program::save_state(fs::writer_t& writer) void gp_program::save_state(fs::writer_t& writer)
@ -147,7 +152,7 @@ namespace blt::gp
save_generation(writer); save_generation(writer);
} }
void gp_program::load_state(fs::reader_t& reader) std::optional<serializer_error_t> gp_program::load_state(fs::reader_t& reader)
{ {
size_t operator_count; size_t operator_count;
BLT_ASSERT(reader.read(&operator_count, sizeof(operator_count)) == sizeof(operator_count)); BLT_ASSERT(reader.read(&operator_count, sizeof(operator_count)) == sizeof(operator_count));
@ -233,6 +238,8 @@ namespace blt::gp
load_stat(reader, statistic_history[i]); load_stat(reader, statistic_history[i]);
load_stat(reader, current_stats); load_stat(reader, current_stats);
load_generation(reader); load_generation(reader);
return {};
} }
void gp_program::create_threads() void gp_program::create_threads()