Skip to content

Evaluate CWL when conditionals before scheduling to avoid wasted batch-system submissions (#3990) - #5569

Open
annagiroti wants to merge 2 commits into
masterfrom
issues/3990-skip-conditional-cwl-scheduling
Open

Evaluate CWL when conditionals before scheduling to avoid wasted batch-system submissions (#3990)#5569
annagiroti wants to merge 2 commits into
masterfrom
issues/3990-skip-conditional-cwl-scheduling

Conversation

@annagiroti

@annagiroti annagiroti commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Changelog Entry

Steps with a when conditional were always scheduled onto the real batch system as a fully-resourced job, even when the condition evaluated false and the step would be skipped. On a busy HPC system, a skipped step that requests large resources can sit queued for hours before discovering it had nothing to do.

CWLJobWrapper already solves this for dynamic resource requirements: it runs as a cheap local job that resolves inputs before spawning the real job. This routes when-conditional steps through the same wrapper, so the condition is checked with fully-resolved inputs — including promises from upstream step outputs — before the real job is ever created. Skipped steps never touch the batch system.

Resolves #3990

To be copied to the draft changelog by merger:

  • PR submitter writes their recommendation for a changelog entry here

Reviewer Checklist

  • Make sure it is coming from issues/XXXX-fix-the-thing in the Toil repo, or from an external repo.
    • If it is coming from an external repo, make sure to pull it in for CI with:
      contrib/admin/test-pr otheruser theirbranchname issues/XXXX-fix-the-thing
      
    • If there is no associated issue, create one.
  • Read through the code changes. Make sure that it doesn't have:
    • Addition of trailing whitespace.
    • New variable or member names in camelCase that want to be in snake_case.
    • New functions without type hints.
    • New functions or classes without informative docstrings.
    • Changes to semantics not reflected in the relevant docstrings.
    • New or changed command line options for Toil workflows that are not reflected in docs/running/{cliOptions,cwl,wdl}.rst
    • New features without tests.
  • Comment on the lines of code where problems exist with a review comment. You can shift-click the line numbers in the diff to select multiple lines.
  • Finish the review with an overall description of your opinion.

Merger Checklist

  • Make sure the PR passed tests, including the Gitlab tests, for the most recent commit in its branch.
  • Make sure the PR has been reviewed. If not, review it. If it has been reviewed and any requested changes seem to have been addressed, proceed.
  • Merge with the Github "Squash and merge" feature.
    • If there are multiple authors' commits, add Co-authored-by to give credit to all contributing authors.
  • Copy its recommended changelog entry to the Draft Changelog.
  • Append the issue number in parentheses to the changelog entry.

…tch-system submissions

Steps with a `when` conditional were always scheduled onto the real
batch system as a fully-resourced job, even when the condition was
going to evaluate false and the step would be skipped. On a busy HPC
system, a skipped step that asks for large resources can sit queued
for hours before finding out it had nothing to do.
CWLJobWrapper already solves this problem for dynamic resource
requirements: it runs as a cheap local job that resolves inputs
before spawning the real job. Route `when`-conditional steps through
the same wrapper, so the condition is checked with resolved inputs
before ever creating the real job, and skipped steps never touch the
batch system.
@annagiroti
annagiroti requested a review from adamnovak August 20, 2026 07:56
@adamnovak

Copy link
Copy Markdown
Member

This closes #5507 by replacing it, I think.

@adamnovak

Copy link
Copy Markdown
Member

@annagiroti Can you fill in the changelog entry (PR submitter writes their recommendation for a changelog entry here above)?

@adamnovak adamnovak left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it should work OK, but:

  • The test has a sleep input, presumably copied from a different test and not changed, which does not control a sleep
  • The docstrings are following the Way of Claude rather than PEP 257, and in particular are not leveraging a theory of mind to make the reader reach true conclusions about the code.

steps:
produce:
in:
sleep: sleep

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rename this input to something other than sleep (maybe number?), because other test workflows will have sleep inputs that make them actually wait, and it's weird that this one doesn't.

Comment thread src/toil/cwl/cwltoil.py
Comment on lines 2892 to +2893
"""
Wrap a CWL job that uses dynamic resources requirement.
Wrap a CWL job that uses a dynamic resources requirement, or that may be

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we want a 1-line summary at the top of our docstring. Maybe say that this job determines how and whether to run the wrapped job?

Comment thread src/toil/cwl/cwltoil.py
"""
Wrap a CWL job that uses dynamic resources requirement.
Wrap a CWL job that uses a dynamic resources requirement, or that may be
skipped by a `when` conditional that can't be safely evaluated until the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saying it that way makes it sound like there are some conditionals that can be safely evaluated without the step's inputs, and others that can't, and our code actually knows the difference and acts on it to evaluate only the conditionals that need the inputs with this mechanism.

That's not true, so we can probably just say "a conditional" instead of the long mis-explanatory phrase.

Comment thread src/toil/cwl/cwltoil.py
Comment on lines -2895 to +2899
When executed, this creates a new child job which has the correct resource
requirement set.
When executed, this runs on the leader with minimal resources, resolves
the job's inputs, and then either reports the step as skipped or creates
a new child job which has the correct resource requirement set.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole piece should probably be cut, because it's a summary rather than an explanation.

If we do want to write down the responsibility, we should say something like "This job is responsible for creating a CWLJob child with the right resource requirements, when the job should not be skipped."

Comment thread src/toil/cwl/cwltoil.py
jobobj,
runtime_context,
parent_name=parent_name,
conditional=conditional,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're still passing the conditional to CWLJob, and CWLJob hasn't had any conditional-checking code removed from it. If CWLJobWrapper is now responsible for evaluating all the conditionals on jobs, CWLJob should probably forget how to do it itself.

Comment thread src/toil/cwl/cwltoil.py
if has_dynamic_resource_requirement or (
conditional is not None and conditional.expression is not None
):
# Resource requirements and the `when` conditional can depend on

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably makes more sense to talk about conditionals in the code's terms, where we have a Conditional type, rather than in CWL language terms where we have a when field in various places in YAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CWL Conditional steps that aren't running still get scheduled to a job scheduler.

2 participants