Skip to content

idnm/cpflow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CPFlow

CPFlow uses variational synthesis to find quantum circuits consisting of CNOTs+arbitrary 1q gates that simultaneously

  • Minimize a given loss function L(U), where U is the unitary of the circuit.
  • Do it with as few CNOT gates as possible.

Indirectly the circuits can also be optimized for CNOT depth and even T count or T depth in some cases. Typical loss functions L(U) correspond to a compilation and a state preparation problem, but arbitrary well-defined loss functions can be handled as well. The cornerstone objective is to obtain the shortest circuits possible, potentially at the cost of a longer search time.

CPFlow implements the synthesis algorithms described in https://arxiv.org/abs/2205.01121. Notebook organizing various plots and circuits presented in the paper resides here. A Mathematica notebook verifying exactness of the decompositions presented in the paper can be viewed here.

Installation

CPFlow is available via pip. It is highly recommended to install the package in a new virtual environment.

pip install cpflow

A feature that allows to decompose sythesized circuits into Clifford+T basis requires yet experimental qiskit branch that can be installed through

pip install git+https://github.com/LNoorl/qiskit-terra@d2e0dc1185ccc3b0c9957e3d7d9bc610dede29d4

Basic example

Decomposing the CCZ gate with linear qubit connectivity 0-1-2. Can be executed in python console but intended for use with Jupyter notebooks.

import numpy as np
from cpflow import *

u_target = np.diag([1, 1, 1, 1, 1, 1, 1, -1])  # CCZ gate
layer = [[0, 1], [1, 2]]  # Linear connectivity
decomposer = Synthesize(layer, target_unitary=u_target, label='ccz_chain')
options = StaticOptions(num_cp_gates=12, accepted_num_cz_gates=10, num_samples=10)

results = decomposer.static(options) # Should take from one to five minutes.

d = results.decompositions[3]  # This turned out to be the best decomposition for refinement.
d.refine()
print(d)
d.circuit.draw()

Output:

< ccz_chain| Clifford+T | loss: 0.0  | CZ count: 8 | CZ depth: 8  | T count: 7 | T depth: 5 >

image

More features

For further examples we encourage to explore a tutorial notebook interactively. For motivation and background see the original paper https://arxiv.org/abs/2205.01121.