Experiments#

Adding simulations to an existing experiment#

import os

from idmtools.builders import SimulationBuilder
from idmtools.core.platform_factory import Platform
from idmtools.entities.experiment import Experiment
from idmtools.entities.templated_simulation import TemplatedSimulations
from idmtools_models.python.json_python_task import JSONConfiguredPythonTask

# load up an existing experiment with completed simulations
with Platform('Calculon', node_group="idm_48cores", priority="Highest"):
    # Create First Experiment
    builder = SimulationBuilder()
    builder.add_sweep_definition(JSONConfiguredPythonTask.set_parameter_partial("a"),
                                 [i * i for i in range(5)])
    model_path = os.path.join("..", "..", "python_model", "inputs", "python_model_with_deps", "Assets", "model.py")
    sims_template = TemplatedSimulations(base_task=JSONConfiguredPythonTask(script_path=model_path))
    sims_template.add_builder(builder=builder)

    experiment = Experiment.from_template(sims_template)
    experiment.run(wait_until_done=True)

    # You could start with experiment = Experiment.from_id(....)
    # create a new sweep for new simulations
    sims_template = TemplatedSimulations(base_task=JSONConfiguredPythonTask(script_path=model_path))
    builder = SimulationBuilder()
    builder.add_sweep_definition(JSONConfiguredPythonTask.set_parameter_partial("a"),
                                 [i * i for i in range(6, 10)])
    sims_template.add_builder(builder=builder)
    experiment.simulations.extend(sims_template)

    # If you are adding a large amount of simulations through a Template, it is recommended to do the following to keep generator use and lower memory footprint
    #
    # sims_template.add_simulations(experiment.simulations)
    # experiment.simulations = simulations

    # run all simulations in the experiment that have not run before and wait
    experiment.run(wait_until_done=True)

Adding simulations to an existing experiment with new common assets#

import os

from idmtools.builders import SimulationBuilder
from idmtools.core.platform_factory import Platform
from idmtools.entities.experiment import Experiment
from idmtools.entities.templated_simulation import TemplatedSimulations
from idmtools_models.python.json_python_task import JSONConfiguredPythonTask

# load up an existing experiment with completed simulations
with Platform('CALCULON'):
    # Create First Experiment
    builder = SimulationBuilder()
    builder.add_sweep_definition(JSONConfiguredPythonTask.set_parameter_partial("a"),
                                 [i for i in range(5)])
    model_path = os.path.join("..", "..", "python_model", "inputs", "python_model_with_deps", "Assets", "model.py")
    sims_template = TemplatedSimulations(base_task=JSONConfiguredPythonTask(script_path=model_path))
    sims_template.add_builder(builder=builder)

    experiment = Experiment.from_template(sims_template)
    experiment.run(wait_until_done=True)

    # IMPORTANT NOTE:
    # Currently it is important you wait on existing Simulations to finish provision when changing assets later
    # idmtools cannot detect this state at the moment and it can leave to unexpected behaviour


    # You could start with experiment = Experiment.from_id(...., copy_assets=True)
    # Changing the Common Assets
    experiment.assets = experiment.assets.copy()
    # Add new simulations to the experiment
    model_path = os.path.join("..", "..", "python_model", "inputs", "python_model_with_deps", "Assets", "newmodel2.py")
    sims_template = TemplatedSimulations(base_task=JSONConfiguredPythonTask(script_path=model_path))
    builder = SimulationBuilder()
    builder.add_sweep_definition(JSONConfiguredPythonTask.set_parameter_partial("a"),
                                 [i for i in range(6, 10)])
    sims_template.add_builder(builder=builder)
    experiment.simulations.extend(sims_template)

    # If you are adding a large amount of simulations through a Template, it is recommended to do the following to keep generator use and lower memory footprint
    #
    # sims_template.add_simulations(experiment.simulations)
    # experiment.simulations = simulations

    # run all simulations in the experiment that have not run before and wait
    experiment.run(wait_until_done=True, regather_common_assets=True)

Creating experiments with one simulation#

When you want to run a single simulation instead of a set, you can create an experiment directly from a task.

from idmtools.core.platform_factory import Platform
from idmtools.entities.command_task import CommandTask
from idmtools.entities.experiment import Experiment

platform = Platform('CALCULON')
task = CommandTask(command="python --version")
experiment = Experiment.from_task(task=task, name="Example of experiment from task")
experiment.run(wait_until_done=True)

Creating an experiment with a pre- and post- creation hook#

Prior to running an experiment or a work item, you can add pre or post creation hooks to the item.

import os
import sys
import typing
from idmtools.builders import SimulationBuilder
from idmtools.core.platform_factory import Platform
from idmtools.entities.experiment import Experiment
from idmtools.entities.templated_simulation import TemplatedSimulations
from idmtools_models.python.json_python_task import JSONConfiguredPythonTask
from idmtools.utils.entities import save_id_as_file_as_hook
from time import time
if typing.TYPE_CHECKING:
    from idmtools_platform_comps.comps_platform import COMPSPlatform

# Define our base task
task = JSONConfiguredPythonTask(script_path=os.path.join("..", "..", "python_model", "inputs", "python_model_with_deps",
                                                         "Assets", "model.py"), parameters=(dict(c=0)))
ts = TemplatedSimulations(base_task=task)

# Build sweeps for our simulations
builder = SimulationBuilder()

class setParam:
    def __init__(self, param):
        self.param = param

    def __call__(self, simulation, value):
        return simulation.task.set_parameter(self.param, value)


builder.add_sweep_definition(setParam("a"), [1, 2, 3])
builder.add_sweep_definition(setParam("b"), [1, 2])

ts.add_builder(builder)

# Create our experiment
experiment = Experiment.from_template(ts, name=os.path.split(sys.argv[0])[1])

# Add our pre-creation and post-creation hooks:
#   Our pre-creation hook adds the date as a tag to our experiment
#   Our post-creation hook saves the experiment ID within a file titled '{item.item_type}.{item.name}.id' (within current directory)
ran_at = str(time())

def add_date_as_tag(experiment: Experiment, platform: 'COMPSPlatform'):
    experiment.tags['date'] = ran_at

# Add a pre/post creation hook to either an experiment or a work item using the 'add_pre_creation_hook' or 'add_post_creation_hook' methods
experiment.add_pre_creation_hook(add_date_as_tag)
experiment.add_post_creation_hook(save_id_as_file_as_hook)

with Platform('CALCULON'):
    experiment.run(True)
    sys.exit(0 if experiment.succeeded else -1)