Repository navigation
230 lines (201 loc) · 9.65 KB
/
Copy pathbuild-perf-analyzer.yml
File metadata and controls
230 lines (201 loc) · 9.65 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
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
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# perf_analyzer tags no release; PyPI's 2.60.0 wheels were built from the r26.04
# head, the commit their binary reports in `perf_analyzer --version`. Upstream's
# wheel build runs in NVIDIA's internal CI, so this follows the documented
# source build (docs/install.md) and packages the binary with the repo's own
# pyproject.toml.
name: Build perf-analyzer wheels (riscv64)
on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/perf-analyzer.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-perf-analyzer.yml'
- 'docs/packages/perf-analyzer.yaml'
- 'patches/perf-analyzer/**'
push:
branches: [main]
paths:
- '.github/workflows/build-perf-analyzer.yml'
- 'docs/packages/perf-analyzer.yaml'
- 'patches/perf-analyzer/**'
run-name: build-perf-analyzer ${{ inputs.version && format('- {0}', inputs.version) || '' }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
env:
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
# Move together with the version in docs/packages/perf-analyzer.yaml.
PERF_ANALYZER_REF: 3a49a23abf06242ed170ee479b5e2e080e4250e6
TRITON_RELEASE_BRANCH: r26.04
# Rocky 10 packages no RapidJSON, and its 1.1.0 release does not compile with GCC 14.
RAPIDJSON_REF: 24b5e7a8b27f42fa16b96fc70aade9106cf7102f
jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: perf-analyzer
version: ${{ inputs.version }}
build_wheels:
name: Build perf-analyzer ${{ matrix.version }} py3-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 720
needs: [setup]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
env:
PERF_ANALYZER_VERSION: ${{ matrix.version }}
steps:
- name: Checkout triton-inference-server/perf_analyzer @ ${{ env.PERF_ANALYZER_REF }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: triton-inference-server/perf_analyzer
ref: ${{ env.PERF_ANALYZER_REF }}
path: perf_analyzer
persist-credentials: false
- name: Checkout python-wheels
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: python-wheels
persist-credentials: false
- name: Apply patches
working-directory: perf_analyzer
run: |
for p in ../python-wheels/patches/perf-analyzer/${PERF_ANALYZER_VERSION}/*.patch; do
git apply --verbose "$p"
done
- name: Pull manylinux_riscv64 image
run: docker pull "${MANYLINUX_RISCV64_IMAGE}"
- name: Build wheel
run: |
mkdir -p wheelhouse
set -o pipefail
docker run --rm -i --network=host \
-v "${GITHUB_WORKSPACE}:/work" \
-w /work \
-e PERF_ANALYZER_VERSION \
-e TRITON_RELEASE_BRANCH \
-e RAPIDJSON_REF \
"${MANYLINUX_RISCV64_IMAGE}" \
bash <<'SCRIPT' 2>&1 | tee build.log
set -eux
dnf install -y --disablerepo=extras --setopt=install_weak_deps=False openssl-devel zlib-ng-compat-devel
export PATH="/opt/python/cp312-cp312/bin:${PATH}"
git config --global --add safe.directory '*'
# c-ares, as pinned by gRPC v1.54.3, declares a cmake_minimum_required below CMake 4's floor.
export CMAKE_POLICY_VERSION_MINIMUM=3.5
# abseil lts_20230125 reads the cycle counter with rdcycle, which Linux 6.6+ traps as SIGILL
# on riscv64; abseil dropped that path for RISC-V upstream (abseil/abseil-cpp#1644).
export CXXFLAGS="-DABSL_USE_UNSCALED_CYCLECLOCK=0"
# perf_analyzer links non-PIE at riscv64's 0x10000 (= mmap_min_addr); the segment auditwheel's
# patchelf prepends for the RPATH would land below it and the CLI would die at exec (gotcha 595).
export LDFLAGS="-Wl,-Ttext-segment=0x200000"
git clone -q https://github.com/Tencent/rapidjson /tmp/rapidjson
git -C /tmp/rapidjson checkout -q "${RAPIDJSON_REF}"
cmake -S /tmp/rapidjson -B /tmp/rapidjson/build \
-DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD_TESTS=OFF
cmake --install /tmp/rapidjson/build
cd /work/perf_analyzer
PA_VERSION="$(python -c 'import runpy; print(runpy.run_path("src/perf_analyzer/__init__.py")["__version__"])')"
test "${PA_VERSION}" = "${PERF_ANALYZER_VERSION}"
cmake -B /tmp/build -S . \
-DTRITON_ENABLE_GPU=OFF \
-DTRITON_CLIENT_REPO_TAG="${TRITON_RELEASE_BRANCH}" \
-DTRITON_COMMON_REPO_TAG="${TRITON_RELEASE_BRANCH}" \
-DTRITON_CORE_REPO_TAG="${TRITON_RELEASE_BRANCH}" \
-DTRITON_THIRD_PARTY_REPO_TAG="${TRITON_RELEASE_BRANCH}"
cmake --build /tmp/build --parallel "$(nproc)"
mkdir /tmp/unit-tests
# "invalid json" asserts RapidJSON 1.1.0's error code 10, which Tencent/rapidjson@85500e8 changed to 12.
# concurrency_sequence and custom_load_sequences' serial_sequences subcase assert wall-clock request
# counts, the latter while the workers still run; both fail intermittently on a busy runner (gotcha 594).
(cd /tmp/unit-tests && /usr/local/bin/perf_analyzer_unit_tests \
--subcase-exclude="invalid json,serial_sequences" \
--test-case-exclude="concurrency_sequence")
CC=/tmp/build/cc_clients/src/cc-clients
TP=/tmp/build/cc_clients/src/cc-clients-build/_deps/repo-third-party-build
PA=/tmp/build/perf_analyzer/src/perf-analyzer-build/_deps
install -m 0644 "${CC}/LICENSE" LICENSE.triton-client
install -m 0644 "${PA}/repo-common-src/LICENSE" LICENSE.triton-common
install -m 0644 "${TP}/grpc-repo/src/grpc/LICENSE" LICENSE.grpc
install -m 0644 "${TP}/grpc-repo/src/grpc/third_party/abseil-cpp/LICENSE" LICENSE.abseil-cpp
install -m 0644 "${TP}/grpc-repo/src/grpc/third_party/protobuf/LICENSE" LICENSE.protobuf
install -m 0644 "${TP}/grpc-repo/src/grpc/third_party/re2/LICENSE" LICENSE.re2
install -m 0644 "${TP}/grpc-repo/src/grpc/third_party/cares/cares/LICENSE.md" LICENSE.c-ares
install -m 0644 "${TP}/curl/src/curl/COPYING" LICENSE.curl
install -m 0644 "${PA}/libb64-src/LICENSE.md" LICENSE.libb64
install -m 0644 /tmp/rapidjson/license.txt LICENSE.rapidjson
install -m 0644 "$(rpm -qL openssl-libs | grep -m1 '/LICENSE')" LICENSE.openssl
install -D -m 0755 /usr/local/bin/perf_analyzer src/perf_analyzer/bin/perf_analyzer
python -m pip install -q -U pip wheel
python -m pip wheel --no-deps -w dist .
# The payload is a CLI the pure-Python wrapper execs, which is why upstream's wheels are py3-none.
python -m wheel tags --platform-tag linux_riscv64 --remove dist/*.whl
auditwheel repair --plat manylinux_2_39_riscv64 -w /work/wheelhouse dist/*.whl
SCRIPT
- name: Upload build log
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: perf-analyzer-${{ env.PERF_ANALYZER_VERSION }}-build-log
path: build.log
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: perf-analyzer-${{ env.PERF_ANALYZER_VERSION }}-py3-manylinux_riscv64
path: wheelhouse/*.whl
if-no-files-found: error
- name: Test wheel
run: |
docker run --rm -i --network=host \
-v "${GITHUB_WORKSPACE}:/work" \
-e PERF_ANALYZER_REF \
"${MANYLINUX_RISCV64_IMAGE}" \
bash <<'SCRIPT'
set -eux
for py in cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t; do
venv="/tmp/venv-${py}"
"/opt/python/${py}/bin/python" -m venv "${venv}"
"${venv}/bin/python" -m pip install -q --only-binary=:all: /work/wheelhouse/*.whl
cd /tmp
"${venv}/bin/perf_analyzer" --version 2>&1 | tee /tmp/version.txt
grep -F "(commit ${PERF_ANALYZER_REF:0:7}" /tmp/version.txt
"${venv}/bin/python" - <<'PY'
import importlib.metadata as md
names = {p.name for p in md.files("perf-analyzer") if "licenses" in p.parts}
expected = {
"LICENSE", "LICENSE.triton-client", "LICENSE.triton-common", "LICENSE.grpc",
"LICENSE.abseil-cpp", "LICENSE.protobuf", "LICENSE.re2", "LICENSE.c-ares",
"LICENSE.curl", "LICENSE.libb64", "LICENSE.rapidjson", "LICENSE.openssl",
}
assert expected <= names, sorted(expected - names)
PY
done
SCRIPT
publish:
name: Publish perf-analyzer ${{ matrix.version }}
needs: [setup, build_wheels]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
secrets:
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
with:
artifact-pattern: perf-analyzer-${{ matrix.version }}-py3-manylinux_riscv64