Add OpenVINO backend for Intel iGPU/dGPU (Arc)
All checks were successful
Mirror to GitHub / mirror (push) Successful in 1s
release / build (push) Successful in 2m12s

Mirrors the rocm/cuda pattern: ort::ep::OpenVINO with device_type "GPU"
(covers both Intel integrated graphics and Arc discrete GPUs through the
same EP), load-dynamic/dlopen so no OpenVINO toolkit is needed at build
time, and its own --openvino flag / backend = "openvino" config value.
Folded into the `full` feature alongside npu/rocm/cuda.

OpenVINO's provider options go through a generic key/value FFI interface
rather than a fixed C struct (unlike MIGraphX's OrtMIGraphXProviderOptions),
so it should be less exposed to the ABI-version-skew crash MIGraphX hit --
but that's inference from the EP's design, not verified against real
hardware. Like CUDA, this is compile-checked only: no Intel GPU in this
dev environment to runtime-verify against.

Version bump: breadmill 0.2.2 -> 0.2.3.
This commit is contained in:
Breadway 2026-07-03 22:58:27 +08:00
parent e5922e9c90
commit c6ed6a41d8
8 changed files with 112 additions and 35 deletions

View file

@ -39,12 +39,14 @@ fn main() {
let use_npu = raw_args.iter().any(|a| a == "--npu");
let use_rocm = raw_args.iter().any(|a| a == "--rocm");
let use_cuda = raw_args.iter().any(|a| a == "--cuda");
let use_openvino = raw_args.iter().any(|a| a == "--openvino");
// Build a view of argv without backend flags for command matching.
let backend_flags = ["--npu", "--rocm", "--cuda", "--openvino"];
let args: Vec<&str> = raw_args
.iter()
.skip(1)
.filter(|a| a.as_str() != "--npu" && a.as_str() != "--rocm" && a.as_str() != "--cuda")
.filter(|a| !backend_flags.contains(&a.as_str()))
.map(|s| s.as_str())
.collect();
@ -59,7 +61,7 @@ fn main() {
}
}
Some("--reindex") | Some("reindex") => {
if let Err(e) = run_daemon(true, use_npu, use_rocm, use_cuda) {
if let Err(e) = run_daemon(true, use_npu, use_rocm, use_cuda, use_openvino) {
eprintln!("breadmill: {}", e);
std::process::exit(1);
}
@ -76,7 +78,7 @@ fn main() {
cli_status();
}
None | Some("serve") | Some("--serve") => {
if let Err(e) = run_daemon(false, use_npu, use_rocm, use_cuda) {
if let Err(e) = run_daemon(false, use_npu, use_rocm, use_cuda, use_openvino) {
eprintln!("breadmill: {}", e);
std::process::exit(1);
}
@ -84,7 +86,7 @@ fn main() {
Some(cmd) => {
eprintln!("breadmill: unknown command: {}", cmd);
eprintln!(
"usage: breadmill [serve|reindex|fetch-model|query <text>|status] [--npu|--rocm|--cuda] [--version]"
"usage: breadmill [serve|reindex|fetch-model|query <text>|status] [--npu|--rocm|--cuda|--openvino] [--version]"
);
std::process::exit(1);
}
@ -93,7 +95,13 @@ fn main() {
// ---- Daemon -----------------------------------------------------------------
fn run_daemon(force_reindex: bool, use_npu: bool, use_rocm: bool, use_cuda: bool) -> Result<(), String> {
fn run_daemon(
force_reindex: bool,
use_npu: bool,
use_rocm: bool,
use_cuda: bool,
use_openvino: bool,
) -> Result<(), String> {
let config = breadsearch_shared::Config::load();
let state_dir = breadsearch_shared::state_dir();
let cache_dir = breadsearch_shared::cache_dir();
@ -115,6 +123,8 @@ fn run_daemon(force_reindex: bool, use_npu: bool, use_rocm: bool, use_cuda: bool
"rocm"
} else if use_cuda {
"cuda"
} else if use_openvino {
"openvino"
} else {
config.model.backend.as_str()
};
@ -132,6 +142,10 @@ fn run_daemon(force_reindex: bool, use_npu: bool, use_rocm: bool, use_cuda: bool
eprintln!("breadmill: CUDA backend selected");
Backend::Cuda
}
"openvino" => {
eprintln!("breadmill: OpenVINO backend selected");
Backend::OpenVino { cache_dir: cache_dir.clone() }
}
_ => Backend::Cpu,
};