Skip to content

Commit

Permalink
Merge pull request #297 from bouthilx/feature/refactored_exp_configur…
Browse files Browse the repository at this point in the history
…ation

 Refactor experiment builder
  • Loading branch information
bouthilx authored Oct 16, 2019
2 parents bef9cd5 + d9c6876 commit 8d7e124
Show file tree
Hide file tree
Showing 49 changed files with 2,283 additions and 2,244 deletions.
1 change: 0 additions & 1 deletion docs/src/code/core/io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ Input/Output
io/resolve_config
io/experiment_builder
io/experiment_branch_builder
io/evc_builder
io/interactive_commands
5 changes: 0 additions & 5 deletions docs/src/code/core/io/evc_builder.rst

This file was deleted.

15 changes: 6 additions & 9 deletions src/orion/client/manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
and link them with a particular existing experiment.
"""
from orion.core.io.experiment_builder import ExperimentBuilder
import orion.core.io.experiment_builder as experiment_builder
from orion.core.utils import format_trials


def insert_trials(experiment_name, points, cmdconfig=None, raise_exc=True):
def insert_trials(experiment_name, points, raise_exc=True):
"""Insert sets of parameters manually, defined in `points`, as new trials
for the experiment name, `experiment_name`.
Expand All @@ -31,15 +31,10 @@ def insert_trials(experiment_name, points, cmdconfig=None, raise_exc=True):
the database.
"""
cmdconfig = cmdconfig if cmdconfig else {}
cmdconfig['name'] = experiment_name

experiment_view = ExperimentBuilder().build_view_from({'config': cmdconfig})
experiment_view = experiment_builder.build_view(name=experiment_name)

valid_points = []

print(experiment_view.space)

for point in points:
try:
assert point in experiment_view.space
Expand All @@ -55,5 +50,7 @@ def insert_trials(experiment_name, points, cmdconfig=None, raise_exc=True):
map(lambda data: format_trials.tuple_to_trial(data, experiment_view.space),
valid_points))

experiment = experiment_builder.build(name=experiment_view.name,
version=experiment_view.version)
for new_trial in new_trials:
ExperimentBuilder().build_from(experiment_view.configuration).register_trial(new_trial)
experiment.register_trial(new_trial)
64 changes: 63 additions & 1 deletion src/orion/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,31 @@
def define_config():
"""Create and define the fields of the configuration object."""
config = Configuration()
define_database_config(config)
define_storage_config(config)
define_experiment_config(config)
define_worker_config(config)
define_evc_config(config)

config.add_option(
'user_script_config', option_type=str, default='config')

return config


def define_storage_config(config):
"""Create and define the fields of the storage configuration."""
storage_config = Configuration()

storage_config.add_option(
'type', option_type=str, default='legacy', env_var='ORION_STORAGE_TYPE')

config.storage = storage_config

define_database_config(config.storage)
# Backward compatibility, should be removed in v0.2.0
define_database_config(config)


def define_database_config(config):
"""Create and define the fields of the database configuration."""
database_config = Configuration()
Expand All @@ -81,6 +97,32 @@ def define_database_config(config):
config.database = database_config


def define_experiment_config(config):
"""Create and define the fields of generic experiment configuration."""
experiment_config = Configuration()

experiment_config.add_option(
'pool_size', option_type=int, default=1)

experiment_config.add_option(
'max_trials', option_type=int, default=int(10e8))

experiment_config.add_option(
'worker_trials', option_type=int, default=int(10e8))

experiment_config.add_option(
'working_dir', option_type=str, default='')

experiment_config.add_option(
'algorithms', option_type=dict, default={'random': {'seed': None}})

experiment_config.producer = Configuration()
experiment_config.producer.add_option(
'strategy', option_type=dict, default={'MaxParallelStrategy': {}})

config.experiment = experiment_config


def define_worker_config(config):
"""Create and define the fields of the worker configuration."""
worker_config = Configuration()
Expand All @@ -95,6 +137,26 @@ def define_worker_config(config):
config.worker = worker_config


def define_evc_config(config):
"""Create and define the fields of the evc configuration."""
evc_config = Configuration()

evc_config.add_option(
'auto_resolution', option_type=bool, default=True)
evc_config.add_option(
'manual_resolution', option_type=bool, default=False)
evc_config.add_option(
'algorithm_change', option_type=bool, default=False)
evc_config.add_option(
'code_change_type', option_type=str, default='break')
evc_config.add_option(
'cli_change_type', option_type=str, default='break')
evc_config.add_option(
'config_change_type', option_type=str, default='break')

config.evc = evc_config


def build_config():
"""Define the config and fill it based on global configuration files."""
config = define_config()
Expand Down
4 changes: 1 addition & 3 deletions src/orion/core/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ def main(argv=None):

load_modules_parser(orion_parser)

orion_parser.execute(argv)

return 0
return orion_parser.execute(argv)


if __name__ == "__main__":
Expand Down
4 changes: 4 additions & 0 deletions src/orion/core/cli/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,12 @@ def execute(self, argv):
function(args)
except NoConfigurationError:
print("Error: No commandline configuration found for new experiment.")
return 1
except DatabaseError as e:
print(e)
return 1

return 0


def get_basic_args_group(parser):
Expand Down
46 changes: 14 additions & 32 deletions src/orion/core/cli/checks/presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,67 +10,49 @@
"""

import orion.core
import orion.core.io.experiment_builder as experiment_builder
import orion.core.utils.backward as backward


class PresenceStage:
"""The presence stage of the checks."""

def __init__(self, experiment_builder, cmdargs):
"""Create an instance of the stage.
Parameters
----------
experiment_builder: `ExperimentBuilder`
An instance of `ExperimentBuilder` to fetch configs.
"""
self.builder = experiment_builder
def __init__(self, cmdargs):
"""Create an instance of the stage."""
self.cmdargs = cmdargs
self.db_config = {}

def checks(self):
"""Return the registered checks."""
yield self.check_default_config
yield self.check_environment_vars
yield self.check_configuration_file

def check_default_config(self):
"""Check for a configuration inside the default paths."""
config = self.builder.fetch_default_options()

if 'database' not in config:
return "Skipping", "No default configuration found for database."

self.db_config = config['database']
print('\n ', self.db_config)
config = orion.core.config.to_dict()

return "Success", ""

def check_environment_vars(self):
"""Check for a configuration inside the environment variables."""
config = self.builder.fetch_env_vars()

config = config['database']
names = ['type', 'name', 'host', 'port']
backward.update_db_config(config)

if not any(name in config for name in names):
return "Skipping", "No environment variables found."
if 'database' not in config.get('storage', {}):
return "Skipping", "No default configuration found for database."

self.db_config.update(config)
self.db_config = config['storage']['database']
print('\n ', self.db_config)

return "Success", ""

def check_configuration_file(self):
"""Check if configuration file has valid database configuration."""
config = self.builder.fetch_file_config(self.cmdargs)
config = experiment_builder.get_cmd_config(self.cmdargs)

if not len(config):
return "Skipping", "Missing configuration file."

if 'database' not in config:
if 'database' not in config.get('storage', {}):
return "Skipping", "No database found in configuration file."

config = config['database']
config = config['storage']['database']
names = ['type', 'name', 'host', 'port']

if not any(name in config for name in names):
Expand Down
4 changes: 1 addition & 3 deletions src/orion/core/cli/db/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from orion.core.cli.checks.creation import CreationStage
from orion.core.cli.checks.operations import OperationsStage
from orion.core.cli.checks.presence import PresenceStage
from orion.core.io.experiment_builder import ExperimentBuilder
from orion.core.utils.exceptions import CheckError

log = logging.getLogger(__name__)
Expand All @@ -36,8 +35,7 @@ def add_subparser(parser):

def main(args):
"""Run through all checks for database."""
experiment_builder = ExperimentBuilder()
presence_stage = PresenceStage(experiment_builder, args)
presence_stage = PresenceStage(args)
creation_stage = CreationStage(presence_stage)
operations_stage = OperationsStage(creation_stage)
stages = [presence_stage, creation_stage, operations_stage]
Expand Down
14 changes: 9 additions & 5 deletions src/orion/core/cli/db/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from orion.core.io.database.ephemeraldb import EphemeralCollection
from orion.core.io.database.mongodb import MongoDB
from orion.core.io.database.pickleddb import PickledDB
from orion.core.io.experiment_builder import ExperimentBuilder
import orion.core.io.experiment_builder as experiment_builder
import orion.core.utils.backward as backward
from orion.storage.base import get_storage
from orion.storage.legacy import Legacy
Expand Down Expand Up @@ -82,11 +82,15 @@ def main(args):
if action in ['no', 'n']:
sys.exit(0)

experiment_builder = ExperimentBuilder()
local_config = experiment_builder.fetch_full_config(args, use_db=False)
local_config['protocol'] = {'type': 'legacy', 'setup': False}
config = experiment_builder.get_cmd_config(args)
storage_config = config.get('storage')

experiment_builder.setup_storage(local_config)
if storage_config is None:
storage_config = {'type': 'legacy'}

storage_config['setup'] = False

experiment_builder.setup_storage(storage_config)

storage = get_storage()

Expand Down
12 changes: 10 additions & 2 deletions src/orion/core/cli/evc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def _add_manual_resolution_argument(parser):
help="Manually resolve conflicts")


def _add_branch_from_argument(parser):
parser.add_argument(
"--branch-from", type=str,
help="Create a new child based on experiment defined by `branch-from`")


def _add_algorithm_argument(parser, resolution_class):
parser.add_argument(
resolution_class.ARGUMENT,
Expand Down Expand Up @@ -54,7 +60,7 @@ def _add_config_argument(parser, resolution_class):
help="Set configuration change type")


def _add_branching_argument(parser, resolution_class):
def _add_branch_to_argument(parser, resolution_class):
parser.add_argument(
'-b', resolution_class.ARGUMENT, metavar='stringID',
help='Unique name for the new branching experiment')
Expand All @@ -67,7 +73,8 @@ def _add_branching_argument(parser, resolution_class):
'code_change_type': _add_code_argument,
'cli_change_type': _add_cli_argument,
'config_change_type': _add_config_argument,
'branch': _add_branching_argument}
'branch_from': _add_branch_from_argument,
'branch_to': _add_branch_to_argument}


UNDEFINED_PARSER_ERROR = (
Expand All @@ -83,6 +90,7 @@ def get_branching_args_group(parser):

_add_manual_resolution_argument(branching_args_group)
_add_auto_resolution_argument(branching_args_group)
_add_branch_from_argument(branching_args_group)

for resolution_class in sorted(Resolution.__subclasses__(), key=lambda cls: cls.__name__):
if not resolution_class.ARGUMENT:
Expand Down
9 changes: 5 additions & 4 deletions src/orion/core/cli/hunt.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

import logging

import orion.core
from orion.core.cli import base as cli
from orion.core.cli import evc as evc_cli
from orion.core.io import resolve_config
from orion.core.io.evc_builder import EVCBuilder
from orion.core.io.experiment_builder import ExperimentBuilder
import orion.core.io.experiment_builder as experiment_builder
from orion.core.worker import workon

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -70,6 +70,7 @@ def main(args):
args['root'] = None
args['leafs'] = []
# TODO: simplify when parameter parsing is refactored
worker_trials = ExperimentBuilder().fetch_full_config(args)['worker_trials']
experiment = EVCBuilder().build_from(args)
experiment = experiment_builder.build_from_args(args)
config = experiment_builder.get_cmd_config(args)
worker_trials = config.get('worker_trials', orion.core.config.experiment.worker_trials)
workon(experiment, worker_trials)
13 changes: 2 additions & 11 deletions src/orion/core/cli/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import sys

from orion.core.cli.base import get_basic_args_group
from orion.core.io.evc_builder import EVCBuilder
import orion.core.io.experiment_builder as experiment_builder

log = logging.getLogger(__name__)

Expand All @@ -28,23 +28,14 @@ def add_subparser(parser):
return info_parser


# pylint: disable=protected-access
def hack_until_config_is_refactored(experiment):
"""Build the space and the algorithm"""
experiment._experiment._instantiate_config(experiment.configuration)
experiment._experiment._init_done = True


def main(args):
"""Fetch config and info experiments"""
try:
experiment = EVCBuilder().build_view_from(args)
experiment = experiment_builder.build_view_from_args(args)
except ValueError:
print('Experiment {} not found in db.'.format(args.get('name', None)))
sys.exit(1)

hack_until_config_is_refactored(experiment)

print(format_info(experiment))


Expand Down
Loading

0 comments on commit 8d7e124

Please sign in to comment.