tnc/builders/
connectivity.rs

1use itertools::Itertools;
2
3/// Struct that defines connectivity of IBM device.
4#[derive(Debug, PartialEq, Eq)]
5pub struct Connectivity {
6    /// The coupling graph of the device.
7    pub connectivity: Vec<(usize, usize)>,
8    name: ConnectivityLayout,
9}
10
11/// Different types of connectivity layouts of IBM devices.
12#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13pub enum ConnectivityLayout {
14    Condor,
15    Eagle,
16    Osprey,
17    Sycamore,
18    /// All-to-all connectivity with the given number of qubits.
19    All(usize),
20    /// Line topology with the given number of qubits.
21    Line(usize),
22}
23
24impl Connectivity {
25    /// Create a new connectivity layout instance.
26    ///
27    /// # Examples
28    /// ```
29    /// # use tnc::builders::connectivity::Connectivity;
30    /// # use tnc::builders::connectivity::ConnectivityLayout;
31    /// let cn = Connectivity::new(ConnectivityLayout::Eagle);
32    /// ```
33    #[must_use]
34    pub fn new(name: ConnectivityLayout) -> Self {
35        let connectivity = match name {
36            ConnectivityLayout::Condor => condor_connect(),
37            ConnectivityLayout::Eagle => eagle_connect(),
38            ConnectivityLayout::Osprey => osprey_connect(),
39            ConnectivityLayout::Sycamore => sycamore_connect(),
40            ConnectivityLayout::All(n) => all_connect(n),
41            ConnectivityLayout::Line(n) => line_connect(n),
42        };
43        Self { connectivity, name }
44    }
45}
46
47fn all_connect(n: usize) -> Vec<(usize, usize)> {
48    assert!(n > 0);
49
50    let mut v = Vec::with_capacity(n * (n - 1) / 2);
51    for i in 0..(n - 1) {
52        for j in (i + 1)..n {
53            v.push((i, j));
54        }
55    }
56    v
57}
58
59fn sycamore_connect() -> Vec<(usize, usize)> {
60    vec![
61        (52, 32),
62        (32, 31),
63        (31, 24),
64        (24, 29),
65        (29, 26),
66        (26, 40),
67        (40, 44),
68        (44, 53),
69        (37, 32),
70        (32, 21),
71        (21, 24),
72        (24, 18),
73        (18, 26),
74        (26, 25),
75        (25, 44),
76        (44, 48),
77        (37, 22),
78        (22, 21),
79        (21, 7),
80        (7, 18),
81        (18, 15),
82        (15, 25),
83        (25, 42),
84        (42, 48),
85        (35, 22),
86        (22, 8),
87        (8, 7),
88        (7, 5),
89        (5, 15),
90        (15, 16),
91        (16, 42),
92        (42, 46),
93        (35, 11),
94        (11, 8),
95        (8, 1),
96        (1, 5),
97        (5, 6),
98        (6, 16),
99        (16, 51),
100        (51, 46),
101        (11, 4),
102        (4, 1),
103        (1, 2),
104        (2, 6),
105        (6, 12),
106        (12, 51),
107        (51, 47),
108        (14, 4),
109        (4, 3),
110        (3, 2),
111        (2, 10),
112        (10, 12),
113        (12, 41),
114        (41, 47),
115        (36, 14),
116        (14, 13),
117        (13, 3),
118        (3, 9),
119        (9, 10),
120        (10, 20),
121        (20, 41),
122        (41, 50),
123        (36, 27),
124        (27, 13),
125        (13, 17),
126        (17, 9),
127        (9, 19),
128        (19, 20),
129        (20, 43),
130        (43, 50),
131        (38, 27),
132        (27, 28),
133        (28, 17),
134        (17, 23),
135        (23, 19),
136        (19, 34),
137        (34, 43),
138        (43, 49),
139        (38, 39),
140        (39, 28),
141        (28, 30),
142        (30, 23),
143        (23, 33),
144        (33, 34),
145        (34, 45),
146        (45, 49),
147    ]
148}
149
150pub(super) fn sycamore_a() -> Vec<(usize, usize)> {
151    vec![
152        (31, 32),
153        (29, 24),
154        (40, 26),
155        (53, 44),
156        (21, 22),
157        (18, 7),
158        (25, 15),
159        (48, 42),
160        (8, 11),
161        (5, 1),
162        (16, 6),
163        (46, 51),
164        (14, 4),
165        (2, 3),
166        (12, 10),
167        (47, 41),
168        (13, 27),
169        (9, 17),
170        (20, 19),
171        (50, 43),
172        (28, 39),
173        (23, 30),
174        (34, 33),
175        (49, 45),
176    ]
177}
178
179pub(super) fn sycamore_b() -> Vec<(usize, usize)> {
180    vec![
181        (32, 37),
182        (24, 21),
183        (26, 18),
184        (44, 25),
185        (22, 35),
186        (7, 8),
187        (15, 5),
188        (42, 16),
189        (1, 4),
190        (6, 2),
191        (51, 12),
192        (14, 36),
193        (3, 13),
194        (10, 9),
195        (41, 20),
196        (27, 38),
197        (17, 28),
198        (19, 23),
199        (43, 34),
200    ]
201}
202
203pub(super) fn sycamore_c() -> Vec<(usize, usize)> {
204    vec![
205        (52, 32),
206        (31, 24),
207        (29, 26),
208        (40, 44),
209        (37, 22),
210        (21, 7),
211        (18, 15),
212        (25, 42),
213        (35, 11),
214        (8, 1),
215        (5, 6),
216        (16, 51),
217        (4, 3),
218        (2, 10),
219        (12, 41),
220        (36, 27),
221        (13, 17),
222        (9, 19),
223        (20, 43),
224        (38, 39),
225        (28, 30),
226        (23, 33),
227        (34, 45),
228    ]
229}
230
231pub(super) fn sycamore_d() -> Vec<(usize, usize)> {
232    vec![
233        (32, 21),
234        (24, 18),
235        (26, 25),
236        (44, 48),
237        (22, 8),
238        (7, 5),
239        (15, 16),
240        (42, 46),
241        (11, 4),
242        (1, 2),
243        (6, 12),
244        (51, 47),
245        (14, 13),
246        (3, 9),
247        (10, 20),
248        (41, 50),
249        (27, 28),
250        (17, 23),
251        (19, 34),
252        (43, 49),
253    ]
254}
255
256#[allow(
257    dead_code,
258    reason = "Might be needed for more advanced Sycamore test cases"
259)]
260pub(super) fn sycamore_e() -> Vec<(usize, usize)> {
261    vec![
262        (52, 32),
263        (29, 26),
264        (24, 18),
265        (21, 7),
266        (22, 8),
267        (35, 11),
268        (44, 48),
269        (25, 42),
270        (15, 16),
271        (5, 6),
272        (1, 2),
273        (4, 3),
274        (14, 13),
275        (36, 27),
276        (51, 47),
277        (12, 41),
278        (10, 20),
279        (9, 19),
280        (17, 23),
281        (28, 30),
282        (43, 49),
283        (34, 45),
284    ]
285}
286
287#[allow(
288    dead_code,
289    reason = "Might be needed for more advanced Sycamore test cases"
290)]
291pub(super) fn sycamore_f() -> Vec<(usize, usize)> {
292    vec![
293        (31, 24),
294        (32, 21),
295        (37, 22),
296        (40, 44),
297        (26, 25),
298        (18, 15),
299        (7, 5),
300        (8, 1),
301        (11, 4),
302        (42, 46),
303        (16, 51),
304        (6, 12),
305        (2, 10),
306        (3, 9),
307        (13, 17),
308        (27, 28),
309        (38, 39),
310        (41, 50),
311        (20, 43),
312        (19, 34),
313        (23, 33),
314    ]
315}
316
317#[allow(
318    dead_code,
319    reason = "Might be needed for more advanced Sycamore test cases"
320)]
321pub(super) fn sycamore_g() -> Vec<(usize, usize)> {
322    vec![
323        (27, 38),
324        (28, 39),
325        (14, 4),
326        (13, 3),
327        (17, 9),
328        (23, 19),
329        (33, 34),
330        (37, 32),
331        (22, 21),
332        (8, 7),
333        (5, 1),
334        (6, 2),
335        (12, 10),
336        (41, 20),
337        (50, 43),
338        (29, 24),
339        (26, 18),
340        (25, 15),
341        (42, 16),
342        (46, 51),
343        (53, 44),
344    ]
345}
346
347#[allow(
348    dead_code,
349    reason = "Might be needed for more advanced Sycamore test cases"
350)]
351pub(super) fn sycamore_h() -> Vec<(usize, usize)> {
352    vec![
353        (14, 36),
354        (13, 27),
355        (17, 28),
356        (23, 30),
357        (22, 35),
358        (8, 11),
359        (1, 4),
360        (2, 3),
361        (10, 9),
362        (20, 19),
363        (43, 34),
364        (49, 45),
365        (31, 32),
366        (24, 21),
367        (18, 7),
368        (15, 5),
369        (16, 6),
370        (51, 12),
371        (47, 41),
372        (40, 26),
373        (44, 25),
374        (48, 42),
375    ]
376}
377
378fn hexagon_connectivity<I>(
379    row_length: usize,
380    connectivity: &mut Vec<(usize, usize)>,
381    stride: usize,
382    mut bridge_cycle_prev: I,
383    bridges: usize,
384    rows: usize,
385) where
386    I: Iterator<Item = usize> + Clone,
387{
388    let mut count = 0;
389    let mut bridge_cycle_next = bridge_cycle_prev.clone();
390    // first row
391    let mut prev_last;
392    let mut next_last = row_length - 2;
393    for i in 0..(row_length - 2) {
394        connectivity.push((i, i + 1));
395
396        if i % stride == 0 {
397            connectivity.push((i, next_last + bridge_cycle_prev.next().unwrap()));
398        }
399    }
400    count += row_length - 1 + bridges;
401    for row in 0..rows {
402        //first push intermediate
403        prev_last = next_last;
404        next_last = count + row_length - 1;
405
406        for i in 0..(row_length - 1) {
407            if (i + 2 * (row % 2)) % 4 == 0 {
408                connectivity.push((prev_last + bridge_cycle_prev.next().unwrap(), count + i));
409            }
410
411            connectivity.push((count + i, count + i + 1));
412
413            if (i + 2 * ((row + 1) % 2)) % 4 == 0 {
414                connectivity.push((count + i, next_last + bridge_cycle_next.next().unwrap()));
415            }
416        }
417        if row % 2 == 0 {
418            connectivity.push((next_last, next_last + bridge_cycle_next.next().unwrap()));
419        }
420        count += row_length + bridges;
421    }
422
423    prev_last = next_last;
424    next_last = count + row_length - 2;
425
426    for i in 0..(row_length - 2) {
427        if (i + 3) % stride == 0 {
428            connectivity.push((prev_last + bridge_cycle_next.next().unwrap(), count + i));
429        }
430        connectivity.push((count + i, count + i + 1));
431    }
432    //last row
433    connectivity.push((prev_last + bridge_cycle_next.next().unwrap(), next_last));
434}
435
436fn eagle_connect() -> Vec<(usize, usize)> {
437    let rows = 5;
438    let row_length = 15;
439    let bridge_cycle = (1..=4).cycle();
440    let bridges = 4;
441    let stride = 4;
442    let mut connectivity = Vec::new();
443
444    hexagon_connectivity(
445        row_length,
446        &mut connectivity,
447        stride,
448        bridge_cycle,
449        bridges,
450        rows,
451    );
452
453    connectivity
454}
455
456fn osprey_connect() -> Vec<(usize, usize)> {
457    let rows = 11;
458    let row_length = 27;
459    let bridge_cycle = (1..=7).cycle();
460    let bridges = 7;
461    let stride = 4;
462    let mut connectivity = Vec::new();
463
464    hexagon_connectivity(
465        row_length,
466        &mut connectivity,
467        stride,
468        bridge_cycle,
469        bridges,
470        rows,
471    );
472
473    connectivity
474}
475
476fn condor_connect() -> Vec<(usize, usize)> {
477    let rows = 19;
478    let row_length = 43;
479    let bridge_cycle = (1..=11).cycle();
480    let bridges = 11;
481    let stride = 4;
482    let mut connectivity = Vec::new();
483
484    hexagon_connectivity(
485        row_length,
486        &mut connectivity,
487        stride,
488        bridge_cycle,
489        bridges,
490        rows,
491    );
492
493    connectivity
494}
495
496fn line_connect(n: usize) -> Vec<(usize, usize)> {
497    (0..n).tuple_windows().collect::<Vec<_>>()
498}