@@ -24,6 +24,7 @@ class MagpieOptions:
2424 save_sim : bool = False
2525 save_sim_freq : int = 6
2626 save_sim_on_end : bool = False
27+ wall_time_limit_minutes : float | None = None
2728
2829
2930class Magpie (Module ):
@@ -37,6 +38,7 @@ class Magpie(Module):
3738 save_sim=True, # save the simulation to a pickle file...
3839 save_sim_freq=3, # ...every n months
3940 save_sim_on_end=True # save the simulation to a pickle file at the end of the simulation
41+ wall_time_limit_minutes=60 # stop the simulation if it runs for more than n minutes (checked every month)
4042 )
4143 ```
4244
@@ -63,6 +65,9 @@ def initialise_simulation(self, sim: Simulation):
6365 if self .options .save_sim :
6466 sim .schedule_event (SaveSimulation (self , self .options .save_sim_freq ), sim .start_date )
6567
68+ if self .options .wall_time_limit_minutes is not None :
69+ sim .schedule_event (WallTimeLimit (self , self .options .wall_time_limit_minutes ), sim .start_date )
70+
6671 def on_birth (self , mother_id , child_id ):
6772 pass
6873
@@ -94,6 +99,23 @@ def apply(self, population):
9499 logger .info (key = "stats" , data = data )
95100
96101
102+ class WallTimeLimit (RegularEvent , PopulationScopeEventMixin ):
103+ def __init__ (self , module , wall_time_limit_minutes ):
104+ super ().__init__ (module , frequency = DateOffset (months = 1 ))
105+ self .wall_time_limit_minutes = wall_time_limit_minutes
106+ self .start_time = time .time ()
107+
108+ def apply (self , population ):
109+ now = time .time ()
110+ elapsed_minutes = (now - self .start_time ) / 60
111+ if elapsed_minutes >= self .wall_time_limit_minutes :
112+ logger .info (
113+ key = "msg" ,
114+ data = f"Terminating simulation after { self .wall_time_limit_minutes } minutes of runtime"
115+ )
116+ self .sim .terminate ()
117+
118+
97119def make_pickle_filename (sim_date ):
98120 strftime = "%Y%m%dT%H%M%S"
99121 timestamp = time .strftime (strftime )
0 commit comments