From df8293c966f3ee01ce2f903d8192dd3cee379649 Mon Sep 17 00:00:00 2001 From: zhenzew Date: Wed, 5 Aug 2026 04:43:36 -0500 Subject: [PATCH 1/4] ci: pin OGA to 0.15.1 and the rebased AMDGPU integration PR Upstream published no v0.15.1 tag and rel-0.15.1 keeps moving, so both workflows check out the release commit instead of a tag. The AMDGPU integration moves from PR #2194 (v0.14.0) to PR #2376, which is the same integration ported to the 0.15.1 device-interface API. The OGA cache key now folds in the resolved head SHA of every patch PR instead of the PR number plus a hand-bumped mm token, so pushing a new commit to a patch PR invalidates the cache on its own. OGA builds with --no_telemetry: 0.15 enables 1DS telemetry by default, which pulls cpp_client_telemetry (plus curl and mbedtls on Linux) into a cold build and would ship Microsoft telemetry in AMD artifacts. --- .github/workflows/linux-build.yml | 55 ++++++++++++++++++------- .github/workflows/windows-build.yml | 62 +++++++++++++++++++++-------- docs/quick_start.md | 24 ++++++----- docs/quick_start_linux.md | 2 +- 4 files changed, 99 insertions(+), 44 deletions(-) diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 6e59fac7c..338819e0b 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -32,11 +32,13 @@ env: # ORT is still built from source either way). Part of the ort-install cache # key. Remove a PR once its fix lands in the pinned ONNX Runtime release. ONNXRUNTIME_PR_PATCHES: "" - OGA_VERSION: "0.14.0" + # onnxruntime-genai 0.15.1. Upstream published no v0.15.1 tag and rel-0.15.1 + # is a moving branch, so pin the release commit itself. + OGA_COMMIT: "3abf4a847fd7876e81d5d1ed3ad97d77284b37e4" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from - # pull/.patch and `git apply` on top of v. Part of the OGA - # cache key. Remove a PR once it lands in the pinned OGA release. - OGA_PR_PATCHES: "2194" + # pull/.patch and `git am` on top of OGA_COMMIT. Part of the OGA cache key. + # Remove a PR once it lands in the pinned OGA commit. + OGA_PR_PATCHES: "2376" # The GPU arch the artifact targets. CI runners have no GPU, so it is passed # explicitly (build.py auto-detects from /sys on a real GPU host). HIP_ARCHITECTURES: gfx1151 @@ -284,12 +286,39 @@ jobs: # build.py (whose target is the project .so) because OGA is a # CI/artifact concern. # ----------------------------------------------------------------------- + # A PR patch is fetched from the PR's head, which moves whenever the PR + # branch is updated, so the PR number alone does not identify the patch + # content. Resolve the head SHAs and fold them into the OGA cache key. + - name: Resolve OGA PR head SHAs + id: oga-pr-shas + env: + GH_TOKEN: ${{ github.token }} + OGA_PRS: ${{ env.OGA_PR_PATCHES }} + run: | + set -euo pipefail + prs="$(echo "$OGA_PRS" | xargs || true)" + if [ -z "$prs" ]; then + echo "shas=none" >> "$GITHUB_OUTPUT" + exit 0 + fi + shas="" + for pr in $prs; do + sha="$(gh api "repos/microsoft/onnxruntime-genai/pulls/${pr}" --jq .head.sha)" + if [ -z "$sha" ]; then + echo "Failed to resolve head SHA for OGA PR #${pr}" + exit 1 + fi + shas="${shas:+${shas}_}${pr}-${sha:0:12}" + done + echo "OGA PR heads: $shas" + echo "shas=$shas" >> "$GITHUB_OUTPUT" + - name: Cache OGA artifacts id: cache-oga uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ${{ runner.workspace }}/oga-artifacts - key: linux-oga-${{ env.OGA_VERSION }}-pr${{ env.OGA_PR_PATCHES }}-am-whl-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} + key: linux-oga-${{ env.OGA_COMMIT }}-pr${{ steps.oga-pr-shas.outputs.shas }}-am-whl-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} # Checkout + build are skipped on an OGA cache hit (step-level gate); the # install-copy below always runs so the @@ -299,7 +328,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: microsoft/onnxruntime-genai - ref: v${{ env.OGA_VERSION }} + ref: ${{ env.OGA_COMMIT }} submodules: recursive path: onnxruntime-genai fetch-depth: 1 @@ -307,11 +336,10 @@ jobs: # Fetch and apply microsoft/onnxruntime-genai PR patches listed in # OGA_PR_PATCHES (env). pull/.patch is a multi-commit mbox; `git am` - # replays each commit in order, so a PR that adds -> modifies -> renames - # the same path within its own series (e.g. #2194: morphizen_ep/* -> - # amdgpu/*) applies cleanly. `git apply` pre-checks every hunk against the - # base tree at once and self-conflicts on such a series. The OGA cache key - # includes the PR list, so editing it forces a rebuild. + # replays each commit in order, so a PR whose series adds -> modifies -> + # renames the same path applies cleanly. `git apply` pre-checks every hunk + # against the base tree at once and self-conflicts on such a series. The + # OGA cache key includes the PR heads, so editing the list forces a rebuild. - name: Apply OGA PR patches if: steps.cache-oga.outputs.cache-hit != 'true' working-directory: onnxruntime-genai @@ -324,10 +352,6 @@ jobs: echo "OGA_PR_PATCHES is empty; nothing to apply" exit 0 fi - # pull/.patch is a format-patch series; apply with `git am` so that - # intra-series file renames (morphizen_ep -> amdgpu) replay against the - # correct intermediate tree. `git apply` flattens the series and chokes - # on the rename whose pre-image only exists after an earlier commit. # git am needs a committer identity on a bare runner. git config user.email "ci@onnx-hipdnn-ep.local" git config user.name "onnx-hipdnn-ep CI" @@ -367,6 +391,7 @@ jobs: --cmake_generator Ninja \ --ort_home "$ORT_HOME" \ --skip_tests --skip_examples \ + --no_telemetry \ --parallel \ --build_dir "${{ runner.workspace }}/build-oga" \ --cmake_extra_defines \ diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 2f3016867..47c6650a0 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -46,11 +46,13 @@ jobs: # Remove a PR number once its fix is in the pinned ONNXRUNTIME_VERSION. ONNXRUNTIME_PR_PATCHES: "" SCCACHE_GHA_ENABLED: "true" - OGA_VERSION: "0.14.0" + # onnxruntime-genai 0.15.1. Upstream published no v0.15.1 tag and + # rel-0.15.1 is a moving branch, so pin the release commit itself. + OGA_COMMIT: "3abf4a847fd7876e81d5d1ed3ad97d77284b37e4" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from - # pull/.patch and `git apply` on top of v. Part of the OGA - # cache key. Remove a PR once it lands in the pinned OGA release. - OGA_PR_PATCHES: "2194" + # pull/.patch and `git am` on top of OGA_COMMIT. Part of the OGA cache + # key. Remove a PR once it lands in the pinned OGA commit. + OGA_PR_PATCHES: "2376" # ilammy/msvc-dev-cmd and mozilla-actions/sccache-action have no # Node.js 24 releases yet; allow Node.js 20 until they are updated. ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: "true" @@ -360,28 +362,53 @@ jobs: # Cache only the two artifacts we need: model_benchmark.exe and # onnxruntime-genai.dll, keyed on OGA commit + ORT version. # ----------------------------------------------------------------------- + # A PR patch is fetched from the PR's head, which moves whenever the PR + # branch is updated, so the PR number alone does not identify the patch + # content. Resolve the head SHAs and fold them into the OGA cache key. + - name: Resolve OGA PR head SHAs + id: oga-pr-shas + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + OGA_PRS: ${{ env.OGA_PR_PATCHES }} + run: | + $prs = $env:OGA_PRS.Trim() + if (-not $prs) { + Add-Content -Path $env:GITHUB_OUTPUT -Value "shas=none" + exit 0 + } + $parts = foreach ($pr in $prs -split '\s+') { + if (-not $pr) { continue } + $sha = gh api "repos/microsoft/onnxruntime-genai/pulls/$pr" --jq .head.sha + if ($LASTEXITCODE -ne 0 -or -not $sha) { + throw "Failed to resolve head SHA for OGA PR #$pr" + } + "$pr-$($sha.Substring(0, 12))" + } + $shas = $parts -join '_' + Write-Host "OGA PR heads: $shas" + Add-Content -Path $env:GITHUB_OUTPUT -Value "shas=$shas" + - name: Cache OGA artifacts id: cache-oga uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ${{ runner.workspace }}/oga-artifacts # OGA is built against the patched ort-install, so the key folds in - # both OGA's own PR list and ONNXRUNTIME_PR_PATCHES; editing either - # forces a rebuild. The mm token bumps when the OGA artifact set - # changes shape, or when a PR's branch content changes under the same - # number (mm2: PR 2194 now carries the AMDGPU OGA integration). - key: oga-dml-mm2-${{ env.OGA_VERSION }}-pr${{ env.OGA_PR_PATCHES }}-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} + # both OGA's own PR heads and ONNXRUNTIME_PR_PATCHES; editing either + # forces a rebuild. + key: oga-dml-${{ env.OGA_COMMIT }}-pr${{ steps.oga-pr-shas.outputs.shas }}-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} # OGA is built from upstream microsoft/onnxruntime-genai + PR patches - # (OGA_PR_PATCHES). PR 2194 (the dynamic-shape-morphizen branch) now also - # carries the AMDGPU umbrella integration, so the patched upstream build - # is the AMDGPU-targeted OGA -- no fork checkout needed. + # (OGA_PR_PATCHES). PR 2376 carries the AMDGPU umbrella integration, so + # the patched upstream build is the AMDGPU-targeted OGA -- no fork + # checkout needed. - name: Checkout OGA if: steps.cache-oga.outputs.cache-hit != 'true' uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: microsoft/onnxruntime-genai - ref: v${{ env.OGA_VERSION }} + ref: ${{ env.OGA_COMMIT }} path: source-oga submodules: true fetch-depth: 1 @@ -403,10 +430,10 @@ jobs: Write-Host "OGA_PR_PATCHES is empty; nothing to apply" exit 0 } - # pull/.patch is a format-patch series; apply with `git am` so that - # intra-series file renames (morphizen_ep -> amdgpu) replay against the - # correct intermediate tree. `git apply` flattens the series and chokes - # on the rename whose pre-image only exists after an earlier commit. + # pull/.patch is a format-patch series; apply with `git am` so each + # commit replays against the intermediate tree it was authored against. + # `git apply` flattens the series and chokes on anything that depends on + # an earlier commit in it (a file rename, for example). git config user.email "ci@rocm.amd.com" git config user.name "ROCm CI" foreach ($pr in $prs -split '\s+') { @@ -446,6 +473,7 @@ jobs: --use_dml \ --ort_home "$ORT_HOME" \ --skip_tests --skip_examples \ + --no_telemetry \ --parallel \ --build_dir "${{ runner.workspace }}/build-oga" \ --cmake_extra_defines \ diff --git a/docs/quick_start.md b/docs/quick_start.md index 5f152e676..0b00f8b93 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -248,19 +248,20 @@ cp "$LOCAL_DIR/bin/onnxruntime_providers_shared.dll" "$ORT_HOME/lib/" ```bash cd .. # Go to workspace directory (sibling of hip-ep) -git clone -b v0.14.0 https://github.com/microsoft/onnxruntime-genai.git +git clone https://github.com/microsoft/onnxruntime-genai.git cd onnxruntime-genai +# Upstream published no v0.15.1 tag, so check out the release commit. +git checkout 3abf4a847fd7876e81d5d1ed3ad97d77284b37e4 git submodule update --init --recursive -# Apply the AMDGPU integration PR on top of the upstream tag. pull/.patch is -# a format-patch series (it renames src/morphizen_ep -> src/amdgpu mid-series), -# so apply it with `git am` -- `git apply` flattens the series and fails on the -# rename whose pre-image only exists after an earlier commit. -curl -fsSL https://github.com/microsoft/onnxruntime-genai/pull/2194.patch -o /tmp/oga-2194.patch -git am --3way --whitespace=nowarn /tmp/oga-2194.patch +# Apply the AMDGPU integration PR on top of the pinned commit. pull/.patch is +# a format-patch series, so apply it with `git am` -- `git apply` flattens the +# series and fails on anything that depends on an earlier commit in it. +curl -fsSL https://github.com/microsoft/onnxruntime-genai/pull/2376.patch -o /tmp/oga-2376.patch +git am --3way --whitespace=nowarn /tmp/oga-2376.patch ``` -> **Note**: the upstream tag + PR list are pinned in CI via `OGA_VERSION` and +> **Note**: the upstream commit + PR list are pinned in CI via `OGA_COMMIT` and > `OGA_PR_PATCHES` in > [`.github/workflows/windows-build.yml`](../.github/workflows/windows-build.yml); > match those for byte-for-byte reproducibility. @@ -281,6 +282,7 @@ python build.py \ --use_dml \ --ort_home "$ORT_HOME" \ --skip_tests --skip_examples \ + --no_telemetry \ --parallel \ --build_dir ../build/onnxruntime-genai \ --cmake_extra_defines \ @@ -371,7 +373,7 @@ python onnxruntime-genai/benchmark/python/benchmark_e2e.py \ `benchmark_e2e.py` runs with the default `-e follow_config`, so the model's `genai_config.json` selects the EP via `provider_options`. With the upstream OGA -(v0.14.0 + PR2194, DeviceType AMDGPU) this is the AMD GPU umbrella +(0.15.1 + PR2376, DeviceType AMDGPU) this is the AMD GPU umbrella (`provider_options [{ "AMDGPU": {"profile": "hip"} }]`), which loads `amdgpu-ep.dll` and needs the umbrella DLLs colocated (see `.github/workflows/windows-build.yml`); the default wheel ships only the hipgpu @@ -488,8 +490,8 @@ present there too. The EP is selected by the model's `genai_config.json` `provider_options` and auto-discovered next to `onnxruntime-genai.dll` -- do NOT pass `--ep_library` -(upstream `model_benchmark` rejects it). With the upstream OGA (v0.14.0 + -PR2194) the EP is the AMD GPU umbrella (`provider_options [{ "AMDGPU": +(upstream `model_benchmark` rejects it). With the upstream OGA (0.15.1 + +PR2376) the EP is the AMD GPU umbrella (`provider_options [{ "AMDGPU": {"profile": "hip"} }]`), so `amdgpu-ep.dll` must sit next to the OGA DLLs (see `.github/workflows/windows-build.yml`). diff --git a/docs/quick_start_linux.md b/docs/quick_start_linux.md index 9b0022412..a3b560e81 100644 --- a/docs/quick_start_linux.md +++ b/docs/quick_start_linux.md @@ -262,7 +262,7 @@ prebuilt package to get it. The EP is selected by the model's `genai_config.json` `provider_options` and auto-discovered next to the OGA runtime lib -- do NOT pass `--ep_library` -(upstream `model_benchmark` rejects it). With the upstream OGA (v0.14.0 + PR2194) +(upstream `model_benchmark` rejects it). With the upstream OGA (0.15.1 + PR2376) the EP is the AMD GPU umbrella (`provider_options [{ "AMDGPU": {"profile": "hip"} }]`); the prebuilt package bundles the umbrella libs. From 7545148495946b42ae6349ffd06c96e5a259b6cb Mon Sep 17 00:00:00 2001 From: zhenzew Date: Wed, 5 Aug 2026 05:24:58 -0500 Subject: [PATCH 2/4] ci: parse model_benchmark's 0.15 peak working set line OGA 0.15 prints "Peak working set size: bytes ( GB)" where 0.14 printed "Peak working set size (bytes): ", so the OGA benchmark summary reported "-" for Peak Mem and the perf-report tools printed "?". Match the current format, which is also what the perf_test parser in the same workflow already expects. --- .github/workflows/windows-build.yml | 2 +- tools/perf-report/format_perf_report.py | 2 +- tools/perf-report/perf_multimodal_report.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 47c6650a0..d9978f0ac 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -1316,7 +1316,7 @@ jobs: $content = Get-Content $f.FullName -Raw $ttftMatch = [regex]::Match($content, 'Prompt processing \(time to first token\):\s*\n\s*avg \(us\):\s+([\d.]+)') $tpsMatch = [regex]::Match($content, 'Token generation:\s*\n\s*avg \(us\):\s+([\d.]+)\s*\n\s*avg \(tokens/s\):\s+([\d.]+)') - $memMatch = [regex]::Match($content, 'Peak working set size \(bytes\):\s+(\d+)') + $memMatch = [regex]::Match($content, 'Peak working set size:\s+(\d+)\s+bytes') $ttft = if ($ttftMatch.Success) { "{0:F1}" -f ([double]$ttftMatch.Groups[1].Value / 1000) } else { "-" } $tps = if ($tpsMatch.Success) { "{0:F1}" -f [double]$tpsMatch.Groups[2].Value } else { "-" } $mem = if ($memMatch.Success) { "{0:F2}" -f ([double]$memMatch.Groups[1].Value / 1GB) } else { "-" } diff --git a/tools/perf-report/format_perf_report.py b/tools/perf-report/format_perf_report.py index 1263663e6..b94fa9529 100755 --- a/tools/perf-report/format_perf_report.py +++ b/tools/perf-report/format_perf_report.py @@ -176,7 +176,7 @@ def parse(cls, lines: list[str]) -> "OgaHeadline": cur_block = None continue - m = re.match(r"Peak working set size \(bytes\):\s*(\d+)", line) + m = re.match(r"Peak working set size:\s*(\d+)\s+bytes", line) if m: out.peak_ws_bytes = int(m.group(1)) cur_block = None diff --git a/tools/perf-report/perf_multimodal_report.py b/tools/perf-report/perf_multimodal_report.py index 76073ca87..9b9ccf94b 100644 --- a/tools/perf-report/perf_multimodal_report.py +++ b/tools/perf-report/perf_multimodal_report.py @@ -178,7 +178,7 @@ def parse(cls, lines: list[str]) -> "OgaHeadline": cur_block = None continue - m = re.match(r"Peak working set size \(bytes\):\s*(\d+)", line) + m = re.match(r"Peak working set size:\s*(\d+)\s+bytes", line) if m: out.peak_ws_bytes = int(m.group(1)) cur_block = None From 64d59a8a52f18a0bb977702990e6ffb4bfc4bf76 Mon Sep 17 00:00:00 2001 From: zhenzew Date: Wed, 5 Aug 2026 05:34:53 -0500 Subject: [PATCH 3/4] ci: track the OGA release branch instead of a hardcoded commit OGA_COMMIT had to be edited by hand every time upstream pushed to rel-0.15.1. OGA_BRANCH names the branch instead, and the step that already resolves patch-PR heads now resolves the branch head too: its short SHA goes into the cache key and the checkout uses the full SHA from the same lookup, so the cached artifacts always correspond to the source they were built from. --- .github/workflows/linux-build.yml | 35 +++++++++++++++++--------- .github/workflows/windows-build.yml | 38 ++++++++++++++++++----------- docs/quick_start.md | 11 ++++----- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 338819e0b..ca5d1c778 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -32,12 +32,13 @@ env: # ORT is still built from source either way). Part of the ort-install cache # key. Remove a PR once its fix lands in the pinned ONNX Runtime release. ONNXRUNTIME_PR_PATCHES: "" - # onnxruntime-genai 0.15.1. Upstream published no v0.15.1 tag and rel-0.15.1 - # is a moving branch, so pin the release commit itself. - OGA_COMMIT: "3abf4a847fd7876e81d5d1ed3ad97d77284b37e4" + # onnxruntime-genai release branch (upstream published no v0.15.1 tag). Its + # head is resolved at run time and folded into the OGA cache key, so a new + # commit on the branch rebuilds instead of reusing a stale artifact. + OGA_BRANCH: "rel-0.15.1" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from - # pull/.patch and `git am` on top of OGA_COMMIT. Part of the OGA cache key. - # Remove a PR once it lands in the pinned OGA commit. + # pull/.patch and `git am` on top of OGA_BRANCH. Part of the OGA cache key. + # Remove a PR once it lands in OGA_BRANCH. OGA_PR_PATCHES: "2376" # The GPU arch the artifact targets. CI runners have no GPU, so it is passed # explicitly (build.py auto-detects from /sys on a real GPU host). @@ -286,16 +287,26 @@ jobs: # build.py (whose target is the project .so) because OGA is a # CI/artifact concern. # ----------------------------------------------------------------------- - # A PR patch is fetched from the PR's head, which moves whenever the PR - # branch is updated, so the PR number alone does not identify the patch - # content. Resolve the head SHAs and fold them into the OGA cache key. - - name: Resolve OGA PR head SHAs - id: oga-pr-shas + # Both the release branch and every patch PR move under a fixed name, so + # neither identifies its content. Resolve their heads once: the cache key + # folds in the short SHAs and the checkout below uses the branch SHA this + # step resolved, so a mid-run push cannot desync key from source. + - name: Resolve OGA source SHAs + id: oga-shas env: GH_TOKEN: ${{ github.token }} OGA_PRS: ${{ env.OGA_PR_PATCHES }} run: | set -euo pipefail + branch="$(gh api "repos/microsoft/onnxruntime-genai/commits/${OGA_BRANCH}" --jq .sha)" + if [ -z "$branch" ]; then + echo "Failed to resolve head SHA for OGA branch ${OGA_BRANCH}" + exit 1 + fi + echo "OGA branch head: ${OGA_BRANCH} ${branch}" + echo "branch-sha=${branch}" >> "$GITHUB_OUTPUT" + echo "branch-sha12=${branch:0:12}" >> "$GITHUB_OUTPUT" + prs="$(echo "$OGA_PRS" | xargs || true)" if [ -z "$prs" ]; then echo "shas=none" >> "$GITHUB_OUTPUT" @@ -318,7 +329,7 @@ jobs: uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: ${{ runner.workspace }}/oga-artifacts - key: linux-oga-${{ env.OGA_COMMIT }}-pr${{ steps.oga-pr-shas.outputs.shas }}-am-whl-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} + key: linux-oga-${{ env.OGA_BRANCH }}-${{ steps.oga-shas.outputs.branch-sha12 }}-pr${{ steps.oga-shas.outputs.shas }}-am-whl-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} # Checkout + build are skipped on an OGA cache hit (step-level gate); the # install-copy below always runs so the @@ -328,7 +339,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: microsoft/onnxruntime-genai - ref: ${{ env.OGA_COMMIT }} + ref: ${{ steps.oga-shas.outputs.branch-sha }} submodules: recursive path: onnxruntime-genai fetch-depth: 1 diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index d9978f0ac..24fe1c8f4 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -46,12 +46,13 @@ jobs: # Remove a PR number once its fix is in the pinned ONNXRUNTIME_VERSION. ONNXRUNTIME_PR_PATCHES: "" SCCACHE_GHA_ENABLED: "true" - # onnxruntime-genai 0.15.1. Upstream published no v0.15.1 tag and - # rel-0.15.1 is a moving branch, so pin the release commit itself. - OGA_COMMIT: "3abf4a847fd7876e81d5d1ed3ad97d77284b37e4" + # onnxruntime-genai release branch (upstream published no v0.15.1 tag). + # Its head is resolved at run time and folded into the OGA cache key, so a + # new commit on the branch rebuilds instead of reusing a stale artifact. + OGA_BRANCH: "rel-0.15.1" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from - # pull/.patch and `git am` on top of OGA_COMMIT. Part of the OGA cache - # key. Remove a PR once it lands in the pinned OGA commit. + # pull/.patch and `git am` on top of OGA_BRANCH. Part of the OGA cache + # key. Remove a PR once it lands in OGA_BRANCH. OGA_PR_PATCHES: "2376" # ilammy/msvc-dev-cmd and mozilla-actions/sccache-action have no # Node.js 24 releases yet; allow Node.js 20 until they are updated. @@ -362,16 +363,25 @@ jobs: # Cache only the two artifacts we need: model_benchmark.exe and # onnxruntime-genai.dll, keyed on OGA commit + ORT version. # ----------------------------------------------------------------------- - # A PR patch is fetched from the PR's head, which moves whenever the PR - # branch is updated, so the PR number alone does not identify the patch - # content. Resolve the head SHAs and fold them into the OGA cache key. - - name: Resolve OGA PR head SHAs - id: oga-pr-shas + # Both the release branch and every patch PR move under a fixed name, so + # neither identifies its content. Resolve their heads once: the cache key + # folds in the short SHAs and the checkout below uses the branch SHA this + # step resolved, so a mid-run push cannot desync key from source. + - name: Resolve OGA source SHAs + id: oga-shas shell: pwsh env: GH_TOKEN: ${{ github.token }} OGA_PRS: ${{ env.OGA_PR_PATCHES }} run: | + $branch = gh api "repos/microsoft/onnxruntime-genai/commits/$env:OGA_BRANCH" --jq .sha + if ($LASTEXITCODE -ne 0 -or -not $branch) { + throw "Failed to resolve head SHA for OGA branch $env:OGA_BRANCH" + } + Write-Host "OGA branch head: $env:OGA_BRANCH $branch" + Add-Content -Path $env:GITHUB_OUTPUT -Value "branch-sha=$branch" + Add-Content -Path $env:GITHUB_OUTPUT -Value "branch-sha12=$($branch.Substring(0, 12))" + $prs = $env:OGA_PRS.Trim() if (-not $prs) { Add-Content -Path $env:GITHUB_OUTPUT -Value "shas=none" @@ -395,9 +405,9 @@ jobs: with: path: ${{ runner.workspace }}/oga-artifacts # OGA is built against the patched ort-install, so the key folds in - # both OGA's own PR heads and ONNXRUNTIME_PR_PATCHES; editing either - # forces a rebuild. - key: oga-dml-${{ env.OGA_COMMIT }}-pr${{ steps.oga-pr-shas.outputs.shas }}-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} + # both OGA's own sources and ONNXRUNTIME_PR_PATCHES; a new commit on + # either side forces a rebuild. + key: oga-dml-${{ env.OGA_BRANCH }}-${{ steps.oga-shas.outputs.branch-sha12 }}-pr${{ steps.oga-shas.outputs.shas }}-ort${{ env.ONNXRUNTIME_VERSION }}-ortpr${{ env.ONNXRUNTIME_PR_PATCHES }} # OGA is built from upstream microsoft/onnxruntime-genai + PR patches # (OGA_PR_PATCHES). PR 2376 carries the AMDGPU umbrella integration, so @@ -408,7 +418,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: microsoft/onnxruntime-genai - ref: ${{ env.OGA_COMMIT }} + ref: ${{ steps.oga-shas.outputs.branch-sha }} path: source-oga submodules: true fetch-depth: 1 diff --git a/docs/quick_start.md b/docs/quick_start.md index 0b00f8b93..b386d46d4 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -248,20 +248,19 @@ cp "$LOCAL_DIR/bin/onnxruntime_providers_shared.dll" "$ORT_HOME/lib/" ```bash cd .. # Go to workspace directory (sibling of hip-ep) -git clone https://github.com/microsoft/onnxruntime-genai.git +# Upstream published no v0.15.1 tag; the release lives on the rel-0.15.1 branch. +git clone -b rel-0.15.1 https://github.com/microsoft/onnxruntime-genai.git cd onnxruntime-genai -# Upstream published no v0.15.1 tag, so check out the release commit. -git checkout 3abf4a847fd7876e81d5d1ed3ad97d77284b37e4 git submodule update --init --recursive -# Apply the AMDGPU integration PR on top of the pinned commit. pull/.patch is -# a format-patch series, so apply it with `git am` -- `git apply` flattens the +# Apply the AMDGPU integration PR on top of the branch. pull/.patch is a +# format-patch series, so apply it with `git am` -- `git apply` flattens the # series and fails on anything that depends on an earlier commit in it. curl -fsSL https://github.com/microsoft/onnxruntime-genai/pull/2376.patch -o /tmp/oga-2376.patch git am --3way --whitespace=nowarn /tmp/oga-2376.patch ``` -> **Note**: the upstream commit + PR list are pinned in CI via `OGA_COMMIT` and +> **Note**: the upstream branch + PR list are pinned in CI via `OGA_BRANCH` and > `OGA_PR_PATCHES` in > [`.github/workflows/windows-build.yml`](../.github/workflows/windows-build.yml); > match those for byte-for-byte reproducibility. From 18be2cafb5e24366f66ba02764ce3d0a0aaf88ab Mon Sep 17 00:00:00 2001 From: zhenzew Date: Wed, 5 Aug 2026 05:37:05 -0500 Subject: [PATCH 4/4] ci: drop the OGA_BRANCH comment --- .github/workflows/linux-build.yml | 3 --- .github/workflows/windows-build.yml | 3 --- 2 files changed, 6 deletions(-) diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index ca5d1c778..1c3fbaf13 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -32,9 +32,6 @@ env: # ORT is still built from source either way). Part of the ort-install cache # key. Remove a PR once its fix lands in the pinned ONNX Runtime release. ONNXRUNTIME_PR_PATCHES: "" - # onnxruntime-genai release branch (upstream published no v0.15.1 tag). Its - # head is resolved at run time and folded into the OGA cache key, so a new - # commit on the branch rebuilds instead of reusing a stale artifact. OGA_BRANCH: "rel-0.15.1" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from # pull/.patch and `git am` on top of OGA_BRANCH. Part of the OGA cache key. diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 24fe1c8f4..79d9b8987 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -46,9 +46,6 @@ jobs: # Remove a PR number once its fix is in the pinned ONNXRUNTIME_VERSION. ONNXRUNTIME_PR_PATCHES: "" SCCACHE_GHA_ENABLED: "true" - # onnxruntime-genai release branch (upstream published no v0.15.1 tag). - # Its head is resolved at run time and folded into the OGA cache key, so a - # new commit on the branch rebuilds instead of reusing a stale artifact. OGA_BRANCH: "rel-0.15.1" # Space-separated microsoft/onnxruntime-genai PR numbers fetched from # pull/.patch and `git am` on top of OGA_BRANCH. Part of the OGA cache