From 4c2418293b506eddea4112ead64e73a3e9f00a41 Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 16:58:50 -0600 Subject: [PATCH 1/9] add warning --- rollo/constraints.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rollo/constraints.py b/rollo/constraints.py index bb666c13..95b65aeb 100644 --- a/rollo/constraints.py +++ b/rollo/constraints.py @@ -119,6 +119,10 @@ def apply_constraints(self, pop): not_constrained = False if not_constrained: new_pop.append(ind) + if len(new_pop) == 0: + raise Exception( + "All individuals were constrained. Run with larger population size or reconsider your constraint choice. " + ) final_pop = [self.toolbox.clone(ind) for ind in new_pop] while len(final_pop) < len(pop): final_pop.append(self.toolbox.clone(random.choice(new_pop))) From b75b301aa8fb17ac7d0ced530a1fc4a65d494b63 Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 17:00:21 -0600 Subject: [PATCH 2/9] add order + keep files --- rollo/evaluation.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/rollo/evaluation.py b/rollo/evaluation.py index 19300e05..d0f3a6b2 100644 --- a/rollo/evaluation.py +++ b/rollo/evaluation.py @@ -63,7 +63,12 @@ def add_evaluator(self, solver_name, input_script, output_script): pass return - def eval_fn_generator(self, control_dict, output_dict, input_evaluators): + def eval_fn_generator( + self, + control_dict, + output_dict, + input_evaluators, + gens): """Returns a function that accepts a DEAP individual and returns a tuple of output values listed in outputs @@ -105,8 +110,9 @@ def eval_function(ind): self.rank_time = time.time() control_vars = self.name_ind(ind, control_dict, input_evaluators) output_vals = [None] * len(output_dict) + order_of_solvers = self.solver_order(input_evaluators) - for solver in input_evaluators: + for solver in order_of_solvers: # path name for solver's run path = solver + "_" + str(ind.gen) + "_" + str(ind.num) # render jinja-ed input script @@ -125,12 +131,21 @@ def eval_function(ind): output_vals = self.get_output_vals( output_vals, solver, output_dict, control_vars, path ) - if not input_evaluators[solver]["keep_files"]: + if input_evaluators[solver]["keep_files"] == "none": shutil.rmtree(path) + elif input_evaluators[solver]["keep_files"] == "only_final": + if ind.gen < gens - 1: + shutil.rmtree(path) return tuple(output_vals) return eval_function + def solver_order(self, input_evaluators): + order = [None] * len(input_evaluators) + for solver in input_evaluators: + order[input_evaluators[solver]["order"]] = solver + return order + def get_output_vals( self, output_vals, From 5b6eabeb8872eaff52094cd69ef7f4a6463bb631 Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 17:01:17 -0600 Subject: [PATCH 3/9] gens --- rollo/executor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rollo/executor.py b/rollo/executor.py index d4719dd1..3c399939 100644 --- a/rollo/executor.py +++ b/rollo/executor.py @@ -193,9 +193,9 @@ def load_evaluator(self, control_dict, output_dict, input_dict): input_script=solver_dict["input_script"], output_script=output_script, ) + gens = input_dict["algorithm"]["generations"] evaluator_fn = evaluator.eval_fn_generator( - control_dict, output_dict, input_dict["evaluators"] - ) + control_dict, output_dict, input_dict["evaluators"], gens) return evaluator_fn def load_toolbox( From a6861f03198c9893980a319d0f0fe6bb97281d81 Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 17:03:48 -0600 Subject: [PATCH 4/9] update input params --- rollo/input_validation.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rollo/input_validation.py b/rollo/input_validation.py index 31706217..55e90b42 100644 --- a/rollo/input_validation.py +++ b/rollo/input_validation.py @@ -38,11 +38,12 @@ def add_all_defaults(self): for solver in input_dict["evaluators"]: input_evaluators[solver] = input_dict["evaluators"][solver] input_evaluators[solver] = self.default_check( - input_evaluators[solver], "keep_files", True + input_evaluators[solver], "keep_files", "all" ) input_algorithm = input_dict["algorithm"] input_algorithm = self.default_check( input_algorithm, "objective", "min") + input_algorithm = self.default_check(input_algorithm, "weight", [1.0]) input_algorithm = self.default_check(input_algorithm, "pop_size", 60) input_algorithm = self.default_check( input_algorithm, "generations", 10) @@ -174,6 +175,10 @@ def validate_algorithm(self, input_algorithm, input_evaluators): "type": "array", "items": {"type": "string"}, }, + "weight": { + "type": "array", + "items": {"type": "number"}, + }, "optimized_variable": { "type": "array", "items": {"type": "string"}, @@ -195,6 +200,7 @@ def validate_algorithm(self, input_algorithm, input_evaluators): [ "parallel", "objective", + "weight", "pop_size", "generations", "mutation_probability", @@ -448,6 +454,7 @@ def validate_evaluators(self, input_evaluators): schema_evaluators["properties"][evaluator] = { "type": "object", "properties": { + "order": {"type": "number"}, "input_script": {"type": "string"}, "inputs": { "type": "array", @@ -458,17 +465,22 @@ def validate_evaluators(self, input_evaluators): "items": {"type": "string"}, }, "output_script": {"type": "string"}, - "keep_files": {"type": "boolean"}, + "keep_files": {"type": "string"}, }, } validate(instance=input_evaluators, schema=schema_evaluators) for evaluator in input_evaluators: self.validate_correct_keys( input_evaluators[evaluator], - ["input_script", "inputs", "outputs"], + ["input_script", "inputs", "outputs", "order"], ["output_script", "keep_files"], "evaluator: " + evaluator, ) + self.validate_in_list( + input_evaluators[evaluator]["keep_files"], + ["none", "all", "only_final"], + "keep_files", + ) # check if outputs are in predefined outputs or inputs, and if not # output_script must be defined in_list, which_strings = self.validate_if_in_list( From aa76e90dc93e7cccaa3bb48b11adcba27877c76a Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 17:04:26 -0600 Subject: [PATCH 5/9] update wt --- rollo/toolbox_generator.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rollo/toolbox_generator.py b/rollo/toolbox_generator.py index 3633aecf..8f5ce21f 100644 --- a/rollo/toolbox_generator.py +++ b/rollo/toolbox_generator.py @@ -38,11 +38,12 @@ def setup( """ weight_list = [] - for obj in input_algorithm["objective"]: + for obj, wt in zip(input_algorithm["objective"], + input_algorithm["weight"]): if obj == "min": - weight_list.append(-1.0) + weight_list.append(-wt) elif obj == "max": - weight_list.append(+1.0) + weight_list.append(+wt) creator.create("obj", base.Fitness, weights=tuple(weight_list)) creator.create("Ind", list, fitness=creator.obj) toolbox = base.Toolbox() From 89f0be16a760df976b823eb64d02ab2e2d458400 Mon Sep 17 00:00:00 2001 From: gwenchee Date: Fri, 4 Mar 2022 17:06:18 -0600 Subject: [PATCH 6/9] update tests --- tests/test_evaluation.py | 5 +++-- tests/test_executor.py | 3 +++ tests/test_toolbox_generator.py | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/test_evaluation.py b/tests/test_evaluation.py index a2e52889..f0c0cd20 100644 --- a/tests/test_evaluation.py +++ b/tests/test_evaluation.py @@ -36,9 +36,10 @@ def test_eval_fn_generator(): } ), input_evaluators={ - "openmc": {"keep_files": True}, - "moltres": {"keep_files": True}, + "openmc": {"keep_files": True, "order": 0}, + "moltres": {"keep_files": True, "order": 1}, }, + gens=2, ) creator.create("obj", base.Fitness, weights=(-1.0,)) diff --git a/tests/test_executor.py b/tests/test_executor.py index a1ee3499..1bc6b19b 100644 --- a/tests/test_executor.py +++ b/tests/test_executor.py @@ -21,6 +21,7 @@ }, "evaluators": { "openmc": { + "order": 0, "input_script": "input_test_eval_fn_generator_openmc_template.py", "inputs": ["packing_fraction", "polynomial_triso"], "outputs": ["packing_fraction", "keff", "num_batches"], @@ -28,6 +29,7 @@ "keep_files": True, }, "moltres": { + "order": 1, "input_script": "input_test_render_jinja_template_python.py", "inputs": [], "outputs": ["max_temp"], @@ -38,6 +40,7 @@ "constraints": {"keff": {"operator": [">"], "constrained_val": [1]}}, "algorithm": { "objective": ["max", "min"], + "weight": [1.0, 1.0], "optimized_variable": ["keff", "packing_fraction"], "pop_size": 100, "generations": 10, diff --git a/tests/test_toolbox_generator.py b/tests/test_toolbox_generator.py index ec70d343..78e6c95c 100644 --- a/tests/test_toolbox_generator.py +++ b/tests/test_toolbox_generator.py @@ -20,12 +20,14 @@ }, "evaluators": { "openmc": { + "order": 0, "input_script": "input_test_eval_fn_generator_openmc_template.py", "inputs": ["packing_fraction", "polynomial_triso"], "outputs": ["packing_fraction", "keff", "num_batches"], "output_script": "input_test_eval_fn_generator_openmc_output.py", }, "moltres": { + "order": 1, "input_script": "input_test_render_jinja_template_python.py", "inputs": [], "outputs": ["max_temp"], @@ -35,6 +37,7 @@ "constraints": {"keff": {"operator": ">", "constrained_val": 1}}, "algorithm": { "objective": ["max", "min"], + "weight": [1.0, 1.0], "optimized_variable": ["keff", "packing_fraction"], "pop_size": 100, "generations": 10, From 17869adf537107a1fdf40cfe15c55f4bd2d5d7df Mon Sep 17 00:00:00 2001 From: gwenchee Date: Mon, 7 Mar 2022 11:11:55 -0600 Subject: [PATCH 7/9] pep8 --- rollo/constraints.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rollo/constraints.py b/rollo/constraints.py index 95b65aeb..45f3931d 100644 --- a/rollo/constraints.py +++ b/rollo/constraints.py @@ -121,8 +121,8 @@ def apply_constraints(self, pop): new_pop.append(ind) if len(new_pop) == 0: raise Exception( - "All individuals were constrained. Run with larger population size or reconsider your constraint choice. " - ) + "All individuals were constrained. Run with larger" + + "population size or reconsider your constraint choice. ") final_pop = [self.toolbox.clone(ind) for ind in new_pop] while len(final_pop) < len(pop): final_pop.append(self.toolbox.clone(random.choice(new_pop))) From 418364c2ac42fb8210d773da1865d10cb338d95d Mon Sep 17 00:00:00 2001 From: gwenchee Date: Tue, 8 Mar 2022 11:07:32 -0600 Subject: [PATCH 8/9] add fn doc string --- rollo/evaluation.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rollo/evaluation.py b/rollo/evaluation.py index d0f3a6b2..1f61393e 100644 --- a/rollo/evaluation.py +++ b/rollo/evaluation.py @@ -141,6 +141,21 @@ def eval_function(ind): return eval_function def solver_order(self, input_evaluators): + """Returns a list with solver name at its order index + + Parameters + ---------- + input_evaluators : dict + evaluators sub-dictionary from input file + + Returns + ------- + list + list with solver name at its order index + e.g. if openmc solver order = 0 and moltres solver order = 1, the + returned list looks like ["openmc", "moltres"] + + """ order = [None] * len(input_evaluators) for solver in input_evaluators: order[input_evaluators[solver]["order"]] = solver From 319aa79a4a7a10814c953a6e6c556b8c0e6e01eb Mon Sep 17 00:00:00 2001 From: gwenchee Date: Tue, 8 Mar 2022 11:08:25 -0600 Subject: [PATCH 9/9] update docstring --- rollo/evaluation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rollo/evaluation.py b/rollo/evaluation.py index 1f61393e..5cf1d404 100644 --- a/rollo/evaluation.py +++ b/rollo/evaluation.py @@ -81,6 +81,8 @@ def eval_fn_generator( Ordered dict of output variables as keys and solvers as values input_evaluators : dict evaluators sub-dictionary from input file + gens: int + total generations in simulation (defined in input file) Returns -------