Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
test_partition.py
Go to the documentation of this file.
1 import pytest
2 import numpy as np
3 from squander import Circuit
4 from squander import utils
5 
6 from squander.partitioning.partition import PartitionCircuitQasm
7 from squander.partitioning.kahn import kahn_partition
8 from squander.partitioning.tools import get_qubits
9 
10 
11 """
12 CORRECTNESS TESTS
13 """
14 
15 
16 @pytest.mark.parametrize("max_qubits", [3, 4, 5])
18  """
19  Test partitioning an empty circuit
20  """
21  empty_c = Circuit(5)
22  top_c, param_order, _ = kahn_partition(empty_c, max_qubits)
23  assert len(top_c.get_Gates()) == 1 # NOTE: should be 0
24  assert len(param_order) == 0
25 
26 
27 @pytest.mark.parametrize("max_qubits", [3, 4, 5])
28 def test_PartitionSingleGate(max_qubits):
29  """
30  Test partitioning a circuit with a single gate
31  """
32  single_c = Circuit(5)
33  single_c.add_CNOT(0, 1)
34  top_c, param_order, _ = kahn_partition(single_c, max_qubits)
35  assert len(top_c.get_Gates()) == 1
36  assert len(param_order) == 1
37 
38 
39 @pytest.mark.parametrize("max_qubits", [3, 4, 5])
40 def test_PartitionTotalGates(max_qubits):
41  """
42  Test total gates after partitioning matches original
43  """
44  c = Circuit(5)
45  c.add_CNOT(0, 1)
46  c.add_CNOT(1, 2)
47  c.add_CNOT(2, 3)
48  top_c, _, _ = kahn_partition(c, max_qubits)
49  total_gates = sum(len(p.get_Gates()) for p in top_c.get_Gates())
50  assert total_gates == len(c.get_Gates())
51 
52 
53 @pytest.mark.parametrize("max_qubits", [3, 4, 5])
55  """
56  Test that each partition respects max qubit constraint
57  """
58  c = Circuit(5)
59  c.add_CNOT(0, 1)
60  c.add_CNOT(1, 2)
61  c.add_CNOT(2, 3)
62  top_c, _, _ = kahn_partition(c, max_qubits)
63  for p in top_c.get_Gates():
64  qubits = set.union(*(get_qubits(gate) for gate in p.get_Gates()))
65  assert len(qubits) <= max_qubits
66 
67 
68 @pytest.mark.parametrize("max_qubits", [3, 4, 5])
70  """
71  Test partitioning when max qubits equals total qubits
72  """
73  c = Circuit(max_qubits)
74  c.add_CNOT(0, 1)
75  c.add_CNOT(1, 2)
76  c.add_CCX(1, [2, 0])
77  c.add_CSWAP([1, 2], [0])
78  c.add_SWAP([1, 2])
79 
80  top_c, _, _ = kahn_partition(c, max_qubits)
81  assert len(top_c.get_Gates()) == 1
82 
83 
85  """
86  Test correctness of partitioned circuit by comparing output states
87  """
88  filename = "examples/partitioning/qasm_samples/heisenberg-16-20.qasm"
89 
90  initial_circuit, initial_parameters, _ = utils.qasm_to_squander_circuit(filename)
91 
92  max_partition_size = 4
93  partitined_circuit, partitioned_parameters, _ = PartitionCircuitQasm(
94  filename, max_partition_size
95  )
96 
97  # generate random initial state on which we test the circuits
98  qbit_num = initial_circuit.get_Qbit_Num()
99 
100  matrix_size = 1 << qbit_num
101  initial_state_real = np.random.uniform(-1.0, 1.0, (matrix_size,))
102  initial_state_imag = np.random.uniform(-1.0, 1.0, (matrix_size,))
103  initial_state = initial_state_real + initial_state_imag * 1j
104  initial_state = initial_state / np.linalg.norm(initial_state)
105 
106  transformed_state_1 = initial_state.copy()
107  transformed_state_2 = initial_state.copy()
108 
109  initial_circuit.apply_to(initial_parameters, transformed_state_1)
110  partitined_circuit.apply_to(partitioned_parameters, transformed_state_2)
111 
112  diff = np.linalg.norm(transformed_state_1 - transformed_state_2)
113 
114  assert diff < 1e-10
def kahn_partition(c, max_qubit, preparts=None)
Definition: kahn.py:7
def test_PartitionTotalGates(max_qubits)
def get_qubits
Definition: tools.py:13
def test_PartitionEmptyCircuit(max_qubits)
def PartitionCircuitQasm
Definition: partition.py:95
def test_PartitionMaxQubitConstraint(max_qubits)
def test_PartitionMaxQubitsEqualsTotalQubits(max_qubits)
def test_PartitionSingleGate(max_qubits)