-
Notifications
You must be signed in to change notification settings - Fork 117
155 lines (150 loc) · 6.87 KB
/
Copy pathbenchmarks_pr.yml
File metadata and controls
155 lines (150 loc) · 6.87 KB
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
name: Continuous Benchmark (PR)
on:
pull_request:
permissions:
contents: read
issues: write
pull-requests: write
concurrency:
# Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
# On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
cancel-in-progress: true
jobs:
benchmark:
name: ${{ matrix.device }} Pytest benchmark
runs-on: linux.g5.4xlarge.nvidia.gpu
strategy:
matrix:
device: [CPU, GPU]
python-version: ['3.12']
defaults:
run:
shell: bash -l {0}
container:
image: nvidia/cuda:12.8.0-runtime-ubuntu22.04
options: --gpus all
steps:
- name: Who triggered this?
run: |
echo "Action triggered by ${{ github.event.pull_request.html_url }}"
- name: Install deps
run: |
export TZ=Europe/London
export DEBIAN_FRONTEND=noninteractive # tzdata bug
apt-get update -y
apt-get update -y
apt-get upgrade -y
apt-get -y install gcc curl g++ unzip wget sudo git cmake
- name: Check ldd --version
run: ldd --version
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 50 # this is to make sure we obtain the target base commit
- name: Python Setup
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Setup git
run: git config --global --add safe.directory /__w/tensordict/tensordict
- name: setup Path
run: |
echo /usr/local/bin >> $GITHUB_PATH
- name: Setup Environment
run: |
set -e
set -x
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
source $HOME/.local/bin/env
# Create a local venv for the benchmark run
uv venv .venv/local --python ${{ matrix.python-version }}
source .venv/local/bin/activate
echo "=== uv version ==="
uv --version
uv pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cu128
uv pip install "pybind11[global]" "setuptools" "wheel" "ninja"
uv pip install pytest pytest-benchmark "zarr>=3.0"
# Do not resolve runtime dependencies here: we want to keep the PyTorch build (nightly)
# that was explicitly installed above, and avoid any solver replacing it.
uv pip install -e . --no-deps
uv run --active python -c "import torch; print(torch.__version__)"
${{ matrix.device == 'CPU' && 'export CUDA_VISIBLE_DEVICES=' || '' }}
- name: check GPU presence
if: matrix.device == 'GPU'
run: |
source .venv/local/bin/activate
uv run --active python -c """import torch
print(f'CUDA available: {torch.cuda.is_available()}')
print(f'CUDA device count: {torch.cuda.device_count()}')
print(f'CUDA version: {torch.version.cuda}')
assert torch.cuda.is_available() and torch.cuda.device_count() > 0, 'CUDA is not available or no GPU devices found'
"""
- name: Setup benchmarks
run: |
source .venv/local/bin/activate
echo "BASE_SHA=$(echo ${{ github.event.pull_request.base.sha }} | cut -c1-8)" >> $GITHUB_ENV
echo "HEAD_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-8)" >> $GITHUB_ENV
echo "BASELINE_JSON=${RUNNER_TEMP}/${{ matrix.device }}-baseline.json" >> $GITHUB_ENV
echo "CONTENDER_JSON=${RUNNER_TEMP}/${{ matrix.device }}-contender.json" >> $GITHUB_ENV
echo "PR_COMMENT=$(mktemp)" >> $GITHUB_ENV
- name: Run benchmarks
run: |
set -e
set -x
source .venv/local/bin/activate
cd benchmarks/
# Check Python version to ensure compatibility with PyTorch Dynamo
uv run --active python --version
uv run --active python -c "import sys; actual_version = f'{sys.version_info.major}.{sys.version_info.minor}'; expected_version = '${{ matrix.python-version }}'; print(f'Expected: {expected_version}, Actual: {actual_version}'); exit(1) if actual_version != expected_version else None; exit(1) if sys.version_info >= (3, 13) else print(f'Python version check passed: {actual_version}')"
export TORCHDYNAMO_INLINE_INBUILT_NN_MODULES=1
export TD_GET_DEFAULTS_TO_NONE=1
RUN_BENCHMARK="uv run --active pytest -vvv --rank 0 --benchmark-json "
git checkout ${{ github.event.pull_request.base.sha }}
$RUN_BENCHMARK ${{ env.BASELINE_JSON }}
git checkout ${{ github.event.pull_request.head.sha }}
$RUN_BENCHMARK ${{ env.CONTENDER_JSON }}
- name: Align benchmark JSONs
run: |
python3 -c "
import json
with open('${{ env.BASELINE_JSON }}') as f:
baseline = json.load(f)
with open('${{ env.CONTENDER_JSON }}') as f:
contender = json.load(f)
base_names = {b['fullname'] for b in baseline['benchmarks']}
cont_names = {b['fullname'] for b in contender['benchmarks']}
common = base_names & cont_names
new_tests = cont_names - base_names
removed_tests = base_names - cont_names
if new_tests:
print(f'New benchmarks (skipped in comparison): {new_tests}')
if removed_tests:
print(f'Removed benchmarks (skipped in comparison): {removed_tests}')
baseline['benchmarks'] = [b for b in baseline['benchmarks'] if b['fullname'] in common]
contender['benchmarks'] = [b for b in contender['benchmarks'] if b['fullname'] in common]
with open('${{ env.BASELINE_JSON }}', 'w') as f:
json.dump(baseline, f)
with open('${{ env.CONTENDER_JSON }}', 'w') as f:
json.dump(contender, f)
"
- name: Upload benchmark comparison data
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.device }}-benchmark-comparison-data
path: |
${{ env.BASELINE_JSON }}
${{ env.CONTENDER_JSON }}
- name: Publish results
continue-on-error: true
uses: apbard/pytest-benchmark-commenter@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
benchmark-file: ${{ env.CONTENDER_JSON }}
comparison-benchmark-file: ${{ env.BASELINE_JSON }}
benchmark-metrics: 'name,max,mean,ops'
comparison-benchmark-metric: 'ops'
comparison-higher-is-better: true
comparison-threshold: 5
benchmark-title: 'Result of ${{ matrix.device }} Benchmark Tests'