build-perf-analyzer #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |