use serde::{Deserialize, Serialize};
use xpile_contracts::ContractId;
use xpile_meta_hir::Module;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Target {
Rust,
Ruchy,
Ptx,
Wgsl,
Spirv,
Lean,
Shell,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Profile {
RustOut,
RuchyOut,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum HwProfile {
Ptx {
compute_capability: String,
},
Wgsl {
features: Vec<String>,
},
Spirv {
version: (u32, u32),
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BackendConfig {
pub target: Target,
pub profile: Profile,
pub hardware: Option<HwProfile>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Artifact {
pub primary: String,
pub sidecars: Vec<(String, Vec<u8>)>,
pub citations: Vec<ContractId>,
#[serde(default = "default_quorum_status")]
pub quorum_status: QuorumStatus,
}
fn default_quorum_status() -> QuorumStatus {
QuorumStatus::Single {
emitter: "unknown".to_string(),
}
}
#[derive(Debug, thiserror::Error)]
pub enum BackendError {
#[error("unsupported target: {0:?}")]
UnsupportedTarget(Target),
#[error("missing hardware profile for target {0:?}")]
MissingHardware(Target),
#[error("lowering error: {0}")]
Lower(String),
#[error("compile-contract citation missing for emitted construct: {0}")]
MissingCompileContractCitation(String),
}
pub trait Backend: Send + Sync {
fn name(&self) -> &'static str;
fn targets(&self) -> &[Target];
fn lower(&self, module: &Module, config: &BackendConfig) -> Result<Artifact, BackendError>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EmitterRole {
General,
Specialist,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "kind")]
pub enum QuorumPolicy {
PreferSpecialist,
DiffExec {
tolerance: f64,
},
Strict,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum QuorumStatus {
Single { emitter: String },
Multi {
emitters: Vec<String>,
diff_exec: Option<DiffExecResult>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum DiffExecResult {
Match { max_abs_diff: f64 },
Divergent { max_abs_diff: f64, tolerance: f64 },
NotRun { reason: String },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ViaEntry {
pub emitter: String,
pub role: EmitterRole,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub crate_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cross_repo: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub shape_filter: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EmittedText {
pub primary: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub citations: Vec<ContractId>,
}
pub trait TargetEmitter: Send + Sync {
fn name(&self) -> &str;
fn try_emit(
&self,
module: &Module,
config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>>;
}
pub trait DiffExecEngine: Send + Sync {
fn execute_and_compare(
&self,
general_text: &str,
specialist_text: &str,
module: &Module,
config: &BackendConfig,
tolerance: f64,
) -> Result<DiffExecResult, String>;
}
pub struct MultiEmitterBackend {
pub target: Target,
pub general: Box<dyn TargetEmitter>,
pub specialist: Option<Box<dyn TargetEmitter>>,
pub quorum_policy: QuorumPolicy,
pub diff_exec_engine: Option<std::sync::Arc<dyn DiffExecEngine>>,
}
impl MultiEmitterBackend {
pub fn new_single(target: Target, general: Box<dyn TargetEmitter>) -> Self {
Self {
target,
general,
specialist: None,
quorum_policy: QuorumPolicy::PreferSpecialist,
diff_exec_engine: None,
}
}
pub fn new_with_specialist(
target: Target,
general: Box<dyn TargetEmitter>,
specialist: Box<dyn TargetEmitter>,
quorum_policy: QuorumPolicy,
) -> Self {
Self {
target,
general,
specialist: Some(specialist),
quorum_policy,
diff_exec_engine: None,
}
}
pub fn with_diff_exec_engine(mut self, engine: std::sync::Arc<dyn DiffExecEngine>) -> Self {
self.diff_exec_engine = Some(engine);
self
}
}
impl Backend for MultiEmitterBackend {
fn name(&self) -> &'static str {
"multi-emitter"
}
fn targets(&self) -> &[Target] {
std::slice::from_ref(&self.target)
}
fn lower(&self, module: &Module, config: &BackendConfig) -> Result<Artifact, BackendError> {
let general_result = self.general.try_emit(module, config).ok_or_else(|| {
BackendError::Lower(format!(
"general emitter {} must always match contract-conforming input",
self.general.name()
))
})??;
let specialist_result = self.specialist.as_ref().and_then(|s| {
s.try_emit(module, config)
.map(|r| (s.name().to_string(), r))
});
match specialist_result {
None => {
Ok(Artifact {
primary: general_result.primary,
sidecars: Vec::new(),
citations: general_result.citations,
quorum_status: QuorumStatus::Single {
emitter: self.general.name().to_string(),
},
})
}
Some((specialist_name, specialist_emit)) => {
let specialist_text = specialist_emit?;
match &self.quorum_policy {
QuorumPolicy::PreferSpecialist => {
Ok(Artifact {
primary: specialist_text.primary,
sidecars: Vec::new(),
citations: specialist_text.citations,
quorum_status: QuorumStatus::Single {
emitter: specialist_name,
},
})
}
QuorumPolicy::Strict => {
let diff_exec = if general_result.primary == specialist_text.primary {
Some(DiffExecResult::Match { max_abs_diff: 0.0 })
} else {
Some(DiffExecResult::Divergent {
max_abs_diff: f64::INFINITY,
tolerance: 0.0,
})
};
Ok(Artifact {
primary: general_result.primary.clone(),
sidecars: vec![(
"specialist_emission".to_string(),
specialist_text.primary.into_bytes(),
)],
citations: general_result.citations,
quorum_status: QuorumStatus::Multi {
emitters: vec![self.general.name().to_string(), specialist_name],
diff_exec,
},
})
}
QuorumPolicy::DiffExec { tolerance } => {
let diff_exec = match &self.diff_exec_engine {
Some(engine) => engine
.execute_and_compare(
&general_result.primary,
&specialist_text.primary,
module,
config,
*tolerance,
)
.map_err(|e| {
BackendError::Lower(format!(
"DiffExec engine for {:?} failed: {e}",
self.target
))
})?,
None => DiffExecResult::NotRun {
reason: format!(
"no DiffExec engine installed (tolerance was {tolerance})"
),
},
};
Ok(Artifact {
primary: general_result.primary.clone(),
sidecars: vec![(
"specialist_emission".to_string(),
specialist_text.primary.into_bytes(),
)],
citations: general_result.citations,
quorum_status: QuorumStatus::Multi {
emitters: vec![self.general.name().to_string(), specialist_name],
diff_exec: Some(diff_exec),
},
})
}
}
}
}
}
}
#[cfg(test)]
mod quorum_scaffolding_tests {
use super::*;
#[test]
fn emitter_role_serde_round_trip() {
let general = EmitterRole::General;
let s = serde_json::to_string(&general).unwrap();
assert_eq!(s, "\"general\"");
let back: EmitterRole = serde_json::from_str(&s).unwrap();
assert_eq!(back, general);
let specialist = EmitterRole::Specialist;
let s = serde_json::to_string(&specialist).unwrap();
assert_eq!(s, "\"specialist\"");
}
#[test]
fn quorum_policy_diff_exec_carries_tolerance() {
let policy = QuorumPolicy::DiffExec { tolerance: 1.0e-3 };
let s = serde_json::to_string(&policy).unwrap();
assert!(s.contains("diff_exec"));
assert!(s.contains("0.001"));
let back: QuorumPolicy = serde_json::from_str(&s).unwrap();
assert_eq!(back, policy);
}
#[test]
fn quorum_status_multi_records_emitters_and_diff() {
let status = QuorumStatus::Multi {
emitters: vec!["rustc_codegen_nvvm".into(), "aprender-gpu".into()],
diff_exec: Some(DiffExecResult::Match {
max_abs_diff: 1.3e-4,
}),
};
let s = serde_json::to_string(&status).unwrap();
assert!(s.contains("multi"));
assert!(s.contains("rustc_codegen_nvvm"));
assert!(s.contains("aprender-gpu"));
}
#[test]
fn diff_exec_divergent_carries_both_diff_and_tolerance() {
let r = DiffExecResult::Divergent {
max_abs_diff: 0.5,
tolerance: 0.001,
};
let s = serde_json::to_string(&r).unwrap();
let back: DiffExecResult = serde_json::from_str(&s).unwrap();
assert_eq!(back, r);
}
#[test]
fn via_entry_general_has_no_specialist_fields() {
let v = ViaEntry {
emitter: "rustc_codegen_nvvm".into(),
role: EmitterRole::General,
crate_name: Some("xpile-ptx-codegen".into()),
cross_repo: None,
shape_filter: None,
};
let s = serde_json::to_string(&v).unwrap();
assert!(!s.contains("cross_repo"));
assert!(!s.contains("shape_filter"));
assert!(s.contains("general"));
}
#[test]
fn via_entry_specialist_carries_cross_repo_and_shape_filter() {
let v = ViaEntry {
emitter: "aprender-gpu".into(),
role: EmitterRole::Specialist,
crate_name: None,
cross_repo: Some("aprender".into()),
shape_filter: Some("gemm_fp16_mma_64x128".into()),
};
let s = serde_json::to_string(&v).unwrap();
assert!(s.contains("specialist"));
assert!(s.contains("aprender"));
assert!(s.contains("gemm_fp16_mma_64x128"));
}
#[test]
fn artifact_quorum_status_defaults_for_older_payloads() {
let legacy_json = r#"{"primary":"// test","sidecars":[],"citations":[]}"#;
let a: Artifact = serde_json::from_str(legacy_json).unwrap();
assert_eq!(
a.quorum_status,
QuorumStatus::Single {
emitter: "unknown".to_string()
}
);
}
#[test]
fn artifact_quorum_status_single_round_trips() {
let a = Artifact {
primary: "// test".into(),
sidecars: Vec::new(),
citations: Vec::new(),
quorum_status: QuorumStatus::Single {
emitter: "xpile-rust-codegen".to_string(),
},
};
let s = serde_json::to_string(&a).unwrap();
let back: Artifact = serde_json::from_str(&s).unwrap();
assert_eq!(back, a);
}
struct MockGeneral {
name: &'static str,
body: String,
}
impl TargetEmitter for MockGeneral {
fn name(&self) -> &str {
self.name
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
Some(Ok(EmittedText {
primary: self.body.clone(),
citations: Vec::new(),
}))
}
}
struct MockSpecialist {
name: &'static str,
matches: bool,
body: String,
}
impl TargetEmitter for MockSpecialist {
fn name(&self) -> &str {
self.name
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
if self.matches {
Some(Ok(EmittedText {
primary: self.body.clone(),
citations: Vec::new(),
}))
} else {
None
}
}
}
fn dummy_module() -> Module {
Module {
name: "test".into(),
source_lang: xpile_meta_hir::SourceLang::Rust,
items: Vec::new(),
ffi_boundaries: Vec::new(),
}
}
fn dummy_config() -> BackendConfig {
BackendConfig {
target: Target::Ptx,
profile: Profile::RustOut,
hardware: None,
}
}
#[test]
fn multi_emitter_specialist_missing_falls_back_to_general() {
let backend = MultiEmitterBackend::new_single(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "general output".into(),
}),
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
assert_eq!(artifact.primary, "general output");
assert_eq!(
artifact.quorum_status,
QuorumStatus::Single {
emitter: "general".to_string()
}
);
}
#[test]
fn multi_emitter_specialist_unmatched_falls_back_to_general() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "general output".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: false,
body: "specialist output".into(),
}),
QuorumPolicy::DiffExec { tolerance: 1e-3 },
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
assert_eq!(artifact.primary, "general output");
assert_eq!(
artifact.quorum_status,
QuorumStatus::Single {
emitter: "general".to_string()
}
);
}
#[test]
fn multi_emitter_prefer_specialist_uses_specialist_output() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "general".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "specialist tuned".into(),
}),
QuorumPolicy::PreferSpecialist,
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
assert_eq!(artifact.primary, "specialist tuned");
assert_eq!(
artifact.quorum_status,
QuorumStatus::Single {
emitter: "specialist".to_string()
}
);
}
#[test]
fn multi_emitter_strict_match_records_zero_diff() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "same output".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "same output".into(),
}),
QuorumPolicy::Strict,
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi {
emitters,
diff_exec,
} => {
assert_eq!(emitters, vec!["general", "specialist"]);
assert_eq!(diff_exec, Some(DiffExecResult::Match { max_abs_diff: 0.0 }));
}
_ => panic!("expected Multi quorum status"),
}
assert_eq!(artifact.sidecars.len(), 1);
assert_eq!(artifact.sidecars[0].0, "specialist_emission");
}
#[test]
fn multi_emitter_strict_divergence_records_infinity() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "general output".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "different output".into(),
}),
QuorumPolicy::Strict,
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi { diff_exec, .. } => {
assert!(matches!(diff_exec, Some(DiffExecResult::Divergent { .. })));
}
_ => panic!("expected Multi quorum status"),
}
}
#[test]
fn multi_emitter_diff_exec_records_not_run_until_engine_plugged_in() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "rustc_codegen_nvvm",
body: "ptx general".into(),
}),
Box::new(MockSpecialist {
name: "aprender-gpu",
matches: true,
body: "ptx specialist".into(),
}),
QuorumPolicy::DiffExec { tolerance: 1e-3 },
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi {
emitters,
diff_exec,
} => {
assert_eq!(emitters, vec!["rustc_codegen_nvvm", "aprender-gpu"]);
assert!(matches!(diff_exec, Some(DiffExecResult::NotRun { .. })));
}
_ => panic!("expected Multi quorum status"),
}
}
struct MockGeneralWithCitations {
body: String,
citations: Vec<ContractId>,
}
impl TargetEmitter for MockGeneralWithCitations {
fn name(&self) -> &str {
"general-with-cites"
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
Some(Ok(EmittedText {
primary: self.body.clone(),
citations: self.citations.clone(),
}))
}
}
struct MockSpecialistWithCitations {
body: String,
citations: Vec<ContractId>,
}
impl TargetEmitter for MockSpecialistWithCitations {
fn name(&self) -> &str {
"specialist-with-cites"
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
Some(Ok(EmittedText {
primary: self.body.clone(),
citations: self.citations.clone(),
}))
}
}
struct MockFailingEmitter {
name: &'static str,
err: String,
}
impl TargetEmitter for MockFailingEmitter {
fn name(&self) -> &str {
self.name
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
Some(Err(BackendError::Lower(self.err.clone())))
}
}
struct MockNoneEmitter;
impl TargetEmitter for MockNoneEmitter {
fn name(&self) -> &str {
"always-none"
}
fn try_emit(
&self,
_module: &Module,
_config: &BackendConfig,
) -> Option<Result<EmittedText, BackendError>> {
None
}
}
#[test]
fn strict_divergence_preserves_general_citations_not_specialist() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneralWithCitations {
body: "general output".into(),
citations: vec![ContractId::new("C-GENERAL-CITED")],
}),
Box::new(MockSpecialistWithCitations {
body: "different output".into(),
citations: vec![ContractId::new("C-SPECIALIST-CITED")],
}),
QuorumPolicy::Strict,
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
assert_eq!(artifact.citations.len(), 1);
assert_eq!(artifact.citations[0].as_str(), "C-GENERAL-CITED");
assert_eq!(artifact.sidecars.len(), 1);
assert_eq!(
artifact.sidecars[0].1,
b"different output".to_vec(),
"specialist body should be preserved in sidecar"
);
}
#[test]
fn prefer_specialist_hides_divergence_by_design() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneralWithCitations {
body: "general thinks the answer is 42".into(),
citations: vec![ContractId::new("C-GENERAL")],
}),
Box::new(MockSpecialistWithCitations {
body: "specialist thinks the answer is 99".into(),
citations: vec![ContractId::new("C-SPECIALIST")],
}),
QuorumPolicy::PreferSpecialist,
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
assert!(artifact.primary.contains("99"));
assert_eq!(artifact.citations[0].as_str(), "C-SPECIALIST");
match artifact.quorum_status {
QuorumStatus::Single { emitter } => {
assert_eq!(emitter, "specialist-with-cites");
}
other => panic!("expected Single quorum status, got {other:?}"),
}
assert!(artifact.sidecars.is_empty());
}
#[test]
fn general_emitter_failure_propagates() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockFailingEmitter {
name: "general-broken",
err: "general blew up".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "specialist output".into(),
}),
QuorumPolicy::PreferSpecialist,
);
let err = backend.lower(&dummy_module(), &dummy_config()).unwrap_err();
match err {
BackendError::Lower(msg) => assert!(msg.contains("general blew up")),
other => panic!("expected Lower error, got {other:?}"),
}
}
#[test]
fn specialist_emitter_failure_propagates_when_matched() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "general output".into(),
}),
Box::new(MockFailingEmitter {
name: "specialist-broken",
err: "specialist blew up after matching".into(),
}),
QuorumPolicy::Strict,
);
let err = backend.lower(&dummy_module(), &dummy_config()).unwrap_err();
match err {
BackendError::Lower(msg) => {
assert!(msg.contains("specialist blew up after matching"))
}
other => panic!("expected Lower error, got {other:?}"),
}
}
#[test]
fn general_returning_none_is_a_hard_contract_violation() {
let backend = MultiEmitterBackend::new_single(Target::Ptx, Box::new(MockNoneEmitter));
let err = backend.lower(&dummy_module(), &dummy_config()).unwrap_err();
match err {
BackendError::Lower(msg) => {
assert!(
msg.contains("always-none"),
"error should name the offending emitter; got: {msg}"
);
assert!(msg.contains("must always match"));
}
other => panic!("expected Lower error, got {other:?}"),
}
}
#[test]
fn diff_exec_not_run_reason_records_tolerance_for_observability() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "g".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "s".into(),
}),
QuorumPolicy::DiffExec { tolerance: 2.5e-4 },
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi {
diff_exec: Some(DiffExecResult::NotRun { reason }),
..
} => {
assert!(
reason.contains("0.00025")
|| reason.contains("2.5e-4")
|| reason.contains("0.000250"),
"tolerance should appear in NotRun reason; got: {reason}"
);
}
other => panic!("expected Multi NotRun status, got {other:?}"),
}
}
#[test]
fn diff_exec_does_not_short_circuit_on_text_equality() {
let backend = MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "byte identical".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "byte identical".into(),
}),
QuorumPolicy::DiffExec { tolerance: 1e-6 },
);
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi { diff_exec, .. } => {
assert!(
matches!(diff_exec, Some(DiffExecResult::NotRun { .. })),
"DiffExec policy must NOT short-circuit on text equality \
— engine compares runtime values, not source text"
);
}
other => panic!("expected Multi quorum status, got {other:?}"),
}
}
struct StubEngine {
result: Result<DiffExecResult, String>,
}
impl DiffExecEngine for StubEngine {
fn execute_and_compare(
&self,
_g: &str,
_s: &str,
_m: &Module,
_c: &BackendConfig,
_tol: f64,
) -> Result<DiffExecResult, String> {
self.result.clone()
}
}
fn diff_exec_backend() -> MultiEmitterBackend {
MultiEmitterBackend::new_with_specialist(
Target::Ptx,
Box::new(MockGeneral {
name: "general",
body: "g".into(),
}),
Box::new(MockSpecialist {
name: "specialist",
matches: true,
body: "s".into(),
}),
QuorumPolicy::DiffExec { tolerance: 1e-6 },
)
}
#[test]
fn diff_exec_engine_records_match() {
let backend = diff_exec_backend().with_diff_exec_engine(std::sync::Arc::new(StubEngine {
result: Ok(DiffExecResult::Match { max_abs_diff: 0.0 }),
}));
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi {
diff_exec: Some(DiffExecResult::Match { .. }),
..
} => {}
other => panic!("expected Multi Match, got {other:?}"),
}
}
#[test]
fn diff_exec_engine_error_is_a_hard_failure() {
let backend = diff_exec_backend().with_diff_exec_engine(std::sync::Arc::new(StubEngine {
result: Err("driver fault: CUDA_ERROR_LAUNCH_FAILED".into()),
}));
let err = backend
.lower(&dummy_module(), &dummy_config())
.expect_err("engine error must surface as a hard BackendError");
assert!(matches!(err, BackendError::Lower(_)));
}
#[test]
fn diff_exec_no_engine_records_not_run() {
let backend = diff_exec_backend();
let artifact = backend.lower(&dummy_module(), &dummy_config()).unwrap();
match artifact.quorum_status {
QuorumStatus::Multi {
diff_exec: Some(DiffExecResult::NotRun { reason }),
..
} => assert!(reason.contains("no DiffExec engine"), "got: {reason}"),
other => panic!("expected Multi NotRun, got {other:?}"),
}
}
}