Skip to content

Commit

Permalink
Update scheduling notebook to use callback to time-out a solver
Browse files Browse the repository at this point in the history
  • Loading branch information
nhuet authored and g-poveda committed Oct 7, 2024
1 parent b5a0ae6 commit c34da35
Showing 1 changed file with 71 additions and 2 deletions.
73 changes: 71 additions & 2 deletions notebooks/13_scheduling_tuto.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,74 @@
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"from skdecide.hub.solver.lazy_astar import LazyAstar\n",
"\n",
"\n",
"# Implement a callback to time-out\n",
"class TimeoutCallback:\n",
" \"\"\"Callback to stop the solve process after a given time.\n",
"\n",
" Stops the solve process if a limit training time has been elapsed.\n",
" This time is checked after each `check_nb_steps` steps.\n",
"\n",
" \"\"\"\n",
"\n",
" def __init__(self, total_seconds: int, check_nb_steps: int = 1):\n",
" \"\"\"\n",
"\n",
" Args:\n",
" total_seconds: Total time in seconds allowed to solve\n",
" check_nb_steps: Number of steps to wait before next time check\n",
"\n",
" \"\"\"\n",
" self.total_seconds = total_seconds\n",
" self.check_nb_steps = check_nb_steps\n",
" self.starting_time = time.perf_counter()\n",
" self.step = 0\n",
"\n",
" def __call__(self, solver) -> bool:\n",
" \"\"\"Called at each solve iteration.\n",
"\n",
" If returning True, the solve process is stopped.\n",
"\n",
" \"\"\"\n",
" if self.step % self.check_nb_steps == 0:\n",
" current_time = time.perf_counter()\n",
" difference = current_time - self.starting_time\n",
" logging.debug(\n",
" f\"step {self.step}: {difference} seconds elapsed since solve start.\"\n",
" )\n",
" if difference >= self.total_seconds:\n",
" logging.info(\n",
" f\"{self.__class__.__name__} stops the solve process before it could finish.\"\n",
" )\n",
" return True\n",
" self.step += 1\n",
" return False\n",
"\n",
"\n",
"# Solve with lazy A* and the time-out callback\n",
"solver = LazyAstar(\n",
" domain_factory=lambda: domain,\n",
" heuristic=None,\n",
" callback=TimeoutCallback(total_seconds=300, check_nb_steps=500),\n",
")\n",
"solver.solve(from_memory=state)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note about how to time-out:** \n",
"\n",
"We use here a callback that is called at each iteration of the solve process to manage the time-out. As Lazy A* iterations are very fast (~ 1000 / second), we choose to check the timer every 500 steps. \n",
"This would not work on other solver with bigger iterations. So be careful to update this number to use it with a different solver.\n",
"\n",
"Another solution could be to use the signal python package, but it would not work on windows. It would be something like the code below:\n",
"```python\n",
"import signal\n",
"\n",
"from skdecide.hub.solver.lazy_astar import LazyAstar\n",
Expand All @@ -673,9 +741,10 @@
"try:\n",
" solver.solve(from_memory=state)\n",
"except Exception:\n",
" print(\"the algorithm could not finish\")\n",
" print(\"The solve process was stopped befor it could finish.\")\n",
"finally:\n",
" signal.alarm(0)"
" signal.alarm(0)\n",
"```\n"
]
},
{
Expand Down

0 comments on commit c34da35

Please sign in to comment.