use crate::circuit::{CircuitError, Instruction};
use crate::device::{DeviceValidationError, LogicalQubit, PhysicalQubit};
use std::fmt;
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct DeviceLoweringDependency {
pub instruction: Instruction,
pub qargs: Vec<PhysicalQubit>,
}
#[derive(Debug, Clone)]
pub struct DeviceLoweringCandidateFailure {
pub template: String,
pub unsatisfied_dependencies: Vec<DeviceLoweringDependency>,
}
#[derive(Debug, Clone)]
pub struct DeviceLoweringFailure {
pub instruction: Instruction,
pub qargs: Vec<PhysicalQubit>,
pub attempted_candidates: Vec<DeviceLoweringCandidateFailure>,
}
impl fmt::Display for DeviceLoweringFailure {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"no device instruction lowering plan for {} on ordered physical qargs {:?}",
self.instruction, self.qargs
)
}
}
impl std::error::Error for DeviceLoweringFailure {}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum SabreRoutingFailure {
#[error("logical unary requirement on {logical} has no executable native terminal")]
NoExecutableUnaryTerminal {
logical: LogicalQubit,
},
#[error(
"logical unary requirement on {logical} at physical qubit {physical} cannot reach an executable location through lowerable SWAP edges"
)]
UnreachableUnaryPlacement {
logical: LogicalQubit,
physical: PhysicalQubit,
},
#[error("logical interaction {logical:?} has no executable native terminal pair")]
NoExecutablePairTerminal {
logical: [LogicalQubit; 2],
},
#[error(
"logical interaction {logical:?} at physical qubits {physical:?} cannot reach an executable terminal pair through lowerable SWAP edges"
)]
UnreachablePairPlacement {
logical: [LogicalQubit; 2],
physical: [PhysicalQubit; 2],
},
#[error(
"no movement-component assignment satisfies all unary, ordered-pair, and capacity constraints"
)]
MovementAssignmentInfeasible,
#[error(
"movement-component assignment exhausted budget {budget} after {expansions} expansions without proving infeasibility"
)]
MovementAssignmentBudgetExhausted {
budget: usize,
expansions: usize,
},
#[error(
"all {evaluated} SABRE layout candidates were infeasible ({missing_terminal} missing a native terminal, {movement_unreachable} movement-unreachable, {unsupported_native} rejected during native lowering)"
)]
NoFeasibleLayoutCandidate {
evaluated: usize,
missing_terminal: usize,
movement_unreachable: usize,
unsupported_native: usize,
},
}
#[derive(Debug, Error)]
pub enum CompilerError {
#[error(transparent)]
Circuit(#[from] CircuitError),
#[error("invalid compiler input: {0}")]
InvalidInput(String),
#[error("compiler transform '{name}' failed: {reason}")]
TransformFailed {
name: &'static str,
reason: String,
},
#[error("compiler invariant violation: {0}")]
InvariantViolation(String),
#[error("device instruction lowering failed: {0}")]
DeviceLoweringFailed(#[source] DeviceLoweringFailure),
#[error("SABRE routing failed: {0}")]
SabreRoutingFailed(#[source] SabreRoutingFailure),
#[error("device validation failed: {0}")]
DeviceValidationFailed(#[from] DeviceValidationError),
}