Workflows
Workflows (spec link) define the computation graph that connects
global inputs, outputs, and tasks together to build a comprehensive execution plan.
While tasks are focused at the atomic computational unit level, workflows are typically
concerned with how to orchestrate the execution of those tasks in a scalable manner.
Common sections with task
Workflows contain multiple sections that are common with tasks, including the input
section, the output section, and the meta and parameter_meta sections. The
description of these sections are identical with tasks and, for brevity, we will not
cover these again in this section of the guide. If you need a refresher, we recommend
you read the relevant sections in the Tasks section.
The call statement
The call statement (spec link) directs the workflow to execute the
specified task or subworkflow. call-ing a task or subworkflow brings its name into
scope within the workflow such that its inputs and outputs can be connected
together—either to global inputs and outputs of the workflow or to other
tasks/subworkflows. Further, you can use the as keyword to avoid naming collisions
(see this design pattern for more information).
Below is an example of a typical workflow that uses call statements.
wdltask stepA { # ... } task stepB { # ... } workflow run { # You can instruct the workflow to run `stepA` by `call`-ing it. call stepA {} # If there are inputs, you can include them within the brackets. call stepB { foo = bar } # Normally, if you wanted to call `stepA` again, there would be # a name conflict because the identifier `stepA` would be brought # into the workflow's scope twice. You can use the `as` keyword # to assign the task an alias. call stepA as stepA_again {} }
Non-sequentialism
A quick note on non-sequentialism: in the example above, tasks are not necessarily
executed in the order they are defined. For example, because stepA_again does not
depend on any outputs from stepA or stepB, it can be run immediately when the
workflow starts. This illustrates a broader point—defining a workflow means that you are
defining a graph of computation—not a serial program to be executed. You can learn
more about this in this section of the spec.
Conditional statement
A conditional statement, also known as an if/else statement (spec
link) allows some subsection of the computation graph to
conditionally occur based on the specified condition. This is useful if, for example,
you want to support different modes of operation based on an input or optionally enable
an entire subanalysis of some data based on passing a QC threshold.
Building on our example above, we can see conditional statements in action.
wdltask stepA { # ... } task stepB { # ... } workflow run { input { Boolean run_stepB } call stepA {} if (run_stepB) { call stepB { value = stepA.out } } # ... }
For a bit more complicated example, the workflow below demonstrates (a) conditionally
executing a "standard" or "alternate" mode for stepA and then (b) only running stepB
if some QC metric from either mode passes.
wdltask stepA { # ... } task stepA_alternate { # ... } task stepB { # ... } workflow run { input { # `alternate_execution_mode` is a required workflow input. Boolean alternate_execution_mode } # Based on the value passed in as an input, either the alternate # execution mode will run, or the standard execution mode will run. if (alternate_execution_mode) { call stepA_alternate {} } else { call stepA {} } # Using `select_first`, we can pick up an output named `qc_passed` # in either `stepA` or `stepA_alternate` (whichever ran) and then # conditionally run `stepB` based on that result. if (select_first([ stepA.qc_passed, stepA_alternate.qc_passed, ])) { call stepB {} } # ... }
Design patterns
Ensuring that your workflow takes full advantage of parallelism is critical to ensuring your workflow scales well. In fact, the ease with which workflows can be defined and scaled is one of the hallmarks of the WDL language. This concept is so important that the is an entire section of the documentation titled "Design Patterns" that covers idiomatic approaches to construct workflows (link). We highly recommend you read that section to take full advantages of the facilities WDL provides.