Skip to content

Commit 4995653

Browse files
committed
Tests: Add CUDA tools tests for accelerated-python, cuda-cpp, and stdpar tutorials.
1 parent 77d5782 commit 4995653

File tree

8 files changed

+337
-13
lines changed

8 files changed

+337
-13
lines changed

tutorials/accelerated-python/brev/test.bash

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,20 @@ START_TIME=$(date +%s.%N)
44

55
nvidia-smi
66

7-
# Run regular package tests.
8-
echo "Running regular package tests..."
9-
pytest /accelerated-computing-hub/tutorials/accelerated-python/test/test_packages.py
10-
EXIT_CODE_PACKAGES=$?
7+
# Run tests.
8+
echo "Running tests..."
9+
pytest /accelerated-computing-hub/tutorials/accelerated-python/test/ \
10+
--ignore=/accelerated-computing-hub/tutorials/accelerated-python/test/test_rapids.py
11+
EXIT_CODE_TESTS=$?
1112

12-
# Run RAPIDS tests.
13+
# Run RAPIDS tests separately because they require a different virtual environment.
1314
echo ""
14-
echo "Running RAPIDS package tests in virtual environment..."
15+
echo "Running RAPIDS tests in virtual environment..."
1516
/opt/venvs/rapids/bin/pytest /accelerated-computing-hub/tutorials/accelerated-python/test/test_rapids.py
1617
EXIT_CODE_RAPIDS=$?
1718

18-
# Test solution notebooks.
19-
echo ""
20-
echo "Running solution notebook tests..."
21-
pytest /accelerated-computing-hub/tutorials/accelerated-python/test/test_notebooks.py
22-
EXIT_CODE_NOTEBOOKS=$?
23-
2419
# Overall exit code is non-zero if any test suite failed.
25-
EXIT_CODE=$((EXIT_CODE_PACKAGES || EXIT_CODE_RAPIDS || EXIT_CODE_NOTEBOOKS))
20+
EXIT_CODE=$((EXIT_CODE_TESTS || EXIT_CODE_RAPIDS))
2621

2722
END_TIME=$(date +%s.%N)
2823
ELAPSED=$(awk "BEGIN {print $END_TIME - $START_TIME}")
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""
2+
Test that CUDA tools (nvcc, nsys, ncu) work correctly.
3+
4+
Compiles a minimal CUDA C++ program using Thrust and verifies that both
5+
Nsight Systems and Nsight Compute can successfully profile it.
6+
"""
7+
8+
import pytest
9+
import subprocess
10+
from pathlib import Path
11+
12+
CUDA_PROGRAM = r"""
13+
#include <thrust/device_vector.h>
14+
#include <thrust/sequence.h>
15+
#include <thrust/reduce.h>
16+
#include <iostream>
17+
#include <cstdlib>
18+
19+
int main() {
20+
constexpr int n = 256;
21+
22+
thrust::device_vector<float> d(n);
23+
thrust::sequence(d.begin(), d.end());
24+
25+
float sum = thrust::reduce(d.begin(), d.end());
26+
float expected = n * (n - 1) / 2.0f;
27+
28+
if (sum != expected) {
29+
std::cerr << "Mismatch: got " << sum << ", expected " << expected << std::endl;
30+
return EXIT_FAILURE;
31+
}
32+
33+
std::cout << "PASS" << std::endl;
34+
}
35+
"""
36+
37+
38+
@pytest.fixture(scope="module")
39+
def cuda_binary(tmp_path_factory):
40+
"""Compile a minimal CUDA C++ program and return the path to the binary."""
41+
tmp_dir = tmp_path_factory.mktemp("nsight_test")
42+
src_path = tmp_dir / "test_program.cu"
43+
bin_path = tmp_dir / "test_program"
44+
45+
src_path.write_text(CUDA_PROGRAM)
46+
47+
result = subprocess.run(
48+
["nvcc", "-o", str(bin_path), str(src_path)],
49+
capture_output=True, text=True, timeout=120
50+
)
51+
assert result.returncode == 0, \
52+
f"nvcc compilation failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
53+
assert bin_path.exists(), "Binary was not created"
54+
55+
return bin_path
56+
57+
58+
def test_cuda_binary_runs(cuda_binary):
59+
"""Verify the compiled CUDA binary runs successfully."""
60+
result = subprocess.run(
61+
[str(cuda_binary)],
62+
capture_output=True, text=True, timeout=30
63+
)
64+
assert result.returncode == 0, \
65+
f"CUDA binary failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
66+
assert "PASS" in result.stdout
67+
68+
69+
def test_nsys_profile(cuda_binary, tmp_path):
70+
"""Test that nsys can profile the CUDA binary."""
71+
report_path = tmp_path / "test_report.nsys-rep"
72+
73+
result = subprocess.run(
74+
["nsys", "profile",
75+
"--force-overwrite=true",
76+
"--output", str(report_path),
77+
str(cuda_binary)],
78+
capture_output=True, text=True, timeout=120
79+
)
80+
assert result.returncode == 0, \
81+
f"nsys profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
82+
assert report_path.exists(), "nsys report file was not created"
83+
84+
85+
def test_ncu_profile(cuda_binary):
86+
"""Test that ncu can profile the CUDA binary."""
87+
result = subprocess.run(
88+
["ncu",
89+
"--target-processes=all",
90+
"--set=basic",
91+
str(cuda_binary)],
92+
capture_output=True, text=True, timeout=120
93+
)
94+
assert result.returncode == 0, \
95+
f"ncu profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"

tutorials/cuda-cpp/brev/test.bash

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
11
#! /bin/bash
22

3+
START_TIME=$(date +%s.%N)
4+
35
nvidia-smi
6+
7+
# Run tests.
8+
echo "Running tests..."
9+
pytest /accelerated-computing-hub/tutorials/cuda-cpp/test/
10+
EXIT_CODE=$?
11+
12+
END_TIME=$(date +%s.%N)
13+
ELAPSED=$(awk "BEGIN {print $END_TIME - $START_TIME}")
14+
15+
echo ""
16+
awk -v elapsed="$ELAPSED" 'BEGIN {
17+
hours = int(elapsed / 3600)
18+
minutes = int((elapsed % 3600) / 60)
19+
seconds = elapsed % 60
20+
printf "Elapsed time: %dh %dm %.3fs\n", hours, minutes, seconds
21+
}'
22+
23+
exit $EXIT_CODE

tutorials/cuda-cpp/test/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
addopts = -v -s --durations=0 --durations-min=0.0
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""
2+
Test that CUDA tools (nvcc, nsys, ncu) work correctly.
3+
4+
Compiles a minimal CUDA C++ program using Thrust and verifies that both
5+
Nsight Systems and Nsight Compute can successfully profile it.
6+
"""
7+
8+
import pytest
9+
import subprocess
10+
from pathlib import Path
11+
12+
CUDA_PROGRAM = r"""
13+
#include <thrust/device_vector.h>
14+
#include <thrust/sequence.h>
15+
#include <thrust/reduce.h>
16+
#include <iostream>
17+
#include <cstdlib>
18+
19+
int main() {
20+
constexpr int n = 256;
21+
22+
thrust::device_vector<float> d(n);
23+
thrust::sequence(d.begin(), d.end());
24+
25+
float sum = thrust::reduce(d.begin(), d.end());
26+
float expected = n * (n - 1) / 2.0f;
27+
28+
if (sum != expected) {
29+
std::cerr << "Mismatch: got " << sum << ", expected " << expected << std::endl;
30+
return EXIT_FAILURE;
31+
}
32+
33+
std::cout << "PASS" << std::endl;
34+
}
35+
"""
36+
37+
38+
@pytest.fixture(scope="module")
39+
def cuda_binary(tmp_path_factory):
40+
"""Compile a minimal CUDA C++ program and return the path to the binary."""
41+
tmp_dir = tmp_path_factory.mktemp("nsight_test")
42+
src_path = tmp_dir / "test_program.cu"
43+
bin_path = tmp_dir / "test_program"
44+
45+
src_path.write_text(CUDA_PROGRAM)
46+
47+
result = subprocess.run(
48+
["nvcc", "-o", str(bin_path), str(src_path)],
49+
capture_output=True, text=True, timeout=120
50+
)
51+
assert result.returncode == 0, \
52+
f"nvcc compilation failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
53+
assert bin_path.exists(), "Binary was not created"
54+
55+
return bin_path
56+
57+
58+
def test_cuda_binary_runs(cuda_binary):
59+
"""Verify the compiled CUDA binary runs successfully."""
60+
result = subprocess.run(
61+
[str(cuda_binary)],
62+
capture_output=True, text=True, timeout=30
63+
)
64+
assert result.returncode == 0, \
65+
f"CUDA binary failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
66+
assert "PASS" in result.stdout
67+
68+
69+
def test_nsys_profile(cuda_binary, tmp_path):
70+
"""Test that nsys can profile the CUDA binary."""
71+
report_path = tmp_path / "test_report.nsys-rep"
72+
73+
result = subprocess.run(
74+
["nsys", "profile",
75+
"--force-overwrite=true",
76+
"--output", str(report_path),
77+
str(cuda_binary)],
78+
capture_output=True, text=True, timeout=120
79+
)
80+
assert result.returncode == 0, \
81+
f"nsys profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
82+
assert report_path.exists(), "nsys report file was not created"
83+
84+
85+
def test_ncu_profile(cuda_binary):
86+
"""Test that ncu can profile the CUDA binary."""
87+
result = subprocess.run(
88+
["ncu",
89+
"--target-processes=all",
90+
"--set=basic",
91+
str(cuda_binary)],
92+
capture_output=True, text=True, timeout=120
93+
)
94+
assert result.returncode == 0, \
95+
f"ncu profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"

tutorials/stdpar/brev/test.bash

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
11
#! /bin/bash
22

3+
START_TIME=$(date +%s.%N)
4+
35
nvidia-smi
6+
7+
# Run tests.
8+
echo "Running tests..."
9+
pytest /accelerated-computing-hub/tutorials/stdpar/test/
10+
EXIT_CODE=$?
11+
12+
END_TIME=$(date +%s.%N)
13+
ELAPSED=$(awk "BEGIN {print $END_TIME - $START_TIME}")
14+
15+
echo ""
16+
awk -v elapsed="$ELAPSED" 'BEGIN {
17+
hours = int(elapsed / 3600)
18+
minutes = int((elapsed % 3600) / 60)
19+
seconds = elapsed % 60
20+
printf "Elapsed time: %dh %dm %.3fs\n", hours, minutes, seconds
21+
}'
22+
23+
exit $EXIT_CODE

tutorials/stdpar/test/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
addopts = -v -s --durations=0 --durations-min=0.0
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""
2+
Test that CUDA tools (nvcc, nsys, ncu) work correctly.
3+
4+
Compiles a minimal CUDA C++ program using Thrust and verifies that both
5+
Nsight Systems and Nsight Compute can successfully profile it.
6+
"""
7+
8+
import pytest
9+
import subprocess
10+
from pathlib import Path
11+
12+
CUDA_PROGRAM = r"""
13+
#include <thrust/device_vector.h>
14+
#include <thrust/sequence.h>
15+
#include <thrust/reduce.h>
16+
#include <iostream>
17+
#include <cstdlib>
18+
19+
int main() {
20+
constexpr int n = 256;
21+
22+
thrust::device_vector<float> d(n);
23+
thrust::sequence(d.begin(), d.end());
24+
25+
float sum = thrust::reduce(d.begin(), d.end());
26+
float expected = n * (n - 1) / 2.0f;
27+
28+
if (sum != expected) {
29+
std::cerr << "Mismatch: got " << sum << ", expected " << expected << std::endl;
30+
return EXIT_FAILURE;
31+
}
32+
33+
std::cout << "PASS" << std::endl;
34+
}
35+
"""
36+
37+
38+
@pytest.fixture(scope="module")
39+
def cuda_binary(tmp_path_factory):
40+
"""Compile a minimal CUDA C++ program and return the path to the binary."""
41+
tmp_dir = tmp_path_factory.mktemp("nsight_test")
42+
src_path = tmp_dir / "test_program.cu"
43+
bin_path = tmp_dir / "test_program"
44+
45+
src_path.write_text(CUDA_PROGRAM)
46+
47+
result = subprocess.run(
48+
["nvcc", "-o", str(bin_path), str(src_path)],
49+
capture_output=True, text=True, timeout=120
50+
)
51+
assert result.returncode == 0, \
52+
f"nvcc compilation failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
53+
assert bin_path.exists(), "Binary was not created"
54+
55+
return bin_path
56+
57+
58+
def test_cuda_binary_runs(cuda_binary):
59+
"""Verify the compiled CUDA binary runs successfully."""
60+
result = subprocess.run(
61+
[str(cuda_binary)],
62+
capture_output=True, text=True, timeout=30
63+
)
64+
assert result.returncode == 0, \
65+
f"CUDA binary failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
66+
assert "PASS" in result.stdout
67+
68+
69+
def test_nsys_profile(cuda_binary, tmp_path):
70+
"""Test that nsys can profile the CUDA binary."""
71+
report_path = tmp_path / "test_report.nsys-rep"
72+
73+
result = subprocess.run(
74+
["nsys", "profile",
75+
"--force-overwrite=true",
76+
"--output", str(report_path),
77+
str(cuda_binary)],
78+
capture_output=True, text=True, timeout=120
79+
)
80+
assert result.returncode == 0, \
81+
f"nsys profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
82+
assert report_path.exists(), "nsys report file was not created"
83+
84+
85+
def test_ncu_profile(cuda_binary):
86+
"""Test that ncu can profile the CUDA binary."""
87+
result = subprocess.run(
88+
["ncu",
89+
"--target-processes=all",
90+
"--set=basic",
91+
str(cuda_binary)],
92+
capture_output=True, text=True, timeout=120
93+
)
94+
assert result.returncode == 0, \
95+
f"ncu profile failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"

0 commit comments

Comments
 (0)