From 7d99bf7623c33a98f641be989d16c93793b1beed Mon Sep 17 00:00:00 2001 From: Winnus <winnus@posteo.de> Date: Fri, 22 Sep 2023 15:52:59 +0200 Subject: [PATCH] Added processing time output to each epoch --- README.md | 7 +++ src/PyGMA.py | 46 ++++++------------- src/components/config_func_op.py | 0 .../config_logical_gate_construction.py | 14 +++--- ...e_construction_no_explicit_input_coding.py | 0 src/components/evolutionary_phase.py | 8 ++++ src/components/genetic_operators.py | 1 - src/config-Copy1.py | 0 src/core/controller.py | 15 ++++-- src/core/mpi_worker.py | 3 +- 10 files changed, 50 insertions(+), 44 deletions(-) mode change 100644 => 100755 src/components/config_func_op.py mode change 100644 => 100755 src/components/config_logical_gate_construction.py mode change 100644 => 100755 src/components/config_logical_gate_construction_no_explicit_input_coding.py mode change 100644 => 100755 src/config-Copy1.py diff --git a/README.md b/README.md index 5137f13..cc018a3 100755 --- a/README.md +++ b/README.md @@ -79,3 +79,10 @@ By conductiong the experiment the a fitness value is generated for the gene. This should be returned. + + +# Todos +- implement a call to the experiment that handles how to save the fittest gene when evolution is finished. + - this has to be user defined and will save the gene into a users usable format for further use + + diff --git a/src/PyGMA.py b/src/PyGMA.py index 3096eb2..bf0e970 100755 --- a/src/PyGMA.py +++ b/src/PyGMA.py @@ -2,16 +2,6 @@ import numpy as np from config import CONFIG, check_config from core.controller import Controller - -# remove here -def bool2int(x): - r = 0 - for i, b in enumerate(x): - if b: - r += b << i - return r - - def mpi_worker(config): # instantiate the worker from core.mpi_worker import MPI_worker @@ -28,16 +18,18 @@ def controller(): """ # Init controller GAController = Controller(CONFIG, rng_seed=9) - print("Init controller") - print(GAController.populations) - print(GAController.populations[0].genetic_operator_stack) - print(GAController.populations[0].individuals[0].genome) + + # print information + print("Init Evolution controller:") + print(f'populations: {len(GAController.populations)}') + for i, pop in zip(range(len(GAController.populations)), GAController.populations): + print(f'Genetic Operators p{i}: {len(pop.genetic_operator_stack)}') # evolution for all phases GAController.evolve() - print("Evolve finished") + print("Evolve finished (fitness or epoch criterion met)") - print("First best genes") + # todo find the population with the best gene # get max fitness values # this is started inside the controller in get_fittest_individuals() @@ -46,24 +38,14 @@ def controller(): m = max(fit_per_pop) i = np.where(fit_per_pop == m) - print(GAController.populations[0].individuals[0].fitness) - print(GAController.populations[0].individuals[1].fitness) + print(f'Population fitness:{fit_per_pop}') - print(GAController.populations[0].individuals[0].genome) - gene = GAController.populations[0].individuals[0].genome - numbers = np.split(gene, 3) - # convert the numbers to ints - x = bool2int(numbers[0]) - y = bool2int(numbers[1]) - z = bool2int(numbers[2]) - print(f"{x} , {y}, {z}") - print(x * 2 + y * 3 + z) +# print(GAController.populations[0].individuals[0].fitness) +# print(GAController.populations[0].individuals[1].fitness) - # epoch loop - # GAController.epoch() - # print('Epoch') - # print(GAController.populations[0].individuals[0].genome) +# print(GAController.populations[0].individuals[0].genome) +# gene = GAController.populations[0].individuals[0].genome return @@ -89,7 +71,7 @@ def main(): rank = comm.Get_rank() # if mpi worker switch to worker mode - if rank != 0: + if rank > 0: mpi_worker(config) # rank 0 is the controller diff --git a/src/components/config_func_op.py b/src/components/config_func_op.py old mode 100644 new mode 100755 diff --git a/src/components/config_logical_gate_construction.py b/src/components/config_logical_gate_construction.py old mode 100644 new mode 100755 index 9f9988b..d0d46c4 --- a/src/components/config_logical_gate_construction.py +++ b/src/components/config_logical_gate_construction.py @@ -64,9 +64,9 @@ def n_bit_multiplication_inout(n): # Populations # Genetic Phases -OP_MUTATION = Mutation_operator(0.05, 10) -OP_CROSSOVER = Single_point_crossover_operator(10) -OP_REMOVAL = Removal_operator(20) +OP_MUTATION = Mutation_operator(0.05, 45) +OP_CROSSOVER = Single_point_crossover_operator(45) +OP_REMOVAL = Removal_operator(90) @@ -90,7 +90,7 @@ exp_inputs, exp_expected_outputs = n_bit_multiplication_inout(num_bits) num_logical_inputs = num_bits+num_bits # we have two numbers each having n bits num_logical_outputs = num_bits+num_bits# we need to save the result -num_logical_gates = 96 # how many logic gates we want to use +num_logical_gates = 128 # how many logic gates we want to use PHASE0_EXPERIMENT = Logical_circuit_experiment(exp_inputs, exp_expected_outputs, num_logical_inputs, num_logical_outputs, num_logical_gates) @@ -121,7 +121,7 @@ CONFIG_CIRCUIT_EVOLVE = { # mpiexec -n 3 python PyGMA.py # or use threads if not specified via slurm # mpiexec -n 3 --use-hwthread-cpus python PyGMA.py - 'use_mpi': False, + 'use_mpi': True, # use mpi4py.futures # this will dynamically spawn workers. @@ -149,7 +149,7 @@ CONFIG_CIRCUIT_EVOLVE = { # pop 0 [OP_REMOVAL, OP_CROSSOVER, OP_CROSSOVER], # pop 1 - [OP_REMOVAL, OP_CROSSOVER, OP_MUTATION], + [OP_REMOVAL, OP_MUTATION, OP_MUTATION], # pop 2 [OP_REMOVAL, OP_CROSSOVER, OP_MUTATION] ], @@ -158,7 +158,7 @@ CONFIG_CIRCUIT_EVOLVE = { # 'num_populations': 3, # how many individuals per population - 'num_individuals': 24, + 'num_individuals': 94, # start genome lenght for each individual 'genome_length': PHASE0_EXPERIMENT.needed_gene_length()[0], diff --git a/src/components/config_logical_gate_construction_no_explicit_input_coding.py b/src/components/config_logical_gate_construction_no_explicit_input_coding.py old mode 100644 new mode 100755 diff --git a/src/components/evolutionary_phase.py b/src/components/evolutionary_phase.py index 693fb93..020196f 100755 --- a/src/components/evolutionary_phase.py +++ b/src/components/evolutionary_phase.py @@ -23,6 +23,14 @@ class Evolutionary_phase: def completed(self, population_fitness: list, epochs: int) -> bool: """ Called to check if the phase has reached its end. + You have to return true or false depending on if the pase is finished or not. + For example: + max_fitness = max(population_fitness) + if max_fitness > 90.9: + return True + if epochs > 900: + return True + return False """ raise NotImplementedError diff --git a/src/components/genetic_operators.py b/src/components/genetic_operators.py index 44581bd..58a6498 100755 --- a/src/components/genetic_operators.py +++ b/src/components/genetic_operators.py @@ -54,7 +54,6 @@ class Set_zeros(Genetic_operator): for gene in old_population: gene[self.indexes] = 0 new_population.append(gene) - print(len(new_population)) return new_population class Mutation_all_operator(Genetic_operator): diff --git a/src/config-Copy1.py b/src/config-Copy1.py old mode 100644 new mode 100755 diff --git a/src/core/controller.py b/src/core/controller.py index eb4b74e..5b98dec 100755 --- a/src/core/controller.py +++ b/src/core/controller.py @@ -1,6 +1,7 @@ from core.population import Population from concurrent.futures import ProcessPoolExecutor import numpy as np +import time as time # FIXME: # implement correct print functions in the classes # such that print(object) can be called @@ -304,7 +305,7 @@ class Controller: # ---------- # init phase # ---------- - print(f'Evolutionary phase {evolutionary_phase}') + print(f'Evolutionary phase: {evolutionary_phase}') # reset epochs self.epochs = 0 @@ -328,13 +329,17 @@ class Controller: # apply genetic operator stack on each population # NOTE: after applying the stack the fitness values # will be zero again for all individuals + t_op_stack = time.time() self.__apply_operator_stack() + t_op_stack = time.time() - t_op_stack # instantiate individuals (get them a fitness value) # tell them the phase index becaus the worker processes # (mpi and local) will have their instance of the # phase list and with it know the experiments. + t_evaluate = time.time() self.__instantiate_individuals(phase_index=p_index) + t_evaluate = time.time() - t_evaluate # check if algorithm stagnates # IMP @@ -346,8 +351,12 @@ class Controller: # epoch done # ---------- # information - print( - f'epoch {self.epochs}, Pop max fitness {self.get_population_fitness()}') + print(f'epoch {self.epochs}') + print('--------------') + print(f't_op({t_op_stack})') + print(f't_eval({t_evaluate})') + print(f'Pop max fitness {self.get_population_fitness()}') + print() # increment counter self.epochs += 1 diff --git a/src/core/mpi_worker.py b/src/core/mpi_worker.py index ba3b5a2..3c453da 100755 --- a/src/core/mpi_worker.py +++ b/src/core/mpi_worker.py @@ -9,12 +9,13 @@ class MPI_worker(): self.comm = MPI.COMM_WORLD self.rank = self.comm.Get_rank() self.sleep_time = sleep_time + print(f'initialized MPI worker with rank {self.rank}') def start(self): # worker # loop until stop is signalled while True: - # print(f'worker {rank} loop') + print(f'worker {self.rank} loop') # signaling that we are waiting for new work self.comm.isend(None, dest=0, tag=mpi_tags.IDLE) -- GitLab