From 4abf7a5444ed32c5b8a864be8ffdfc7387c2cd9f Mon Sep 17 00:00:00 2001 From: Ale Rigazzi Date: Thu, 31 Aug 2023 13:39:12 -0500 Subject: [PATCH 1/9] Add log to file of parameters and test --- smartsim/_core/generation/generator.py | 63 ++++++++++++++++++++++-- smartsim/_core/generation/modelwriter.py | 27 +++++++--- smartsim/experiment.py | 10 +++- tests/test_configs/log_params_truth.txt | 32 ++++++++++++ tests/test_generator.py | 21 +++++++- tests/test_modelwriter.py | 25 ++++++++-- 6 files changed, 159 insertions(+), 19 deletions(-) create mode 100644 tests/test_configs/log_params_truth.txt diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index 86c96f4e9..c1789b8e3 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -29,7 +29,10 @@ import typing as t from distutils import dir_util # pylint: disable=deprecated-module +from logging import INFO, DEBUG from os import mkdir, path, symlink +from os.path import join, relpath +from tabulate import tabulate from ...entity import Model, TaggedFilesHierarchy from ...log import get_logger @@ -49,7 +52,9 @@ class Generator: and writing into configuration files as well. """ - def __init__(self, gen_path: str, overwrite: bool = False) -> None: + def __init__( + self, gen_path: str, overwrite: bool = False, verbose: bool = False + ) -> None: """Initialize a generator object if overwrite is true, replace any existing @@ -59,12 +64,18 @@ def __init__(self, gen_path: str, overwrite: bool = False) -> None: is false, raises EntityExistsError when there is a name collision between entities. + :param gen_path: Path in which files need to be generated + :type gen_path: str :param overwrite: toggle entity replacement, defaults to False :type overwrite: bool, optional + :param verbose: Whether generation information should be logged to std out + :type verbose: bool, optional """ self._writer = ModelWriter() self.gen_path = gen_path + self.log_file = join(gen_path, "param_settings.txt") self.overwrite = overwrite + self.log_level = DEBUG if not verbose else INFO def generate_experiment(self, *args: t.Any) -> None: """Run ensemble and experiment file structure generation @@ -129,7 +140,9 @@ def _gen_exp_dir(self) -> None: # keep exists ok for race conditions on NFS pathlib.Path(self.gen_path).mkdir(exist_ok=True) else: - logger.info("Working in previously created experiment") + logger.log( + level=self.log_level, msg="Working in previously created experiment" + ) def _gen_orc_dir(self, orchestrator: t.Optional[Orchestrator]) -> None: """Create the directory that will hold the error, output and @@ -249,10 +262,50 @@ def _build_tagged_files(tagged: TaggedFilesHierarchy) -> None: # write in changes to configurations if isinstance(entity, Model): - logger.debug( - f"Configuring model {entity.name} with params {entity.params}" + files_to_params = self._writer.configure_tagged_model_files( + to_write, entity.params + ) + self._log_params(entity, files_to_params) + + def _log_params( + self, entity: Model, files_to_params: t.Dict[str, t.Dict[str, str]] + ) -> None: + """Log which files were modified during generation + + and what values were set to the parameters + + :param entity: the model being generated + :type entity: Model + :param files_to_params: a dict connecting each file to its parameter settings + :type files_to_params: t.Dict[str, t.Dict[str, str]] + """ + used_params: t.Dict[str, str] = {} + file_to_tables: t.Dict[str, str] = {} + for file, params in files_to_params.items(): + used_params.update(params) + table = tabulate([[param, value] for param, value in params.items()]) + file_to_tables[relpath(file, self.gen_path)] = table + + if used_params: + used_params_str = ", ".join( + [f"{name}={value}" for name, value in used_params.items()] + ) + logger.log( + level=self.log_level, + msg=f"Configured model {entity.name} with params {used_params_str}", + ) + with open(self.log_file, mode="a", encoding="utf-8") as logfile: + logfile.write(f"Model name: {entity.name}" + "\n") + file_table = tabulate( + [[file, table] for file, table in file_to_tables.items()], + headers=["File name", "Parameters"], ) - self._writer.configure_tagged_model_files(to_write, entity.params) + logfile.write(file_table + "\n\n") + else: + logger.log( + level=self.log_level, + msg=f"Configured model {entity.name} with no parameters", + ) @staticmethod def _copy_entity_files(entity: Model) -> None: diff --git a/smartsim/_core/generation/modelwriter.py b/smartsim/_core/generation/modelwriter.py index eb0e389aa..0cf071082 100644 --- a/smartsim/_core/generation/modelwriter.py +++ b/smartsim/_core/generation/modelwriter.py @@ -63,7 +63,7 @@ def configure_tagged_model_files( tagged_files: t.List[str], params: t.Dict[str, str], make_missing_tags_fatal: bool = False, - ) -> None: + ) -> t.Dict[str, t.Dict[str, str]]: """Read, write and configure tagged files attached to a Model instance. @@ -71,13 +71,19 @@ def configure_tagged_model_files( :type model: list[str] :param params: model parameters :type params: dict[str, str] - :param make_missing_tags_fatal: blow up if a tag is missing + :param make_missing_tags_fatal: raise an error if a tag is missing :type make_missing_tags_fatal: bool + :returns: A dict connecting each file to its parameter settings + :rtype: dict[str,dict[str,str]] """ + files_to_tags: t.Dict[str, t.Dict[str, str]] = {} for tagged_file in tagged_files: self._set_lines(tagged_file) - self._replace_tags(params, make_missing_tags_fatal) + used_tags = self._replace_tags(params, make_missing_tags_fatal) self._write_changes(tagged_file) + files_to_tags[tagged_file] = used_tags + + return files_to_tags def _set_lines(self, file_path: str) -> None: """Set the lines for the modelwrtter to iterate over @@ -104,8 +110,10 @@ def _write_changes(self, file_path: str) -> None: except (IOError, OSError) as e: raise ParameterWriterError(file_path, read=False) from e - def _replace_tags(self, params: t.Dict[str, str], make_fatal: bool = False) -> None: - """Replace the tagged within the tagged file attached to this + def _replace_tags( + self, params: t.Dict[str, str], make_fatal: bool = False + ) -> t.Dict[str, str]: + """Replace the tagged parameters within the file attached to this model. The tag defaults to ";" :param model: The model instance @@ -113,9 +121,12 @@ def _replace_tags(self, params: t.Dict[str, str], make_fatal: bool = False) -> N :param make_fatal: (Optional) Set to True to force a fatal error if a tag is not matched :type make_fatal: bool + :returns: A dict of parameter names and values set for the file + :rtype: dict[str,str] """ edited = [] unused_tags: t.Dict[str, t.List[int]] = {} + used_params: t.Dict[str, str] = {} for i, line in enumerate(self.lines): search = re.search(self.regex, line) if search: @@ -126,6 +137,7 @@ def _replace_tags(self, params: t.Dict[str, str], make_fatal: bool = False) -> N new_val = str(params[previous_value]) new_line = re.sub(self.regex, new_val, line, 1) search = re.search(self.regex, new_line) + used_params[previous_value] = new_val if not search: edited.append(new_line) else: @@ -143,13 +155,12 @@ def _replace_tags(self, params: t.Dict[str, str], make_fatal: bool = False) -> N else: edited.append(line) for tag, value in unused_tags.items(): - missing_tag_message = ( - f"Unused tag {tag} on line(s): {str(value)}" - ) + missing_tag_message = f"Unused tag {tag} on line(s): {str(value)}" if make_fatal: raise SmartSimError(missing_tag_message) logger.warning(missing_tag_message) self.lines = edited + return used_params def _is_ensemble_spec( self, tagged_line: str, model_params: t.Dict[str, str] diff --git a/smartsim/experiment.py b/smartsim/experiment.py index 639d0e7c9..6c6b1ba34 100644 --- a/smartsim/experiment.py +++ b/smartsim/experiment.py @@ -231,7 +231,11 @@ def stop(self, *args: t.Any) -> None: raise def generate( - self, *args: t.Any, tag: t.Optional[str] = None, overwrite: bool = False + self, + *args: t.Any, + tag: t.Optional[str] = None, + overwrite: bool = False, + verbose: bool = False, ) -> None: """Generate the file structure for an ``Experiment`` @@ -251,9 +255,11 @@ def generate( :param overwrite: overwrite existing folders and contents, defaults to False :type overwrite: bool, optional + :param verbose: log parameter settings to std out + :type verbose: bool """ try: - generator = Generator(self.exp_path, overwrite=overwrite) + generator = Generator(self.exp_path, overwrite=overwrite, verbose=verbose) if tag: generator.set_tag(tag) generator.generate_experiment(*args) diff --git a/tests/test_configs/log_params_truth.txt b/tests/test_configs/log_params_truth.txt new file mode 100644 index 000000000..b94d214c0 --- /dev/null +++ b/tests/test_configs/log_params_truth.txt @@ -0,0 +1,32 @@ +Model name: dir_test_0 +File name Parameters +-------------------------- ------------ +dir_test/dir_test_0/in.atm ------ -- + THERMO 10 + STEPS 10 + ------ -- + +Model name: dir_test_1 +File name Parameters +-------------------------- ------------ +dir_test/dir_test_1/in.atm ------ -- + THERMO 10 + STEPS 20 + ------ -- + +Model name: dir_test_2 +File name Parameters +-------------------------- ------------ +dir_test/dir_test_2/in.atm ------ -- + THERMO 20 + STEPS 10 + ------ -- + +Model name: dir_test_3 +File name Parameters +-------------------------- ------------ +dir_test/dir_test_3/in.atm ------ -- + THERMO 20 + STEPS 20 + ------ -- + diff --git a/tests/test_generator.py b/tests/test_generator.py index 1fb55d05b..b92516786 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -24,6 +24,7 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import filecmp from os import path as osp import pytest @@ -108,7 +109,6 @@ def test_ensemble_overwrite_error(fileutils): def test_full_exp(fileutils, wlmutils): - test_dir = fileutils.make_test_dir() exp = Experiment("gen-test", test_dir, launcher="local") @@ -182,6 +182,24 @@ def test_multiple_tags(fileutils): ) +def test_generation_log(fileutils): + """Test that an error is issued when a tag is unused and make_fatal is True""" + + test_dir = fileutils.make_test_dir() + exp = Experiment("gen-log-test", test_dir, launcher="local") + + params = {"THERMO": [10, 20], "STEPS": [10, 20]} + ensemble = exp.create_ensemble("dir_test", params=params, run_settings=rs) + conf_file = fileutils.get_test_dir_path("in.atm") + ensemble.attach_generator_files(to_configure=conf_file) + + exp.generate(ensemble, verbose=True) + assert filecmp.cmp( + osp.join(test_dir, "param_settings.txt"), + fileutils.get_test_dir_path("log_params_truth.txt"), + ) + + def test_config_dir(fileutils): """Test the generation and configuration of models with tagged files that are directories with subdirectories and files @@ -198,6 +216,7 @@ def test_config_dir(fileutils): gen.generate_experiment(ensemble) assert osp.isdir(osp.join(test_dir, "test")) + # assert False def _check_generated(test_num, param_0, param_1): conf_test_dir = osp.join(test_dir, "test", f"test_{test_num}") diff --git a/tests/test_modelwriter.py b/tests/test_modelwriter.py index ba5393c4f..f360ff90b 100644 --- a/tests/test_modelwriter.py +++ b/tests/test_modelwriter.py @@ -32,14 +32,13 @@ import pytest from smartsim._core.generation.modelwriter import ModelWriter -from smartsim.error.errors import ParameterWriterError +from smartsim.error.errors import ParameterWriterError, SmartSimError from smartsim.settings import RunSettings mw_run_settings = RunSettings("python", exe_args="sleep.py") def test_write_easy_configs(fileutils): - test_dir = fileutils.make_test_dir() param_dict = { @@ -69,7 +68,6 @@ def test_write_easy_configs(fileutils): def test_write_med_configs(fileutils): - test_dir = fileutils.make_test_dir() param_dict = { @@ -144,3 +142,24 @@ def test_mw_error_2(): writer = ModelWriter() with pytest.raises(ParameterWriterError): writer._write_changes("[not/a/path]") + + +def test_write_mw_error_3(fileutils): + test_dir = fileutils.make_test_dir() + + param_dict = { + "5": 10, # MOM_input + } + + conf_path = fileutils.get_test_dir_path("easy/marked/") + correct_path = fileutils.get_test_dir_path("easy/correct/") + # copy confs to gen directory + dir_util.copy_tree(conf_path, test_dir) + assert path.isdir(test_dir) + + # init modelwriter + writer = ModelWriter() + with pytest.raises(SmartSimError): + writer.configure_tagged_model_files( + glob(test_dir + "/*"), param_dict, make_missing_tags_fatal=True + ) From d23cea654dad8fedc06bb6823be0db79705285b2 Mon Sep 17 00:00:00 2001 From: Ale Rigazzi Date: Thu, 31 Aug 2023 14:44:09 -0500 Subject: [PATCH 2/9] Remove trailing space --- smartsim/_core/generation/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index c1789b8e3..8f1ad45e5 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -53,7 +53,7 @@ class Generator: """ def __init__( - self, gen_path: str, overwrite: bool = False, verbose: bool = False + self, gen_path: str, overwrite: bool = False, verbose: bool = True ) -> None: """Initialize a generator object @@ -271,7 +271,7 @@ def _log_params( self, entity: Model, files_to_params: t.Dict[str, t.Dict[str, str]] ) -> None: """Log which files were modified during generation - + and what values were set to the parameters :param entity: the model being generated From 184694a0d5618be5283ca6a6d5db17273375f482 Mon Sep 17 00:00:00 2001 From: Al Rigazzi Date: Thu, 7 Sep 2023 19:15:01 +0200 Subject: [PATCH 3/9] Clean up test files --- smartsim/_core/generation/generator.py | 16 ++++--- .../circular_config}/h2o.inp | 0 .../circular_config/sub_dir/circle | 0 .../circular_config/sub_dir/hello.sh | 0 .../easy/correct/MOM_input | 0 .../easy/correct/example_input.i | 0 .../easy/correct/in.airebo | 0 .../{ => generator_files}/easy/correct/in.atm | 0 .../easy/correct/in.crack | 0 .../easy/correct/in.ellipse.gayberne | 0 .../easy/correct/input-file.inp | 0 .../easy/correct/input.nml | 0 .../easy/correct/simple-H20.xml | 0 .../easy/marked/MOM_input | 0 .../easy/marked/example_input.i | 0 .../easy/marked/in.airebo | 0 .../{ => generator_files}/easy/marked/in.atm | 0 .../easy/marked/in.crack | 0 .../easy/marked/in.ellipse.gayberne | 0 .../easy/marked/input-file.inp | 0 .../easy/marked/input.nml | 0 .../easy/marked/simple-H20.xml | 0 .../test_configs/{ => generator_files}/in.atm | 0 .../dir_test/dir_test_0/param_settings.txt | 8 ++++ .../dir_test/dir_test_1/param_settings.txt | 8 ++++ .../dir_test/dir_test_2/param_settings.txt | 8 ++++ .../dir_test/dir_test_3/param_settings.txt | 8 ++++ .../log_params/param_settings.txt | 32 ++++++++++++++ .../med/correct/MOM_input | 0 .../med/correct/diag_table | 0 .../med/correct/example_input.i | 0 .../med/correct/in.airebo | 0 .../{ => generator_files}/med/correct/in.atm | 0 .../med/correct/in.crack | 0 .../med/correct/in.ellipse.gayberne | 0 .../med/correct/input-file.inp | 0 .../med/correct/input.nml | 0 .../med/correct/simple-H20.xml | 0 .../med/marked/MOM_input | 0 .../med/marked/diag_table | 0 .../med/marked/example_input.i | 0 .../med/marked/in.airebo | 0 .../{ => generator_files}/med/marked/in.atm | 0 .../{ => generator_files}/med/marked/in.crack | 0 .../med/marked/in.ellipse.gayberne | 0 .../med/marked/input-file.inp | 0 .../med/marked/input.nml | 0 .../med/marked/simple-H20.xml | 0 .../multi_tags_template.sh | 0 .../new-tag/correct/MOM_input | 0 .../new-tag/correct/diag_table | 0 .../new-tag/correct/example_input.i | 0 .../new-tag/correct/in.airebo | 0 .../new-tag/correct/in.atm | 0 .../new-tag/correct/in.crack | 0 .../new-tag/correct/in.ellipse.gayberne | 0 .../new-tag/correct/input-file.inp | 0 .../new-tag/correct/input.nml | 0 .../new-tag/correct/simple-H20.xml | 0 .../new-tag/marked/MOM_input | 0 .../new-tag/marked/diag_table | 0 .../new-tag/marked/example_input.i | 0 .../new-tag/marked/in.airebo | 0 .../new-tag/marked/in.atm | 0 .../new-tag/marked/in.crack | 0 .../new-tag/marked/in.ellipse.gayberne | 0 .../new-tag/marked/input-file.inp | 0 .../new-tag/marked/input.nml | 0 .../new-tag/marked/simple-H20.xml | 0 .../tag_dir_template/nested_0/tagged_0.sh | 0 .../tag_dir_template/nested_1/tagged_1.sh | 0 .../{ => generator_files}/test_dir/test.py | 0 .../test_dir/test_dir_1/config.txt | 0 .../to_copy_dir/mock.txt | 0 .../to_symlink_dir/mock2.txt | 0 tests/test_configs/log_params_truth.txt | 32 -------------- tests/test_generator.py | 43 +++++++++++-------- 77 files changed, 100 insertions(+), 55 deletions(-) rename tests/test_configs/{ => generator_files/circular_config}/h2o.inp (100%) rename tests/test_configs/{ => generator_files}/circular_config/sub_dir/circle (100%) rename tests/test_configs/{ => generator_files}/circular_config/sub_dir/hello.sh (100%) rename tests/test_configs/{ => generator_files}/easy/correct/MOM_input (100%) rename tests/test_configs/{ => generator_files}/easy/correct/example_input.i (100%) rename tests/test_configs/{ => generator_files}/easy/correct/in.airebo (100%) rename tests/test_configs/{ => generator_files}/easy/correct/in.atm (100%) rename tests/test_configs/{ => generator_files}/easy/correct/in.crack (100%) rename tests/test_configs/{ => generator_files}/easy/correct/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/easy/correct/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/easy/correct/input.nml (100%) rename tests/test_configs/{ => generator_files}/easy/correct/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/easy/marked/MOM_input (100%) rename tests/test_configs/{ => generator_files}/easy/marked/example_input.i (100%) rename tests/test_configs/{ => generator_files}/easy/marked/in.airebo (100%) rename tests/test_configs/{ => generator_files}/easy/marked/in.atm (100%) rename tests/test_configs/{ => generator_files}/easy/marked/in.crack (100%) rename tests/test_configs/{ => generator_files}/easy/marked/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/easy/marked/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/easy/marked/input.nml (100%) rename tests/test_configs/{ => generator_files}/easy/marked/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/in.atm (100%) create mode 100644 tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt create mode 100644 tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt create mode 100644 tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt create mode 100644 tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt create mode 100644 tests/test_configs/generator_files/log_params/param_settings.txt rename tests/test_configs/{ => generator_files}/med/correct/MOM_input (100%) rename tests/test_configs/{ => generator_files}/med/correct/diag_table (100%) rename tests/test_configs/{ => generator_files}/med/correct/example_input.i (100%) rename tests/test_configs/{ => generator_files}/med/correct/in.airebo (100%) rename tests/test_configs/{ => generator_files}/med/correct/in.atm (100%) rename tests/test_configs/{ => generator_files}/med/correct/in.crack (100%) rename tests/test_configs/{ => generator_files}/med/correct/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/med/correct/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/med/correct/input.nml (100%) rename tests/test_configs/{ => generator_files}/med/correct/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/med/marked/MOM_input (100%) rename tests/test_configs/{ => generator_files}/med/marked/diag_table (100%) rename tests/test_configs/{ => generator_files}/med/marked/example_input.i (100%) rename tests/test_configs/{ => generator_files}/med/marked/in.airebo (100%) rename tests/test_configs/{ => generator_files}/med/marked/in.atm (100%) rename tests/test_configs/{ => generator_files}/med/marked/in.crack (100%) rename tests/test_configs/{ => generator_files}/med/marked/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/med/marked/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/med/marked/input.nml (100%) rename tests/test_configs/{ => generator_files}/med/marked/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/multi_tags_template.sh (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/MOM_input (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/diag_table (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/example_input.i (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/in.airebo (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/in.atm (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/in.crack (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/input.nml (100%) rename tests/test_configs/{ => generator_files}/new-tag/correct/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/MOM_input (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/diag_table (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/example_input.i (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/in.airebo (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/in.atm (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/in.crack (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/in.ellipse.gayberne (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/input-file.inp (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/input.nml (100%) rename tests/test_configs/{ => generator_files}/new-tag/marked/simple-H20.xml (100%) rename tests/test_configs/{ => generator_files}/tag_dir_template/nested_0/tagged_0.sh (100%) rename tests/test_configs/{ => generator_files}/tag_dir_template/nested_1/tagged_1.sh (100%) rename tests/test_configs/{ => generator_files}/test_dir/test.py (100%) rename tests/test_configs/{ => generator_files}/test_dir/test_dir_1/config.txt (100%) rename tests/test_configs/{ => generator_files}/to_copy_dir/mock.txt (100%) rename tests/test_configs/{ => generator_files}/to_symlink_dir/mock2.txt (100%) delete mode 100644 tests/test_configs/log_params_truth.txt diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index 8f1ad45e5..a5b1d759e 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -283,7 +283,8 @@ def _log_params( file_to_tables: t.Dict[str, str] = {} for file, params in files_to_params.items(): used_params.update(params) - table = tabulate([[param, value] for param, value in params.items()]) + table = tabulate([[param, value] for param, value in params.items()], + headers=["Name", "Value"]) file_to_tables[relpath(file, self.gen_path)] = table if used_params: @@ -294,13 +295,18 @@ def _log_params( level=self.log_level, msg=f"Configured model {entity.name} with params {used_params_str}", ) - with open(self.log_file, mode="a", encoding="utf-8") as logfile: - logfile.write(f"Model name: {entity.name}" + "\n") - file_table = tabulate( + file_table = tabulate( [[file, table] for file, table in file_to_tables.items()], headers=["File name", "Parameters"], ) - logfile.write(file_table + "\n\n") + log_entry = f"Model name: {entity.name}" + "\n" + file_table + "\n\n" + with open(self.log_file, mode="a", encoding="utf-8") as logfile: + logfile.write(log_entry) + with open(join(entity.path, "param_settings.txt"), + mode="a", + encoding="utf-8") as local_logfile: + local_logfile.write(log_entry) + else: logger.log( level=self.log_level, diff --git a/tests/test_configs/h2o.inp b/tests/test_configs/generator_files/circular_config/h2o.inp similarity index 100% rename from tests/test_configs/h2o.inp rename to tests/test_configs/generator_files/circular_config/h2o.inp diff --git a/tests/test_configs/circular_config/sub_dir/circle b/tests/test_configs/generator_files/circular_config/sub_dir/circle similarity index 100% rename from tests/test_configs/circular_config/sub_dir/circle rename to tests/test_configs/generator_files/circular_config/sub_dir/circle diff --git a/tests/test_configs/circular_config/sub_dir/hello.sh b/tests/test_configs/generator_files/circular_config/sub_dir/hello.sh similarity index 100% rename from tests/test_configs/circular_config/sub_dir/hello.sh rename to tests/test_configs/generator_files/circular_config/sub_dir/hello.sh diff --git a/tests/test_configs/easy/correct/MOM_input b/tests/test_configs/generator_files/easy/correct/MOM_input similarity index 100% rename from tests/test_configs/easy/correct/MOM_input rename to tests/test_configs/generator_files/easy/correct/MOM_input diff --git a/tests/test_configs/easy/correct/example_input.i b/tests/test_configs/generator_files/easy/correct/example_input.i similarity index 100% rename from tests/test_configs/easy/correct/example_input.i rename to tests/test_configs/generator_files/easy/correct/example_input.i diff --git a/tests/test_configs/easy/correct/in.airebo b/tests/test_configs/generator_files/easy/correct/in.airebo similarity index 100% rename from tests/test_configs/easy/correct/in.airebo rename to tests/test_configs/generator_files/easy/correct/in.airebo diff --git a/tests/test_configs/easy/correct/in.atm b/tests/test_configs/generator_files/easy/correct/in.atm similarity index 100% rename from tests/test_configs/easy/correct/in.atm rename to tests/test_configs/generator_files/easy/correct/in.atm diff --git a/tests/test_configs/easy/correct/in.crack b/tests/test_configs/generator_files/easy/correct/in.crack similarity index 100% rename from tests/test_configs/easy/correct/in.crack rename to tests/test_configs/generator_files/easy/correct/in.crack diff --git a/tests/test_configs/easy/correct/in.ellipse.gayberne b/tests/test_configs/generator_files/easy/correct/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/easy/correct/in.ellipse.gayberne rename to tests/test_configs/generator_files/easy/correct/in.ellipse.gayberne diff --git a/tests/test_configs/easy/correct/input-file.inp b/tests/test_configs/generator_files/easy/correct/input-file.inp similarity index 100% rename from tests/test_configs/easy/correct/input-file.inp rename to tests/test_configs/generator_files/easy/correct/input-file.inp diff --git a/tests/test_configs/easy/correct/input.nml b/tests/test_configs/generator_files/easy/correct/input.nml similarity index 100% rename from tests/test_configs/easy/correct/input.nml rename to tests/test_configs/generator_files/easy/correct/input.nml diff --git a/tests/test_configs/easy/correct/simple-H20.xml b/tests/test_configs/generator_files/easy/correct/simple-H20.xml similarity index 100% rename from tests/test_configs/easy/correct/simple-H20.xml rename to tests/test_configs/generator_files/easy/correct/simple-H20.xml diff --git a/tests/test_configs/easy/marked/MOM_input b/tests/test_configs/generator_files/easy/marked/MOM_input similarity index 100% rename from tests/test_configs/easy/marked/MOM_input rename to tests/test_configs/generator_files/easy/marked/MOM_input diff --git a/tests/test_configs/easy/marked/example_input.i b/tests/test_configs/generator_files/easy/marked/example_input.i similarity index 100% rename from tests/test_configs/easy/marked/example_input.i rename to tests/test_configs/generator_files/easy/marked/example_input.i diff --git a/tests/test_configs/easy/marked/in.airebo b/tests/test_configs/generator_files/easy/marked/in.airebo similarity index 100% rename from tests/test_configs/easy/marked/in.airebo rename to tests/test_configs/generator_files/easy/marked/in.airebo diff --git a/tests/test_configs/easy/marked/in.atm b/tests/test_configs/generator_files/easy/marked/in.atm similarity index 100% rename from tests/test_configs/easy/marked/in.atm rename to tests/test_configs/generator_files/easy/marked/in.atm diff --git a/tests/test_configs/easy/marked/in.crack b/tests/test_configs/generator_files/easy/marked/in.crack similarity index 100% rename from tests/test_configs/easy/marked/in.crack rename to tests/test_configs/generator_files/easy/marked/in.crack diff --git a/tests/test_configs/easy/marked/in.ellipse.gayberne b/tests/test_configs/generator_files/easy/marked/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/easy/marked/in.ellipse.gayberne rename to tests/test_configs/generator_files/easy/marked/in.ellipse.gayberne diff --git a/tests/test_configs/easy/marked/input-file.inp b/tests/test_configs/generator_files/easy/marked/input-file.inp similarity index 100% rename from tests/test_configs/easy/marked/input-file.inp rename to tests/test_configs/generator_files/easy/marked/input-file.inp diff --git a/tests/test_configs/easy/marked/input.nml b/tests/test_configs/generator_files/easy/marked/input.nml similarity index 100% rename from tests/test_configs/easy/marked/input.nml rename to tests/test_configs/generator_files/easy/marked/input.nml diff --git a/tests/test_configs/easy/marked/simple-H20.xml b/tests/test_configs/generator_files/easy/marked/simple-H20.xml similarity index 100% rename from tests/test_configs/easy/marked/simple-H20.xml rename to tests/test_configs/generator_files/easy/marked/simple-H20.xml diff --git a/tests/test_configs/in.atm b/tests/test_configs/generator_files/in.atm similarity index 100% rename from tests/test_configs/in.atm rename to tests/test_configs/generator_files/in.atm diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt new file mode 100644 index 000000000..373cec87e --- /dev/null +++ b/tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt @@ -0,0 +1,8 @@ +Model name: dir_test_0 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_0/in.atm Name Value + ------ ------- + THERMO 10 + STEPS 10 + diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt new file mode 100644 index 000000000..e45ebb6bf --- /dev/null +++ b/tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt @@ -0,0 +1,8 @@ +Model name: dir_test_1 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_1/in.atm Name Value + ------ ------- + THERMO 10 + STEPS 20 + diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt new file mode 100644 index 000000000..081dc56c6 --- /dev/null +++ b/tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt @@ -0,0 +1,8 @@ +Model name: dir_test_2 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_2/in.atm Name Value + ------ ------- + THERMO 20 + STEPS 10 + diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt new file mode 100644 index 000000000..3403f7c71 --- /dev/null +++ b/tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt @@ -0,0 +1,8 @@ +Model name: dir_test_3 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_3/in.atm Name Value + ------ ------- + THERMO 20 + STEPS 20 + diff --git a/tests/test_configs/generator_files/log_params/param_settings.txt b/tests/test_configs/generator_files/log_params/param_settings.txt new file mode 100644 index 000000000..6866960a4 --- /dev/null +++ b/tests/test_configs/generator_files/log_params/param_settings.txt @@ -0,0 +1,32 @@ +Model name: dir_test_0 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_0/in.atm Name Value + ------ ------- + THERMO 10 + STEPS 10 + +Model name: dir_test_1 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_1/in.atm Name Value + ------ ------- + THERMO 10 + STEPS 20 + +Model name: dir_test_2 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_2/in.atm Name Value + ------ ------- + THERMO 20 + STEPS 10 + +Model name: dir_test_3 +File name Parameters +-------------------------- --------------- +dir_test/dir_test_3/in.atm Name Value + ------ ------- + THERMO 20 + STEPS 20 + diff --git a/tests/test_configs/med/correct/MOM_input b/tests/test_configs/generator_files/med/correct/MOM_input similarity index 100% rename from tests/test_configs/med/correct/MOM_input rename to tests/test_configs/generator_files/med/correct/MOM_input diff --git a/tests/test_configs/med/correct/diag_table b/tests/test_configs/generator_files/med/correct/diag_table similarity index 100% rename from tests/test_configs/med/correct/diag_table rename to tests/test_configs/generator_files/med/correct/diag_table diff --git a/tests/test_configs/med/correct/example_input.i b/tests/test_configs/generator_files/med/correct/example_input.i similarity index 100% rename from tests/test_configs/med/correct/example_input.i rename to tests/test_configs/generator_files/med/correct/example_input.i diff --git a/tests/test_configs/med/correct/in.airebo b/tests/test_configs/generator_files/med/correct/in.airebo similarity index 100% rename from tests/test_configs/med/correct/in.airebo rename to tests/test_configs/generator_files/med/correct/in.airebo diff --git a/tests/test_configs/med/correct/in.atm b/tests/test_configs/generator_files/med/correct/in.atm similarity index 100% rename from tests/test_configs/med/correct/in.atm rename to tests/test_configs/generator_files/med/correct/in.atm diff --git a/tests/test_configs/med/correct/in.crack b/tests/test_configs/generator_files/med/correct/in.crack similarity index 100% rename from tests/test_configs/med/correct/in.crack rename to tests/test_configs/generator_files/med/correct/in.crack diff --git a/tests/test_configs/med/correct/in.ellipse.gayberne b/tests/test_configs/generator_files/med/correct/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/med/correct/in.ellipse.gayberne rename to tests/test_configs/generator_files/med/correct/in.ellipse.gayberne diff --git a/tests/test_configs/med/correct/input-file.inp b/tests/test_configs/generator_files/med/correct/input-file.inp similarity index 100% rename from tests/test_configs/med/correct/input-file.inp rename to tests/test_configs/generator_files/med/correct/input-file.inp diff --git a/tests/test_configs/med/correct/input.nml b/tests/test_configs/generator_files/med/correct/input.nml similarity index 100% rename from tests/test_configs/med/correct/input.nml rename to tests/test_configs/generator_files/med/correct/input.nml diff --git a/tests/test_configs/med/correct/simple-H20.xml b/tests/test_configs/generator_files/med/correct/simple-H20.xml similarity index 100% rename from tests/test_configs/med/correct/simple-H20.xml rename to tests/test_configs/generator_files/med/correct/simple-H20.xml diff --git a/tests/test_configs/med/marked/MOM_input b/tests/test_configs/generator_files/med/marked/MOM_input similarity index 100% rename from tests/test_configs/med/marked/MOM_input rename to tests/test_configs/generator_files/med/marked/MOM_input diff --git a/tests/test_configs/med/marked/diag_table b/tests/test_configs/generator_files/med/marked/diag_table similarity index 100% rename from tests/test_configs/med/marked/diag_table rename to tests/test_configs/generator_files/med/marked/diag_table diff --git a/tests/test_configs/med/marked/example_input.i b/tests/test_configs/generator_files/med/marked/example_input.i similarity index 100% rename from tests/test_configs/med/marked/example_input.i rename to tests/test_configs/generator_files/med/marked/example_input.i diff --git a/tests/test_configs/med/marked/in.airebo b/tests/test_configs/generator_files/med/marked/in.airebo similarity index 100% rename from tests/test_configs/med/marked/in.airebo rename to tests/test_configs/generator_files/med/marked/in.airebo diff --git a/tests/test_configs/med/marked/in.atm b/tests/test_configs/generator_files/med/marked/in.atm similarity index 100% rename from tests/test_configs/med/marked/in.atm rename to tests/test_configs/generator_files/med/marked/in.atm diff --git a/tests/test_configs/med/marked/in.crack b/tests/test_configs/generator_files/med/marked/in.crack similarity index 100% rename from tests/test_configs/med/marked/in.crack rename to tests/test_configs/generator_files/med/marked/in.crack diff --git a/tests/test_configs/med/marked/in.ellipse.gayberne b/tests/test_configs/generator_files/med/marked/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/med/marked/in.ellipse.gayberne rename to tests/test_configs/generator_files/med/marked/in.ellipse.gayberne diff --git a/tests/test_configs/med/marked/input-file.inp b/tests/test_configs/generator_files/med/marked/input-file.inp similarity index 100% rename from tests/test_configs/med/marked/input-file.inp rename to tests/test_configs/generator_files/med/marked/input-file.inp diff --git a/tests/test_configs/med/marked/input.nml b/tests/test_configs/generator_files/med/marked/input.nml similarity index 100% rename from tests/test_configs/med/marked/input.nml rename to tests/test_configs/generator_files/med/marked/input.nml diff --git a/tests/test_configs/med/marked/simple-H20.xml b/tests/test_configs/generator_files/med/marked/simple-H20.xml similarity index 100% rename from tests/test_configs/med/marked/simple-H20.xml rename to tests/test_configs/generator_files/med/marked/simple-H20.xml diff --git a/tests/test_configs/multi_tags_template.sh b/tests/test_configs/generator_files/multi_tags_template.sh similarity index 100% rename from tests/test_configs/multi_tags_template.sh rename to tests/test_configs/generator_files/multi_tags_template.sh diff --git a/tests/test_configs/new-tag/correct/MOM_input b/tests/test_configs/generator_files/new-tag/correct/MOM_input similarity index 100% rename from tests/test_configs/new-tag/correct/MOM_input rename to tests/test_configs/generator_files/new-tag/correct/MOM_input diff --git a/tests/test_configs/new-tag/correct/diag_table b/tests/test_configs/generator_files/new-tag/correct/diag_table similarity index 100% rename from tests/test_configs/new-tag/correct/diag_table rename to tests/test_configs/generator_files/new-tag/correct/diag_table diff --git a/tests/test_configs/new-tag/correct/example_input.i b/tests/test_configs/generator_files/new-tag/correct/example_input.i similarity index 100% rename from tests/test_configs/new-tag/correct/example_input.i rename to tests/test_configs/generator_files/new-tag/correct/example_input.i diff --git a/tests/test_configs/new-tag/correct/in.airebo b/tests/test_configs/generator_files/new-tag/correct/in.airebo similarity index 100% rename from tests/test_configs/new-tag/correct/in.airebo rename to tests/test_configs/generator_files/new-tag/correct/in.airebo diff --git a/tests/test_configs/new-tag/correct/in.atm b/tests/test_configs/generator_files/new-tag/correct/in.atm similarity index 100% rename from tests/test_configs/new-tag/correct/in.atm rename to tests/test_configs/generator_files/new-tag/correct/in.atm diff --git a/tests/test_configs/new-tag/correct/in.crack b/tests/test_configs/generator_files/new-tag/correct/in.crack similarity index 100% rename from tests/test_configs/new-tag/correct/in.crack rename to tests/test_configs/generator_files/new-tag/correct/in.crack diff --git a/tests/test_configs/new-tag/correct/in.ellipse.gayberne b/tests/test_configs/generator_files/new-tag/correct/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/new-tag/correct/in.ellipse.gayberne rename to tests/test_configs/generator_files/new-tag/correct/in.ellipse.gayberne diff --git a/tests/test_configs/new-tag/correct/input-file.inp b/tests/test_configs/generator_files/new-tag/correct/input-file.inp similarity index 100% rename from tests/test_configs/new-tag/correct/input-file.inp rename to tests/test_configs/generator_files/new-tag/correct/input-file.inp diff --git a/tests/test_configs/new-tag/correct/input.nml b/tests/test_configs/generator_files/new-tag/correct/input.nml similarity index 100% rename from tests/test_configs/new-tag/correct/input.nml rename to tests/test_configs/generator_files/new-tag/correct/input.nml diff --git a/tests/test_configs/new-tag/correct/simple-H20.xml b/tests/test_configs/generator_files/new-tag/correct/simple-H20.xml similarity index 100% rename from tests/test_configs/new-tag/correct/simple-H20.xml rename to tests/test_configs/generator_files/new-tag/correct/simple-H20.xml diff --git a/tests/test_configs/new-tag/marked/MOM_input b/tests/test_configs/generator_files/new-tag/marked/MOM_input similarity index 100% rename from tests/test_configs/new-tag/marked/MOM_input rename to tests/test_configs/generator_files/new-tag/marked/MOM_input diff --git a/tests/test_configs/new-tag/marked/diag_table b/tests/test_configs/generator_files/new-tag/marked/diag_table similarity index 100% rename from tests/test_configs/new-tag/marked/diag_table rename to tests/test_configs/generator_files/new-tag/marked/diag_table diff --git a/tests/test_configs/new-tag/marked/example_input.i b/tests/test_configs/generator_files/new-tag/marked/example_input.i similarity index 100% rename from tests/test_configs/new-tag/marked/example_input.i rename to tests/test_configs/generator_files/new-tag/marked/example_input.i diff --git a/tests/test_configs/new-tag/marked/in.airebo b/tests/test_configs/generator_files/new-tag/marked/in.airebo similarity index 100% rename from tests/test_configs/new-tag/marked/in.airebo rename to tests/test_configs/generator_files/new-tag/marked/in.airebo diff --git a/tests/test_configs/new-tag/marked/in.atm b/tests/test_configs/generator_files/new-tag/marked/in.atm similarity index 100% rename from tests/test_configs/new-tag/marked/in.atm rename to tests/test_configs/generator_files/new-tag/marked/in.atm diff --git a/tests/test_configs/new-tag/marked/in.crack b/tests/test_configs/generator_files/new-tag/marked/in.crack similarity index 100% rename from tests/test_configs/new-tag/marked/in.crack rename to tests/test_configs/generator_files/new-tag/marked/in.crack diff --git a/tests/test_configs/new-tag/marked/in.ellipse.gayberne b/tests/test_configs/generator_files/new-tag/marked/in.ellipse.gayberne similarity index 100% rename from tests/test_configs/new-tag/marked/in.ellipse.gayberne rename to tests/test_configs/generator_files/new-tag/marked/in.ellipse.gayberne diff --git a/tests/test_configs/new-tag/marked/input-file.inp b/tests/test_configs/generator_files/new-tag/marked/input-file.inp similarity index 100% rename from tests/test_configs/new-tag/marked/input-file.inp rename to tests/test_configs/generator_files/new-tag/marked/input-file.inp diff --git a/tests/test_configs/new-tag/marked/input.nml b/tests/test_configs/generator_files/new-tag/marked/input.nml similarity index 100% rename from tests/test_configs/new-tag/marked/input.nml rename to tests/test_configs/generator_files/new-tag/marked/input.nml diff --git a/tests/test_configs/new-tag/marked/simple-H20.xml b/tests/test_configs/generator_files/new-tag/marked/simple-H20.xml similarity index 100% rename from tests/test_configs/new-tag/marked/simple-H20.xml rename to tests/test_configs/generator_files/new-tag/marked/simple-H20.xml diff --git a/tests/test_configs/tag_dir_template/nested_0/tagged_0.sh b/tests/test_configs/generator_files/tag_dir_template/nested_0/tagged_0.sh similarity index 100% rename from tests/test_configs/tag_dir_template/nested_0/tagged_0.sh rename to tests/test_configs/generator_files/tag_dir_template/nested_0/tagged_0.sh diff --git a/tests/test_configs/tag_dir_template/nested_1/tagged_1.sh b/tests/test_configs/generator_files/tag_dir_template/nested_1/tagged_1.sh similarity index 100% rename from tests/test_configs/tag_dir_template/nested_1/tagged_1.sh rename to tests/test_configs/generator_files/tag_dir_template/nested_1/tagged_1.sh diff --git a/tests/test_configs/test_dir/test.py b/tests/test_configs/generator_files/test_dir/test.py similarity index 100% rename from tests/test_configs/test_dir/test.py rename to tests/test_configs/generator_files/test_dir/test.py diff --git a/tests/test_configs/test_dir/test_dir_1/config.txt b/tests/test_configs/generator_files/test_dir/test_dir_1/config.txt similarity index 100% rename from tests/test_configs/test_dir/test_dir_1/config.txt rename to tests/test_configs/generator_files/test_dir/test_dir_1/config.txt diff --git a/tests/test_configs/to_copy_dir/mock.txt b/tests/test_configs/generator_files/to_copy_dir/mock.txt similarity index 100% rename from tests/test_configs/to_copy_dir/mock.txt rename to tests/test_configs/generator_files/to_copy_dir/mock.txt diff --git a/tests/test_configs/to_symlink_dir/mock2.txt b/tests/test_configs/generator_files/to_symlink_dir/mock2.txt similarity index 100% rename from tests/test_configs/to_symlink_dir/mock2.txt rename to tests/test_configs/generator_files/to_symlink_dir/mock2.txt diff --git a/tests/test_configs/log_params_truth.txt b/tests/test_configs/log_params_truth.txt deleted file mode 100644 index b94d214c0..000000000 --- a/tests/test_configs/log_params_truth.txt +++ /dev/null @@ -1,32 +0,0 @@ -Model name: dir_test_0 -File name Parameters --------------------------- ------------ -dir_test/dir_test_0/in.atm ------ -- - THERMO 10 - STEPS 10 - ------ -- - -Model name: dir_test_1 -File name Parameters --------------------------- ------------ -dir_test/dir_test_1/in.atm ------ -- - THERMO 10 - STEPS 20 - ------ -- - -Model name: dir_test_2 -File name Parameters --------------------------- ------------ -dir_test/dir_test_2/in.atm ------ -- - THERMO 20 - STEPS 10 - ------ -- - -Model name: dir_test_3 -File name Parameters --------------------------- ------------ -dir_test/dir_test_3/in.atm ------ -- - THERMO 20 - STEPS 20 - ------ -- - diff --git a/tests/test_generator.py b/tests/test_generator.py index ecc15da44..8d448689c 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -35,8 +35,6 @@ from smartsim.settings import RunSettings from tabulate import tabulate -from smartsim.settings import SbatchSettings - rs = RunSettings("python", exe_args="sleep.py") @@ -50,6 +48,9 @@ """ +def get_gen_file(fileutils, filename): + return fileutils.get_test_conf_path(osp.join("generator_files", filename)) + def test_ensemble(fileutils): exp = Experiment("gen-test", launcher="local") @@ -59,7 +60,7 @@ def test_ensemble(fileutils): params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("test", params=params, run_settings=rs) - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=config) gen.generate_experiment(ensemble) @@ -77,12 +78,12 @@ def test_ensemble_overwrite(fileutils): params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("test", params=params, run_settings=rs) - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=[config]) gen.generate_experiment(ensemble) # re generate without overwrite - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=[config]) gen.generate_experiment(ensemble) @@ -100,12 +101,12 @@ def test_ensemble_overwrite_error(fileutils): params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("test", params=params, run_settings=rs) - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=[config]) gen.generate_experiment(ensemble) # re generate without overwrite - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=[config]) with pytest.raises(FileExistsError): gen.generate_experiment(ensemble) @@ -123,7 +124,7 @@ def test_full_exp(fileutils, wlmutils): params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("test_ens", params=params, run_settings=rs) - config = fileutils.get_test_conf_path("in.atm") + config = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=config) exp.generate(orc, ensemble, model) @@ -150,7 +151,7 @@ def test_dir_files(fileutils): params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("dir_test", params=params, run_settings=rs) - conf_dir = fileutils.get_test_dir_path("test_dir") + conf_dir = get_gen_file(fileutils, "test_dir") ensemble.attach_generator_files(to_configure=conf_dir) exp.generate(ensemble) @@ -178,9 +179,9 @@ def test_print_files(fileutils, capsys): params = {"THERMO": [10, 20], "STEPS": [20, 30]} ensemble = exp.create_ensemble("dir_test", params=params, run_settings=rs) - gen_dir = fileutils.get_test_dir_path("test_dir") - symlink_dir = fileutils.get_test_dir_path("to_symlink_dir") - copy_dir = fileutils.get_test_dir_path("to_copy_dir") + gen_dir = get_gen_file(fileutils, "test_dir") + symlink_dir = get_gen_file(fileutils, "to_symlink_dir") + copy_dir = get_gen_file(fileutils, "to_copy_dir") ensemble.print_attached_files() captured = capsys.readouterr() @@ -254,7 +255,7 @@ def test_multiple_tags(fileutils): parameterized_model = exp.create_model( "multi-tags", run_settings=model_settings, params=model_params ) - config = fileutils.get_test_conf_path("multi_tags_template.sh") + config = get_gen_file(fileutils, "multi_tags_template.sh") parameterized_model.attach_generator_files(to_configure=[config]) exp.generate(parameterized_model, overwrite=True) exp.start(parameterized_model, block=True) @@ -274,13 +275,19 @@ def test_generation_log(fileutils): params = {"THERMO": [10, 20], "STEPS": [10, 20]} ensemble = exp.create_ensemble("dir_test", params=params, run_settings=rs) - conf_file = fileutils.get_test_dir_path("in.atm") + conf_file = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=conf_file) exp.generate(ensemble, verbose=True) assert filecmp.cmp( osp.join(test_dir, "param_settings.txt"), - fileutils.get_test_dir_path("log_params_truth.txt"), + get_gen_file(fileutils, osp.join("log_params", "param_settings.txt")), + ) + + for entity in ensemble: + assert filecmp.cmp( + osp.join(entity.path, "param_settings.txt"), + get_gen_file(fileutils, osp.join("log_params", "dir_test", entity.name, "param_settings.txt")), ) @@ -295,7 +302,7 @@ def test_config_dir(fileutils): params = {"PARAM0": [0, 1], "PARAM1": [2, 3]} ensemble = exp.create_ensemble("test", params=params, run_settings=rs) - config = fileutils.get_test_conf_path("tag_dir_template") + config = get_gen_file(fileutils, "tag_dir_template") ensemble.attach_generator_files(to_configure=config) gen.generate_experiment(ensemble) @@ -327,7 +334,7 @@ def test_no_gen_if_file_not_exist(fileutils): """ exp = Experiment("file-not-found", launcher="local") ensemble = exp.create_ensemble("test", params={"P": [0, 1]}, run_settings=rs) - config = fileutils.get_test_conf_path("path_not_exist") + config = get_gen_file(fileutils, "path_not_exist") with pytest.raises(FileNotFoundError): ensemble.attach_generator_files(to_configure=config) @@ -339,6 +346,6 @@ def test_no_gen_if_symlink_to_dir(fileutils): """ exp = Experiment("circular-config-files", launcher="local") ensemble = exp.create_ensemble("test", params={"P": [0, 1]}, run_settings=rs) - config = fileutils.get_test_conf_path("circular_config") + config = get_gen_file(fileutils, "circular_config") with pytest.raises(ValueError): ensemble.attach_generator_files(to_configure=config) From d8a163952a4032d74d27a057fd131c39530d193c Mon Sep 17 00:00:00 2001 From: Al Rigazzi Date: Thu, 7 Sep 2023 20:05:45 +0200 Subject: [PATCH 4/9] Fix modelwriter tests --- tests/test_modelwriter.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/test_modelwriter.py b/tests/test_modelwriter.py index f360ff90b..11d887e2d 100644 --- a/tests/test_modelwriter.py +++ b/tests/test_modelwriter.py @@ -37,6 +37,8 @@ mw_run_settings = RunSettings("python", exe_args="sleep.py") +def get_gen_file(fileutils, filename): + return fileutils.get_test_conf_path(path.join("generator_files", filename)) def test_write_easy_configs(fileutils): test_dir = fileutils.make_test_dir() @@ -50,8 +52,8 @@ def test_write_easy_configs(fileutils): "1200": "120", # input.nml } - conf_path = fileutils.get_test_dir_path("easy/marked/") - correct_path = fileutils.get_test_dir_path("easy/correct/") + conf_path = get_gen_file(fileutils, "easy/marked/") + correct_path = get_gen_file(fileutils, "easy/correct/") # copy confs to gen directory dir_util.copy_tree(conf_path, test_dir) assert path.isdir(test_dir) @@ -79,8 +81,8 @@ def test_write_med_configs(fileutils): "3*12.0": "3*14.0", # MOM_input } - conf_path = fileutils.get_test_dir_path("med/marked/") - correct_path = fileutils.get_test_dir_path("med/correct/") + conf_path = get_gen_file(fileutils, "med/marked/") + correct_path = get_gen_file(fileutils, "med/correct/") # copy confs to gen directory dir_util.copy_tree(conf_path, test_dir) @@ -113,8 +115,8 @@ def test_write_new_tag_configs(fileutils): "3*12.0": "3*14.0", # MOM_input } - conf_path = fileutils.get_test_dir_path("new-tag/marked/") - correct_path = fileutils.get_test_dir_path("new-tag/correct/") + conf_path = get_gen_file(fileutils, "new-tag/marked/") + correct_path = get_gen_file(fileutils, "new-tag/correct/") # copy confs to gen directory dir_util.copy_tree(conf_path, test_dir) @@ -151,8 +153,8 @@ def test_write_mw_error_3(fileutils): "5": 10, # MOM_input } - conf_path = fileutils.get_test_dir_path("easy/marked/") - correct_path = fileutils.get_test_dir_path("easy/correct/") + conf_path = get_gen_file(fileutils, "easy/marked/") + # copy confs to gen directory dir_util.copy_tree(conf_path, test_dir) assert path.isdir(test_dir) From 887abebd97aa2e2b790fb265d3706060a2c321e4 Mon Sep 17 00:00:00 2001 From: Al Rigazzi Date: Fri, 8 Sep 2023 20:17:58 +0200 Subject: [PATCH 5/9] Set global log file open mode to w --- smartsim/_core/generation/generator.py | 11 ++++++- .../log_params/param_settings.txt | 2 +- .../generator_files/test_dir/test.py | 3 ++ tests/test_generator.py | 33 +++++++++++++------ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index a5b1d759e..675c1447e 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -28,6 +28,7 @@ import shutil import typing as t +from datetime import datetime from distutils import dir_util # pylint: disable=deprecated-module from logging import INFO, DEBUG from os import mkdir, path, symlink @@ -144,6 +145,14 @@ def _gen_exp_dir(self) -> None: level=self.log_level, msg="Working in previously created experiment" ) + # The log_file only keeps track of the last generation + # this is to avoid gigantic files in case the user repeats + # generation several times. The information is anyhow + # redundant, as it is also written in each entity's dir + with open(self.log_file, mode= 'w') as log_file: + dt_string = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + log_file.write("Generation start date and time: " + dt_string + "\n") + def _gen_orc_dir(self, orchestrator: t.Optional[Orchestrator]) -> None: """Create the directory that will hold the error, output and configuration files for the orchestrator. @@ -303,7 +312,7 @@ def _log_params( with open(self.log_file, mode="a", encoding="utf-8") as logfile: logfile.write(log_entry) with open(join(entity.path, "param_settings.txt"), - mode="a", + mode="w", encoding="utf-8") as local_logfile: local_logfile.write(log_entry) diff --git a/tests/test_configs/generator_files/log_params/param_settings.txt b/tests/test_configs/generator_files/log_params/param_settings.txt index 6866960a4..6ac92049f 100644 --- a/tests/test_configs/generator_files/log_params/param_settings.txt +++ b/tests/test_configs/generator_files/log_params/param_settings.txt @@ -1,3 +1,4 @@ +Generation start date and time: 08/09/2023 18:22:44 Model name: dir_test_0 File name Parameters -------------------------- --------------- @@ -29,4 +30,3 @@ dir_test/dir_test_3/in.atm Name Value ------ ------- THERMO 20 STEPS 20 - diff --git a/tests/test_configs/generator_files/test_dir/test.py b/tests/test_configs/generator_files/test_dir/test.py index bf6fd954c..8a0a76ee2 100644 --- a/tests/test_configs/generator_files/test_dir/test.py +++ b/tests/test_configs/generator_files/test_dir/test.py @@ -23,3 +23,6 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +thermo = @THERMO@ +steps = @STEPS@ \ No newline at end of file diff --git a/tests/test_generator.py b/tests/test_generator.py index 8d448689c..3b27866f0 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -48,6 +48,7 @@ """ + def get_gen_file(fileutils, filename): return fileutils.get_test_conf_path(osp.join("generator_files", filename)) @@ -56,7 +57,6 @@ def test_ensemble(fileutils): exp = Experiment("gen-test", launcher="local") test_dir = fileutils.get_test_dir() gen = Generator(test_dir) - params = {"THERMO": [10, 20, 30], "STEPS": [10, 20, 30]} ensemble = exp.create_ensemble("test", params=params, run_settings=rs) @@ -154,7 +154,7 @@ def test_dir_files(fileutils): conf_dir = get_gen_file(fileutils, "test_dir") ensemble.attach_generator_files(to_configure=conf_dir) - exp.generate(ensemble) + exp.generate(ensemble, tag="@") assert osp.isdir(osp.join(test_dir, "dir_test/")) for i in range(9): @@ -278,18 +278,31 @@ def test_generation_log(fileutils): conf_file = get_gen_file(fileutils, "in.atm") ensemble.attach_generator_files(to_configure=conf_file) + def not_header(line): + """you can add other general checks in here""" + if line.startswith("Generation start date and time:"): + return False # ignore it + return True + exp.generate(ensemble, verbose=True) - assert filecmp.cmp( - osp.join(test_dir, "param_settings.txt"), - get_gen_file(fileutils, osp.join("log_params", "param_settings.txt")), - ) + + log_file = osp.join(test_dir, "param_settings.txt") + ground_truth = get_gen_file(fileutils, osp.join("log_params", "param_settings.txt")) + + with open(log_file) as f1, open(ground_truth) as f2: + assert(not not_header(f1.readline())) + f1 = filter(not_header, f1) + f2 = filter(not_header, f2) + assert all(x == y for x, y in zip(f1, f2)) for entity in ensemble: assert filecmp.cmp( - osp.join(entity.path, "param_settings.txt"), - get_gen_file(fileutils, osp.join("log_params", "dir_test", entity.name, "param_settings.txt")), - ) - + osp.join(entity.path, "param_settings.txt"), + get_gen_file( + fileutils, + osp.join("log_params", "dir_test", entity.name, "param_settings.txt"), + ), + ) def test_config_dir(fileutils): """Test the generation and configuration of models with From 159dcf223d1b702059e95cf7175eafff6cd08e85 Mon Sep 17 00:00:00 2001 From: Al Rigazzi Date: Fri, 8 Sep 2023 20:56:21 +0200 Subject: [PATCH 6/9] Lint --- smartsim/_core/generation/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index 675c1447e..b02c687ab 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -149,7 +149,7 @@ def _gen_exp_dir(self) -> None: # this is to avoid gigantic files in case the user repeats # generation several times. The information is anyhow # redundant, as it is also written in each entity's dir - with open(self.log_file, mode= 'w') as log_file: + with open(self.log_file, mode= 'w', encoding='utf-8') as log_file: dt_string = datetime.now().strftime("%d/%m/%Y %H:%M:%S") log_file.write("Generation start date and time: " + dt_string + "\n") From 2e7b2dfb086b95224488abda93c7a0301be869ee Mon Sep 17 00:00:00 2001 From: Ale Rigazzi Date: Fri, 22 Sep 2023 17:39:03 -0500 Subject: [PATCH 7/9] Address reviewer's comments --- smartsim/_core/generation/generator.py | 22 ++++++--- smartsim/entity/model.py | 47 ++++++++++++------- ...param_settings.txt => smartsim_params.txt} | 0 ...param_settings.txt => smartsim_params.txt} | 0 ...param_settings.txt => smartsim_params.txt} | 0 ...param_settings.txt => smartsim_params.txt} | 0 ...param_settings.txt => smartsim_params.txt} | 0 tests/test_generator.py | 23 ++++++--- 8 files changed, 62 insertions(+), 30 deletions(-) rename tests/test_configs/generator_files/log_params/dir_test/dir_test_0/{param_settings.txt => smartsim_params.txt} (100%) rename tests/test_configs/generator_files/log_params/dir_test/dir_test_1/{param_settings.txt => smartsim_params.txt} (100%) rename tests/test_configs/generator_files/log_params/dir_test/dir_test_2/{param_settings.txt => smartsim_params.txt} (100%) rename tests/test_configs/generator_files/log_params/dir_test/dir_test_3/{param_settings.txt => smartsim_params.txt} (100%) rename tests/test_configs/generator_files/log_params/{param_settings.txt => smartsim_params.txt} (100%) diff --git a/smartsim/_core/generation/generator.py b/smartsim/_core/generation/generator.py index b02c687ab..b80e4b448 100644 --- a/smartsim/_core/generation/generator.py +++ b/smartsim/_core/generation/generator.py @@ -74,10 +74,20 @@ def __init__( """ self._writer = ModelWriter() self.gen_path = gen_path - self.log_file = join(gen_path, "param_settings.txt") self.overwrite = overwrite self.log_level = DEBUG if not verbose else INFO + @property + def log_file(self) -> str: + """Returns the location of the file + summarizing the parameters used for the last generation + of all generated entities. + + :returns: path to file with parameter settings + :rtype: str + """ + return join(self.gen_path, "smartsim_params.txt") + def generate_experiment(self, *args: t.Any) -> None: """Run ensemble and experiment file structure generation @@ -151,7 +161,7 @@ def _gen_exp_dir(self) -> None: # redundant, as it is also written in each entity's dir with open(self.log_file, mode= 'w', encoding='utf-8') as log_file: dt_string = datetime.now().strftime("%d/%m/%Y %H:%M:%S") - log_file.write("Generation start date and time: " + dt_string + "\n") + log_file.write(f"Generation start date and time: {dt_string}\n") def _gen_orc_dir(self, orchestrator: t.Optional[Orchestrator]) -> None: """Create the directory that will hold the error, output and @@ -292,7 +302,7 @@ def _log_params( file_to_tables: t.Dict[str, str] = {} for file, params in files_to_params.items(): used_params.update(params) - table = tabulate([[param, value] for param, value in params.items()], + table = tabulate(params.items(), headers=["Name", "Value"]) file_to_tables[relpath(file, self.gen_path)] = table @@ -305,13 +315,13 @@ def _log_params( msg=f"Configured model {entity.name} with params {used_params_str}", ) file_table = tabulate( - [[file, table] for file, table in file_to_tables.items()], + file_to_tables.items(), headers=["File name", "Parameters"], ) - log_entry = f"Model name: {entity.name}" + "\n" + file_table + "\n\n" + log_entry = f"Model name: {entity.name}\n{file_table}\n\n" with open(self.log_file, mode="a", encoding="utf-8") as logfile: logfile.write(log_entry) - with open(join(entity.path, "param_settings.txt"), + with open(join(entity.path, "smartsim_params.txt"), mode="w", encoding="utf-8") as local_logfile: local_logfile.write(log_entry) diff --git a/smartsim/entity/model.py b/smartsim/entity/model.py index a86be546b..56ab48d5e 100644 --- a/smartsim/entity/model.py +++ b/smartsim/entity/model.py @@ -27,21 +27,23 @@ from __future__ import annotations import collections.abc +import itertools import sys import typing as t import warnings +from os import path as osp from .._core.utils.helpers import cat_arg_and_value, init_default from ..error import EntityExistsError, SSUnsupportedError +from ..log import get_logger +from ..settings.base import BatchSettings, RunSettings from .dbobject import DBModel, DBScript from .entity import SmartSimEntity from .files import EntityFiles -from ..settings.base import BatchSettings, RunSettings -from ..log import get_logger - logger = get_logger(__name__) + class Model(SmartSimEntity): def __init__( self, @@ -163,6 +165,18 @@ def attach_generator_files( to_copy = init_default([], to_copy, (list, str)) to_symlink = init_default([], to_symlink, (list, str)) to_configure = init_default([], to_configure, (list, str)) + + # Check that no file collides with the parameter file written + # by Generator. We check the basename, even though it is more + # restrictive than what we need (but it avoids relative path issues) + if any( + osp.basename(filename) == "smartsim_params.txt" + for filename in list(itertools.chain(to_copy, to_symlink, to_configure)) + ): + raise ValueError( + "`smartsim_params.txt` is a file automatically " + + "generated by SmartSim and cannot be ovewritten." + ) self.files = EntityFiles(to_configure, to_copy, to_symlink) @property @@ -177,8 +191,7 @@ def attached_files_table(self) -> str: return str(self.files) def print_attached_files(self) -> None: - """Print a table of the attached files on std out - """ + """Print a table of the attached files on std out""" print(self.attached_files_table) def colocate_db(self, *args: t.Any, **kwargs: t.Any) -> None: @@ -187,7 +200,8 @@ def colocate_db(self, *args: t.Any, **kwargs: t.Any) -> None: ( "`colocate_db` has been deprecated and will be removed in a \n" "future release. Please use `colocate_db_tcp` or `colocate_db_uds`." - ), FutureWarning + ), + FutureWarning, ) self.colocate_db_tcp(*args, **kwargs) @@ -333,8 +347,7 @@ def _set_colocated_db_settings( # TODO list which db settings can be extras common_options["custom_pinning"] = self._create_pinning_string( - common_options["custom_pinning"], - common_options["cpus"] + common_options["custom_pinning"], common_options["cpus"] ) colo_db_config = {} @@ -358,13 +371,13 @@ def _set_colocated_db_settings( @staticmethod def _create_pinning_string( - pin_ids: t.Optional[t.Iterable[t.Union[int, t.Iterable[int]]]], - cpus: int - ) -> t.Optional[str]: + pin_ids: t.Optional[t.Iterable[t.Union[int, t.Iterable[int]]]], cpus: int + ) -> t.Optional[str]: """Create a comma-separated string CPU ids. By default, None returns 0,1,...,cpus-1; an empty iterable will disable pinning altogether, and an iterable constructs a comma separate string (e.g. 0,2,5) """ + def _stringify_id(_id: int) -> str: """Return the cPU id as a string if an int, otherwise raise a ValueError""" if isinstance(_id, int): @@ -389,14 +402,14 @@ def _stringify_id(_id: int) -> str: warnings.warn( "CPU pinning is not supported on MacOSX. Ignoring pinning " "specification.", - RuntimeWarning + RuntimeWarning, ) return None raise TypeError(_invalid_input_message) # Flatten the iterable into a list and check to make sure that the resulting # elements are all ints if pin_ids is None: - return ','.join(_stringify_id(i) for i in range(cpus)) + return ",".join(_stringify_id(i) for i in range(cpus)) if not pin_ids: return None if isinstance(pin_ids, collections.abc.Iterable): @@ -406,7 +419,7 @@ def _stringify_id(_id: int) -> str: pin_list.extend([_stringify_id(j) for j in pin_id]) else: pin_list.append(_stringify_id(pin_id)) - return ','.join(sorted(set(pin_list))) + return ",".join(sorted(set(pin_list))) raise TypeError(_invalid_input_message) def params_to_args(self) -> None: @@ -433,7 +446,7 @@ def add_ml_model( backend: str, model: t.Optional[str] = None, model_path: t.Optional[str] = None, - device: t.Literal["CPU","GPU"] = "CPU", + device: t.Literal["CPU", "GPU"] = "CPU", devices_per_node: int = 1, batch_size: int = 0, min_batch_size: int = 0, @@ -495,7 +508,7 @@ def add_script( name: str, script: t.Optional[str] = None, script_path: t.Optional[str] = None, - device: t.Literal["CPU","GPU"] = "CPU", + device: t.Literal["CPU", "GPU"] = "CPU", devices_per_node: int = 1, ) -> None: """TorchScript to launch with this Model instance @@ -539,7 +552,7 @@ def add_function( self, name: str, function: t.Optional[str] = None, - device: t.Literal["CPU","GPU"] = "CPU", + device: t.Literal["CPU", "GPU"] = "CPU", devices_per_node: int = 1, ) -> None: """TorchScript function to launch with this Model instance diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_0/smartsim_params.txt similarity index 100% rename from tests/test_configs/generator_files/log_params/dir_test/dir_test_0/param_settings.txt rename to tests/test_configs/generator_files/log_params/dir_test/dir_test_0/smartsim_params.txt diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_1/smartsim_params.txt similarity index 100% rename from tests/test_configs/generator_files/log_params/dir_test/dir_test_1/param_settings.txt rename to tests/test_configs/generator_files/log_params/dir_test/dir_test_1/smartsim_params.txt diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_2/smartsim_params.txt similarity index 100% rename from tests/test_configs/generator_files/log_params/dir_test/dir_test_2/param_settings.txt rename to tests/test_configs/generator_files/log_params/dir_test/dir_test_2/smartsim_params.txt diff --git a/tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt b/tests/test_configs/generator_files/log_params/dir_test/dir_test_3/smartsim_params.txt similarity index 100% rename from tests/test_configs/generator_files/log_params/dir_test/dir_test_3/param_settings.txt rename to tests/test_configs/generator_files/log_params/dir_test/dir_test_3/smartsim_params.txt diff --git a/tests/test_configs/generator_files/log_params/param_settings.txt b/tests/test_configs/generator_files/log_params/smartsim_params.txt similarity index 100% rename from tests/test_configs/generator_files/log_params/param_settings.txt rename to tests/test_configs/generator_files/log_params/smartsim_params.txt diff --git a/tests/test_generator.py b/tests/test_generator.py index 3b27866f0..938d15599 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -280,14 +280,12 @@ def test_generation_log(fileutils): def not_header(line): """you can add other general checks in here""" - if line.startswith("Generation start date and time:"): - return False # ignore it - return True + return not line.startswith("Generation start date and time:") exp.generate(ensemble, verbose=True) - log_file = osp.join(test_dir, "param_settings.txt") - ground_truth = get_gen_file(fileutils, osp.join("log_params", "param_settings.txt")) + log_file = osp.join(test_dir, "smartsim_params.txt") + ground_truth = get_gen_file(fileutils, osp.join("log_params", "smartsim_params.txt")) with open(log_file) as f1, open(ground_truth) as f2: assert(not not_header(f1.readline())) @@ -297,10 +295,10 @@ def not_header(line): for entity in ensemble: assert filecmp.cmp( - osp.join(entity.path, "param_settings.txt"), + osp.join(entity.path, "smartsim_params.txt"), get_gen_file( fileutils, - osp.join("log_params", "dir_test", entity.name, "param_settings.txt"), + osp.join("log_params", "dir_test", entity.name, "smartsim_params.txt"), ), ) @@ -362,3 +360,14 @@ def test_no_gen_if_symlink_to_dir(fileutils): config = get_gen_file(fileutils, "circular_config") with pytest.raises(ValueError): ensemble.attach_generator_files(to_configure=config) + + +def test_no_file_overwrite(): + exp = Experiment("test_no_file_overwrite", launcher="local") + ensemble = exp.create_ensemble("test", params={"P": [0, 1]}, run_settings=rs) + with pytest.raises(ValueError): + ensemble.attach_generator_files(to_configure=["/normal/file.txt", "/path/to/smartsim_params.txt"]) + with pytest.raises(ValueError): + ensemble.attach_generator_files(to_symlink=["/normal/file.txt", "/path/to/smartsim_params.txt"]) + with pytest.raises(ValueError): + ensemble.attach_generator_files(to_copy=["/normal/file.txt", "/path/to/smartsim_params.txt"]) \ No newline at end of file From b3c78dabe0f9751840fb3791cb8c6bf636c31b82 Mon Sep 17 00:00:00 2001 From: Ale Rigazzi Date: Fri, 22 Sep 2023 17:46:08 -0500 Subject: [PATCH 8/9] Circumvent type issue --- smartsim/entity/model.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/smartsim/entity/model.py b/smartsim/entity/model.py index 56ab48d5e..056e3056f 100644 --- a/smartsim/entity/model.py +++ b/smartsim/entity/model.py @@ -169,14 +169,16 @@ def attach_generator_files( # Check that no file collides with the parameter file written # by Generator. We check the basename, even though it is more # restrictive than what we need (but it avoids relative path issues) - if any( - osp.basename(filename) == "smartsim_params.txt" - for filename in list(itertools.chain(to_copy, to_symlink, to_configure)) - ): - raise ValueError( - "`smartsim_params.txt` is a file automatically " - + "generated by SmartSim and cannot be ovewritten." - ) + for strategy in [to_copy, to_symlink, to_configure]: + if strategy is not None and any( + osp.basename(filename) == "smartsim_params.txt" + for filename in strategy + ): + raise ValueError( + "`smartsim_params.txt` is a file automatically " + + "generated by SmartSim and cannot be ovewritten." + ) + self.files = EntityFiles(to_configure, to_copy, to_symlink) @property From dc937f2790e68d1bb76c33045fb255affda4e42d Mon Sep 17 00:00:00 2001 From: Ale Rigazzi Date: Fri, 22 Sep 2023 17:54:21 -0500 Subject: [PATCH 9/9] Remove unused import --- smartsim/entity/model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/smartsim/entity/model.py b/smartsim/entity/model.py index 056e3056f..35690c526 100644 --- a/smartsim/entity/model.py +++ b/smartsim/entity/model.py @@ -27,7 +27,6 @@ from __future__ import annotations import collections.abc -import itertools import sys import typing as t import warnings