Skip to main content

q_rust/
backend.rs

1use petgraph::Directed;
2use petgraph::graph::{Graph, NodeIndex};
3use std::collections::HashSet;
4
5/// Backend Specification
6#[derive(Debug, Clone)]
7pub struct Backend {
8    pub name: String,
9    pub num_qubits: usize,
10    pub basis_gates: HashSet<String>,
11    /// Coupling map representing physical qubit connectivity.
12    /// Nodes are physical qubits, edges represent allowed 2-qubit gates.
13    pub coupling_map: Graph<(), (), Directed>,
14}
15
16impl Backend {
17    pub fn new(name: String, num_qubits: usize) -> Self {
18        let mut graph = Graph::new();
19        // Initialize nodes for each qubit
20        for _ in 0..num_qubits {
21            graph.add_node(());
22        }
23
24        Self {
25            name,
26            num_qubits,
27            basis_gates: HashSet::new(),
28            coupling_map: graph,
29        }
30    }
31
32    pub fn add_basis_gate(&mut self, gate: &str) {
33        self.basis_gates.insert(gate.to_string());
34    }
35
36    /// Sets the coupling map from a list of edges.
37    /// Edges are directed: (source, target).
38    pub fn set_coupling_map(&mut self, edges: Vec<(usize, usize)>) {
39        self.coupling_map.clear_edges();
40        for (u, v) in edges {
41            // Ensure indices are within bounds
42            if u < self.num_qubits && v < self.num_qubits {
43                self.coupling_map
44                    .add_edge(NodeIndex::new(u), NodeIndex::new(v), ());
45            }
46        }
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_backend_creation() {
56        let backend = Backend::new("test_backend".to_string(), 5);
57        assert_eq!(backend.num_qubits, 5);
58        assert_eq!(backend.coupling_map.node_count(), 5);
59        assert_eq!(backend.coupling_map.edge_count(), 0);
60    }
61
62    #[test]
63    fn test_coupling_map() {
64        let mut backend = Backend::new("test_backend".to_string(), 3);
65        // Linear connectivity: 0 -> 1 -> 2
66        let edges = vec![(0, 1), (1, 2)];
67        backend.set_coupling_map(edges);
68
69        assert_eq!(backend.coupling_map.edge_count(), 2);
70        assert!(
71            backend
72                .coupling_map
73                .contains_edge(NodeIndex::new(0), NodeIndex::new(1))
74        );
75        assert!(
76            backend
77                .coupling_map
78                .contains_edge(NodeIndex::new(1), NodeIndex::new(2))
79        );
80        assert!(
81            !backend
82                .coupling_map
83                .contains_edge(NodeIndex::new(0), NodeIndex::new(2))
84        );
85    }
86}