Skip to content

Commit 0ce935d

Browse files
committed
Add GPU tests
1 parent fc95d21 commit 0ce935d

12 files changed

Lines changed: 240 additions & 28 deletions

File tree

.github/actions/get-shards/action.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,30 @@ runs:
2828
id: shards
2929
shell: bash
3030
run: |
31-
# Run nf-test with dynamic parameter
32-
nftest_output=$(nf-test test \
33-
--profile +docker \
34-
$(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \
35-
--dry-run \
36-
--ci \
37-
--changed-since HEAD^) || {
38-
echo "nf-test command failed with exit code $?"
39-
echo "Full output: $nftest_output"
40-
exit 1
41-
}
31+
# When paths are provided (from detect-nf-test-changes), run path-based dry-run.
32+
# Otherwise use tags and --changed-since (legacy).
33+
if [ -n "${{ inputs.paths }}" ]; then
34+
nftest_output=$(nf-test test \
35+
--dry-run \
36+
--profile +docker \
37+
--filter process,workflow \
38+
${{ inputs.paths }}) || {
39+
echo "nf-test command failed with exit code $?"
40+
echo "Full output: $nftest_output"
41+
exit 1
42+
}
43+
else
44+
nftest_output=$(nf-test test \
45+
--profile +docker \
46+
$(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \
47+
--dry-run \
48+
--ci \
49+
--changed-since HEAD^) || {
50+
echo "nf-test command failed with exit code $?"
51+
echo "Full output: $nftest_output"
52+
exit 1
53+
}
54+
fi
4255
echo "nf-test dry-run output: $nftest_output"
4356
4457
# Default values for shard and total_shards

.github/actions/nf-test/action.yml

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ inputs:
1111
description: "Total number of test shards(NOT the total number of matrix jobs)"
1212
required: true
1313
paths:
14-
description: "Test paths"
15-
required: true
14+
description: "Test paths (when provided, run path-based; otherwise use tags and --changed-since)"
15+
required: false
1616
tags:
1717
description: "Tags to pass as argument for nf-test --tag parameter"
1818
required: false
@@ -61,17 +61,28 @@ runs:
6161
env:
6262
NFT_WORKDIR: ${{ env.NFT_WORKDIR }}
6363
run: |
64-
nf-test test \
65-
--profile=+${{ inputs.profile }} \
66-
$(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \
67-
--ci \
68-
--changed-since HEAD^ \
69-
--verbose \
70-
--tap=test.tap \
71-
--shard ${{ inputs.shard }}/${{ inputs.total_shards }}
64+
if [ -n "${{ inputs.paths }}" ]; then
65+
nf-test test \
66+
--profile=+${{ inputs.profile }} \
67+
--ci \
68+
--verbose \
69+
--tap=test.tap \
70+
--shard ${{ inputs.shard }}/${{ inputs.total_shards }} \
71+
--filter process,workflow \
72+
${{ inputs.paths }}
73+
else
74+
nf-test test \
75+
--profile=+${{ inputs.profile }} \
76+
$(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \
77+
--ci \
78+
--changed-since HEAD^ \
79+
--verbose \
80+
--tap=test.tap \
81+
--shard ${{ inputs.shard }}/${{ inputs.total_shards }}
82+
fi
7283
73-
# Save the absolute path of the test.tap file to the output
74-
echo "tap_file_path=$(realpath test.tap)" >> $GITHUB_OUTPUT
84+
# Save the absolute path of the test.tap file to the output
85+
echo "tap_file_path=$(realpath test.tap)" >> $GITHUB_OUTPUT
7586
7687
- name: Generate test summary
7788
if: always()

.github/workflows/nf-test-gpu.yml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: Run GPU nf-tests
2+
on:
3+
push:
4+
branches:
5+
- dev
6+
- master
7+
- main
8+
paths-ignore:
9+
- "docs/**"
10+
- "**/meta.yml"
11+
- "**/*.md"
12+
- "**/*.png"
13+
- "**/*.svg"
14+
pull_request:
15+
paths-ignore:
16+
- "docs/**"
17+
- "**/meta.yml"
18+
- "**/*.md"
19+
- "**/*.png"
20+
- "**/*.svg"
21+
workflow_dispatch:
22+
23+
# Cancel if a newer run is started
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
26+
cancel-in-progress: true
27+
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
NFT_VER: "0.9.3"
31+
NFT_WORKDIR: "~"
32+
NXF_ANSI_LOG: false
33+
NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity
34+
NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity
35+
NXF_VER: "25.10.0"
36+
37+
jobs:
38+
nf-test-changes:
39+
name: nf-test-changes
40+
runs-on: # use self-hosted runners; use a GPU-capable runner for nf-test-gpu job
41+
- runs-on=${{ github.run_id }}-nf-test-changes-gpu
42+
- runner=4cpu-linux-x64
43+
outputs:
44+
paths: ${{ steps.list.outputs.components }}
45+
shard: ${{ steps.shard-outputs.outputs.shard }}
46+
total_shards: ${{ steps.shard-outputs.outputs.total_shards }}
47+
steps:
48+
- name: Clean Workspace
49+
run: |
50+
ls -la ./
51+
rm -rf ./* || true
52+
rm -rf ./.??* || true
53+
ls -la ./
54+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
55+
with:
56+
fetch-depth: 0
57+
58+
- name: List nf-test files (GPU only)
59+
id: list
60+
uses: adamrtalbot/detect-nf-test-changes@de3c3c8e113031b4f15a3c1104b5f135e8346997 # v0.0.6
61+
with:
62+
head: ${{ github.sha }}
63+
base: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || 'origin/main' }}
64+
n_parents: 0
65+
tags: "gpu"
66+
67+
- name: get number of shards
68+
id: set-shards
69+
if: ${{ steps.list.outputs.components != '[]' }}
70+
uses: ./.github/actions/get-shards
71+
env:
72+
NFT_VER: ${{ env.NFT_VER }}
73+
with:
74+
max_shards: 2
75+
paths: "${{ join(fromJson(steps.list.outputs.components), ' ') }}"
76+
77+
- name: Set shard outputs
78+
id: shard-outputs
79+
run: |
80+
if [ '${{ steps.list.outputs.components }}' = '[]' ]; then
81+
echo "shard=[]" >> $GITHUB_OUTPUT
82+
echo "total_shards=0" >> $GITHUB_OUTPUT
83+
else
84+
echo "shard=${{ steps.set-shards.outputs.shard }}" >> $GITHUB_OUTPUT
85+
echo "total_shards=${{ steps.set-shards.outputs.total_shards }}" >> $GITHUB_OUTPUT
86+
fi
87+
88+
- name: debug
89+
run: |
90+
echo ${{ steps.list.outputs.components }}
91+
echo ${{ steps.shard-outputs.outputs.shard }}
92+
echo ${{ steps.shard-outputs.outputs.total_shards }}
93+
94+
nf-test-gpu:
95+
name: "GPU | ${{ matrix.profile }} | ${{ matrix.shard }}/${{ needs.nf-test-changes.outputs.total_shards }}"
96+
needs: [nf-test-changes]
97+
if: ${{ needs.nf-test-changes.outputs.total_shards != '0' }}
98+
runs-on: # use a GPU-capable runner (e.g. self-hosted with GPU or cloud GPU instance)
99+
- runs-on=${{ github.run_id }}-nf-test-gpu
100+
- runner=4cpu-linux-x64
101+
- gpu
102+
strategy:
103+
fail-fast: false
104+
matrix:
105+
shard: ${{ fromJson(needs.nf-test-changes.outputs.shard) }}
106+
profile: [docker, singularity]
107+
env:
108+
NXF_ANSI_LOG: false
109+
TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }}
110+
NXF_VERSION: ${{ env.NXF_VER }}
111+
112+
steps:
113+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
114+
with:
115+
fetch-depth: 0
116+
117+
- name: Verify GPU
118+
run: |
119+
nvidia-smi -L || true
120+
121+
- name: Run nf-test
122+
id: run_nf_test
123+
uses: ./.github/actions/nf-test
124+
env:
125+
NFT_WORKDIR: ${{ env.NFT_WORKDIR }}
126+
NXF_VERSION: ${{ env.NXF_VER }}
127+
with:
128+
profile: ${{ matrix.profile }},gpu
129+
shard: ${{ matrix.shard }}
130+
total_shards: ${{ env.TOTAL_SHARDS }}
131+
paths: "${{ join(fromJson(needs.nf-test-changes.outputs.paths), ' ') }}"
132+
133+
confirm-pass-gpu:
134+
needs: [nf-test-gpu]
135+
if: always()
136+
runs-on:
137+
- runs-on=${{ github.run_id }}-confirm-pass-gpu
138+
- runner=2cpu-linux-x64
139+
steps:
140+
- name: One or more tests failed
141+
if: ${{ contains(needs.*.result, 'failure') }}
142+
run: exit 1
143+
144+
- name: One or more tests cancelled
145+
if: ${{ contains(needs.*.result, 'cancelled') }}
146+
run: exit 1
147+
148+
- name: All tests ok
149+
if: ${{ contains(needs.*.result, 'success') }}
150+
run: exit 0
151+
152+
- name: debug-print
153+
if: always()
154+
run: |
155+
echo "toJSON(needs) = ${{ toJSON(needs) }}"
156+
echo "toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}"

.github/workflows/nf-test.yml

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ jobs:
4242
- runs-on=${{ github.run_id }}-nf-test-changes
4343
- runner=4cpu-linux-x64
4444
outputs:
45-
shard: ${{ steps.set-shards.outputs.shard }}
46-
total_shards: ${{ steps.set-shards.outputs.total_shards }}
45+
paths: ${{ steps.list.outputs.components }}
46+
shard: ${{ steps.shard-outputs.outputs.shard }}
47+
total_shards: ${{ steps.shard-outputs.outputs.total_shards }}
4748
steps:
4849
- name: Clean Workspace # Purge the workspace in case it's running on a self-hosted runner
4950
run: |
@@ -55,19 +56,41 @@ jobs:
5556
with:
5657
fetch-depth: 0
5758

59+
- name: List nf-test files
60+
id: list
61+
uses: adamrtalbot/detect-nf-test-changes@de3c3c8e113031b4f15a3c1104b5f135e8346997 # v0.0.6
62+
with:
63+
head: ${{ github.sha }}
64+
base: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || 'origin/main' }}
65+
n_parents: 0
66+
exclude_tags: "gpu"
67+
5868
- name: get number of shards
5969
id: set-shards
70+
if: ${{ steps.list.outputs.components != '[]' }}
6071
uses: ./.github/actions/get-shards
6172
env:
6273
NFT_VER: ${{ env.NFT_VER }}
6374
with:
6475
max_shards: 25
65-
tags: modules_local,subworkflows_local,pipeline
76+
paths: "${{ join(fromJson(steps.list.outputs.components), ' ') }}"
77+
78+
- name: Set shard outputs
79+
id: shard-outputs
80+
run: |
81+
if [ '${{ steps.list.outputs.components }}' = '[]' ]; then
82+
echo "shard=[]" >> $GITHUB_OUTPUT
83+
echo "total_shards=0" >> $GITHUB_OUTPUT
84+
else
85+
echo "shard=${{ steps.set-shards.outputs.shard }}" >> $GITHUB_OUTPUT
86+
echo "total_shards=${{ steps.set-shards.outputs.total_shards }}" >> $GITHUB_OUTPUT
87+
fi
6688
6789
- name: debug
6890
run: |
69-
echo ${{ steps.set-shards.outputs.shard }}
70-
echo ${{ steps.set-shards.outputs.total_shards }}
91+
echo ${{ steps.list.outputs.components }}
92+
echo ${{ steps.shard-outputs.outputs.shard }}
93+
echo ${{ steps.shard-outputs.outputs.total_shards }}
7194
7295
nf-test:
7396
name: "${{ matrix.profile }} | ${{ matrix.NXF_VER }} | ${{ matrix.shard }}/${{ needs.nf-test-changes.outputs.total_shards }}"
@@ -113,6 +136,7 @@ jobs:
113136
profile: ${{ matrix.profile }}
114137
shard: ${{ matrix.shard }}
115138
total_shards: ${{ env.TOTAL_SHARDS }}
139+
paths: "${{ join(fromJson(needs.nf-test-changes.outputs.paths), ' ') }}"
116140

117141
- name: Report test status
118142
if: ${{ always() }}

modules/local/rapidssinglecell/bbknn/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
test("Should run without failures") {
1112

modules/local/rapidssinglecell/filter/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
test("Should run without failures") {
1112

modules/local/rapidssinglecell/harmony/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
test("Should run without failures") {
1112

modules/local/rapidssinglecell/hvgs/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
test("Should run without a specified number of HVGs") {
1112

modules/local/rapidssinglecell/leiden/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
setup {
1112
run("RAPIDSSINGLECELL_PCA") {

modules/local/rapidssinglecell/neighbors/tests/main.nf.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ nextflow_process {
66

77
tag "modules"
88
tag "modules_local"
9+
tag "gpu"
910

1011
setup {
1112
run("RAPIDSSINGLECELL_PCA") {

0 commit comments

Comments
 (0)