From 9261a9dbddcbba169415ab495f539fc3e8cb040c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Gonz=C3=A1lez=20Duque?= Date: Fri, 2 Aug 2024 08:53:27 +0200 Subject: [PATCH] Simplifies isolation mechanisms (#224) * Clarifies registration and env creation using create * Removes problem registration from all black boxes * Fixes a misimport in toy function testing * Modifies the logic of the force isolation test * Removes problem registration in create * Refactors some of the utilities of isolation * removes problem registration related functions * removes external black boxes and problem factory scripts * Removes force registration kwarg * Improves comments and docs * Runs the ruff linter * Cleans comments in objective factory * Adds a force isolation flag to the abstract black box * Changes the commit message on rmf --- .../workflows/python-tox-testing-rmf-env.yml | 2 +- .../parallel_query.py | 1 - .../environment.yml | 9 - .../querying_aloha.py | 30 --- .../registering_aloha.py | 74 ------ src/poli/core/abstract_black_box.py | 2 + src/poli/core/abstract_problem_factory.py | 5 +- src/poli/core/registry.py | 171 ------------ .../core/util/isolation/external_black_box.py | 133 ---------- src/poli/core/util/isolation/instancing.py | 169 ++++++------ .../objective_management/make_run_script.py | 58 +---- src/poli/core/util/observer_wrapper.py | 2 +- src/poli/external_isolated_function_script.py | 46 ---- src/poli/external_problem_factory_script.py | 177 ------------- src/poli/objective_factory.py | 243 +++--------------- src/poli/objective_repository/__init__.py | 5 +- .../albuterol_similarity/register.py | 11 - .../objective_repository/aloha/register.py | 16 +- .../amlodipine_mpo/register.py | 11 - .../celecoxib_rediscovery/register.py | 11 - .../objective_repository/deco_hop/register.py | 11 - .../dockstring/register.py | 12 +- .../drd2_docking/register.py | 11 - .../drd3_docking/register.py | 11 - .../objective_repository/ehrlich/register.py | 1 + .../fexofenadine_mpo/register.py | 11 - .../foldx_rfp_lambo/register.py | 11 - .../foldx_sasa/register.py | 10 - .../foldx_stability/register.py | 10 - .../foldx_stability_and_sasa/register.py | 10 - .../objective_repository/gfp_cbas/register.py | 25 -- .../gfp_select/register.py | 10 - .../gsk3_beta/register.py | 11 - .../isomer_c7h8n2o2/register.py | 11 - .../isomer_c9h10n2o2pf2cl/register.py | 11 - .../objective_repository/jnk3/register.py | 11 - .../objective_repository/median_1/register.py | 11 - .../objective_repository/median_2/register.py | 11 - .../mestranol_similarity/register.py | 11 - .../osimetrinib_mpo/register.py | 11 - .../penalized_logp_lambo/register.py | 9 - .../perindopril_mpo/register.py | 11 - .../ranolazine_mpo/register.py | 11 - .../objective_repository/rasp/register.py | 11 - .../rdkit_logp/register.py | 16 +- .../rdkit_qed/register.py | 16 +- .../rfp_foldx_stability_and_sasa/register.py | 10 - .../rmf_landscape/register.py | 10 - .../objective_repository/sa_tdc/register.py | 10 - .../scaffold_hop/register.py | 11 - .../sitagliptin_mpo/register.py | 11 - .../super_mario_bros/register.py | 11 - .../thiothixene_rediscovery/register.py | 11 - .../toy_continuous_problem/register.py | 16 +- .../troglitazone_rediscovery/register.py | 11 - .../valsartan_smarts/register.py | 11 - .../white_noise/register.py | 16 +- .../zaleplon_mpo/register.py | 11 - src/poli/registered_objectives/__init__.py | 1 - .../parallelization/test_parallelization.py | 2 - .../chemistry/test_chemistry_objectives.py | 34 --- src/poli/tests/registry/proteins/test_rasp.py | 1 - .../tests/registry/test_force_isolation.py | 35 ++- 63 files changed, 170 insertions(+), 1513 deletions(-) delete mode 100644 examples/the_basics/a_simple_objective_function_registration/environment.yml delete mode 100644 examples/the_basics/a_simple_objective_function_registration/querying_aloha.py delete mode 100644 examples/the_basics/a_simple_objective_function_registration/registering_aloha.py delete mode 100644 src/poli/core/util/isolation/external_black_box.py delete mode 100644 src/poli/external_problem_factory_script.py delete mode 100644 src/poli/registered_objectives/__init__.py diff --git a/.github/workflows/python-tox-testing-rmf-env.yml b/.github/workflows/python-tox-testing-rmf-env.yml index 3d26cdc1..0036673b 100644 --- a/.github/workflows/python-tox-testing-rmf-env.yml +++ b/.github/workflows/python-tox-testing-rmf-env.yml @@ -24,6 +24,6 @@ jobs: - name: Install dependencies run: | python -m pip install tox - - name: Test rmf-related black boxes with tox and pytest + - name: Test RMF-related black boxes with tox and pytest run: | tox -c tox.ini -e poli-rmf-py39 diff --git a/examples/protein_stability_and_sasa/evaluating_stability_and_sasa_in_parallel/parallel_query.py b/examples/protein_stability_and_sasa/evaluating_stability_and_sasa_in_parallel/parallel_query.py index 52b6c6b3..9fcffbc1 100644 --- a/examples/protein_stability_and_sasa/evaluating_stability_and_sasa_in_parallel/parallel_query.py +++ b/examples/protein_stability_and_sasa/evaluating_stability_and_sasa_in_parallel/parallel_query.py @@ -12,7 +12,6 @@ parallelize=True, num_workers=5, batch_size=10, - force_register=True, ) f, x0 = foldx_problem_in_parallel.black_box, foldx_problem_in_parallel.x0 print("Running in parallel") diff --git a/examples/the_basics/a_simple_objective_function_registration/environment.yml b/examples/the_basics/a_simple_objective_function_registration/environment.yml deleted file mode 100644 index 77d338fb..00000000 --- a/examples/the_basics/a_simple_objective_function_registration/environment.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: poli_aloha_problem -channels: - - defaults -dependencies: - - python=3.9 - - pip - - pip: - - numpy<2 - - "git+https://github.com/MachineLearningLifeScience/poli.git@dev" diff --git a/examples/the_basics/a_simple_objective_function_registration/querying_aloha.py b/examples/the_basics/a_simple_objective_function_registration/querying_aloha.py deleted file mode 100644 index 69773f1a..00000000 --- a/examples/the_basics/a_simple_objective_function_registration/querying_aloha.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -Once registered, we can create instances of the black box -function. This function is evaluated in an isolated process, -using the conda enviroment we specified at registration. -""" - -import numpy as np - -from poli import objective_factory - -if __name__ == "__main__": - # Creating an instance of the problem - f, x0, y0 = objective_factory.create( - name="our_aloha", observer_init_info=None, observer=None - ) - print(x0, y0) - - # At this point, you can call f. This will create - # a new isolated process, where the AlohaBlackBox - # will run inside the conda environment poli_aloha. - x1 = np.array(["F", "L", "E", "A", "S"]).reshape(1, -1) - y1 = f(x1) - print(x1, y1) - f.terminate() - - # Another example (using the start function) - with objective_factory.start(name="our_aloha") as f: - x = np.array(["F", "L", "E", "A", "S"]).reshape(1, -1) - y = f(x) - print(x, y) diff --git a/examples/the_basics/a_simple_objective_function_registration/registering_aloha.py b/examples/the_basics/a_simple_objective_function_registration/registering_aloha.py deleted file mode 100644 index 19c722c4..00000000 --- a/examples/the_basics/a_simple_objective_function_registration/registering_aloha.py +++ /dev/null @@ -1,74 +0,0 @@ -""" -This is the minimal example of how to register -a problem factory, which allows for creating -instances of the problem: the objective function, -the initial point, and its first evaluation. -""" - -from string import ascii_uppercase - -import numpy as np - -from poli.core.abstract_black_box import AbstractBlackBox -from poli.core.abstract_problem_factory import AbstractProblemFactory -from poli.core.black_box_information import BlackBoxInformation -from poli.core.problem import Problem - -our_aloha_information = BlackBoxInformation( - name="our_aloha", - max_sequence_length=5, - aligned=True, - fixed_length=True, - deterministic=True, - alphabet=list(ascii_uppercase), - log_transform_recommended=False, - discrete=True, - fidelity=None, - padding_token="", -) - - -class OurAlohaBlackBox(AbstractBlackBox): - def __init__( - self, - batch_size: int = None, - parallelize: bool = False, - num_workers: int = None, - evaluation_budget: int = float("inf"), - ): - super().__init__(batch_size, parallelize, num_workers, evaluation_budget) - - # The only method you have to define - def _black_box(self, x: np.ndarray, context: dict = None) -> np.ndarray: - matches = x == np.array(["A", "L", "O", "H", "A"]) - return np.sum(matches, axis=1, keepdims=True) - - @staticmethod - def get_black_box_info() -> BlackBoxInformation: - return our_aloha_information - - -class OurAlohaProblemFactory(AbstractProblemFactory): - def get_setup_information(self) -> BlackBoxInformation: - # The alphabet: ["A", "B", "C", ...] - return our_aloha_information - - def create(self, seed: int = None, **kwargs) -> Problem: - f = OurAlohaBlackBox() - x0 = np.array([["A", "L", "O", "O", "F"]]) - - return Problem(f, x0) - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - aloha_problem_factory = OurAlohaProblemFactory() - register_problem( - aloha_problem_factory, - conda_environment_name="poli_aloha_problem", - ) diff --git a/src/poli/core/abstract_black_box.py b/src/poli/core/abstract_black_box.py index f4899fad..fea9761b 100644 --- a/src/poli/core/abstract_black_box.py +++ b/src/poli/core/abstract_black_box.py @@ -75,6 +75,7 @@ def __init__( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ): """ Initialize the AbstractBlackBox object. @@ -95,6 +96,7 @@ def __init__( self.parallelize = parallelize self.evaluation_budget = evaluation_budget self.num_evaluations = 0 + self.force_isolation = force_isolation if num_workers is None: num_workers = cpu_count() // 2 diff --git a/src/poli/core/abstract_problem_factory.py b/src/poli/core/abstract_problem_factory.py index ca5226ba..1cc410ee 100644 --- a/src/poli/core/abstract_problem_factory.py +++ b/src/poli/core/abstract_problem_factory.py @@ -59,6 +59,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """ Returns a blackbox function and initial observations. @@ -75,7 +76,9 @@ def create( The number of workers for parallel evaluation. Default is None. evaluation_budget: int, optional The maximum number of function evaluations. Default is infinity. - + force_isolation: bool, optional + Whether to force the isolation of the black box. Default + is False. Returns -------- problem: AbstractProblem diff --git a/src/poli/core/registry.py b/src/poli/core/registry.py index f30b2d54..e3d66b53 100644 --- a/src/poli/core/registry.py +++ b/src/poli/core/registry.py @@ -2,19 +2,16 @@ """ import configparser -import subprocess import warnings from pathlib import Path from typing import List, Type, Union from poli.core.abstract_black_box import AbstractBlackBox from poli.core.abstract_isolated_function import AbstractIsolatedFunction -from poli.core.abstract_problem_factory import AbstractProblemFactory from poli.core.util.abstract_observer import AbstractObserver from poli.core.util.objective_management.make_run_script import ( make_isolated_function_script, make_observer_script, - make_run_script, ) # from poli.objective_repository import AVAILABLE_PROBLEM_FACTORIES, AVAILABLE_OBJECTIVES @@ -125,59 +122,6 @@ def remove_default_observer(): _write_config() -def register_problem( - problem_factory: AbstractProblemFactory, - conda_environment_name: Union[str, Path] = None, - python_paths: List[str] = None, - force: bool = True, - **kwargs, -): - """Registers a problem. - - This function takes a problem factory, a conda environment, a list of python - environments, and additional keyword arguments. With these, it creates a - script that can be run to instantiate the problem factory in a separate - process. It also sets the configuration so that the problem factory can be - instantiated later. - - Parameters - ---------- - problem_factory : AbstractProblemFactory or str - The problem factory to be registered. - conda_environment_name : str or Path - The name or path of the conda environment to be used. - python_paths : List[str] - A list of paths to append to the python path of the run script. - force : bool - Flag indicating whether to overwrite the existing problem. - **kwargs : dict - Additional keyword arguments to be passed to the problem factory. - """ - if "conda_environment_location" in kwargs: - conda_environment_name = kwargs["conda_environment_location"] - - problem_name = problem_factory.get_setup_information().get_problem_name() - if problem_name not in config.sections(): - config.add_section(problem_name) - elif not force: - # If force is false, we warn the user and ask for confirmation - user_input = input( - f"Problem {problem_name} already exists. " - f"Do you want to overwrite it? (y/[n]) " - ) - if user_input.lower() != "y": - warnings.warn(f"Problem {problem_name} already exists. Not overwriting.") - return - - warnings.warn(f"Problem {problem_name} already exists. Overwriting.") - - run_script_location = make_run_script( - type(problem_factory), conda_environment_name, python_paths, **kwargs - ) - config[problem_name][_RUN_SCRIPT_LOCATION] = run_script_location - _write_config() - - def register_isolated_function( isolated_function: Union[AbstractBlackBox, AbstractIsolatedFunction], name: str, @@ -216,121 +160,6 @@ def register_isolated_function( _write_config() -def register_problem_from_repository(name: str, quiet: bool = False): - """Registers a problem from the repository. - - This function takes a problem name, and registers it. The problem name - corresponds to a folder inside the objective_repository folder. The - function will: - 1. create the environment from the yaml file - 2. run the file from said enviroment (since we can't - import the factory: it may have dependencies that are - not installed) - - Parameters - ---------- - name : str - The name of the problem to be registered. - quiet : bool, optional - If True, we squelch the feedback about environment creation and - problem registration, by default False. - """ - # the name is actually the folder inside - # poli/objective_repository, so we need - # to - # 1. create the environment from the yaml file - # 2. run the file from said enviroment (since - # we can't import the factory: it may have - # dependencies that are not installed) - - # Load up the environment name - PATH_TO_REPOSITORY = ( - Path(__file__).parent.parent / "objective_repository" - ).resolve() - - with open(PATH_TO_REPOSITORY / name / "environment.yml", "r") as f: - # This is a really crude way of doing this, - # but it works. We should probably use a - # yaml parser instead, but the idea is to keep - # the dependencies to a minimum. - yml = f.read() - lines = yml.split("\n") - conda_env_name_line = lines[0] - assert conda_env_name_line.startswith("name:"), ( - "The first line of the environment.yml file " - "should be the name of the environment" - ) - env_name = lines[0].split(":")[1].strip() - - # Moreover, we should only be doing this - # if the problem is not already registered. - # TODO: do we? - if name in config.sections(): - warnings.warn(f"Problem {name} already registered. Skipping") - return - - # 1. create the environment from the yaml file - if not quiet: - print(f"poli 🧪: creating environment {env_name} from {name}/environment.yml") - try: - subprocess.run( - " ".join( - [ - "conda", - "env", - "create", - "-f", - str(PATH_TO_REPOSITORY / name / "environment.yml"), - ] - ), - shell=True, - check=True, - capture_output=True, - ) - except subprocess.CalledProcessError as e: - if "already exists" in e.stderr.decode(): - if not quiet: - print( - f"poli 🧪: creating environment {env_name} from {name}/environment.yml" - ) - warnings.warn(f"Environment {env_name} already exists. Will not create it.") - else: - raise e - - # 2. run the file from said enviroment (since - # we can't import the factory: it may have - # dependencies that are not installed) - - # Running the file - file_to_run = PATH_TO_REPOSITORY / name / "register.py" - command = " ".join(["conda", "run", "-n", env_name, "python", str(file_to_run)]) - warnings.warn("Running the following command: %s. " % command) - - if not quiet: - print(f"poli 🧪: running registration of {name} from environment {env_name}") - try: - subprocess.run(command, check=True, shell=True, capture_output=True) - except subprocess.CalledProcessError as e: - raise RuntimeError( - f"Found error when running {file_to_run} from environment {env_name}: \n" - f"{e.stderr.decode()}" - ) - - -def delete_problem(problem_name: str): - """Deletes a problem. - - This function takes a problem name, and deletes it from the configuration. - - Parameters - ---------- - problem_name : str - The name of the problem to be deleted. - """ - config.remove_section(problem_name) - _write_config() - - def _write_config(): with open(config_file, "w+") as configfile: config.write(configfile) diff --git a/src/poli/core/util/isolation/external_black_box.py b/src/poli/core/util/isolation/external_black_box.py deleted file mode 100644 index 9ba06e7f..00000000 --- a/src/poli/core/util/isolation/external_black_box.py +++ /dev/null @@ -1,133 +0,0 @@ -from typing import Any - -from poli.core.abstract_black_box import AbstractBlackBox -from poli.core.black_box_information import BlackBoxInformation -from poli.core.util.inter_process_communication.process_wrapper import ProcessWrapper - - -class ExternalBlackBox(AbstractBlackBox): - """An external version of the black-box function to be instantiated in isolated processes.""" - - def __init__(self, process_wrapper: ProcessWrapper): - """ - Initialize the ExternalBlackBox object. - - Parameters - ---------- - info : ProblemSetupInformation - The information about the problem. - process_wrapper : ProcessWrapper - The process wrapper to communicate with the objective process. - """ - # We don't need to pass the kwargs to the parent class, - # because we overwrite the __getattr__ method to communicate - # with the isolated objective process. - super().__init__() - self.process_wrapper = process_wrapper - - def _black_box(self, x, context=None): - """ - Evaluates the black-box function. - - In this external black-box, the evaluation is done by sending a message - to the objective process and waiting for the response. The interprocess - communication is handled by the ProcessWrapper class, which maintains - an isolated process in which a black-box function runs with, potentially, - a completely different python executable (e.g. inside another conda - environment). - - Parameters - ---------- - x : np.ndarray - The input data points. - context : object - Additional context for the observation. - - Returns - ------- - y : np.ndarray - The output data points. - """ - self.process_wrapper.send(["QUERY", x, context]) - msg_type, *val = self.process_wrapper.recv() - if msg_type == "EXCEPTION": - e, traceback_ = val - print(traceback_) - raise e - elif msg_type == "QUERY": - y = val[0] - - return y - else: - raise ValueError( - f"Internal error: received {msg_type} when expecting QUERY or EXCEPTION" - ) - - @property - def info(self) -> BlackBoxInformation: - """The information about the black-box function.""" - self.process_wrapper.send(["ATTRIBUTE", "info"]) - msg_type, *msg = self.process_wrapper.recv() - if msg_type == "EXCEPTION": - e, traceback_ = msg - print(traceback_) - raise e - else: - assert msg_type == "ATTRIBUTE" - attribute = msg[0] - return attribute - - def terminate(self): - """Terminates the external black box.""" - # terminate objective process - if self.process_wrapper is not None: - try: - self.process_wrapper.send(["QUIT", None]) - self.process_wrapper.close() # clean up connection - except AttributeError: - # This means that the process has already been terminated - pass - self.process_wrapper = None - # terminate observer - if self.observer is not None: - try: - self.observer.finish() - self.observer = None - except Exception: - pass - - def __getattr__(self, __name: str) -> Any: - """Gets an attribute from the underlying black-box function. - - Asks for the attribute of the underlying - black-box function by sending a message - to the process w. the msg_type "ATTRIBUTE". - - Parameters - ---------- - __name : str - The name of the attribute. - - Returns - ------- - attribute : Any - The attribute of the underlying black-box function. - """ - if __name == "process_wrapper": - return self.process_wrapper - self.process_wrapper.send(["ATTRIBUTE", __name]) - msg_type, *msg = self.process_wrapper.recv() - if msg_type == "EXCEPTION": - e, traceback_ = msg - print(traceback_) - raise e - else: - assert msg_type == "ATTRIBUTE" - attribute = msg[0] - return attribute - - def __del__(self): - self.terminate() - - def __exit__(self, exc_type, exc_val, exc_tb): - return self.terminate() diff --git a/src/poli/core/util/isolation/instancing.py b/src/poli/core/util/isolation/instancing.py index dc6d7bd3..cde12103 100644 --- a/src/poli/core/util/isolation/instancing.py +++ b/src/poli/core/util/isolation/instancing.py @@ -36,6 +36,44 @@ def load_config(): return config +def __read_env_name(environment_file: Path) -> str: + with open(environment_file, "r") as f: + # This is a really crude way of doing this, + # but it works. We should probably use a + # yaml parser instead, but the idea is to keep + # the dependencies to a minimum. + yml = f.read() + lines = yml.split("\n") + conda_env_name_line = lines[0] + assert conda_env_name_line.startswith("name:"), ( + "The first line of the environment.yml file " + "should be the name of the environment" + ) + env_name = lines[0].split(":")[1].strip() + return env_name + + +def __create_conda_env(environment_file: Path, quiet: bool = False): + env_name = __read_env_name(environment_file=environment_file) + + # 1. create the environment from the yaml file + if not quiet: + print(f"poli 🧪: creating environment {env_name} from {environment_file}") + try: + subprocess.run( + " ".join(["conda", "env", "create", "-f", str(environment_file)]), + shell=True, + check=True, + capture_output=True, + ) + except subprocess.CalledProcessError as e: + if "already exists" in e.stderr.decode(): + if not quiet: + print(f"poli 🧪: {env_name} already exists.") + else: + raise e + + def __register_isolated_function_from_repository( name: str, quiet: bool = False ) -> None: @@ -57,10 +95,6 @@ def __register_isolated_function_from_repository( If True, we squelch the feedback about environment creation and problem registration, by default False. """ - assert name.endswith( - "__isolated" - ), "By convention, the names of isolated functions always end with '__isolated'" - # Load up the environment name PATH_TO_REPOSITORY = ( Path(__file__).parent.parent.parent.parent / "objective_repository" @@ -70,7 +104,7 @@ def __register_isolated_function_from_repository( environment_file = PATH_TO_REPOSITORY / name_without_isolated / "environment.yml" isolated_file = PATH_TO_REPOSITORY / name_without_isolated / "isolated_function.py" - __register_isolated_function( + __register_isolated_file( environment_file=environment_file, isolated_file=isolated_file, name_for_show=name, @@ -102,7 +136,7 @@ def __register_isolated_function_from_core(name: str, quiet: bool = False) -> No isolated_file = ( ROOT_DIR_OF_POLI_PACKAGE / "core" / "chemistry" / "tdc_isolated_function.py" ) - __register_isolated_function( + __register_isolated_file( environment_file=environment_file, isolated_file=isolated_file, name_for_show="TDC isolated function", @@ -115,51 +149,35 @@ def __register_isolated_function_from_core(name: str, quiet: bool = False) -> No ) -def __register_isolated_function( +def __run_file_in_env(env_name: str, file_path: Path): + """ + Runs a file from a given conda env. + """ + command = " ".join(["conda", "run", "-n", env_name, "python", str(file_path)]) + try: + subprocess.run(command, check=True, shell=True, capture_output=True) + except subprocess.CalledProcessError as e: + raise RuntimeError( + f"Found error when running {file_path} from environment {env_name}: \n" + f"{e.stderr.decode()}" + ) from e + + +def __register_isolated_file( environment_file: Path, isolated_file: Path, name_for_show: str = None, quiet: bool = False, ): - with open(environment_file, "r") as f: - # This is a really crude way of doing this, - # but it works. We should probably use a - # yaml parser instead, but the idea is to keep - # the dependencies to a minimum. - yml = f.read() - lines = yml.split("\n") - conda_env_name_line = lines[0] - assert conda_env_name_line.startswith("name:"), ( - "The first line of the environment.yml file " - "should be the name of the environment" - ) - env_name = lines[0].split(":")[1].strip() - - # 1. create the environment from the yaml file - if not quiet: - print(f"poli 🧪: creating environment {env_name} from {environment_file}") - try: - subprocess.run( - " ".join(["conda", "env", "create", "-f", str(environment_file)]), - shell=True, - check=True, - capture_output=True, - ) - except subprocess.CalledProcessError as e: - if "already exists" in e.stderr.decode(): - if not quiet: - print(f"poli 🧪: {env_name} already exists.") - else: - raise e - - # 2. run the file from said enviroment (since - # we can't import the factory: it may have - # dependencies that are not installed) - - # Running the file - command = " ".join(["conda", "run", "-n", env_name, "python", str(isolated_file)]) - # warnings.warn("Running the following command: %s. " % command) + """ + Creates the conda environment in the environment file and + runs the isolated file. + """ + # 1. Create the conda env. + __create_conda_env(environment_file, quiet=quiet) + env_name = __read_env_name(environment_file) + # 2. Running the file if not quiet: if name_for_show: print( @@ -167,18 +185,11 @@ def __register_isolated_function( ) else: print(f"poli 🧪: running {isolated_file} from environment {env_name}") - try: - subprocess.run(command, check=True, shell=True, capture_output=True) - except subprocess.CalledProcessError as e: - raise RuntimeError( - f"Found error when running {isolated_file} from environment {env_name}: \n" - f"{e.stderr.decode()}" - ) from e + __run_file_in_env(env_name, isolated_file) -def register_isolated_function_if_available( - name: str, force_register: bool = True, quiet: bool = False -): + +def register_isolated_function(name: str, quiet: bool = False): """Registers the objective function if it is available in the repository. If the objective function is not available in the repository, @@ -196,41 +207,22 @@ def register_isolated_function_if_available( `isolated_function.py`. An exception to this is "tdc__isolated", which registers the TDCIsolatedFunction. - force_register : bool, optional - If True, then the objective function is registered without asking - for confirmation, overwriting any previous registration. By default, - it is True. quiet : bool, optional If True, we squelch the messages giving feedback about the creation process. By default, it is False. """ config = load_config() if name not in config: - # if name not in AVAILABLE_OBJECTIVES: - # raise ValueError( - # f"Objective function '{name}' is not registered, " - # "and it is not available in the repository." - # ) - - # At this point, we know that the function is available - # in the repository - if force_register: - # Then we install it. - answer = "y" - else: - # We ask the user for their confirmation - answer = input( - f"Objective function '{name}' is not registered, " - "but it is available in the repository. Do you " - "want to install it? (y/[n]): " - ) - - if answer != "y": - raise ValueError( - f"Objective function '{name}' is not registered. Aborting." - ) - # Register problem + + # Two cases: + # (i) some of the isolated functions are not alongside + # their black boxes and problem factories, but are rather inside + # the core of poli. For now, the only case is tdc, but more may + # come in the future. + # + # (ii) the isolated function is in the repository, living alongside + # the black box and the problem factory. if name == "tdc__isolated": logging.debug( "poli 🧪: Registered the isolated function from the repository." @@ -313,15 +305,11 @@ def instance_function_as_isolated_process( name: str, seed: int = None, quiet: bool = False, - force_register: bool = True, **kwargs_for_black_box, ) -> ExternalFunction: - # Register the problem - register_isolated_function_if_available( - name=name, force_register=force_register, quiet=quiet - ) + # Register the problem if it hasn't been registered. + register_isolated_function(name=name, quiet=quiet) - # Create the external process wrapper f = __create_function_as_isolated_process( name=name, seed=seed, @@ -329,7 +317,6 @@ def instance_function_as_isolated_process( **kwargs_for_black_box, ) - # return it. return f @@ -378,6 +365,6 @@ class from the sibling isolated_function.py file of each register.py. ) else: inner_function = instance_function_as_isolated_process( - name=isolated_function_name, **kwargs + name=isolated_function_name, seed=seed, quiet=quiet, **kwargs ) return inner_function diff --git a/src/poli/core/util/objective_management/make_run_script.py b/src/poli/core/util/objective_management/make_run_script.py index f66f09c3..0793be69 100644 --- a/src/poli/core/util/objective_management/make_run_script.py +++ b/src/poli/core/util/objective_management/make_run_script.py @@ -9,12 +9,11 @@ from pathlib import Path from typing import List, Type, Union -from poli import external_isolated_function_script, external_problem_factory_script +from poli import external_isolated_function_script from poli.core.abstract_isolated_function import AbstractIsolatedFunction -from poli.core.abstract_problem_factory import AbstractProblemFactory from poli.core.util import observer_wrapper from poli.core.util.abstract_observer import AbstractObserver -from poli.external_problem_factory_script import ADDITIONAL_IMPORT_SEARCH_PATHES_KEY +from poli.external_isolated_function_script import ADDITIONAL_IMPORT_SEARCH_PATHES_KEY # By default, we will store the run scripts inside the # home folder of the user, on the hidden folder @@ -51,44 +50,11 @@ def make_isolated_function_script( """ command = inspect.getfile(external_isolated_function_script) - return _make_run_script( + return _make_run_script_from_template( command, isolated_function, conda_environment_name, python_paths, cwd, **kwargs ) -def make_run_script( - problem_factory: Type[AbstractProblemFactory], - conda_environment_name: Union[str, Path] = None, - python_paths: List[str] = None, - cwd=None, - **kwargs, -) -> str: - """ - Create a run script for a given problem factory. - - Parameters - ---------- - problem_factory : AbstractProblemFactory - The problem factory to create the run script for. - conda_environment_name : str or Path, optional - The conda environment to use for the run script. - Either a string containing the name, or a path to the environment. - python_paths : list of str, optional - A list of paths to append to the python path of the run script. - cwd : str or Path, optional - The working directory of the run script. - - Returns - ------- - run_script: str - The generated run script. - """ - command = inspect.getfile(external_problem_factory_script) - return _make_run_script( - command, problem_factory, conda_environment_name, python_paths, cwd, **kwargs - ) - - def make_observer_script( observer: Type[AbstractObserver], conda_environment: Union[str, Path] = None, @@ -116,27 +82,17 @@ def make_observer_script( """ command = inspect.getfile(observer_wrapper) - return _make_run_script(command, observer, conda_environment, python_paths, cwd) - - -def _make_black_box_script( - command: str, - command_for_instancing_the_black_box: str, - conda_environment_name: Union[str, Path], - python_paths: List[str], - cwd=None, -): - # TODO: implement in such a way that - ... + return _make_run_script_from_template( + command, observer, conda_environment, python_paths, cwd + ) -def _make_run_script( +def _make_run_script_from_template( command: str, non_instantiated_object, conda_environment_name: Union[str, Path], python_paths: List[str], cwd=None, - **kwargs, ): """ An internal function for creating run scripts; returns the location of the run script. diff --git a/src/poli/core/util/observer_wrapper.py b/src/poli/core/util/observer_wrapper.py index 527e74b5..7de468de 100644 --- a/src/poli/core/util/observer_wrapper.py +++ b/src/poli/core/util/observer_wrapper.py @@ -7,7 +7,7 @@ from poli.core.util.abstract_observer import AbstractObserver from poli.core.util.inter_process_communication.process_wrapper import get_connection -from poli.external_problem_factory_script import dynamically_instantiate +from poli.external_isolated_function_script import dynamically_instantiate def start_observer_process(observer_name, port: int, password: str): diff --git a/src/poli/external_isolated_function_script.py b/src/poli/external_isolated_function_script.py index 4c2aed18..f24c3595 100644 --- a/src/poli/external_isolated_function_script.py +++ b/src/poli/external_isolated_function_script.py @@ -16,52 +16,6 @@ ADDITIONAL_IMPORT_SEARCH_PATHES_KEY = "ADDITIONAL_IMPORT_PATHS" -def parse_factory_kwargs(factory_kwargs: str) -> dict: - """Parses the factory kwargs passed to the objective function. - - Parameters - ---------- - factory_kwargs : str - The string containing the factory kwargs (see ProcessWrapper - for details about how this factory_kwargs strings is built). - - Returns - ------- - kwargs : dict - A dictionary containing the factory kwargs, parsed from the string. - """ - if factory_kwargs == "": - # Then the user didn't pass any arguments - kwargs = {} - else: - factory_kwargs = factory_kwargs.split() - kwargs = {} - for item in factory_kwargs: - item = item.strip("--") - key, value = item.split("=") - if value.startswith("list:"): - # Then we assume that the value was a list - value = value.strip("list:") - value = value.split(",") - elif value.startswith("int:"): - value = int(value.strip("int:")) - elif value.startswith("float:"): - if value == "float:inf": - value = float("inf") - elif value == "float:-inf": - value = float("-inf") - else: - value = float(value.strip("float:")) - elif value.startswith("bool:"): - value = value.strip("bool:") == "True" - elif value.startswith("none:"): - value = None - - kwargs[key] = value - - return kwargs - - def dynamically_instantiate(obj: str, **kwargs): """Dynamically instantiates an object from a string. diff --git a/src/poli/external_problem_factory_script.py b/src/poli/external_problem_factory_script.py deleted file mode 100644 index 25a69437..00000000 --- a/src/poli/external_problem_factory_script.py +++ /dev/null @@ -1,177 +0,0 @@ -"""Executable script used for isolation of objective factories and functions.""" - -import argparse -import logging -import os -import sys -import traceback - -from poli.core.abstract_problem_factory import AbstractProblemFactory -from poli.core.util.inter_process_communication.process_wrapper import get_connection - -ADDITIONAL_IMPORT_SEARCH_PATHES_KEY = "ADDITIONAL_IMPORT_PATHS" - - -def parse_factory_kwargs(factory_kwargs: str) -> dict: - """Parses the factory kwargs passed to the objective function. - - Parameters - ---------- - factory_kwargs : str - The string containing the factory kwargs (see ProcessWrapper - for details about how this factory_kwargs strings is built). - - Returns - ------- - kwargs : dict - A dictionary containing the factory kwargs, parsed from the string. - """ - if factory_kwargs == "": - # Then the user didn't pass any arguments - kwargs = {} - else: - factory_kwargs = factory_kwargs.split() - kwargs = {} - for item in factory_kwargs: - item = item.strip("--") - key, value = item.split("=") - if value.startswith("list:"): - # Then we assume that the value was a list - value = value.strip("list:") - value = value.split(",") - elif value.startswith("int:"): - value = int(value.strip("int:")) - elif value.startswith("float:"): - if value == "float:inf": - value = float("inf") - elif value == "float:-inf": - value = float("-inf") - else: - value = float(value.strip("float:")) - elif value.startswith("bool:"): - value = value.strip("bool:") == "True" - elif value.startswith("none:"): - value = None - - kwargs[key] = value - - return kwargs - - -def dynamically_instantiate(obj: str, **kwargs): - """Dynamically instantiates an object from a string. - - This function is used internally to instantiate objective - factories dynamically, inside isolated processes. It is - also used to instantiate external observers. - - Parameters - ---------- - obj : str - The string containing the name of the object to be instantiated. - **kwargs : dict - The keyword arguments to be passed to the object constructor. - """ - # FIXME: this method opens up a serious security vulnerability - # TODO: possible alternative: importlib - # TODO: another possible alternative: hydra - # sys.path.append(os.getcwd()) - if ADDITIONAL_IMPORT_SEARCH_PATHES_KEY in os.environ: - sys.path.extend(os.environ[ADDITIONAL_IMPORT_SEARCH_PATHES_KEY].split(":")) - # sys.path.extend(os.environ['PYTHONPATH'].split(':')) - last_dot = obj.rfind(".") - - command = ( - "from " - + obj[:last_dot] - + " import " - + obj[last_dot + 1 :] - + " as DynamicObject" - ) - try: - exec(command) - instantiated_object = eval("DynamicObject")(**kwargs) - except ImportError as e: - logging.fatal(f"Path: {os.environ['PATH']}") - logging.fatal(f"Python path: {sys.path}") - logging.fatal(f"Path: {os.environ[ADDITIONAL_IMPORT_SEARCH_PATHES_KEY]}") - if "PYTHONPATH" in os.environ.keys(): - logging.fatal(f"Path: {os.environ['PYTHONPATH']}") - else: - logging.fatal("PYTHONPATH is not part of the environment variables.") - raise e - return instantiated_object - - -def run(factory_kwargs: str, objective_name: str, port: int, password: str) -> None: - """Starts an objective function listener loop to wait for requests. - - Parameters - ---------- - factory_kwargs : str - The string containing the factory kwargs (see ProcessWrapper - for details about how this factory_kwargs strings is built). - objective_name : str - The name of the objective function to be instantiated. - port : int - The port number for the connection with the mother process. - password : str - The password for the connection with the mother process. - """ - kwargs = parse_factory_kwargs(factory_kwargs) - - # make connection with the mother process - conn = get_connection(port, password) - - # TODO: We could be receiving the kwargs for the factory here. - msg_type, seed = conn.recv() - kwargs["seed"] = seed - - # dynamically load objective function module - # At this point, the black box objective function - # is exactly the same as the one used in the - # registration (?). - try: - objective_factory: AbstractProblemFactory = dynamically_instantiate( - objective_name - ) - problem = objective_factory.create(**kwargs) - f, x0 = problem.black_box, problem.x0 - - # give mother process the signal that we're ready - conn.send(["SETUP", x0]) - except Exception as e: - tb = traceback.format_exc() - conn.send(["EXCEPTION", e, tb]) - raise e - - # now wait for objective function calls - while True: - msg_type, *msg = conn.recv() - # x, context = msg - if msg_type == "QUIT": - break - try: - if msg_type == "QUERY": - x, context = msg - y = f(x, context=context) - conn.send(["QUERY", y]) - elif msg_type == "ATTRIBUTE": - attribute = getattr(f, msg[0]) - conn.send(["ATTRIBUTE", attribute]) - except Exception as e: - tb = traceback.format_exc() - conn.send(["EXCEPTION", e, tb]) - - # conn.close() - # exit() # kill other threads, and close file handles - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--objective-name", required=True) - parser.add_argument("--port", required=True, type=int) - parser.add_argument("--password", required=True, type=str) - - args, factory_kwargs = parser.parse_known_args() - run(factory_kwargs[0], args.objective_name, args.port, args.password) diff --git a/src/poli/objective_factory.py b/src/poli/objective_factory.py index 9e20f985..da889f57 100644 --- a/src/poli/objective_factory.py +++ b/src/poli/objective_factory.py @@ -3,11 +3,7 @@ """ import configparser -import logging from pathlib import Path -from typing import Tuple - -import numpy as np from poli.core import registry from poli.core.abstract_black_box import AbstractBlackBox @@ -17,17 +13,13 @@ _DEFAULT, _DEFAULT_OBSERVER_RUN_SCRIPT, _OBSERVER, - _RUN_SCRIPT_LOCATION, DEFAULT_OBSERVER_NAME, - register_problem_from_repository, ) from poli.core.util.abstract_observer import AbstractObserver from poli.core.util.algorithm_observer_wrapper import AlgorithmObserverWrapper from poli.core.util.default_observer import DefaultObserver from poli.core.util.external_observer import ExternalObserver -from poli.core.util.inter_process_communication.process_wrapper import ProcessWrapper -from poli.core.util.isolation.external_black_box import ExternalBlackBox -from poli.external_problem_factory_script import dynamically_instantiate +from poli.external_isolated_function_script import dynamically_instantiate from poli.objective_repository import AVAILABLE_OBJECTIVES, AVAILABLE_PROBLEM_FACTORIES @@ -55,14 +47,13 @@ def __create_problem_from_repository( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, observer: AbstractObserver = None, **kwargs_for_factory, -) -> Tuple[AbstractBlackBox, np.ndarray, np.ndarray]: +) -> Problem: """Creates the objective function from the repository. - If the problem is available in AVAILABLE_PROBLEM_FACTORIES - (i.e. if the user could import all the dependencies directly), - we create the problem directly. Otherwise, we raise an error. + We create the problem directly, without starting it as an isolated process. Parameters ---------- @@ -86,10 +77,23 @@ def __create_problem_from_repository( Additional keyword arguments for the factory. """ if name not in AVAILABLE_PROBLEM_FACTORIES: - raise ValueError( - f"Objective function '{name}' is not available in the repository." - ) - + if name in AVAILABLE_OBJECTIVES: + # For poli developers: + # If you get this error while developing a new black box, + # it might be because you forgot to register your problem + # factory and black box inside the __init__.py file of + # the objective_repository. Remember that you need to add + # them to AVAILABLE_PROBLEM_FACTORIES and AVAILABLE_BLACK_BOXES. + raise ValueError( + f"Objective function '{name}' is available in the repository, " + "but it is not registered as available. This is an internal error. " + "We encourage you to report it to the developers by creating an " + "issue in the GitHub repository of poli." + ) + else: + raise ValueError( + f"Objective function '{name}' is not available in the repository." + ) problem_factory: AbstractProblemFactory = AVAILABLE_PROBLEM_FACTORIES[name]() problem = problem_factory.create( seed=seed, @@ -97,6 +101,7 @@ def __create_problem_from_repository( parallelize=parallelize, num_workers=num_workers, evaluation_budget=evaluation_budget, + force_isolation=force_isolation, **kwargs_for_factory, ) @@ -106,152 +111,12 @@ def __create_problem_from_repository( return problem -def __create_problem_as_isolated_process( - name: str, - seed: int = None, - batch_size: int = None, - parallelize: bool = False, - num_workers: int = None, - evaluation_budget: int = float("inf"), - quiet: bool = False, - **kwargs_for_factory, -) -> Problem: - """Creates the objective function as an isolated process. - - If the problem is registered, we create it as an isolated - process. Otherwise, we raise an error. That is, this function - expects the problem to be registered. - - Parameters - ---------- - name : str - The name of the objective function. - seed : int, optional - The seed value for random number generation. - batch_size : int, optional - The batch size, passed to the black box to run evaluations on batches. - If None, it will evaluate all inputs at once. - parallelize : bool, optional - If True, then the objective function runs in parallel. - num_workers : int, optional - When parallelize is True, this specifies the number of processes to use. - By default, it uses half the number of available CPUs (rounded down). - evaluation_budget : int, optional - The maximum number of evaluations allowed. By default, it is infinity. - quiet : bool, optional - If True, we squelch the messages giving feedback about the creation process. - By default, it is False. - **kwargs_for_factory : dict, optional - Additional keyword arguments for the factory. - """ - config = load_config() - if name not in config: - raise ValueError(f"Objective function '{name}' is not registered. ") - - # start objective process - # VERY IMPORTANT: the script MUST accept port and password as arguments - kwargs_for_factory["batch_size"] = batch_size - kwargs_for_factory["parallelize"] = parallelize - kwargs_for_factory["num_workers"] = num_workers - kwargs_for_factory["evaluation_budget"] = evaluation_budget - - if not quiet: - print(f"poli 🧪: Starting the problem {name} as an isolated objective process.") - - process_wrapper = ProcessWrapper( - config[name][_RUN_SCRIPT_LOCATION], **kwargs_for_factory - ) - # TODO: add signal listener that intercepts when proc ends - # wait for connection from objective process - # TODO: potential (unlikely) race condition! (process might try to connect before listener is ready!) - # TODO: We could be sending all the kwargs for the factory here. - process_wrapper.send(("SETUP", seed)) - - msg_type, *msg = process_wrapper.recv() - if msg_type == "SETUP": - # Then the instance of the abstract factory - # was correctly set-up, and - x0 = msg[0] - elif msg_type == "EXCEPTION": - e, tb = msg - print(tb) - raise e - else: - raise ValueError( - f"Internal error: received {msg_type} when expecting SETUP or EXCEPTION" - ) - - f = ExternalBlackBox(process_wrapper) - external_problem = Problem( - black_box=f, - x0=x0, - ) - - return external_problem - - -def __register_objective_if_available( - name: str, force_register: bool = True, quiet: bool = False -): - """Registers the objective function if it is available in the repository. - - If the objective function is not available in the repository, - then we raise an error. If it is available, then we ask the - user for confirmation to register it. If the user confirms, - then we register it. Otherwise, we raise an error. - - Parameters - ---------- - name : str - The name of the objective function. - force_register : bool, optional - If True, then the objective function is registered without asking - for confirmation, overwriting any previous registration. By default, - it is True. - quiet : bool, optional - If True, we squelch the messages giving feedback about the creation process. - By default, it is False. - """ - config = load_config() - if name not in config: - if name not in AVAILABLE_OBJECTIVES: - raise ValueError( - f"Objective function '{name}' is not registered, " - "and it is not available in the repository." - ) - - # At this point, we know that the function is available - # in the repository - if force_register: - # Then we install it. - answer = "y" - else: - # We ask the user for their confirmation - answer = input( - f"Objective function '{name}' is not registered, " - "but it is available in the repository. Do you " - "want to install it? (y/[n]): " - ) - - if answer == "y": - # Register problem - logging.debug("poli 🧪: Registered the objective from the repository.") - register_problem_from_repository(name, quiet=quiet) - # Refresh the config - config = load_config() - else: - raise ValueError( - f"Objective function '{name}' won't be registered. Aborting." - ) - - def create( name: str, *, seed: int = None, observer_init_info: dict = None, observer_name: str = None, - force_register: bool = True, force_isolation: bool = False, batch_size: int = None, parallelize: bool = False, @@ -273,10 +138,6 @@ def create( Optional information about the caller that is forwarded to the logger to initialize the run. observer_name : str, optional The observer to use. - force_register : bool, optional - If True, then the objective function is registered without asking - for confirmation, overwriting any previous registration. By default, - it is True. force_isolation : bool, optional If True, then the objective function is instantiated as an isolated process. @@ -301,51 +162,23 @@ def create( problem : AbstractProblem The black-box function, initial value, and related information. """ - # If the user can run it with the envionment they currently - # have, then we do not need to install it. - if name in AVAILABLE_PROBLEM_FACTORIES and not force_isolation: - if not quiet: - print(f"poli 🧪: Creating the objective {name} from the repository.") - - problem = __create_problem_from_repository( - name, - seed=seed, - batch_size=batch_size, - parallelize=parallelize, - num_workers=num_workers, - evaluation_budget=evaluation_budget, - **kwargs_for_factory, - ) - else: - # Check if the name is indeed registered, or - # available in the objective repository - __register_objective_if_available( - name, force_register=force_register, quiet=quiet - ) - - # At this point, we know the name is registered. - # Thus, we should be able to start it as an isolated process - if not quiet: - print(f"poli 🧪: Creating an isolated problem ({name}).") - problem = __create_problem_as_isolated_process( - name, - seed=seed, - batch_size=batch_size, - parallelize=parallelize, - num_workers=num_workers, - evaluation_budget=evaluation_budget, - quiet=quiet, - **kwargs_for_factory, - ) + problem = __create_problem_from_repository( + name, + seed=seed, + batch_size=batch_size, + parallelize=parallelize, + num_workers=num_workers, + evaluation_budget=evaluation_budget, + force_isolation=force_isolation, + **kwargs_for_factory, + ) + # instantiate observer (if desired) observer = _instantiate_observer(observer_name, quiet) observer_info = observer.initialize_observer( problem.black_box.info, observer_init_info, seed ) - # TODO: Should we send the y0 to the observer initialization? - # f, x0 = problem.black_box, problem.x0 - # y0 = f(x0) f = problem.black_box f.set_observer(observer) f.set_observer_info(observer_info) @@ -359,7 +192,6 @@ def start( seed: int = None, caller_info: dict = None, observer_name: str = None, - force_register: bool = False, force_isolation: bool = False, **kwargs_for_factory, ) -> AbstractBlackBox: @@ -392,9 +224,6 @@ def start( Optional information about the caller that is forwarded to the logger to initialize the run. observer_name : str, optional The observer to use. - force_register : bool, optional - If True, then the objective function is registered without asking - for confirmation, overwriting any previous registration. force_isolation : bool, optional If True, then the objective function is instantiated as an isolated process. @@ -406,9 +235,8 @@ def start( seed=seed, observer_init_info=caller_info, observer_name=observer_name, - force_register=force_register, force_isolation=force_isolation, - kwargs_for_factory=kwargs_for_factory, + **kwargs_for_factory, ) f = problem.black_box @@ -432,8 +260,7 @@ def _instantiate_observer(observer_name: str, quiet: bool = False) -> AbstractOb Returns ------- observer : AbstractObserver - The black-box function, initial value, and related information. - + The observer, either dynamically instantiated or started as an isolated process. """ if _OBSERVER not in registry.config[_DEFAULT]: registry.config[_DEFAULT][_OBSERVER] = _DEFAULT_OBSERVER_RUN_SCRIPT diff --git a/src/poli/objective_repository/__init__.py b/src/poli/objective_repository/__init__.py index b9d4e7e5..060706a1 100644 --- a/src/poli/objective_repository/__init__.py +++ b/src/poli/objective_repository/__init__.py @@ -123,6 +123,9 @@ AVAILABLE_OBJECTIVES = sorted(AVAILABLE_OBJECTIVES) +# Available problem factories +# maps names of problems to their respective +# problem factories AVAILABLE_PROBLEM_FACTORIES = { "aloha": AlohaProblemFactory, "ehrlich": EhrlichProblemFactory, @@ -215,4 +218,4 @@ def get_problems(): - return list(AVAILABLE_PROBLEM_FACTORIES.keys()) + return AVAILABLE_OBJECTIVES diff --git a/src/poli/objective_repository/albuterol_similarity/register.py b/src/poli/objective_repository/albuterol_similarity/register.py index 86ee0b50..8f0bb099 100644 --- a/src/poli/objective_repository/albuterol_similarity/register.py +++ b/src/poli/objective_repository/albuterol_similarity/register.py @@ -213,14 +213,3 @@ def create( ) return albuterol_similarity_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - AlbuterolSimilarityProblemFactory(), - name="albuterol_similarity", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/aloha/register.py b/src/poli/objective_repository/aloha/register.py index 76ca58bd..9b0f1465 100644 --- a/src/poli/objective_repository/aloha/register.py +++ b/src/poli/objective_repository/aloha/register.py @@ -175,6 +175,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """ Returns an Aloha blackbox function and initial observations. @@ -217,18 +218,3 @@ def create( ) return aloha_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - aloha_problem_factory = AlohaProblemFactory() - register_problem( - aloha_problem_factory, - conda_environment_name="poli__base", - # force=True - ) diff --git a/src/poli/objective_repository/amlodipine_mpo/register.py b/src/poli/objective_repository/amlodipine_mpo/register.py index 1b7cb425..eab1b686 100644 --- a/src/poli/objective_repository/amlodipine_mpo/register.py +++ b/src/poli/objective_repository/amlodipine_mpo/register.py @@ -208,14 +208,3 @@ def create( ) return amlodipine_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - AmlodipineMPOProblemFactory(), - name="amlodipine_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/celecoxib_rediscovery/register.py b/src/poli/objective_repository/celecoxib_rediscovery/register.py index 26735616..a8d40f5b 100644 --- a/src/poli/objective_repository/celecoxib_rediscovery/register.py +++ b/src/poli/objective_repository/celecoxib_rediscovery/register.py @@ -211,14 +211,3 @@ def create( ) return celecoxib_rediscovery_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - CelecoxibRediscoveryProblemFactory(), - name="celecoxib_rediscovery", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/deco_hop/register.py b/src/poli/objective_repository/deco_hop/register.py index 9a1e4aea..a100c328 100644 --- a/src/poli/objective_repository/deco_hop/register.py +++ b/src/poli/objective_repository/deco_hop/register.py @@ -209,14 +209,3 @@ def create( ) return deco_hop_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - DecoHopProblemFactory(), - name="deco_hop", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/dockstring/register.py b/src/poli/objective_repository/dockstring/register.py index 0980cc27..bc7cb86d 100644 --- a/src/poli/objective_repository/dockstring/register.py +++ b/src/poli/objective_repository/dockstring/register.py @@ -207,6 +207,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """Creates a dockstring black box function and initial observations. @@ -248,6 +249,7 @@ def create( parallelize=parallelize, num_workers=num_workers, evaluation_budget=evaluation_budget, + force_isolation=force_isolation, ) # Using the initial example they provide in the @@ -268,13 +270,3 @@ def create( dockstring_problem = Problem(black_box=dockstring_black_box, x0=x0) return dockstring_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - dockstring_problem_factory = DockstringProblemFactory() - register_problem( - dockstring_problem_factory, - conda_environment_name="poli__dockstring", - ) diff --git a/src/poli/objective_repository/drd2_docking/register.py b/src/poli/objective_repository/drd2_docking/register.py index 6915c54e..23962c4c 100644 --- a/src/poli/objective_repository/drd2_docking/register.py +++ b/src/poli/objective_repository/drd2_docking/register.py @@ -209,14 +209,3 @@ def create( ) return drd2_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - DRD2ProblemFactory(), - name="drd2_docking", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/drd3_docking/register.py b/src/poli/objective_repository/drd3_docking/register.py index 028264b4..e6557fc7 100644 --- a/src/poli/objective_repository/drd3_docking/register.py +++ b/src/poli/objective_repository/drd3_docking/register.py @@ -177,14 +177,3 @@ def create( ) return drd3_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - DRD3ProblemFactory(), - name="drd3_docking", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/ehrlich/register.py b/src/poli/objective_repository/ehrlich/register.py index 79d418dd..21f6195e 100644 --- a/src/poli/objective_repository/ehrlich/register.py +++ b/src/poli/objective_repository/ehrlich/register.py @@ -385,6 +385,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """ Creates an Ehrlich function problem (containing an Ehrlich black box and diff --git a/src/poli/objective_repository/fexofenadine_mpo/register.py b/src/poli/objective_repository/fexofenadine_mpo/register.py index c729c40a..5cf09978 100644 --- a/src/poli/objective_repository/fexofenadine_mpo/register.py +++ b/src/poli/objective_repository/fexofenadine_mpo/register.py @@ -206,14 +206,3 @@ def create( ) return fexofenadine_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - FexofenadineMPOProblemFactory(), - name="fexofenadine_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/foldx_rfp_lambo/register.py b/src/poli/objective_repository/foldx_rfp_lambo/register.py index cdae6474..4dc011c5 100644 --- a/src/poli/objective_repository/foldx_rfp_lambo/register.py +++ b/src/poli/objective_repository/foldx_rfp_lambo/register.py @@ -104,14 +104,3 @@ def create( x0 = black_box.inner_function.x0 return Problem(black_box, x0) - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - rfp_problem_factory = FoldXRFPLamboProblemFactory() - register_problem( - rfp_problem_factory, - conda_environment_name="poli__lambo", - force=True, - ) diff --git a/src/poli/objective_repository/foldx_sasa/register.py b/src/poli/objective_repository/foldx_sasa/register.py index 72e8582e..b6df5b6b 100644 --- a/src/poli/objective_repository/foldx_sasa/register.py +++ b/src/poli/objective_repository/foldx_sasa/register.py @@ -287,13 +287,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - foldx_problem_factory = FoldXSASAProblemFactory() - register_problem( - foldx_problem_factory, - conda_environment_name="poli__protein", - ) diff --git a/src/poli/objective_repository/foldx_stability/register.py b/src/poli/objective_repository/foldx_stability/register.py index 4194e404..fe1af98e 100644 --- a/src/poli/objective_repository/foldx_stability/register.py +++ b/src/poli/objective_repository/foldx_stability/register.py @@ -277,13 +277,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - foldx_problem_factory = FoldXStabilityProblemFactory() - register_problem( - foldx_problem_factory, - conda_environment_name="poli__protein", - ) diff --git a/src/poli/objective_repository/foldx_stability_and_sasa/register.py b/src/poli/objective_repository/foldx_stability_and_sasa/register.py index 5efe0d39..d0d5aa2d 100644 --- a/src/poli/objective_repository/foldx_stability_and_sasa/register.py +++ b/src/poli/objective_repository/foldx_stability_and_sasa/register.py @@ -291,13 +291,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - foldx_problem_factory = FoldXStabilityAndSASAProblemFactory() - register_problem( - foldx_problem_factory, - conda_environment_name="poli__protein", - ) diff --git a/src/poli/objective_repository/gfp_cbas/register.py b/src/poli/objective_repository/gfp_cbas/register.py index 30239ba3..ca9d4cf5 100644 --- a/src/poli/objective_repository/gfp_cbas/register.py +++ b/src/poli/objective_repository/gfp_cbas/register.py @@ -148,28 +148,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - gfp_problem_factory = GFPCBasProblemFactory() - register_problem( - gfp_problem_factory, - conda_environment_name="poli__protein_cbas", - ) - # NOTE: default problem is GP problem - gfp_problem_factory.create(seed=12) - # instantiate different types of CBas problems: - gfp_problem_factory_vae = GFPCBasProblemFactory(problem_type="vae") - register_problem( - gfp_problem_factory_vae, - conda_environment_name="poli__protein_cbas", - ) - gfp_problem_factory_vae.create(seed=12, problem_type="vae") - gfp_problem_factory_elbo = GFPCBasProblemFactory(problem_type="elbo") - register_problem( - gfp_problem_factory_elbo, - conda_environment_name="poli__protein_cbas", - ) - gfp_problem_factory_elbo.create(seed=12, problem_type="elbo") diff --git a/src/poli/objective_repository/gfp_select/register.py b/src/poli/objective_repository/gfp_select/register.py index 7bd51a35..7c77de37 100644 --- a/src/poli/objective_repository/gfp_select/register.py +++ b/src/poli/objective_repository/gfp_select/register.py @@ -89,13 +89,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - gfp_problem_factory = GFPSelectionProblemFactory() - register_problem( - gfp_problem_factory, - conda_environment_name="poli__protein_cbas", - ) diff --git a/src/poli/objective_repository/gsk3_beta/register.py b/src/poli/objective_repository/gsk3_beta/register.py index 3c9260e6..373c286f 100644 --- a/src/poli/objective_repository/gsk3_beta/register.py +++ b/src/poli/objective_repository/gsk3_beta/register.py @@ -226,14 +226,3 @@ def create( ) return gsk3_beta_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - GSK3BetaProblemFactory(), - name="gs3_beta", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/isomer_c7h8n2o2/register.py b/src/poli/objective_repository/isomer_c7h8n2o2/register.py index 87a187ec..bbc26469 100644 --- a/src/poli/objective_repository/isomer_c7h8n2o2/register.py +++ b/src/poli/objective_repository/isomer_c7h8n2o2/register.py @@ -206,14 +206,3 @@ def create( ) return isomer_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - IsomerC7H8N2O2ProblemFactory(), - name="isomer_c7h8n2o2", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/isomer_c9h10n2o2pf2cl/register.py b/src/poli/objective_repository/isomer_c9h10n2o2pf2cl/register.py index de754851..a23c1974 100644 --- a/src/poli/objective_repository/isomer_c9h10n2o2pf2cl/register.py +++ b/src/poli/objective_repository/isomer_c9h10n2o2pf2cl/register.py @@ -211,14 +211,3 @@ def create( ) return isomer_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - IsomerC9H10N2O2PF2ClProblemFactory(), - name="isomer_c9h10n2o2pf2cl", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/jnk3/register.py b/src/poli/objective_repository/jnk3/register.py index eef6317a..4f815dec 100644 --- a/src/poli/objective_repository/jnk3/register.py +++ b/src/poli/objective_repository/jnk3/register.py @@ -222,14 +222,3 @@ def create( ) return jnk3_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - JNK3ProblemFactory(), - name="jnk3", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/median_1/register.py b/src/poli/objective_repository/median_1/register.py index 9bdca95f..89c9b606 100644 --- a/src/poli/objective_repository/median_1/register.py +++ b/src/poli/objective_repository/median_1/register.py @@ -205,14 +205,3 @@ def create( ) return median_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - Median1ProblemFactory(), - name="median_1", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/median_2/register.py b/src/poli/objective_repository/median_2/register.py index 2e33d5a3..0ae9a932 100644 --- a/src/poli/objective_repository/median_2/register.py +++ b/src/poli/objective_repository/median_2/register.py @@ -204,14 +204,3 @@ def create( ) return median_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - Median2ProblemFactory(), - name="median_2", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/mestranol_similarity/register.py b/src/poli/objective_repository/mestranol_similarity/register.py index 48212d0e..e421cf37 100644 --- a/src/poli/objective_repository/mestranol_similarity/register.py +++ b/src/poli/objective_repository/mestranol_similarity/register.py @@ -211,14 +211,3 @@ def create( ) return mestranol_similarity_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - MestranolSimilarityProblemFactory(), - name="mestranol_similarity", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/osimetrinib_mpo/register.py b/src/poli/objective_repository/osimetrinib_mpo/register.py index 35dda2e2..1365779f 100644 --- a/src/poli/objective_repository/osimetrinib_mpo/register.py +++ b/src/poli/objective_repository/osimetrinib_mpo/register.py @@ -205,14 +205,3 @@ def create( ) return osimetrinib_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - OsimetrinibMPOProblemFactory(), - name="osimetrinib_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/penalized_logp_lambo/register.py b/src/poli/objective_repository/penalized_logp_lambo/register.py index 9505cfb0..d5dd5fa4 100644 --- a/src/poli/objective_repository/penalized_logp_lambo/register.py +++ b/src/poli/objective_repository/penalized_logp_lambo/register.py @@ -140,12 +140,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - PenalizedLogPLamboProblemFactory(), - conda_environment_name="poli__lambo", - ) diff --git a/src/poli/objective_repository/perindopril_mpo/register.py b/src/poli/objective_repository/perindopril_mpo/register.py index db61fe85..71882dd7 100644 --- a/src/poli/objective_repository/perindopril_mpo/register.py +++ b/src/poli/objective_repository/perindopril_mpo/register.py @@ -204,14 +204,3 @@ def create( ) return perindopril_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - PerindoprilMPOProblemFactory(), - name="perindopril_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/ranolazine_mpo/register.py b/src/poli/objective_repository/ranolazine_mpo/register.py index 9144861b..6dec57e0 100644 --- a/src/poli/objective_repository/ranolazine_mpo/register.py +++ b/src/poli/objective_repository/ranolazine_mpo/register.py @@ -205,14 +205,3 @@ def create( ) return ranolazine_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - RanolazineMPOProblemFactory(), - name="ranolazine_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/rasp/register.py b/src/poli/objective_repository/rasp/register.py index ceac32e2..3acf212a 100644 --- a/src/poli/objective_repository/rasp/register.py +++ b/src/poli/objective_repository/rasp/register.py @@ -287,14 +287,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - rasp_problem_factory = RaspProblemFactory() - register_problem( - rasp_problem_factory, - conda_environment_name="poli__rasp", - force=True, - ) diff --git a/src/poli/objective_repository/rdkit_logp/register.py b/src/poli/objective_repository/rdkit_logp/register.py index c923448c..e67508e6 100644 --- a/src/poli/objective_repository/rdkit_logp/register.py +++ b/src/poli/objective_repository/rdkit_logp/register.py @@ -167,6 +167,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """Creates a logP problem instance. @@ -217,18 +218,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - logp_problem_factory = LogPProblemFactory() - register_problem( - logp_problem_factory, - conda_environment_name="poli__chem", - # force=True, - ) diff --git a/src/poli/objective_repository/rdkit_qed/register.py b/src/poli/objective_repository/rdkit_qed/register.py index 33e3bedb..4519166f 100644 --- a/src/poli/objective_repository/rdkit_qed/register.py +++ b/src/poli/objective_repository/rdkit_qed/register.py @@ -197,6 +197,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """Creates a QED black box function and initial observations. @@ -245,18 +246,3 @@ def create( x0 = np.array([["[C]"]]) return Problem(f, x0) - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - qed_problem_factory = QEDProblemFactory() - register_problem( - qed_problem_factory, - conda_environment_name="poli__chem", - # force=True, - ) diff --git a/src/poli/objective_repository/rfp_foldx_stability_and_sasa/register.py b/src/poli/objective_repository/rfp_foldx_stability_and_sasa/register.py index 9b1ff5a9..4044152c 100644 --- a/src/poli/objective_repository/rfp_foldx_stability_and_sasa/register.py +++ b/src/poli/objective_repository/rfp_foldx_stability_and_sasa/register.py @@ -230,13 +230,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - rfp_foldx_problem_factory = RFPFoldXStabilityAndSASAProblemFactory() - register_problem( - rfp_foldx_problem_factory, - conda_environment_name="poli__protein", - ) diff --git a/src/poli/objective_repository/rmf_landscape/register.py b/src/poli/objective_repository/rmf_landscape/register.py index 8add28d4..08944abf 100644 --- a/src/poli/objective_repository/rmf_landscape/register.py +++ b/src/poli/objective_repository/rmf_landscape/register.py @@ -242,13 +242,3 @@ def create( x0 = np.array(wildtype).reshape(1, len(wildtype)) problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - rmf_problem_factory = RMFProblemFactory() - register_problem( - rmf_problem_factory, - conda_environment_name="poli__rmf", - ) diff --git a/src/poli/objective_repository/sa_tdc/register.py b/src/poli/objective_repository/sa_tdc/register.py index 7ed82a39..52a7715a 100644 --- a/src/poli/objective_repository/sa_tdc/register.py +++ b/src/poli/objective_repository/sa_tdc/register.py @@ -175,13 +175,3 @@ def create( x0=x0, ) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - SAProblemFactory(), - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/scaffold_hop/register.py b/src/poli/objective_repository/scaffold_hop/register.py index e2e25f34..bca24aa1 100644 --- a/src/poli/objective_repository/scaffold_hop/register.py +++ b/src/poli/objective_repository/scaffold_hop/register.py @@ -205,14 +205,3 @@ def create( ) return scaffold_hop_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - ScaffoldHopProblemFactory(), - name="scaffold_hop", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/sitagliptin_mpo/register.py b/src/poli/objective_repository/sitagliptin_mpo/register.py index a4eda1bc..bf688ae1 100644 --- a/src/poli/objective_repository/sitagliptin_mpo/register.py +++ b/src/poli/objective_repository/sitagliptin_mpo/register.py @@ -204,14 +204,3 @@ def create( ) return sitagliptin_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - SitagliptinMPOProblemFactory(), - name="sitagliptin_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/super_mario_bros/register.py b/src/poli/objective_repository/super_mario_bros/register.py index ae3a4bd8..f7e1a060 100644 --- a/src/poli/objective_repository/super_mario_bros/register.py +++ b/src/poli/objective_repository/super_mario_bros/register.py @@ -197,14 +197,3 @@ def create( problem = Problem(f, x0) return problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # (once) we have to register our factory - smb_problem_factory = SuperMarioBrosProblemFactory() - register_problem( - smb_problem_factory, - conda_environment_name="poli__mario", - ) diff --git a/src/poli/objective_repository/thiothixene_rediscovery/register.py b/src/poli/objective_repository/thiothixene_rediscovery/register.py index b820d4e3..0f89bdaf 100644 --- a/src/poli/objective_repository/thiothixene_rediscovery/register.py +++ b/src/poli/objective_repository/thiothixene_rediscovery/register.py @@ -208,14 +208,3 @@ def create( ) return thiothixene_rediscovery_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - ThiothixeneRediscoveryProblemFactory(), - name="thiothixene_rediscovery", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/toy_continuous_problem/register.py b/src/poli/objective_repository/toy_continuous_problem/register.py index 39e4e3b8..c85916c5 100644 --- a/src/poli/objective_repository/toy_continuous_problem/register.py +++ b/src/poli/objective_repository/toy_continuous_problem/register.py @@ -161,6 +161,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """ Creates a new instance of the toy continuous problem. @@ -217,18 +218,3 @@ def create( x0 = f.function.x0 return Problem(f, x0) - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - toy_continuous_problem_factory = ToyContinuousProblemFactory() - register_problem( - toy_continuous_problem_factory, - conda_environment_name="poli__base", - # force=True - ) diff --git a/src/poli/objective_repository/troglitazone_rediscovery/register.py b/src/poli/objective_repository/troglitazone_rediscovery/register.py index e44519ca..b8180e06 100644 --- a/src/poli/objective_repository/troglitazone_rediscovery/register.py +++ b/src/poli/objective_repository/troglitazone_rediscovery/register.py @@ -208,14 +208,3 @@ def create( ) return troglitazone_rediscovery_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - TroglitazoneRediscoveryProblemFactory(), - name="troglitazone_rediscovery", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/valsartan_smarts/register.py b/src/poli/objective_repository/valsartan_smarts/register.py index 01bd49cb..cfe93171 100644 --- a/src/poli/objective_repository/valsartan_smarts/register.py +++ b/src/poli/objective_repository/valsartan_smarts/register.py @@ -205,14 +205,3 @@ def create( ) return valsartan_smarts_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - ValsartanSMARTSProblemFactory(), - name="valsartan_smarts", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/objective_repository/white_noise/register.py b/src/poli/objective_repository/white_noise/register.py index 3efcd2ab..0d32cb4d 100644 --- a/src/poli/objective_repository/white_noise/register.py +++ b/src/poli/objective_repository/white_noise/register.py @@ -134,6 +134,7 @@ def create( parallelize: bool = False, num_workers: int = None, evaluation_budget: int = float("inf"), + force_isolation: bool = False, ) -> Problem: """ Create a white noise problem with the specified parameters. @@ -171,18 +172,3 @@ def create( white_noise_problem = Problem(black_box=f, x0=x0) return white_noise_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - # Once we have created a simple conda enviroment - # (see the environment.yml file in this folder), - # we can register our problem s.t. it uses - # said conda environment. - white_noise_problem_factory = WhiteNoiseProblemFactory() - register_problem( - white_noise_problem_factory, - conda_environment_name="poli__base", - force=True, - ) diff --git a/src/poli/objective_repository/zaleplon_mpo/register.py b/src/poli/objective_repository/zaleplon_mpo/register.py index d51526e3..4e3f66c7 100644 --- a/src/poli/objective_repository/zaleplon_mpo/register.py +++ b/src/poli/objective_repository/zaleplon_mpo/register.py @@ -205,14 +205,3 @@ def create( ) return zaleplon_mpo_problem - - -if __name__ == "__main__": - from poli.core.registry import register_problem - - register_problem( - ZaleplonMPOProblemFactory(), - name="zaleplon_mpo", - conda_environment_name="poli__tdc", - force=True, - ) diff --git a/src/poli/registered_objectives/__init__.py b/src/poli/registered_objectives/__init__.py deleted file mode 100644 index 8b137891..00000000 --- a/src/poli/registered_objectives/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/poli/tests/parallelization/test_parallelization.py b/src/poli/tests/parallelization/test_parallelization.py index 14280c79..50783ec3 100644 --- a/src/poli/tests/parallelization/test_parallelization.py +++ b/src/poli/tests/parallelization/test_parallelization.py @@ -35,7 +35,6 @@ def test_parallelization_in_qed(): num_workers=NUM_WORKERS, batch_size=4, string_representation="SMILES", - force_register=True, ) f = problem.black_box @@ -68,7 +67,6 @@ def test_parallelization_in_foldx_stability_and_sasa(): parallelize=True, num_workers=NUM_WORKERS, batch_size=3, - force_register=True, ) f, x0 = problem.black_box, problem.x0 diff --git a/src/poli/tests/registry/chemistry/test_chemistry_objectives.py b/src/poli/tests/registry/chemistry/test_chemistry_objectives.py index c861f3a2..dc6eeda6 100644 --- a/src/poli/tests/registry/chemistry/test_chemistry_objectives.py +++ b/src/poli/tests/registry/chemistry/test_chemistry_objectives.py @@ -35,38 +35,6 @@ SEED = np.random.randint(0, 1000) -def test_force_registering_qed(): - """ - We test whether we can force-register the qed problem - if rdkit and selfies are not installed. - """ - problem = objective_factory.create( - name="rdkit_qed", - force_register=True, - ) - f, x0 = problem.black_box, problem.x0 - y0 = f(x0) - - # Asserting that the QED of a single carbon - # is close to 0.35978494 (according to RDKit). - assert np.isclose(y0, 0.35978494).all() - f.terminate() - - -def test_force_registering_qed_with_context_manager(): - """ - Tests the objective_factory.start method on QED. - """ - with objective_factory.start( - name="rdkit_qed", - force_register=True, - force_isolation=True, - ) as f: - x = np.array([["C"]]) - y = f(x) - assert np.isclose(y, 0.35978494).all() - - @pytest.mark.poli__lambo def test_penalized_logp_lambo(): """ @@ -90,7 +58,6 @@ def test_querying_dockstring_using_smiles(): name="dockstring", target_name="DRD2", string_representation="SMILES", - force_register=True, ) f = problem.black_box @@ -112,7 +79,6 @@ def test_querying_dockstring_using_selfies(): name="dockstring", target_name="ABL1", string_representation="SELFIES", - force_register=True, ) f = problem.black_box diff --git a/src/poli/tests/registry/proteins/test_rasp.py b/src/poli/tests/registry/proteins/test_rasp.py index aec5edce..da1d595f 100644 --- a/src/poli/tests/registry/proteins/test_rasp.py +++ b/src/poli/tests/registry/proteins/test_rasp.py @@ -53,7 +53,6 @@ def test_rasp_on_3ned_against_notebooks_results_isolated(): problem = objective_factory.create( name="rasp", wildtype_pdb_path=THIS_DIR / "3ned.pdb", - force_register=True, ) f, x0 = problem.black_box, problem.x0 diff --git a/src/poli/tests/registry/test_force_isolation.py b/src/poli/tests/registry/test_force_isolation.py index 8764e67d..ad905135 100644 --- a/src/poli/tests/registry/test_force_isolation.py +++ b/src/poli/tests/registry/test_force_isolation.py @@ -1,14 +1,39 @@ """This module tests whether forcing the isolation of black -box objectives indeed spawns an isolated process.""" +box objectives (i) creates the relevant conda environment, and +(ii) writes the isolated function script in the config, +(iii) getting the inner function works as expected.""" +import subprocess -def test_force_isolation_on_aloha(): +from poli.core.util.isolation.instancing import get_inner_function + + +def test_force_isolation_on_tdc(): from poli import objective_factory problem = objective_factory.create( - name="aloha", - force_register=True, + name="deco_hop", force_isolation=True, ) - assert isinstance(problem.black_box, objective_factory.ExternalBlackBox) + # After creating the problem, we check that: + # (i) creates the relevant conda environment + assert "poli__tdc" in subprocess.check_output("conda env list".split()).decode() + + # (ii) writes the isolated function script in the config + from poli.objective_factory import load_config + + config = load_config() + assert config["tdc__isolated"] + + # (iii) we can call the inner function + inner_f = get_inner_function( + isolated_function_name="tdc__isolated", + class_name="TDCIsolatedLogic", + module_to_import="poli.core.chemistry.tdc_isolated_function", + force_isolation=True, + oracle_name="deco_hop", + from_smiles=True, + quiet=True, + ) + assert (problem.black_box(problem.x0) == inner_f(problem.x0)).all()