My workflow contains dependencies on future cycle points. While I understand that cylc ignores intercycle dependencies before the initial cycle point, it does not seem to behave analogously for dependencies after the final cycle point.
As an example, in the following workflow, the hello task runs three times, as expected:
[scheduling]
cycling mode = integer
initial cycle point = 1
final cycle point = 3
P1 = hello
P1 = hello[-P1] => hello
But if the last line is changed so that hello depends on hello[+P1] instead of hello[-P1], the task doesn’t run at all.
What’s the “best practice” approach to make cylc ignore all dependencies after the final cycle point? Any help would be much appreciated!
Cylc does ignore dependence on tasks beyond the final cycle point.
Your example graph is just a bit too simplistic, to the point that it doesn’t make sense given Cylc’s inherent forward-cycling nature (i.e., you can have tasks that depend on future cycle points, but you can’t actually cycle backwards - you still have to start from the initial point and cycle forward to the final point).
If I plot your graph (with cylc graph):
… nothing will run because the first task 1/hello depends on 2/hello which hasn’t run yet, and so on. This graph would only work if Cylc could actually cycle backwards from the final point.
Here’s a functional example with future-point dependence:
This example runs fine, because 1/foo can kick things off at the initial cycle point 1 and the rest flows naturally from there. Then, 4/foo is beyond the final point so Cylc will ignore 3/qux and log this:
WARNING - [3/qux:waiting] not spawned: a prerequisite is beyond the workflow
stop point (3)
(Actually this isn’t quite symmetric with initial point handling, which would ignore the dependency and run the task … but perhaps it makes more sense this way for the final point )
Thank you for the clarification! This asymmetry between the handling of dependencies before the initial cycle point versus those after the final cycle point was the source of my confusion.
Using your graph as an example, the essence of my problem is that I need 3/qux to be run. The workaround that I’ve come up with (again, using your graph as an example) is along the lines of the following:
So I suppose my question now boils down to: in a more complicated graph with many dependencies after the final cycle point that must be ignored, is this still the best approach, or is there a more elegant way to ignore all those dependencies?
That’s good - you’ve basically done it properly, by defining the correct dependencies in every cycle.
It’s really the automatic ignoring of out-of-bounds dependencies that is a convenient workaround (to allow us to avoid the extra work of doing it properly)! However, I’ll raise it with the team to check if the current final cycle implementation of that needs to be changed…