Source code for sbmlsim.examples.example_parallel

"""
Parallel execution of timecourses
"""
import tempfile
import time

import numpy as np
import roadrunner

from sbmlsim.model import RoadrunnerSBMLModel
from sbmlsim.simulation import Dimension, ScanSim, Timecourse, TimecourseSim
from sbmlsim.simulator import SimulatorSerial
from sbmlsim.simulator.simulation_ray import (
    SimulatorActor,
    SimulatorParallel,
    cpu_count,
    ray,
)
from sbmlsim.test import MODEL_GLCWB, MODEL_REPRESSILATOR
from sbmlsim.units import Units, UnitsInformation


[docs]def example_single_actor(): """Creates a single stateful simulator actor and executes timecourse. Actors should never created manually ! Use the SimulatorParallel to run parallel simulations. :return: """ # create state file r = roadrunner.RoadRunner(str(MODEL_REPRESSILATOR)) RoadrunnerSBMLModel.set_timecourse_selections(r) uinfo = UnitsInformation.from_sbml_path(MODEL_REPRESSILATOR) f_state = tempfile.NamedTemporaryFile(suffix=".dat") r.saveState(f_state.name) # Create single actor process sa = SimulatorActor.remote(f_state.name) # run simulation tcsim = TimecourseSim( [ Timecourse(start=0, end=100, steps=100), Timecourse(start=0, end=100, steps=100, changes={"X": 10, "Y": 20}), ] ) tcsim.normalize(uinfo=uinfo) tc_id = sa._timecourse.remote(tcsim) results = ray.get(tc_id) return results
[docs]def example_multiple_actors(): """Multiple independent simulator actors. Actors should never be created manually, use the SimulatorParallel! """ # create state file r = roadrunner.RoadRunner(str(MODEL_REPRESSILATOR)) RoadrunnerSBMLModel.set_timecourse_selections(r) uinfo = UnitsInformation.from_sbml_path(MODEL_REPRESSILATOR) f_state = tempfile.NamedTemporaryFile(suffix=".dat") r.saveState(f_state.name) # create ten Simulators. simulators = [SimulatorActor.remote(f_state.name) for _ in range(16)] # define timecourse tcsim = TimecourseSim( [ Timecourse(start=0, end=100, steps=100), Timecourse(start=0, end=100, steps=100, changes={"X": 10, "Y": 20}), ] ) tcsim.normalize(uinfo=uinfo) # run simulation on simulators tc_ids = [s._timecourse.remote(tcsim) for s in simulators] # collect results results = ray.get(tc_ids) return results
[docs]def example_parallel_timecourse(nsim=40, actor_count=15): """Execute multiple simulations with model in parallel. :param nsim: number of simulations :return: """ # collect all simulation definitions (see also the ensemble functions) scan = ScanSim( simulation=TimecourseSim( [ Timecourse( start=0, end=100, steps=100, changes={ "IVDOSE_som": 0.0, # [mg] "PODOSE_som": 0.0, # [mg] "Ri_som": 10.0e-6, # [mg/min] }, ) ] ), dimensions=[Dimension("dim1", index=np.arange(nsim))], ) def message(info, time): print(f"{info:<10}: {time:4.3f}") # load model once for caching (fair comparison) r = roadrunner.RoadRunner(str(MODEL_GLCWB)) # simulator definitions simulator_defs = [ { "key": "parallel", "simulator": SimulatorParallel, "kwargs": {"actor_count": actor_count}, }, {"key": "serial", "simulator": SimulatorSerial, "kwargs": {}}, ] print("-" * 80) print(f"Run '{nsim}' simulations") print("-" * 80) sim_info = [] for sim_def in simulator_defs: key = sim_def["key"] print("***", key, "***") Simulator = sim_def["simulator"] kwargs = sim_def["kwargs"] # run simulation (with model reading) start_time = time.time() # create a simulator with 16 parallel actors simulator = Simulator(model=MODEL_GLCWB, **kwargs) load_time = time.time() - start_time message(f"load", load_time) start_time = time.time() results = simulator.run_scan(scan=scan) sim_time = time.time() - start_time total_time = load_time + sim_time message("simulate", sim_time) message("total", total_time) assert len(results.coords["dim1"]) == nsim # run parallel simulation (without model reading) start_time = time.time() results = simulator.run_scan(scan=scan) repeat_time = time.time() - start_time message(f"repeat", repeat_time) assert len(results.coords["dim1"]) == nsim actor_count = kwargs.get("actor_count", 1) times = { "load": load_time, "simulate": sim_time, "total": total_time, "repeat": repeat_time, } sim_info.extend( [ { "key": key, "nsim": nsim, "actor_count": actor_count, "time_type": k, "time": v, } for (k, v) in times.items() ] ) print("-" * 80) return sim_info
if __name__ == "__main__": # example_single_actor() # example_multiple_actors()
[docs] sim_info = example_parallel_timecourse(nsim=100, actor_count=15)
ray.timeline(filename="timeline.json")