virtio_accel_openvino/lib.rs
1//! Intel OpenVINO host backend for NPU, GPU, and CPU execution.
2//!
3//! The production path accepts device-neutral TOSA 1.0 FlatBuffers, validates and analyzes them
4//! with `virtio-accel-tosa`, and lowers supported static floating-point and exact INT8 graphs to
5//! in-memory OpenVINO IR inside this host-native crate. Models are compiled with the `ACCURACY` execution
6//! mode hint so plugins may not silently execute a declared-FP32 graph at reduced precision.
7//! Program buffers are page-aligned allocations wrapped directly by OpenVINO tensors created
8//! from host pointers; output execution is accepted only when the runtime uses the same
9//! allocation as its output tensor.
10//!
11//! The native modules compile only when the build script detects an OpenVINO C runtime
12//! (`libopenvino_c`) via pkg-config or the `VIRTIO_ACCEL_OPENVINO_LIB_DIR` override; the
13//! `VIRTIO_ACCEL_OPENVINO` variable forces the probe on (`1`, failing loudly when the runtime is
14//! missing) or off (`0`). Builds without the runtime keep the portable lowering module and an
15//! unsupported-runtime placeholder.
16
17#![cfg_attr(not(va_openvino), forbid(unsafe_code))]
18
19mod lower;
20
21pub use lower::{
22 LoweringError, OPENVINO_TOSA_CAPABILITY, OPENVINO_TOSA_FP8_CAPABILITY,
23 OPENVINO_TOSA_FP8_TARGET, OPENVINO_TOSA_INTEGER_CAPABILITY, OPENVINO_TOSA_INTEGER_TARGET,
24 OPENVINO_TOSA_TARGET, supports_tosa_dtype, supports_tosa_operator,
25};
26
27use virtio_accel_tosa::CapabilityDescriptor;
28#[cfg(not(va_openvino))]
29use virtio_accel_tosa::TosaCapabilityProvider;
30
31#[cfg(va_openvino)]
32const TOSA_CAPABILITIES: &[CapabilityDescriptor] =
33 &[OPENVINO_TOSA_CAPABILITY, OPENVINO_TOSA_INTEGER_CAPABILITY];
34/// What an instance advertises when its device's compiler accepted the FP8 probe.
35///
36/// FP8 support is a property of the device, not of this backend: Intel NPU arch 5010 (Panther
37/// Lake) compiles FP8 graphs and arch 40XX (Lunar Lake) refuses even an FP8 `IDENTITY`. An
38/// unconditional descriptor would have a placement layer admit an FP8 graph and then fail it at
39/// load, which is exactly the silent-then-explode behaviour this crate refuses everywhere else.
40#[cfg(va_openvino)]
41const TOSA_CAPABILITIES_WITH_FP8: &[CapabilityDescriptor] = &[
42 OPENVINO_TOSA_CAPABILITY,
43 OPENVINO_TOSA_INTEGER_CAPABILITY,
44 OPENVINO_TOSA_FP8_CAPABILITY,
45];
46#[cfg(not(va_openvino))]
47const TOSA_CAPABILITIES: &[CapabilityDescriptor] = &[];
48
49/// The OpenVINO runtime does not publish a finite upper bound for compiled-model residency.
50///
51/// Requiring the maximal charge makes the provider promise truthful: a process cannot retain
52/// `u64::MAX` bytes for one model. Device integrations must set their aggregate program-residency
53/// policy accordingly when admitting an OpenVINO program.
54pub const REQUIRED_RESIDENT_BYTES: u64 = u64::MAX;
55
56/// Failure to initialize an OpenVINO backend instance.
57#[derive(Clone, Copy, Debug, PartialEq, Eq)]
58pub enum InitError {
59 /// The crate was built without an OpenVINO C runtime (`libopenvino_c`).
60 RuntimeUnavailable,
61 /// The OpenVINO core object could not be created.
62 CoreCreationFailed,
63 /// Device enumeration failed inside the OpenVINO runtime.
64 DeviceEnumerationFailed,
65 /// No requested or known inference device is available on this host.
66 DeviceUnavailable,
67}
68
69impl std::fmt::Display for InitError {
70 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 write!(formatter, "{self:?}")
72 }
73}
74
75impl std::error::Error for InitError {}
76
77#[cfg(va_openvino)]
78mod ffi;
79#[cfg(va_openvino)]
80mod native;
81#[cfg(va_openvino)]
82pub use native::{
83 OpenVinoAccelerator, OpenVinoBuffer, OpenVinoContext, OpenVinoEvent, OpenVinoProgram,
84 OpenVinoQueue,
85};
86
87/// Placeholder that keeps workspace consumers portable when no OpenVINO runtime was detected.
88#[cfg(not(va_openvino))]
89#[derive(Clone, Copy, Debug, Default)]
90pub struct OpenVinoAccelerator;
91
92#[cfg(not(va_openvino))]
93impl OpenVinoAccelerator {
94 /// Report that no OpenVINO runtime was detected when this crate was built.
95 pub fn new() -> Result<Self, InitError> {
96 Err(InitError::RuntimeUnavailable)
97 }
98
99 /// Report that no OpenVINO runtime was detected when this crate was built.
100 pub fn with_device(_device: &str) -> Result<Self, InitError> {
101 Err(InitError::RuntimeUnavailable)
102 }
103
104 /// Report that no OpenVINO runtime was detected when this crate was built.
105 pub fn available_devices() -> Result<Vec<String>, InitError> {
106 Err(InitError::RuntimeUnavailable)
107 }
108}
109
110#[cfg(not(va_openvino))]
111impl TosaCapabilityProvider for OpenVinoAccelerator {
112 fn tosa_capabilities(&self) -> &'static [CapabilityDescriptor] {
113 TOSA_CAPABILITIES
114 }
115}