1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# Two Sub-graph Pipeline
# Demonstrates 2 independent sub-graphs with 4 stages, implicit file dependencies
#
# Structure:
# Stage 1: prep_a, prep_b (run on 1 shared node)
# Stage 2: work_a_1..5, work_b_1..5 (2 independent sub-graphs, different schedulers)
# Stage 3: post_a, post_b (each on its own node)
# Stage 4: final (aggregates both sub-graphs)
name: two_subgraph_pipeline
description: Demonstrates 2 independent sub-graphs with 4 stages, implicit file dependencies
# ==============================================================================
# FILES - All dependencies are implicit based on input_files/output_files
# ==============================================================================
files:
# Stage 1 inputs (must exist before workflow starts)
- name: input_a
path: input_a.txt
- name: input_b
path: input_b.txt
# Stage 1 outputs -> Stage 2 inputs
- name: prep_a_out
path: output/prep_a.txt
- name: prep_b_out
path: output/prep_b.txt
# Stage 2 outputs -> Stage 3 inputs (parameterized)
- name: "work_a_{i}_out"
path: "output/work_a_{i}.txt"
parameters:
i: "1:5"
- name: "work_b_{i}_out"
path: "output/work_b_{i}.txt"
parameters:
i: "1:5"
# Stage 3 outputs -> Stage 4 inputs
- name: post_a_out
path: output/post_a.txt
- name: post_b_out
path: output/post_b.txt
# Stage 4 output (final result)
- name: final_out
path: output/final.txt
# ==============================================================================
# JOBS - Organized by stage
# ==============================================================================
jobs:
# --- Stage 1: Preprocessing ---
- name: prep_a
command: ./scripts/prep.sh a
input_files:
output_files:
resource_requirements: small
- name: prep_b
command: ./scripts/prep.sh b
input_files:
output_files:
resource_requirements: small
# --- Stage 2: Work (two independent sub-graphs) ---
# Sub-graph A: CPU-intensive work
- name: "work_a_{i}"
command: "./scripts/work.sh a {i}"
input_files:
output_files:
resource_requirements: work_large
parameters:
i: "1:5"
# Sub-graph B: GPU-accelerated work
- name: "work_b_{i}"
command: "./scripts/work.sh b {i}"
input_files:
output_files:
resource_requirements: work_gpu
parameters:
i: "1:5"
# --- Stage 3: Post-processing ---
- name: post_a
command: ./scripts/post.sh a
input_files:
- work_a_1_out
- work_a_2_out
- work_a_3_out
- work_a_4_out
- work_a_5_out
output_files:
resource_requirements: medium
- name: post_b
command: ./scripts/post.sh b
input_files:
- work_b_1_out
- work_b_2_out
- work_b_3_out
- work_b_4_out
- work_b_5_out
output_files:
resource_requirements: medium
# --- Stage 4: Final aggregation ---
- name: final
command: ./scripts/aggregate.sh
input_files:
output_files:
resource_requirements: large
# ==============================================================================
# RESOURCE REQUIREMENTS
# ==============================================================================
resource_requirements:
- name: small
num_cpus: 1
memory: 2g
runtime: PT30M
- name: work_large
num_cpus: 8
memory: 32g
runtime: PT2H
- name: work_gpu
num_cpus: 4
memory: 16g
num_gpus: 1
runtime: PT4H
- name: medium
num_cpus: 2
memory: 8g
runtime: PT1H
- name: large
num_cpus: 4
memory: 16g
runtime: PT2H
# ==============================================================================
# SLURM SCHEDULERS - Each stage/sub-graph gets its own scheduler
# ==============================================================================
slurm_schedulers:
# Stage 1: Both prep jobs share one node
- name: prep_sched
account: myproject
partition: standard
nodes: 1
walltime: "01:00:00"
# Stage 2: Sub-graph A gets 3 CPU nodes
- name: work_a_sched
account: myproject
partition: standard
nodes: 3
walltime: "04:00:00"
# Stage 2: Sub-graph B gets 2 GPU nodes
- name: work_b_sched
account: myproject
partition: gpu
nodes: 2
walltime: "06:00:00"
extra: "--gres=gpu:1"
# Stage 3: Each post job gets its own node
- name: post_a_sched
account: myproject
partition: standard
nodes: 1
walltime: "02:00:00"
- name: post_b_sched
account: myproject
partition: standard
nodes: 1
walltime: "02:00:00"
# Stage 4: Final job gets its own node
- name: final_sched
account: myproject
partition: standard
nodes: 1
walltime: "03:00:00"
# ==============================================================================
# ACTIONS - Schedule compute nodes when jobs become ready
# ==============================================================================
actions:
# Stage 1: Triggered at workflow start
- trigger_type: on_workflow_start
action_type: schedule_nodes
scheduler: prep_sched
scheduler_type: slurm
jobs:
# Stage 2: Triggered when work jobs become ready
# These trigger simultaneously since sub-graphs are independent
- trigger_type: on_jobs_ready
action_type: schedule_nodes
scheduler: work_a_sched
scheduler_type: slurm
job_name_regexes:
- trigger_type: on_jobs_ready
action_type: schedule_nodes
scheduler: work_b_sched
scheduler_type: slurm
job_name_regexes:
# Stage 3: Triggered when post jobs become ready
- trigger_type: on_jobs_ready
action_type: schedule_nodes
scheduler: post_a_sched
scheduler_type: slurm
jobs:
- trigger_type: on_jobs_ready
action_type: schedule_nodes
scheduler: post_b_sched
scheduler_type: slurm
jobs:
# Stage 4: Triggered when final job becomes ready
- trigger_type: on_jobs_ready
action_type: schedule_nodes
scheduler: final_sched
scheduler_type: slurm
jobs: