Ship the OpenVINO and WebGPU runtimes in every desktop package

The Windows installer and the Flatpak carried no ONNX Runtime, so they
ran every model on tract's one core; the Arch package left it to an
optional dependency. Each now installs two builds under runtimes/ —
Intel's OpenVINO build and the generic WebGPU one, both with the CPU
provider — fetched by tools/fetch-bundled-runtimes.sh from PyPI wheels
pinned by SHA-256, pruned to the native libraries (81 + 31 MB on Linux,
67 + 42 MB on Windows), licence texts beside them.

darkroom-desktop searches runtimes/openvino and runtimes/webgpu under
each place a package installs to; the engine opens all it finds and
keeps the one that fits the GPU, so a CUDA or ROCm runtime installed
beside them still wins on its vendor's card. On Windows the chosen
runtime's directory goes on PATH, because Intel's build leaves OpenVINO's
DLLs for the loader to find there.

The Windows image gains unzip; the installer smoke test checks both
runtimes landed.
This commit is contained in:
2026-10-04 21:00:15 -04:00
parent 2ced6f114f
commit cb97ebe7ac
9 changed files with 210 additions and 13 deletions
+20 -7
View File
@@ -106,24 +106,37 @@ fn main() -> anyhow::Result<()> {
/// providers, or against the wrong cuDNN — and a system copy whose providers
/// do not load is not a problem, only a slower app: the probe builds a real
/// session before believing a provider.
///
/// The order breaks ties only. The engine opens every runtime on this list
/// and loads the one whose providers fit the GPU (inference.md §3.2), so a
/// package's bundled builds — `runtimes/openvino` and `runtimes/webgpu`
/// beside each place a package installs to, from
/// `tools/fetch-bundled-runtimes.sh` — sit beside a CUDA or ROCm runtime
/// without hiding it.
fn runtime_dirs() -> Vec<PathBuf> {
// A place a package installs to, and the bundled runtimes under it.
fn packaged(dirs: &mut Vec<PathBuf>, base: PathBuf) {
dirs.push(base.join("runtimes/openvino"));
dirs.push(base.join("runtimes/webgpu"));
dirs.push(base);
}
let mut dirs = Vec::new();
if let Some(dir) = std::env::var_os("DARKROOM_ORT_DIR") {
dirs.push(PathBuf::from(dir));
}
if let Ok(exe) = std::env::current_exe() {
if let Some(bin) = exe.parent() {
dirs.push(bin.to_path_buf());
dirs.push(bin.join("../lib/darkroom"));
packaged(&mut dirs, bin.to_path_buf());
packaged(&mut dirs, bin.join("../lib/darkroom"));
}
}
dirs.push(dr_ui::inference::user_runtime_dir());
#[cfg(target_os = "linux")]
dirs.extend([
PathBuf::from("/app/lib/darkroom"),
PathBuf::from("/usr/lib/darkroom"),
PathBuf::from("/usr/lib"),
]);
{
packaged(&mut dirs, PathBuf::from("/app/lib/darkroom"));
packaged(&mut dirs, PathBuf::from("/usr/lib/darkroom"));
dirs.push(PathBuf::from("/usr/lib"));
}
// An app bundle keeps its libraries in `Contents/Frameworks`, beside
// the `Contents/MacOS` the executable is in; then Homebrew's
// `onnxruntime`, Apple silicon's prefix before Intel's. Homebrew's build