use super::{GateSynthesis, SynthesisOptions};
use crate::photonic::fabric::{
FabricConstraints, PacketRequest, PacketScheduler, RailPacketScheduler, RailRoute,
WavelengthConstraints,
};
use crate::photonic::{CompileOptions, Fabric, NodeId, NodeKind, RailTransmission, Route};
use crate::{Circuit, Error, Operation, Result};
use serde::Serialize;
mod calibrated_execution;
mod calibration;
pub(super) mod execution;
mod scheduling;
pub use calibrated_execution::CalibratedOutcome;
pub use calibration::{PhysicalCalibration, ResourceFactoryModel};
pub use execution::{PhysicalOutcome, PhysicalRun};
#[derive(Clone, Debug, Serialize)]
pub struct PhysicalRailOptions {
pub fusion_ticks: Vec<u64>,
pub constraints: WavelengthConstraints,
pub wavelengths: [usize; 2],
}
#[derive(Clone, Debug, Serialize)]
pub struct PhysicalPlacement {
pub inputs: Vec<NodeId>,
pub resource: NodeId,
pub analyzer: NodeId,
pub feedback_ticks: u64,
}
#[derive(Clone, Debug, Serialize)]
pub struct PhysicalGate {
pub(super) operation: Operation,
pub(super) wires: Vec<usize>,
pub(super) input: Vec<RailTransmission>,
pub(super) resource_measured: Vec<RailTransmission>,
pub(super) resource_outputs: Vec<RailTransmission>,
routes: Vec<Route>,
rail_routes: Vec<RailRoute>,
start: u64,
finish: u64,
}
impl PhysicalGate {
pub fn operation(&self) -> &Operation {
&self.operation
}
pub fn wires(&self) -> &[usize] {
&self.wires
}
pub fn routes(&self) -> &[Route] {
&self.routes
}
pub fn rail_routes(&self) -> &[RailRoute] {
&self.rail_routes
}
pub fn start_tick(&self) -> u64 {
self.start
}
pub fn finish_tick(&self) -> u64 {
self.finish
}
}
#[derive(Clone, Debug, Serialize)]
pub struct PhysicalCircuit {
version: u32,
pub(super) source: Circuit,
fabric: Fabric,
placement: PhysicalPlacement,
options: CompileOptions,
pub(super) gates: Vec<PhysicalGate>,
pub(super) final_storage: Vec<RailTransmission>,
synthesis_error: f64,
constraints: Option<FabricConstraints>,
calibration: Option<PhysicalCalibration>,
rail_options: Option<PhysicalRailOptions>,
finish: u64,
}
impl PhysicalCircuit {
pub fn source(&self) -> &Circuit {
&self.source
}
pub fn gates(&self) -> &[PhysicalGate] {
&self.gates
}
pub fn finish_tick(&self) -> u64 {
self.finish
}
pub fn resource_photons(&self) -> usize {
if let Some(model) = &self.calibration {
self.gates
.iter()
.map(|g| {
model
.resource(g.wires.len())
.unwrap()
.factory()
.max_photons()
})
.sum()
} else {
2 * self.gates.iter().map(|g| g.wires.len()).sum::<usize>()
}
}
pub fn synthesis_error(&self) -> f64 {
self.synthesis_error
}
pub fn constraints(&self) -> Option<&FabricConstraints> {
self.constraints.as_ref()
}
pub fn rail_options(&self) -> Option<&PhysicalRailOptions> {
self.rail_options.as_ref()
}
pub fn calibration(&self) -> Option<&PhysicalCalibration> {
self.calibration.as_ref()
}
}