#!/usr/bin/env bash # Fetch the two ONNX Runtime builds a desktop package ships # (docs/dev/inference.md §3.2), each into its own directory: # # DEST/openvino Intel's build: the OpenVINO rung on an Intel GPU # DEST/webgpu Microsoft's WebGPU build: the generic rung on any other # # ./tools/fetch-bundled-runtimes.sh {linux|windows} DEST # # Only one runtime loads per process; the app opens every one it finds and # keeps the one that fits the device's GPU (`dr_inference_engine::api`). # Both carry ONNX Runtime's CPU provider, which is the floor either way. # A CUDA or ROCm runtime is never bundled (§3.1) — the user's own, found # beside these, outranks both on its vendor's GPU. # # The wheels are PyPI's, pinned by SHA-256: the option names the engine # sets were read from these versions' source (CLAUDE.md, "Providers"). # Only the native libraries are kept — not the Python bindings, not # OpenVINO's CPU plugin (ONNX Runtime's CPU provider is the floor), not # the duplicate versioned copies a wheel holds as files. # # Licences: ONNX Runtime MIT, OpenVINO Apache-2.0, oneTBB Apache-2.0, the # DirectX shader compiler (Windows WebGPU) LLVM/MIT; the texts go beside # the libraries. set -euo pipefail PLATFORM="${1:?usage: fetch-bundled-runtimes.sh linux|windows DEST}" DEST="${2:?usage: fetch-bundled-runtimes.sh linux|windows DEST}" PYPI="https://files.pythonhosted.org/packages" case "${PLATFORM}" in linux) ORT_OPENVINO="${PYPI}/08/07/f225999919f56506b603aaa3ff837ad563ab26f86906ed7fa7e5abcd849e/onnxruntime_openvino-1.24.1-cp313-cp313-manylinux_2_28_x86_64.whl" ORT_OPENVINO_SHA=2c3bb73e68ac27f4891af8a595c1faf574ec68b772e6583c90a0b997a1822782 ORT_WEBGPU="${PYPI}/7a/4e/782b2457b863e1748866b82d918323e61c2d0108a01906a278e7a86a3a55/onnxruntime_webgpu-1.27.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" ORT_WEBGPU_SHA=3eb30b487d2b428d2e5c1ac538177ab6336cce9b204197135dc5a16753b0258e # The Linux wheel carries OpenVINO itself, under the names the provider # was linked against. OPENVINO_KEEP=(libonnxruntime.so.1.24.1 libonnxruntime_providers_shared.so libonnxruntime_providers_openvino.so libopenvino.so.2541 libopenvino_onnx_frontend.so.2541 libopenvino_intel_gpu_plugin.so libtbb.so.12 libtbbmalloc.so) WEBGPU_KEEP=(libonnxruntime.so.1.27.0 libonnxruntime_providers_shared.so) ;; windows) ORT_OPENVINO="${PYPI}/3e/92/46ae2cd565961a89189900f385bb2f13a9fa731ea4674001d23720fbb1e0/onnxruntime_openvino-1.24.1-cp313-cp313-win_amd64.whl" ORT_OPENVINO_SHA=434bf49aa71393c577a456c9d76c98e6d6958a833fa0876793e3d5437b5a511a ORT_WEBGPU="${PYPI}/dd/f3/6294f9617e97035771593d604729a420a848150054cc1c422a47a4915412/onnxruntime_webgpu-1.27.0-cp313-cp313-win_amd64.whl" ORT_WEBGPU_SHA=c45377099fcf23ae87427eb52e2b1d35415cabb4e3419dc645f9ee08f730e9aa # The Windows wheel leaves OpenVINO to the `openvino` wheel; its DLLs # go in the same directory, which the engine puts on the DLL search # path when it chooses this runtime. OPENVINO_LIBS="${PYPI}/3c/e5/da52a86cc5f1c86871002712429cdcca0c0dbff12dfbce730b05db60340b/openvino-2025.4.1-20426-cp313-cp313-win_amd64.whl" OPENVINO_LIBS_SHA=a28eef35e3ed497c3238eb8f3d1ee90647c449707a8b0a7630758cd15555d8dd OPENVINO_KEEP=(onnxruntime.dll onnxruntime_providers_shared.dll onnxruntime_providers_openvino.dll openvino.dll openvino_onnx_frontend.dll openvino_intel_gpu_plugin.dll tbb12.dll tbbmalloc.dll) WEBGPU_KEEP=(onnxruntime.dll onnxruntime_providers_shared.dll dxcompiler.dll dxil.dll) ;; *) echo "error: platform is linux or windows, not ${PLATFORM}" >&2 exit 2 ;; esac WORK="$(mktemp -d)" trap 'rm -rf "${WORK}"' EXIT # fetch URL SHA256 DIR: download a wheel, check it, unpack it into DIR. fetch() { local url="$1" sha="$2" dir="$3" whl whl="${WORK}/$(basename "${url}")" echo "==> $(basename "${url}")" curl -fsSL -o "${whl}" "${url}" echo "${sha} ${whl}" | sha256sum -c --quiet - || { echo "error: $(basename "${url}") does not match its pinned SHA-256" >&2 exit 1 } mkdir -p "${dir}" unzip -q -o "${whl}" -d "${dir}" } # keep FROM TO NAMES...: copy only NAMES, every one of which must exist. keep() { local from="$1" to="$2" name shift 2 mkdir -p "${to}" for name in "$@"; do local src src="$(find "${from}" -name "${name}" -type f | head -1)" [[ -n "${src}" ]] || { echo "error: ${name} is not in the wheel" >&2 exit 1 } install -m755 "${src}" "${to}/${name}" done } fetch "${ORT_OPENVINO}" "${ORT_OPENVINO_SHA}" "${WORK}/openvino" if [[ -n "${OPENVINO_LIBS:-}" ]]; then fetch "${OPENVINO_LIBS}" "${OPENVINO_LIBS_SHA}" "${WORK}/openvino" fi fetch "${ORT_WEBGPU}" "${ORT_WEBGPU_SHA}" "${WORK}/webgpu" rm -rf "${DEST}/openvino" "${DEST}/webgpu" keep "${WORK}/openvino" "${DEST}/openvino" "${OPENVINO_KEEP[@]}" keep "${WORK}/webgpu" "${DEST}/webgpu" "${WEBGPU_KEEP[@]}" # The wheels' own licence and notice files — ONNX Runtime keeps its in the # package directory, OpenVINO in `dist-info` — beside what they cover, # each under the name of the directory it came from: two wheels unpacked # into one directory both carry a `LICENSE`. for rt in openvino webgpu; do find "${WORK}/${rt}" -maxdepth 3 -type f \ \( -iname 'LICENSE*' -o -iname 'NOTICE*' -o -iname 'ThirdPartyNotices*' \) | while IFS= read -r f; do wheel="$(basename "$(dirname "${f}")" .dist-info)" [[ "${wheel}" == licenses ]] && wheel="$(basename "$(dirname "$(dirname "${f}")")" .dist-info)" install -m644 "${f}" "${DEST}/${rt}/${wheel}.$(basename "${f}")" done done # The Linux wheel bundles OpenVINO without its licence; Apache-2.0 asks # for the text beside the binaries. From the tag the libraries were built at. if [[ "${PLATFORM}" == linux ]]; then curl -fsSL -o "${DEST}/openvino/openvino-2025.4.1.LICENSE" \ "https://raw.githubusercontent.com/openvinotoolkit/openvino/2025.4.1/LICENSE" echo "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4 ${DEST}/openvino/openvino-2025.4.1.LICENSE" | sha256sum -c --quiet - fi du -sh "${DEST}/openvino" "${DEST}/webgpu"