Let the probe's clock be its proof, not disable_cpu_ep_fallback

The strict flag refused the Hexagon over the ten quantise/dequantise
nodes at the graph's edges that QNN declines by policy, which cost
microseconds. A provider that hands real work to the CPU is slower than
the CPU floor and the timing already rejects it; the tablet measured
2.3 ms on the NPU against a 29.7 ms floor.
This commit is contained in:
2026-09-19 16:13:19 +02:00
parent 691af96e3e
commit cbbe67fbd7
5 changed files with 26 additions and 29 deletions
+7 -13
View File
@@ -7,22 +7,16 @@ use crate::{Config, Role, Rung};
/// Build a session for `bytes` on `rung`.
///
/// `strict` is the probe's flag: with it, a provider that would hand any
/// node to the CPU fails the build instead, so "the session built" means
/// "the provider took the graph" and not "the provider registered" (§4).
pub fn build(
rung: Rung,
role: Role,
bytes: &[u8],
cfg: &Config,
strict: bool,
) -> ort::Result<Session> {
/// Not strict about the CPU: `session.disable_cpu_ep_fallback` was tried as
/// the probe's proof that a provider took the graph, and it refuses the
/// Hexagon over the ten quantise/dequantise nodes at the graph's edges that
/// QNN declines by policy and that cost microseconds. The probe's proof is
/// its clock instead (§4): a provider that hands real work to the CPU is
/// slower than the CPU floor and rejected by the same measurement.
pub fn build(rung: Rung, role: Role, bytes: &[u8], cfg: &Config) -> ort::Result<Session> {
let mut b = Session::builder()?
.with_optimization_level(GraphOptimizationLevel::Level3)?
.with_intra_threads(threads(cfg))?;
if strict && rung != Rung::Cpu {
b = b.with_config_entry("session.disable_cpu_ep_fallback", "1")?;
}
// A Hexagon session loads the compiled context when there is one and
// compiles it from the model when there is not; the engine thread is
// what makes the second case rare (§6).