@@ -307,82 +307,48 @@ def compute_runahead(self, force=False) -> bool:
307
307
308
308
With force=True we recompute the limit even if the base point has not
309
309
changed (needed if max_future_offset changed, or on reload).
310
- """
311
310
311
+ """
312
312
limit = self .config .runahead_limit # e.g. P2 or P2D
313
313
count_cycles = False
314
314
with suppress (TypeError ):
315
315
# Count cycles (integer cycling, and optional for datetime too).
316
316
ilimit = int (limit ) # type: ignore
317
317
count_cycles = True
318
318
319
- base_point : 'PointBase'
320
- points : List ['PointBase' ] = []
319
+ base_point : Optional ['PointBase' ] = None
321
320
321
+ # First get the runahead base point.
322
322
if not self .main_pool :
323
- # No tasks yet, just consider sequence points.
324
- if count_cycles :
325
- # Get the first ilimit points in each sequence.
326
- # (After workflow start point - sequence may begin earlier).
327
- points = [
328
- point
329
- for plist in [
330
- seq .get_first_n_points (
331
- ilimit , self .config .start_point )
332
- for seq in self .config .sequences
333
- ]
334
- for point in plist
335
- ]
336
- # Drop points beyond the limit.
337
- points = sorted (points )[:ilimit + 1 ]
338
- base_point = min (points )
339
-
340
- else :
341
- # Start at first point in each sequence.
342
- # (After workflow start point - sequence may begin earlier).
343
- points = [
344
- point
345
- for point in {
346
- seq .get_first_point (self .config .start_point )
347
- for seq in self .config .sequences
348
- }
349
- if point is not None
350
- ]
351
- base_point = min (points )
352
- # Drop points beyond the limit.
353
- points = [
354
- point
355
- for point in points
356
- if point <= base_point + limit
357
- ]
358
-
323
+ # Find the earliest sequence point beyond the workflow start point.
324
+ base_point = min (
325
+ point
326
+ for point in {
327
+ seq .get_first_point (self .config .start_point )
328
+ for seq in self .config .sequences
329
+ }
330
+ if point is not None
331
+ )
359
332
else :
360
- # Find the earliest point with unfinished tasks.
333
+ # Find the earliest point with incomplete tasks.
361
334
for point , itasks in sorted (self .get_tasks_by_point ().items ()):
335
+ # All n=0 tasks are incomplete by definition, but Cylc 7
336
+ # ignores failed ones (it does not ignore submit-failed!).
362
337
if (
363
- points # got the limit already so this point too
364
- or any (
365
- not itask .state (
366
- TASK_STATUS_FAILED ,
367
- TASK_STATUS_SUCCEEDED ,
368
- TASK_STATUS_EXPIRED
369
- )
370
- or (
371
- # For Cylc 7 back-compat, ignore incomplete tasks.
372
- # (Success is required in back-compat mode, so
373
- # failedtasks end up as incomplete; and Cylc 7
374
- # ignores failed tasks in computing the limit).
375
- itask .state .outputs .is_incomplete ()
376
- and not cylc .flow .flags .cylc7_back_compat
377
- )
338
+ cylc .flow .flags .cylc7_back_compat and
339
+ all (
340
+ itask .state (TASK_STATUS_FAILED )
378
341
for itask in itasks
379
342
)
380
343
):
381
- points .append (point )
344
+ continue
345
+ base_point = point
346
+ break
382
347
383
- if not points :
384
- return False
385
- base_point = min (points )
348
+ if base_point is None :
349
+ return False
350
+
351
+ LOG .debug (f"Runahead: base point { base_point } " )
386
352
387
353
if self ._prev_runahead_base_point is None :
388
354
self ._prev_runahead_base_point = base_point
@@ -399,8 +365,10 @@ def compute_runahead(self, force=False) -> bool:
399
365
# change or the runahead limit is already at stop point.
400
366
return False
401
367
402
- # Get all cycle points possible after the base point.
403
- sequence_points : Set ['PointBase' ]
368
+ # Now generate all possible cycle points from the base point and stop
369
+ # at the runahead limit point. Note both cycle count and time interval
370
+ # limits involve all possible cycles, not just active cycles.
371
+ sequence_points : Set ['PointBase' ] = set ()
404
372
if (
405
373
not force
406
374
and self ._prev_runahead_sequence_points
@@ -410,44 +378,48 @@ def compute_runahead(self, force=False) -> bool:
410
378
sequence_points = self ._prev_runahead_sequence_points
411
379
else :
412
380
# Recompute possible points.
413
- sequence_points = set ()
414
381
for sequence in self .config .sequences :
415
- seq_point = sequence .get_next_point (base_point )
382
+ seq_point = sequence .get_first_point (base_point )
416
383
count = 1
417
384
while seq_point is not None :
418
385
if count_cycles :
419
386
# P0 allows only the base cycle point to run.
420
387
if count > 1 + ilimit :
388
+ # this point may be beyond the runahead limit
421
389
break
422
390
else :
423
391
# PT0H allows only the base cycle point to run.
424
392
if seq_point > base_point + limit :
393
+ # this point can not be beyond the runahead limit
425
394
break
426
395
count += 1
427
396
sequence_points .add (seq_point )
428
397
seq_point = sequence .get_next_point (seq_point )
429
398
self ._prev_runahead_sequence_points = sequence_points
430
399
self ._prev_runahead_base_point = base_point
431
400
432
- points = set (points ).union (sequence_points )
433
-
434
401
if count_cycles :
435
- # Some sequences may have different intervals.
436
- limit_point = sorted (points )[:( ilimit + 1 ) ][- 1 ]
402
+ # (len(list) may be less than ilimit due to sequence end)
403
+ limit_point = sorted (sequence_points )[:ilimit + 1 ][- 1 ]
437
404
else :
438
- # We already stopped at the runahead limit.
439
- limit_point = sorted (points )[- 1 ]
405
+ limit_point = max (sequence_points )
440
406
441
- # Adjust for future offset and stop point, if necessary .
407
+ # Adjust for future offset and stop point.
442
408
pre_adj_limit = limit_point
443
409
if self .max_future_offset is not None :
444
410
limit_point += self .max_future_offset
445
- LOG .debug (f"{ pre_adj_limit } -> { limit_point } (future offset)" )
411
+ LOG .debug (
412
+ "Runahead (future trigger adjust):"
413
+ f" { pre_adj_limit } -> { limit_point } "
414
+ )
446
415
if self .stop_point and limit_point > self .stop_point :
447
416
limit_point = self .stop_point
448
- LOG .debug (f"{ pre_adj_limit } -> { limit_point } (stop point)" )
449
- LOG .debug (f"Runahead limit: { limit_point } " )
417
+ LOG .debug (
418
+ "Runahead (stop point adjust):"
419
+ f" { pre_adj_limit } -> { limit_point } (stop point)"
420
+ )
450
421
422
+ LOG .debug (f"Runahead limit: { limit_point } " )
451
423
self .runahead_limit_point = limit_point
452
424
return True
453
425
0 commit comments