Skip to content

Commit aadfeba

Browse files
fix: properly fall back to greedy scheduler in case of pulp/cbc errors
1 parent 4d2bbe5 commit aadfeba

2 files changed

Lines changed: 23 additions & 4 deletions

File tree

src/snakemake/scheduling/job_scheduler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ def __init__(
157157
# Choose job selector (greedy or ILP)
158158
self.job_selector_greedy = self._greedy_scheduler.select_jobs
159159
self._job_selector = scheduler.select_jobs
160+
self._scheduler = scheduler
160161

161162
self._user_kill = None
162163
try:

src/snakemake/scheduling/milp.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,22 @@ class SchedulerSettings(SchedulerSettingsBase):
3434

3535

3636
class Scheduler(SchedulerBase):
37+
def __post_init__(self) -> None:
38+
self._technical_failure = False
39+
3740
def select_jobs(
3841
self,
3942
selectable_jobs: Sequence[JobSchedulerInterface],
4043
remaining_jobs: Sequence[JobSchedulerInterface],
4144
available_resources: Mapping[str, Union[int, str]],
4245
input_sizes: Dict[AnnotatedStringInterface, int],
43-
) -> Sequence[JobSchedulerInterface]:
46+
) -> Optional[Sequence[JobSchedulerInterface]]:
47+
if self._technical_failure:
48+
# fallback early since we failed before already
49+
return None
4450
import pulp
4551
from pulp import lpSum
52+
from pulp import PulpSolverError
4653

4754
scheduled_jobs = {
4855
job: pulp.LpVariable(
@@ -148,15 +155,26 @@ def select_jobs(
148155

149156
prob += temp_file_deletable[temp_file] <= temp_job_improvement[temp_file]
150157

151-
status = self._solve_ilp(prob, time_limit=10)
158+
try:
159+
status = self._solve_ilp(prob, time_limit=10)
160+
except PulpSolverError as e:
161+
self._technical_failure = True
162+
self.logger.warning(
163+
"Failed to solve scheduling problem with ILP solver, falling back to "
164+
"greedy scheduler. You likely have to fix your ILP solver "
165+
f"installation. Error message: {e}"
166+
)
167+
return None
152168
if pulp.LpStatus[status] != "Optimal":
153169
if pulp.LpStatus[status] == "Not Solved":
154170
self.logger.warning(
155-
"Failed to solve scheduling problem with ILP solver in time (10s)."
171+
"Failed to solve scheduling problem with ILP solver in time (10s), "
172+
"falling back to greedy scheduler."
156173
)
157174
elif pulp.LpStatus[status] == "Infeasible":
158175
self.logger.warning(
159-
"Failed to solve scheduling problem with ILP solver."
176+
"Failed to solve scheduling problem with ILP solver, falling back "
177+
"to greedy scheduler."
160178
)
161179
return None
162180

0 commit comments

Comments
 (0)