From c0290274ff34655c8467afa62a7cf04bfc3c8364 Mon Sep 17 00:00:00 2001 From: jlnav Date: Mon, 14 Aug 2023 10:28:57 -0500 Subject: [PATCH 1/4] enable test_ensemble test as standard, pin numpy, cleanup ci.yml --- .github/workflows/ci.yml | 12 -- .../unit_tests/mpich-only_test_ensemble.py | 110 ------------------ setup.py | 2 +- 3 files changed, 1 insertion(+), 123 deletions(-) delete mode 100644 libensemble/tests/unit_tests/mpich-only_test_ensemble.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f1ac1306..b96ea3ce4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,18 +30,6 @@ jobs: python-version: "3.10" mpi-version: "mpich" comms-type: t - # - os: ubuntu-latest - # mpi-version: "openmpi" - # python-version: "3.10" - # comms-type: l - # - os: windows-latest - # python-version: "3.10" - # comms-type: l - # mpi-version: "msmpi" - # - os: windows-latest - # python-version: "3.10" - # comms-type: m - # mpi-version: "msmpi" env: HYDRA_LAUNCHER: "fork" diff --git a/libensemble/tests/unit_tests/mpich-only_test_ensemble.py b/libensemble/tests/unit_tests/mpich-only_test_ensemble.py deleted file mode 100644 index 6c4c34656..000000000 --- a/libensemble/tests/unit_tests/mpich-only_test_ensemble.py +++ /dev/null @@ -1,110 +0,0 @@ -import numpy as np -import pytest - -import libensemble.tests.unit_tests.setup as setup - - -@pytest.mark.extra -def test_ensemble_init(): - """testing init attrs""" - from libensemble.ensemble import Ensemble - - e = Ensemble( - libE_specs={"comms": "local", "nworkers": 4} - ) # without specifying, class assumes MPI since pytest runs without --comms local - assert "comms" in e.libE_specs, "internal parse_args() didn't populate defaults for class's libE_specs" - assert e.is_manager, "parse_args() didn't populate defaults for class's libE_specs" - - assert e.logger.get_level() == 20, "Default log level should be 20." - - -@pytest.mark.extra -def test_from_files(): - """Test that Ensemble() specs dicts resemble setup dicts""" - from libensemble.ensemble import Ensemble - - for ft in ["yaml", "json", "toml"]: - e = Ensemble(libE_specs={"comms": "local", "nworkers": 4}) - file_path = f"./simdir/test_example.{ft}" - if ft == "yaml": - e.from_yaml(file_path) - elif ft == "json": - e.from_json(file_path) - else: - e.from_toml(file_path) - - sim_specs, gen_specs, exit_criteria = setup.make_criteria_and_specs_0() - - e.gen_specs.user["ub"] = np.ones(1) - e.gen_specs.user["lb"] = np.zeros(1) - - sim_specs["inputs"] = sim_specs["in"] - sim_specs.pop("in") - assert all([i in e.sim_specs.__dict__.items() for i in sim_specs.items()]) - assert all([i in e.gen_specs.__dict__.items() for i in gen_specs.items()]) - assert all([i in e.exit_criteria.__dict__.items() for i in exit_criteria.items()]) - - -@pytest.mark.extra -def test_bad_func_loads(): - """Test that Ensemble() raises expected errors (with warnings) on incorrect imports""" - from libensemble.ensemble import Ensemble - - yaml_errors = { - "./simdir/test_example_badfuncs_attribute.yaml": AttributeError, - "./simdir/test_example_badfuncs_notfound.yaml": ModuleNotFoundError, - } - - for f in yaml_errors: - e = Ensemble(libE_specs={"comms": "local", "nworkers": 4}) - flag = 1 - try: - e.from_yaml(f) - except yaml_errors[f]: - flag = 0 - assert flag == 0 - - -@pytest.mark.extra -def test_full_workflow(): - """Test initializing a workflow via Specs and Ensemble.run()""" - from libensemble.ensemble import Ensemble - from libensemble.specs import ExitCriteria, GenSpecs, LibeSpecs, SimSpecs - - LS = LibeSpecs(comms="local", nworkers=4) - - # parameterizes and validates everything! - ens = Ensemble( - libE_specs=LS, - sim_specs=SimSpecs(inputs=["x"], out=[("f", float)]), - gen_specs=GenSpecs( - out=[("x", float, (1,))], - user={ - "gen_batch_size": 100, - "lb": np.array([-3]), - "ub": np.array([3]), - }, - ), - exit_criteria=ExitCriteria(gen_max=101), - ) - ens.add_random_streams() - ens.run() - if ens.is_manager: - assert len(ens.H) >= 101 - - # test a dry run - LS = LibeSpecs(comms="local", nworkers=4, dry_run=True) - ens.libE_specs = LS - flag = 1 - try: - ens.run() - except SystemExit: - flag = 0 - assert not flag, "Ensemble didn't exit after specifying dry_run" - - -if __name__ == "__main__": - test_ensemble_init() - test_from_files() - test_bad_func_loads() - test_full_workflow() diff --git a/setup.py b/setup.py index 711713bfb..fcd20ce1c 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ def run_tests(self): "libensemble.tests.unit_tests", "libensemble.tests.regression_tests", ], - install_requires=["numpy", "psutil", "pydantic<2", "tomli", "pyyaml"], + install_requires=["numpy>=1.21", "psutil", "pydantic<2", "tomli", "pyyaml"], # If run tests through setup.py - downloads these but does not install tests_require=[ "pytest>=3.1", From 21e86eb2d3f853ade453207bd1c2929b99008356 Mon Sep 17 00:00:00 2001 From: jlnav Date: Mon, 14 Aug 2023 11:02:19 -0500 Subject: [PATCH 2/4] forgot the rename --- libensemble/tests/unit_tests/test_ensemble.py | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 libensemble/tests/unit_tests/test_ensemble.py diff --git a/libensemble/tests/unit_tests/test_ensemble.py b/libensemble/tests/unit_tests/test_ensemble.py new file mode 100644 index 000000000..6c4c34656 --- /dev/null +++ b/libensemble/tests/unit_tests/test_ensemble.py @@ -0,0 +1,110 @@ +import numpy as np +import pytest + +import libensemble.tests.unit_tests.setup as setup + + +@pytest.mark.extra +def test_ensemble_init(): + """testing init attrs""" + from libensemble.ensemble import Ensemble + + e = Ensemble( + libE_specs={"comms": "local", "nworkers": 4} + ) # without specifying, class assumes MPI since pytest runs without --comms local + assert "comms" in e.libE_specs, "internal parse_args() didn't populate defaults for class's libE_specs" + assert e.is_manager, "parse_args() didn't populate defaults for class's libE_specs" + + assert e.logger.get_level() == 20, "Default log level should be 20." + + +@pytest.mark.extra +def test_from_files(): + """Test that Ensemble() specs dicts resemble setup dicts""" + from libensemble.ensemble import Ensemble + + for ft in ["yaml", "json", "toml"]: + e = Ensemble(libE_specs={"comms": "local", "nworkers": 4}) + file_path = f"./simdir/test_example.{ft}" + if ft == "yaml": + e.from_yaml(file_path) + elif ft == "json": + e.from_json(file_path) + else: + e.from_toml(file_path) + + sim_specs, gen_specs, exit_criteria = setup.make_criteria_and_specs_0() + + e.gen_specs.user["ub"] = np.ones(1) + e.gen_specs.user["lb"] = np.zeros(1) + + sim_specs["inputs"] = sim_specs["in"] + sim_specs.pop("in") + assert all([i in e.sim_specs.__dict__.items() for i in sim_specs.items()]) + assert all([i in e.gen_specs.__dict__.items() for i in gen_specs.items()]) + assert all([i in e.exit_criteria.__dict__.items() for i in exit_criteria.items()]) + + +@pytest.mark.extra +def test_bad_func_loads(): + """Test that Ensemble() raises expected errors (with warnings) on incorrect imports""" + from libensemble.ensemble import Ensemble + + yaml_errors = { + "./simdir/test_example_badfuncs_attribute.yaml": AttributeError, + "./simdir/test_example_badfuncs_notfound.yaml": ModuleNotFoundError, + } + + for f in yaml_errors: + e = Ensemble(libE_specs={"comms": "local", "nworkers": 4}) + flag = 1 + try: + e.from_yaml(f) + except yaml_errors[f]: + flag = 0 + assert flag == 0 + + +@pytest.mark.extra +def test_full_workflow(): + """Test initializing a workflow via Specs and Ensemble.run()""" + from libensemble.ensemble import Ensemble + from libensemble.specs import ExitCriteria, GenSpecs, LibeSpecs, SimSpecs + + LS = LibeSpecs(comms="local", nworkers=4) + + # parameterizes and validates everything! + ens = Ensemble( + libE_specs=LS, + sim_specs=SimSpecs(inputs=["x"], out=[("f", float)]), + gen_specs=GenSpecs( + out=[("x", float, (1,))], + user={ + "gen_batch_size": 100, + "lb": np.array([-3]), + "ub": np.array([3]), + }, + ), + exit_criteria=ExitCriteria(gen_max=101), + ) + ens.add_random_streams() + ens.run() + if ens.is_manager: + assert len(ens.H) >= 101 + + # test a dry run + LS = LibeSpecs(comms="local", nworkers=4, dry_run=True) + ens.libE_specs = LS + flag = 1 + try: + ens.run() + except SystemExit: + flag = 0 + assert not flag, "Ensemble didn't exit after specifying dry_run" + + +if __name__ == "__main__": + test_ensemble_init() + test_from_files() + test_bad_func_loads() + test_full_workflow() From 2e1011b846e068a6683e839fa6fb4905b1eec666 Mon Sep 17 00:00:00 2001 From: jlnav Date: Mon, 14 Aug 2023 11:45:00 -0500 Subject: [PATCH 3/4] pin psutil, tomli, pyyaml --- setup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fcd20ce1c..45651bb9f 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,10 @@ def run_tests(self): "libensemble.tests.unit_tests", "libensemble.tests.regression_tests", ], - install_requires=["numpy>=1.21", "psutil", "pydantic<2", "tomli", "pyyaml"], + install_requires=["numpy>=1.21", "psutil>=5.9.4", "pydantic<2", "tomli>=1.2.1", "pyyaml>=6.0"], + # numpy - oldest working version. psutil - oldest working version. + # pydantic - avoid major release/rework for now. tomli - max 2-years old version. + # pyyaml - oldest working version. # If run tests through setup.py - downloads these but does not install tests_require=[ "pytest>=3.1", From 0e36ff204e456f29265a028c3d0013a621d63a0e Mon Sep 17 00:00:00 2001 From: jlnav Date: Mon, 14 Aug 2023 13:30:40 -0500 Subject: [PATCH 4/4] remove rename --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b96ea3ce4..775e75133 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -210,11 +210,6 @@ jobs: pip install -e . flake8 libensemble - - name: Activate API unit test if using mpich - if: matrix.mpi-version == 'mpich' - run: | - mv libensemble/tests/unit_tests/mpich-only_test_ensemble.py libensemble/tests/unit_tests/test_ensemble.py - - name: Remove ytopt-heffte test on Python 3.11 (easy way) if: matrix.python-version == '3.11' run: |