Skip to content

Commit

Permalink
Cache 2q clifford integer table of the tensor product of 1q clifford …
Browse files Browse the repository at this point in the history
…integers in a file
  • Loading branch information
itoko committed Apr 8, 2024
1 parent 38e4636 commit 0c3bd30
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
_valid_sparse_indices = _clifford_compose_2q_data["valid_sparse_indices"]
# map a clifford number to the index of _CLIFFORD_COMPOSE_2Q_DENSE
_clifford_num_to_dense_index = {idx: ii for ii, idx in enumerate(_valid_sparse_indices)}
_CLIFFORD_TENSOR_1Q = np.load(f"{_DATA_FOLDER}/clifford_tensor_1q.npz")["table"]

# Transpilation utilities
def _transpile_clifford_circuit(
Expand Down Expand Up @@ -740,12 +741,6 @@ def _layer_indices_from_num(num: Integral) -> Tuple[Integral, Integral, Integral
return idx0, idx1, idx2


@lru_cache(maxsize=24 * 24)
def _product_1q_nums(first: Integral, second: Integral) -> Integral:
"""Return the 2-qubit Clifford integer that represents the product of 1-qubit Cliffords."""
qc0 = CliffordUtils.clifford_1_qubit_circuit(first)
qc1 = CliffordUtils.clifford_1_qubit_circuit(second)
qc = QuantumCircuit(2)
qc.compose(qc0, qubits=(0,), inplace=True)
qc.compose(qc1, qubits=(1,), inplace=True)
return num_from_2q_circuit(qc)
def _tensor_1q_nums(first: Integral, second: Integral) -> Integral:
"""Return the 2-qubit Clifford integer that is the tensor product of 1-qubit Cliffords."""
return _CLIFFORD_TENSOR_1Q[first, second]
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _hash_cliff(cliff):


def gen_clifford_inverse_1q():
"""Generate table data for integer 1Q Clifford inversion"""
"""Generate data for integer 1Q Clifford inversion table"""
invs = np.empty(NUM_CLIFFORD_1Q, dtype=int)
for i, cliff_i in _CLIFF_1Q.items():
invs[i] = _TO_INT_1Q[_hash_cliff(cliff_i.adjoint())]
Expand All @@ -68,7 +68,7 @@ def gen_clifford_inverse_1q():


def gen_clifford_compose_1q():
"""Generate table data for integer 1Q Clifford composition."""
"""Generate data for integer 1Q Clifford composition table"""
products = np.empty((NUM_CLIFFORD_1Q, NUM_CLIFFORD_1Q), dtype=int)
for i, cliff_i in _CLIFF_1Q.items():
for j, cliff_j in _CLIFF_1Q.items():
Expand All @@ -83,7 +83,7 @@ def gen_clifford_compose_1q():


def gen_clifford_inverse_2q():
"""Generate table data for integer 2Q Clifford inversion"""
"""Generate data for integer 2Q Clifford inversion table"""
invs = np.empty(NUM_CLIFFORD_2Q, dtype=int)
for i, cliff_i in _CLIFF_2Q.items():
invs[i] = _TO_INT_2Q[_hash_cliff(cliff_i.adjoint())]
Expand Down Expand Up @@ -191,6 +191,16 @@ def gen_cliff_single_2q_gate_map():
return table


def gen_clifford_tensor_1q():
"""Generate data for 2Q integer Clifford table of the tensor product of 1Q integer Cliffords."""
products = np.empty((NUM_CLIFFORD_1Q, NUM_CLIFFORD_1Q), dtype=int)
for i, cliff_i in _CLIFF_1Q.items():
for j, cliff_j in _CLIFF_1Q.items():
cliff = cliff_i.tensor(cliff_j)
products[i, j] = _TO_INT_2Q[_hash_cliff(cliff)]
return products


if __name__ == "__main__":
if _CLIFF_SINGLE_GATE_MAP_1Q != gen_cliff_single_1q_gate_map():
raise Exception(
Expand All @@ -212,3 +222,5 @@ def gen_cliff_single_2q_gate_map():
table=_CLIFFORD_COMPOSE_2Q_DENSE,
valid_sparse_indices=valid_sparse_indices,
)

np.savez_compressed("clifford_tensor_1q.npz", table=gen_clifford_tensor_1q())
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
inverse_1q,
inverse_2q,
num_from_2q_circuit,
_product_1q_nums,
_tensor_1q_nums,
_clifford_1q_int_to_instruction,
_clifford_2q_int_to_instruction,
_decompose_clifford_ops,
Expand Down Expand Up @@ -403,8 +403,11 @@ def __circuit_body(
for j, qpair in enumerate(two_qubit_layer):
# sample product of two 1q-Cliffords as 2q interger Clifford
samples = rng.integers(NUM_1Q_CLIFFORD, size=2)
cliffs_2q[j] = compose_2q(cliffs_2q[j], _product_1q_nums(*samples))
for sample, q in zip(samples, qpair):
cliffs_2q[j] = compose_2q(cliffs_2q[j], _tensor_1q_nums(*samples))
# For Clifford 1 (x) Clifford 2, in its circuit representation,
# Clifford 1 acts on the 2nd qubit and Clifford 2 acts on the 1st qubit.
# That's why the qpair is reversed here.
for sample, q in zip(samples, reversed(qpair)):
circ._append(_to_gate_1q(sample), (circ.qubits[q],), ())
for k, q in enumerate(one_qubits):
sample = rng.integers(NUM_1Q_CLIFFORD)
Expand Down

0 comments on commit 0c3bd30

Please sign in to comment.