docs/ had 26 developer documents flat beside the manual, and the two audiences are very differently sized: most readers want the manual and the gesture reference, a few want the register, the designs and the measurements. The manual and gestures.md stay at the top; everything for someone changing the code moves to docs/dev/, and the two documents that name their own successors — the v0.1 milestone and the UI-refinement plan — go to docs/dev/archive/ rather than being deleted, since both are still cited. docs/README.md is the index, users first. Every reference follows: code comments, Cargo manifests, the workflows, the pre-commit hook, the bench and traceability tools (which locate the repo root by docs/dev/requirements.md now), packaging, the Docker READMEs, CLAUDE.md, CONTRIBUTING.md and the README. The matrix links one level deeper and is regenerated. Links out of the moved documents into the tree gain a level; a link checker over every Markdown file finds none broken.
97 lines
4.6 KiB
Bash
Executable File
97 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Fetch the inference runtime the Android APK carries (docs/dev/inference.md §3).
|
||
#
|
||
# ./tools/fetch-android-runtime.sh [DEST]
|
||
#
|
||
# Two Maven artefacts, pinned to each other by ONNX Runtime's own POM:
|
||
#
|
||
# com.microsoft.onnxruntime:onnxruntime-android-qnn MIT
|
||
# com.qualcomm.qti:qnn-runtime Qualcomm AI Engine Direct SDK licence
|
||
#
|
||
# The first is ONNX Runtime built with the CPU, QNN, XNNPACK, NNAPI and WebGPU
|
||
# providers; the second is Qualcomm's HTP backend — the ARM-side compiler and
|
||
# the per-generation Hexagon "skel" the DSP loads. Both ship as AARs whose
|
||
# `jni/arm64-v8a/` is what an APK's `lib/arm64-v8a/` wants, so this script
|
||
# unpacks exactly that and nothing else, plus the licence texts, which travel
|
||
# with the libraries (§3.1).
|
||
#
|
||
# ## What is and is not taken from the Qualcomm package
|
||
#
|
||
# Every HTP generation has its own skel and stub, 16 MB a pair. `QNN_HTP_ARCHS`
|
||
# names the ones to ship; the default is the generations in devices sold since
|
||
# the 8 Gen 2 (V73 — the MagicPad 2's 8s Gen 3 is one), through the 8 Elite
|
||
# (V79) and its successor (V81). V66–V69 are 2020–2021 silicon and are left
|
||
# out, which is 50 MB the tablet never loads. `libQnnHtpPrepare.so`, the
|
||
# on-device graph compiler, is 84 MB and cannot be left out: it is what turns
|
||
# an int8 ONNX graph into something the DSP runs, once per device (§5).
|
||
#
|
||
# `libQnnGpu.so` and `libQnnDsp*.so` are not taken: the Adreno rung measured
|
||
# slower than the Hexagon everywhere the Hexagon exists (§1.1), and the cDSP
|
||
# path is the pre-HTP generation.
|
||
#
|
||
# ## Why a script and not a checked-in copy
|
||
#
|
||
# 150 MB of vendor binaries in LFS, re-fetched by every clone, for files that
|
||
# Maven serves with checksums. The cache directory keeps them across builds;
|
||
# CI's is the target cache it already mounts.
|
||
set -euo pipefail
|
||
|
||
ORT_VERSION="${ORT_VERSION:-1.29.0}"
|
||
QNN_VERSION="${QNN_VERSION:-2.42.0}"
|
||
QNN_HTP_ARCHS="${QNN_HTP_ARCHS:-73 75 79 81}"
|
||
DEST="${1:-${PWD}/target-android/runtime}"
|
||
MAVEN="https://repo1.maven.org/maven2"
|
||
|
||
fetch() {
|
||
# A Maven artefact and its SHA-1, verified before anything is unpacked.
|
||
local group="$1" artefact="$2" version="$3" out="$4"
|
||
local url="${MAVEN}/${group//.//}/${artefact}/${version}/${artefact}-${version}.aar"
|
||
if [[ -f "${out}" && -f "${out}.sha1" ]] \
|
||
&& [[ "$(sha1sum "${out}" | cut -d' ' -f1)" == "$(cut -c1-40 "${out}.sha1")" ]]; then
|
||
return
|
||
fi
|
||
echo "==> fetching ${artefact} ${version}"
|
||
curl -fsSL -o "${out}.sha1" "${url}.sha1"
|
||
curl -fsSL -o "${out}" "${url}"
|
||
[[ "$(sha1sum "${out}" | cut -d' ' -f1)" == "$(cut -c1-40 "${out}.sha1")" ]] || {
|
||
echo "error: ${artefact}-${version}.aar does not match its published SHA-1" >&2
|
||
rm -f "${out}"
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
mkdir -p "${DEST}/aar" "${DEST}/lib"
|
||
fetch com.microsoft.onnxruntime onnxruntime-android-qnn "${ORT_VERSION}" \
|
||
"${DEST}/aar/onnxruntime-android-qnn-${ORT_VERSION}.aar"
|
||
fetch com.qualcomm.qti qnn-runtime "${QNN_VERSION}" \
|
||
"${DEST}/aar/qnn-runtime-${QNN_VERSION}.aar"
|
||
|
||
# The ONNX Runtime POM names the QNN version it was built against; a pair
|
||
# that disagrees loads and then fails at the first graph, which is the kind
|
||
# of failure the probe would only report as "Hexagon failed".
|
||
pom="${DEST}/aar/onnxruntime-android-qnn-${ORT_VERSION}.pom"
|
||
[[ -f "${pom}" ]] || curl -fsSL -o "${pom}" \
|
||
"${MAVEN}/com/microsoft/onnxruntime/onnxruntime-android-qnn/${ORT_VERSION}/onnxruntime-android-qnn-${ORT_VERSION}.pom"
|
||
wanted="$(sed -n '/<artifactId>qnn-runtime<\/artifactId>/{n;s/.*<version>\(.*\)<\/version>.*/\1/p}' "${pom}")"
|
||
if [[ -n "${wanted}" && "${wanted}" != "${QNN_VERSION}" ]]; then
|
||
echo "error: ONNX Runtime ${ORT_VERSION} was built against QNN ${wanted}, not ${QNN_VERSION}" >&2
|
||
exit 1
|
||
fi
|
||
|
||
rm -rf "${DEST}/lib"
|
||
mkdir -p "${DEST}/lib"
|
||
unzip -q -o -j "${DEST}/aar/onnxruntime-android-qnn-${ORT_VERSION}.aar" \
|
||
'jni/arm64-v8a/libonnxruntime.so' -d "${DEST}/lib"
|
||
members=(jni/arm64-v8a/libQnnHtp.so jni/arm64-v8a/libQnnHtpPrepare.so jni/arm64-v8a/libQnnSystem.so)
|
||
for arch in ${QNN_HTP_ARCHS}; do
|
||
members+=("jni/arm64-v8a/libQnnHtpV${arch}Skel.so" "jni/arm64-v8a/libQnnHtpV${arch}Stub.so")
|
||
done
|
||
unzip -q -o -j "${DEST}/aar/qnn-runtime-${QNN_VERSION}.aar" "${members[@]}" -d "${DEST}/lib"
|
||
unzip -q -o -j "${DEST}/aar/qnn-runtime-${QNN_VERSION}.aar" 'LICENSE.pdf' 'NOTICE.txt' -d "${DEST}" 2>/dev/null || true
|
||
mv -f "${DEST}/LICENSE.pdf" "${DEST}/QNN-LICENSE.pdf" 2>/dev/null || true
|
||
mv -f "${DEST}/NOTICE.txt" "${DEST}/QNN-NOTICE.txt" 2>/dev/null || true
|
||
|
||
echo "==> runtime in ${DEST}/lib:"
|
||
du -sh "${DEST}/lib" | cut -f1 | sed 's/^/ /'
|
||
ls "${DEST}/lib" | sed 's/^/ /'
|