diff --git a/docs/examples/calling_scripts.rst b/docs/examples/calling_scripts.rst index 183128b6e..708a9d128 100644 --- a/docs/examples/calling_scripts.rst +++ b/docs/examples/calling_scripts.rst @@ -45,19 +45,6 @@ One worker runs a persistent generator and the other four run the forces simulat :caption: tests/scaling_tests/forces/forces_simple/run_libe_forces.py :linenos: -Object + yaml Version -~~~~~~~~~~~~~~~~~~~~~ - -.. literalinclude:: ../../libensemble/tests/scaling_tests/forces/forces_adv/run_libe_forces_from_yaml.py - :language: python - :caption: tests/scaling_tests/forces/forces_adv/run_libe_forces_from_yaml.py - :linenos: - -.. literalinclude:: ../../libensemble/tests/scaling_tests/forces/forces_adv/forces.yaml - :language: yaml - :caption: tests/scaling_tests/forces/forces_adv/forces.yaml - :linenos: - Persistent APOSMM with Gradients -------------------------------- diff --git a/libensemble/ensemble.py b/libensemble/ensemble.py index 0ceba2ab3..b6a220818 100644 --- a/libensemble/ensemble.py +++ b/libensemble/ensemble.py @@ -1,10 +1,6 @@ -import importlib -import json import logging import numpy.typing as npt -import tomli -import yaml from libensemble.executors import Executor from libensemble.libE import libE @@ -117,110 +113,6 @@ class Ensemble: experiment = Ensemble() experiment.sim_specs = sim_specs - .. dropdown:: Option 3: Loading parameters from files - - .. code-block:: python - :linenos: - - from libensemble import Ensemble - - experiment = Ensemble() - - my_experiment.from_yaml("my_parameters.yaml") - # or... - my_experiment.from_toml("my_parameters.toml") - # or... - my_experiment.from_json("my_parameters.json") - - .. tab-set:: - - .. tab-item:: my_parameters.yaml - - .. code-block:: yaml - :linenos: - - libE_specs: - save_every_k_gens: 20 - - exit_criteria: - sim_max: 80 - - gen_specs: - gen_f: generator.gen_random_sample - outputs: - x: - type: float - size: 1 - user: - gen_batch_size: 5 - - sim_specs: - sim_f: simulator.sim_find_sine - inputs: - - x - outputs: - y: - type: float - - .. tab-item:: my_parameters.toml - - .. code-block:: toml - :linenos: - - [libE_specs] - save_every_k_gens = 300 - - [exit_criteria] - sim_max = 80 - - [gen_specs] - gen_f = "generator.gen_random_sample" - [gen_specs.outputs] - [gen_specs.outputs.x] - type = "float" - size = 1 - [gen_specs.user] - gen_batch_size = 5 - - [sim_specs] - sim_f = "simulator.sim_find_sine" - inputs = ["x"] - [sim_specs.outputs] - [sim_specs.outputs.y] - type = "float" - - .. tab-item:: my_parameters.json - - .. code-block:: json - :linenos: - - { - "libE_specs": { - "save_every_k_gens": 300, - }, - "exit_criteria": { - "sim_max": 80 - }, - "gen_specs": { - "gen_f": "generator.gen_random_sample", - "outputs": { - "x": { - "type": "float", - "size": 1 - } - }, - "user": { - "gen_batch_size": 5 - } - }, - "sim_specs": { - "sim_f": "simulator.sim_find_sine", - "inputs": ["x"], - "outputs": { - "f": {"type": "float"} - } - } - } Parameters ---------- @@ -431,111 +323,6 @@ def nworkers(self, value): if self._libE_specs: self._libE_specs.nworkers = value - def _get_func(self, loaded): - """Extracts user function specified in loaded dict""" - func_path_split = loaded.rsplit(".", 1) - func_name = func_path_split[-1] - try: - return getattr(importlib.import_module(func_path_split[0]), func_name) - except AttributeError: - self._util_logger.manager_warning(ATTR_ERR_MSG.format(func_name)) - raise - except ModuleNotFoundError: - self._util_logger.manager_warning(NOTFOUND_ERR_MSG.format(func_name)) - raise - - @staticmethod - def _get_outputs(loaded): - """Extracts output parameters from loaded dict""" - if not loaded: - return [] - fields = [i for i in loaded] - field_params = [i for i in loaded.values()] - results = [] - for i in range(len(fields)): - field_type = field_params[i]["type"] - built_in_type = __builtins__.get(field_type, field_type) - try: - if field_params[i]["size"] == 1: - size = (1,) # formatting how size=1 is typically preferred - else: - size = field_params[i]["size"] - results.append((fields[i], built_in_type, size)) - except KeyError: - results.append((fields[i], built_in_type)) - return results - - @staticmethod - def _get_normal(loaded): - return loaded - - def _get_option(self, specs, name): - """Gets a specs value, underlying spec is either a dict or a class""" - attr = getattr(self, specs) - if isinstance(attr, dict): - return attr.get(name) - else: - return getattr(attr, name) - - def _parse_spec(self, loaded_spec): - """Parses and creates traditional libEnsemble dictionary from loaded dict info""" - - field_f = { - "sim_f": self._get_func, - "gen_f": self._get_func, - "alloc_f": self._get_func, - "inputs": self._get_normal, - "persis_in": self._get_normal, - "outputs": self._get_outputs, - "globus_compute_endpoint": self._get_normal, - "user": self._get_normal, - } - - userf_fields = [f for f in loaded_spec if f in field_f.keys()] - - if len(userf_fields): - for f in userf_fields: - loaded_spec[f] = field_f[f](loaded_spec[f]) - - return loaded_spec - - def _parameterize(self, loaded): - """Updates and sets attributes from specs loaded from file""" - for f in loaded: - loaded_spec = self._parse_spec(loaded[f]) - old_spec = getattr(self, f) - ClassType = CORRESPONDING_CLASSES[f] - if isinstance(old_spec, dict): - old_spec.update(loaded_spec) - if old_spec.get("in") and old_spec.get("inputs"): - old_spec.pop("inputs") # avoid clashes - elif old_spec.get("out") and old_spec.get("outputs"): - old_spec.pop("outputs") # avoid clashes - setattr(self, f, ClassType(**old_spec)) - else: # None. attribute not set yet - setattr(self, f, ClassType(**loaded_spec)) - - def from_yaml(self, file_path: str): - """Parameterizes libEnsemble from ``yaml`` file""" - with open(file_path, "r") as f: - loaded = yaml.full_load(f) - - self._parameterize(loaded) - - def from_toml(self, file_path: str): - """Parameterizes libEnsemble from ``toml`` file""" - with open(file_path, "rb") as f: - loaded = tomli.load(f) - - self._parameterize(loaded) - - def from_json(self, file_path: str): - """Parameterizes libEnsemble from ``json`` file""" - with open(file_path, "rb") as f: - loaded = json.load(f) - - self._parameterize(loaded) - def add_random_streams(self, num_streams: int = 0, seed: str = ""): """ diff --git a/libensemble/tests/functionality_tests/1d_sampling.json b/libensemble/tests/functionality_tests/1d_sampling.json deleted file mode 100644 index 6066cdd69..000000000 --- a/libensemble/tests/functionality_tests/1d_sampling.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "libE_specs": { - "save_every_k_gens": 300, - "safe_mode": false - }, - "exit_criteria": { - "gen_max": 501 - }, - "sim_specs": { - "sim_f": "libensemble.sim_funcs.simple_sim.norm_eval", - "inputs": [ - "x" - ], - "outputs": { - "f": { - "type": "float" - } - } - }, - "gen_specs": { - "gen_f": "libensemble.gen_funcs.sampling.latin_hypercube_sample", - "outputs": { - "x": { - "type": "float", - "size": 1 - } - }, - "user": { - "gen_batch_size": 500 - } - } -} diff --git a/libensemble/tests/functionality_tests/1d_sampling.toml b/libensemble/tests/functionality_tests/1d_sampling.toml deleted file mode 100644 index 6618019a6..000000000 --- a/libensemble/tests/functionality_tests/1d_sampling.toml +++ /dev/null @@ -1,22 +0,0 @@ -[libE_specs] - save_every_k_gens = 300 - safe_mode = false - -[exit_criteria] - gen_max = 501 - -[sim_specs] - sim_f = "libensemble.sim_funcs.simple_sim.norm_eval" - inputs = ["x"] - [sim_specs.outputs] - [sim_specs.outputs.f] - type = "float" - -[gen_specs] - gen_f = "libensemble.gen_funcs.sampling.latin_hypercube_sample" - [gen_specs.outputs] - [gen_specs.outputs.x] - type = "float" - size = 1 - [gen_specs.user] - gen_batch_size = 500 diff --git a/libensemble/tests/functionality_tests/1d_sampling.yaml b/libensemble/tests/functionality_tests/1d_sampling.yaml deleted file mode 100644 index 3e82548ae..000000000 --- a/libensemble/tests/functionality_tests/1d_sampling.yaml +++ /dev/null @@ -1,24 +0,0 @@ -libE_specs: - save_every_k_gens: 300 - safe_mode: False - use_workflow_dir: True - -exit_criteria: - gen_max: 501 - -sim_specs: - sim_f: libensemble.sim_funcs.simple_sim.norm_eval - inputs: - - x - outputs: - f: - type: float - -gen_specs: - gen_f: libensemble.gen_funcs.sampling.latin_hypercube_sample - outputs: - x: - type: float - size: 1 - user: - gen_batch_size: 500 diff --git a/libensemble/tests/functionality_tests/test_1d_sampling_from_files.py b/libensemble/tests/functionality_tests/test_1d_sampling_from_files.py deleted file mode 100644 index d80025d23..000000000 --- a/libensemble/tests/functionality_tests/test_1d_sampling_from_files.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Runs libEnsemble with Latin hypercube sampling on a simple 1D problem using -the libEnsemble yaml interface - -Execute via one of the following commands (e.g. 3 workers): - mpiexec -np 4 python test_1d_sampling_from_yaml.py - python test_1d_sampling_from_yaml.py --nworkers 3 - python test_1d_sampling_from_yaml.py --nworkers 3 --comms tcp - -The number of concurrent evaluations of the objective function will be 4-1=3. -""" - -# Do not change these lines - they are parsed by run-tests.sh -# TESTSUITE_COMMS: mpi local tcp -# TESTSUITE_NPROCS: 2 4 -# TESTSUITE_EXTRA: true - -import numpy as np - -from libensemble import Ensemble - -# Main block is necessary only when using local comms with spawn start method (default on macOS and Windows). -if __name__ == "__main__": - sampling = Ensemble(parse_args=True) - sampling.from_json("1d_sampling.json") - sampling.from_toml("1d_sampling.toml") - sampling.from_yaml("1d_sampling.yaml") - - sampling.gen_specs.user.update( - { - "lb": np.array([-3]), - "ub": np.array([3]), - } - ) - - sampling.add_random_streams() - - # Perform the run - sampling.run() - - if sampling.is_manager: - assert len(sampling.H) >= 501 - print("\nlibEnsemble with random sampling has generated enough points") - sampling.save_output(__file__) diff --git a/libensemble/tests/scaling_tests/forces/forces_adv/forces.yaml b/libensemble/tests/scaling_tests/forces/forces_adv/forces.yaml deleted file mode 100644 index e3f38da8a..000000000 --- a/libensemble/tests/scaling_tests/forces/forces_adv/forces.yaml +++ /dev/null @@ -1,45 +0,0 @@ -libE_specs: - save_every_k_gens: 1000 - sim_dirs_make: True - profile: False - -exit_criteria: - sim_max: 8 - -sim_specs: - sim_f: forces_simf.run_forces - inputs: - - x - outputs: - energy: - type: float - - user: - keys: - - seed - cores: 1 - sim_particles: 1.e+3 - sim_timesteps: 5 - sim_kill_minutes: 10.0 - particle_variance: 0.2 - kill_rate: 0.5 - fail_on_sim: False - fail_on_submit: False - -gen_specs: - gen_f: libensemble.gen_funcs.sampling.uniform_random_sample - outputs: - x: - type: float - size: 1 - user: - gen_batch_size: 1000 - -alloc_specs: - alloc_f: libensemble.alloc_funcs.give_sim_work_first.give_sim_work_first - outputs: - allocated: - type: bool - user: - batch_mode: True - num_active_gens: 1 diff --git a/libensemble/tests/scaling_tests/forces/forces_adv/readme.md b/libensemble/tests/scaling_tests/forces/forces_adv/readme.md index 2d0daf9f7..e34cdfe8c 100644 --- a/libensemble/tests/scaling_tests/forces/forces_adv/readme.md +++ b/libensemble/tests/scaling_tests/forces/forces_adv/readme.md @@ -45,12 +45,6 @@ To remove output before the next run: ./cleanup.sh -### Using YAML in calling script (optional) - -An alternative calling script `run_libe_forces_from_yaml.py` can be run in the same -way as `run_libe_forces.py` above. This uses an alternative libEnsemble interface, where -an ensemble object is created and parameters can be read from the `forces.yaml` file. - ### Using batch scripts See `examples/libE_submission_scripts` diff --git a/libensemble/tests/scaling_tests/forces/forces_adv/run_libe_forces_from_yaml.py b/libensemble/tests/scaling_tests/forces/forces_adv/run_libe_forces_from_yaml.py deleted file mode 100644 index 0bca5e93d..000000000 --- a/libensemble/tests/scaling_tests/forces/forces_adv/run_libe_forces_from_yaml.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -import numpy as np - -from libensemble.ensemble import Ensemble -from libensemble.executors.mpi_executor import MPIExecutor -from libensemble.tools import add_unique_random_streams - -#################### - -sim_app = os.path.join(os.getcwd(), "../forces_app/forces.x") - -if not os.path.isfile(sim_app): - sys.exit("forces.x not found - please build first in ../forces_app dir") - - -#################### - -forces = Ensemble(parse_args=True) -forces.from_yaml("forces.yaml") - -forces.logger.set_level("INFO") - -if forces.is_manager: - print(f"\nRunning with {forces.nworkers} workers\n") - -exctr = MPIExecutor() -exctr.register_app(full_path=sim_app, app_name="forces") - -forces.libE_specs["ensemble_dir_path"] = "./ensemble" -forces.gen_specs.user.update( - { - "lb": np.array([0]), - "ub": np.array([32767]), - } -) - -forces.persis_info = add_unique_random_streams({}, forces.nworkers + 1) - -forces.run() -forces.save_output(__file__) diff --git a/libensemble/tests/scaling_tests/forces/globus_compute_forces/cleanup.sh b/libensemble/tests/scaling_tests/forces/globus_compute_forces/cleanup.sh deleted file mode 100755 index 54c41aa6e..000000000 --- a/libensemble/tests/scaling_tests/forces/globus_compute_forces/cleanup.sh +++ /dev/null @@ -1 +0,0 @@ -rm -r ensemble_* *.npy *.pickle ensemble.log lib*.txt diff --git a/libensemble/tests/scaling_tests/forces/globus_compute_forces/forces_simf.py b/libensemble/tests/scaling_tests/forces/globus_compute_forces/forces_simf.py deleted file mode 100644 index c3a31ff5d..000000000 --- a/libensemble/tests/scaling_tests/forces/globus_compute_forces/forces_simf.py +++ /dev/null @@ -1,137 +0,0 @@ -def run_forces_globus_compute(H, persis_info, sim_specs, libE_info): - import os - import secrets - import time - - import numpy as np - - from libensemble.executors.mpi_executor import MPIExecutor - from libensemble.message_numbers import TASK_FAILED, WORKER_DONE, WORKER_KILL - - class ForcesException(Exception): - """Raised on some issue with Forces""" - - def perturb(particles, seed, max_fraction): - MAX_SEED = 32767 - """Modify particle count""" - seed_fraction = seed / MAX_SEED - max_delta = particles * max_fraction - delta = seed_fraction * max_delta - delta = delta - max_delta / 2 # translate so -/+ - new_particles = particles + delta - return int(new_particles) - - def read_last_line(filepath): - """Read last line of statfile""" - try: - with open(filepath, "rb") as fh: - line = fh.readlines()[-1].decode().rstrip() - except Exception: - line = "" # In case file is empty or not yet created - return line - - if sim_specs["user"]["fail_on_sim"]: - raise ForcesException(Exception) - - calc_status = 0 # Returns to worker - - x = H["x"] - sim_particles = sim_specs["user"]["sim_particles"] - sim_timesteps = sim_specs["user"]["sim_timesteps"] - time_limit = sim_specs["user"]["sim_kill_minutes"] * 60.0 - sim_app = sim_specs["user"]["sim_app"] - - exctr = MPIExecutor() - exctr.register_app(full_path=sim_app, app_name="forces") - - calc_dir = os.path.join(sim_specs["user"]["remote_ensemble_dir"], secrets.token_hex(nbytes=4)) - os.makedirs(calc_dir, exist_ok=True) - os.chdir(calc_dir) - - # Get from dictionary if key exists, else return default (e.g. 0) - cores = sim_specs["user"].get("cores", None) - kill_rate = sim_specs["user"].get("kill_rate", 0) - particle_variance = sim_specs["user"].get("particle_variance", 0) - - # Composing variable names and x values to set up simulation - seed = int(np.rint(x[0][0])) - - # This is to give a random variance of work-load - sim_particles = perturb(sim_particles, seed, particle_variance) - print(f"seed: {seed} particles: {sim_particles}") - - args = str(int(sim_particles)) + " " + str(sim_timesteps) + " " + str(seed) + " " + str(kill_rate) - - machinefile = None - if sim_specs["user"]["fail_on_submit"]: - machinefile = "fail" - - # Machinefile only used here for exception testing - if cores: - task = exctr.submit( - app_name="forces", - num_procs=cores, - app_args=args, - stdout="out.txt", - stderr="err.txt", - wait_on_start=True, - machinefile=machinefile, - ) - else: - task = exctr.submit( - app_name="forces", - app_args=args, - stdout="out.txt", - stderr="err.txt", - wait_on_start=True, - hyperthreads=True, - machinefile=machinefile, - ) # Auto-partition - - # Stat file to check for bad runs - statfile = "forces.stat" - filepath = os.path.join(task.workdir, statfile) - line = None - - poll_interval = 1 # secs - while not task.finished: - # Read last line of statfile - line = read_last_line(filepath) - if line == "kill": - task.kill() # Bad run - elif task.runtime > time_limit: - task.kill() # Timeout - else: - time.sleep(poll_interval) - task.poll() - - if task.finished: - if task.state == "FINISHED": - print(f"Task {task.name} completed") - calc_status = WORKER_DONE - if read_last_line(filepath) == "kill": - # Generally mark as complete if want results (completed after poll - before readline) - print("Warning: Task completed although marked as a bad run (kill flag set in forces.stat)") - elif task.state == "FAILED": - print(f"Warning: Task {task.name} failed: Error code {task.errcode}") - calc_status = TASK_FAILED - elif task.state == "USER_KILLED": - print(f"Warning: Task {task.name} has been killed") - calc_status = WORKER_KILL - else: - print(f"Warning: Task {task.name} in unknown state {task.state}. Error code {task.errcode}") - - time.sleep(0.2) - try: - data = np.loadtxt(filepath) - # task.read_file_in_workdir(statfile) - final_energy = data[-1] - except Exception: - final_energy = np.nan - # print('Warning - Energy Nan') - - outspecs = sim_specs["out"] - output = np.zeros(1, dtype=outspecs) - output["energy"][0] = final_energy - - return output, persis_info, calc_status diff --git a/libensemble/tests/scaling_tests/forces/globus_compute_forces/globus_compute_forces.yaml b/libensemble/tests/scaling_tests/forces/globus_compute_forces/globus_compute_forces.yaml deleted file mode 100644 index c7c0463bc..000000000 --- a/libensemble/tests/scaling_tests/forces/globus_compute_forces/globus_compute_forces.yaml +++ /dev/null @@ -1,37 +0,0 @@ -libE_specs: - save_every_k_gens: 1000 - profile: False - -exit_criteria: - sim_max: 8 - -sim_specs: - sim_f: libensemble.tests.scaling_tests.forces.globus_compute_forces.forces_simf.run_forces_globus_compute - inputs: - - x - outputs: - energy: - type: float - globus_compute_endpoint: ca766d22-49df-466a-8b51-cd0190c58bb0 - user: - keys: - - seed - sim_app: /home/jnavarro/libensemble/libensemble/tests/scaling_tests/forces/forces_app/forces.x - remote_ensemble_dir: /home/jnavarro/bebop_output/ensemble_ - cores: 1 - sim_particles: 1.e+3 - sim_timesteps: 5 - sim_kill_minutes: 10.0 - particle_variance: 0.2 - kill_rate: 0.5 - fail_on_sim: False - fail_on_submit: False - -gen_specs: - gen_f: libensemble.gen_funcs.sampling.uniform_random_sample - outputs: - x: - type: float - size: 1 - user: - gen_batch_size: 1000 diff --git a/libensemble/tests/scaling_tests/forces/globus_compute_forces/readme.md b/libensemble/tests/scaling_tests/forces/globus_compute_forces/readme.md deleted file mode 100644 index 793d869f4..000000000 --- a/libensemble/tests/scaling_tests/forces/globus_compute_forces/readme.md +++ /dev/null @@ -1,39 +0,0 @@ -## Running test run_libe_forces_funcx.py - -Naive Electrostatics Code Test - -This is designed only as an artificial, highly configurable test -code for a libEnsemble sim func. This variant is primarily to test libEnsemble's -capability to submit simulation functions to a separate machine from where libEnsemble's -manager and workers are running. - -### Forces Mini-App - -A system of charged particles is initialized and simulated over a number of time-steps. - -See `forces_app` directory for details. - -This application will need to be compiled on the remote machine where the sim_f will run. -See below. - -### Running with libEnsemble. - -On the remote machine, Configure the endpoint's `config.py` to include your project information and -match the machine's specifications. - -Then to run with local comms (multiprocessing) with one manager and `N` workers: - - python run_libe_forces_globus_compute.py --comms local --nworkers N - -To run with MPI comms using one manager and `N-1` workers: - - mpirun -np N python run_libe_forces_globus_compute.py - -Application parameters can be adjusted in `globus_compute_forces.yaml`. - -Note that each function and path must be accessible and/or importable on the -remote machine. Absolute paths are recommended. - -To remove output before the next run: - - ./cleanup.sh diff --git a/libensemble/tests/scaling_tests/forces/globus_compute_forces/run_libe_forces_globus_compute.py b/libensemble/tests/scaling_tests/forces/globus_compute_forces/run_libe_forces_globus_compute.py deleted file mode 100644 index d9ac4e04b..000000000 --- a/libensemble/tests/scaling_tests/forces/globus_compute_forces/run_libe_forces_globus_compute.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -import secrets - -import numpy as np - -from libensemble.ensemble import Ensemble - -if __name__ == "__main__": - forces = Ensemble(parse_args=True) - forces.from_yaml("globus_compute_forces.yaml") - - forces.sim_specs.user["remote_ensemble_dir"] += secrets.token_hex(nbytes=3) - - forces.gen_specs.user.update( - { - "lb": np.array([0]), - "ub": np.array([32767]), - } - ) - - forces.add_random_streams() - - forces.run() diff --git a/libensemble/tests/unit_tests/simdir/test_example.json b/libensemble/tests/unit_tests/simdir/test_example.json deleted file mode 100644 index a6f5e2cb8..000000000 --- a/libensemble/tests/unit_tests/simdir/test_example.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "libE_specs": { - "use_persis_return_sim": true - }, - "exit_criteria": { - "sim_max": 10 - }, - "sim_specs": { - "sim_f": "numpy.linalg.norm", - "inputs": [ - "x_on_cube" - ], - "outputs": { - "f": { - "type": "float" - }, - "fvec": { - "type": "float", - "size": 3 - } - } - }, - "gen_specs": { - "gen_f": "numpy.random.uniform", - "outputs": { - "priority": { - "type": "float" - }, - "local_pt": { - "type": "bool" - }, - "local_min": { - "type": "bool" - }, - "num_active_runs": { - "type": "int" - }, - "x_on_cube": { - "type": "float" - } - }, - "user": { - "nu": 0 - } - } -} diff --git a/libensemble/tests/unit_tests/simdir/test_example.toml b/libensemble/tests/unit_tests/simdir/test_example.toml deleted file mode 100644 index 1ac156cbb..000000000 --- a/libensemble/tests/unit_tests/simdir/test_example.toml +++ /dev/null @@ -1,31 +0,0 @@ -[libE_specs] - use_persis_return_sim = true - -[exit_criteria] - sim_max = 10 - -[sim_specs] - sim_f = "numpy.linalg.norm" - inputs = ["x_on_cube"] - [sim_specs.outputs] - [sim_specs.outputs.f] - type = "float" - [sim_specs.outputs.fvec] - type = "float" - size = 3 - -[gen_specs] - gen_f = "numpy.random.uniform" - [gen_specs.outputs] - [gen_specs.outputs.priority] - type = "float" - [gen_specs.outputs.local_pt] - type = "bool" - [gen_specs.outputs.local_min] - type = "bool" - [gen_specs.outputs.num_active_runs] - type = "int" - [gen_specs.outputs.x_on_cube] - type = "float" - [gen_specs.user] - nu = 0 diff --git a/libensemble/tests/unit_tests/simdir/test_example.yaml b/libensemble/tests/unit_tests/simdir/test_example.yaml deleted file mode 100644 index af2cb34b3..000000000 --- a/libensemble/tests/unit_tests/simdir/test_example.yaml +++ /dev/null @@ -1,32 +0,0 @@ -libE_specs: - use_persis_return_sim: True - -exit_criteria: - sim_max: 10 - -sim_specs: - sim_f: numpy.linalg.norm - inputs: - - x_on_cube - outputs: - f: - type: float - fvec: - type: float - size: 3 - -gen_specs: - gen_f: numpy.random.uniform - outputs: - priority: - type: float - local_pt: - type: bool - local_min: - type: bool - num_active_runs: - type: int - x_on_cube: - type: float - user: - nu: 0 diff --git a/libensemble/tests/unit_tests/simdir/test_example_badfuncs_attribute.yaml b/libensemble/tests/unit_tests/simdir/test_example_badfuncs_attribute.yaml deleted file mode 100644 index 85b3c90f4..000000000 --- a/libensemble/tests/unit_tests/simdir/test_example_badfuncs_attribute.yaml +++ /dev/null @@ -1,32 +0,0 @@ -libE_specs: - use_persis_return_gen: True - -exit_criteria: - sim_max: 10 - -sim_specs: - sim_f: numpy.linalg.asdf - inputs: - - x_on_cube - outputs: - f: - type: float - fvec: - type: float - size: 3 - -gen_specs: - gen_f: numpy.random.uniform - outputs: - priority: - type: float - local_pt: - type: bool - local_min: - type: bool - num_active_runs: - type: int - x_on_cube: - type: float - user: - nu: 0 diff --git a/libensemble/tests/unit_tests/simdir/test_example_badfuncs_notfound.yaml b/libensemble/tests/unit_tests/simdir/test_example_badfuncs_notfound.yaml deleted file mode 100644 index da95afd1d..000000000 --- a/libensemble/tests/unit_tests/simdir/test_example_badfuncs_notfound.yaml +++ /dev/null @@ -1,32 +0,0 @@ -libE_specs: - use_persis_return_sim: True - -exit_criteria: - sim_max: 10 - -sim_specs: - sim_f: numpy.linalg.norm - inputs: - - x_on_cube - outputs: - f: - type: float - fvec: - type: float - size: 3 - -gen_specs: - gen_f: asdf - outputs: - priority: - type: float - local_pt: - type: bool - local_min: - type: bool - num_active_runs: - type: int - x_on_cube: - type: float - user: - nu: 0 diff --git a/libensemble/tests/unit_tests/test_ensemble.py b/libensemble/tests/unit_tests/test_ensemble.py index 271932573..94c4865ad 100644 --- a/libensemble/tests/unit_tests/test_ensemble.py +++ b/libensemble/tests/unit_tests/test_ensemble.py @@ -2,7 +2,6 @@ import numpy as np -import libensemble.tests.unit_tests.setup as setup from libensemble.utils.misc import specs_dump @@ -37,55 +36,6 @@ def test_ensemble_parse_args_false(): assert e.libE_specs.nworkers == 8, "libE_specs nworkers not adjusted" -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["outputs"] = sim_specs["out"] - gen_specs["outputs"] = gen_specs["out"] - sim_specs.pop("in") - sim_specs.pop("out") - gen_specs.pop("out") - assert all([i in specs_dump(e.sim_specs).items() for i in sim_specs.items()]) - assert all([i in specs_dump(e.gen_specs).items() for i in gen_specs.items()]) - assert all([i in specs_dump(e.exit_criteria).items() for i in exit_criteria.items()]) - - -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 - - def test_full_workflow(): """Test initializing a workflow via Specs and Ensemble.run()""" from libensemble.ensemble import Ensemble @@ -233,8 +183,6 @@ def test_local_comms_without_nworkers(): if __name__ == "__main__": test_ensemble_init() test_ensemble_parse_args_false() - test_from_files() - test_bad_func_loads() test_full_workflow() test_flakey_workflow() test_ensemble_specs_update_libE_specs() diff --git a/pyproject.toml b/pyproject.toml index 80535d8cb..e025e7f02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ authors = [{name = "Jeffrey Larson"}, {name = "Stephen Hudson"}, {name = "Stefan M. Wild"}, {name = "David Bindel"}, {name = "John-Luke Navarro"}] -dependencies = [ "numpy", "psutil", "pydantic", "pyyaml", "tomli"] +dependencies = [ "numpy", "psutil", "pydantic"] description = "A Python toolkit for coordinating asynchronous and dynamic ensembles of calculations." name = "libensemble" @@ -88,7 +88,6 @@ autodoc-pydantic = ">=2.1.0,<3" ipdb = ">=0.13.13,<0.14" mypy = ">=1.15.0,<2" types-psutil = ">=6.1.0.20241221,<7" -types-pyyaml = ">=6.0.12.20250402,<7" [tool.pixi.dependencies] python = ">=3.10,<3.14" @@ -96,8 +95,6 @@ pip = ">=24.3.1,<25" setuptools = ">=75.6.0,<76" numpy = ">=1.21,<3" pydantic = ">=1.10,<3" -pyyaml = ">=6.0,<7" -tomli = ">=1.2.1,<3" psutil = ">=5.9.4,<7" [tool.pixi.target.osx-arm64.dependencies]