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