Skip to content

Commit edefee1

Browse files
committed
Version 1.5 Release
* JKQ QCEC now provides full Python bindings and is available on [PyPI](https://pypi.org/project/jkq.qcec/) (#2) * Configuration options now also include optimization passes applied before equivalence checking * New optimization `removeDiagonalGatesBeforeMeasure` (#4) * removed `--extern` from git submodule update * Updated README.md Signed-off-by: Lukas Burgholzer <[email protected]>
1 parent e2d83e7 commit edefee1

15 files changed

+287
-142
lines changed

Diff for: .travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ jobs:
137137
- CIBW_MANYLINUX_X86_64_IMAGE="manylinux2014"
138138
- CIBW_MANYLINUX_AARCH64_IMAGE="manylinux2014"
139139
- CIBW_BUILD="cp3?-*"
140-
- CIBW_SKIP="*-win32 *-manylinux_i686"
140+
- CIBW_SKIP="*-win32 *-manylinux_i686 cp35-*"
141141
- CIBW_BUILD_VERBOSITY=1
142142
- CIBW_TEST_COMMAND="python -c \"from jkq import qcec\""
143143
- CC=gcc CXX=g++

Diff for: CMakeLists.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
cmake_minimum_required(VERSION 3.10...3.16)
1+
cmake_minimum_required(VERSION 3.10...3.19)
22
if(${CMAKE_VERSION} VERSION_LESS 3.12)
33
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
44
endif()
55

66
project(qcec
7-
VERSION 1.4.5
7+
VERSION 1.5.0
88
DESCRIPTION "A JKQ tool for quantum circuit equivalence checking (JKQ QCEC)"
99
LANGUAGES CXX)
1010

@@ -27,11 +27,11 @@ macro(handle_submodule MODULENAME)
2727
find_package(Git QUIET)
2828
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git" AND GIT_SUBMODULE)
2929
message(STATUS "${MODULENAME} update")
30-
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive --remote -- extern/${MODULENAME}
30+
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- extern/${MODULENAME}
3131
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
3232
RESULT_VARIABLE GIT_SUBMOD_RESULT)
3333
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
34-
message(FATAL_ERROR "git submodule update --init --recursive --remote -- extern/${MODULENAME} failed with ${GIT_SUBMOD_RESULT}.")
34+
message(FATAL_ERROR "git submodule update --init --recursive -- extern/${MODULENAME} failed with ${GIT_SUBMOD_RESULT}.")
3535
endif()
3636
endif()
3737

Diff for: README.md

+93-80
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
[![Build Status](https://travis-ci.com/iic-jku/qcec.svg?branch=master)](https://travis-ci.com/iic-jku/qcec)
2-
[![codecov](https://codecov.io/gh/iic-jku/qcec/branch/master/graph/badge.svg)](https://codecov.io/gh/iic-jku/qcec)
3-
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4-
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2004.08420&color=inactive)](https://arxiv.org/abs/2004.08420)
5-
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2009.02376&color=inactive)](https://arxiv.org/abs/2009.02376)
6-
[![toolset: JKQ](https://img.shields.io/badge/toolset-JKQ-blue)](https://github.com/iic-jku/jkq)
1+
[![PyPI](https://img.shields.io/pypi/v/jkq.qcec?logo=pypi&style=plastic)](https://pypi.org/project/jkq.qcec/)
2+
[![Travis (.com) branch](https://img.shields.io/travis/com/iic-jku/qcec/master?logo=travis&style=plastic)](https://travis-ci.com/iic-jku/qcec)
3+
[![Codecov branch](https://img.shields.io/codecov/c/github/iic-jku/qcec/master?label=codecov&logo=codecov&style=plastic)](https://codecov.io/gh/iic-jku/qcec)
4+
![GitHub](https://img.shields.io/github/license/iic-jku/qcec?style=plastic)
5+
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2004.08420&color=inactive&style=plastic)](https://arxiv.org/abs/2004.08420)
6+
[![arXiv](https://img.shields.io/static/v1?label=arXiv&message=2009.02376&color=inactive&style=plastic)](https://arxiv.org/abs/2009.02376)
7+
[![toolset: JKQ](https://img.shields.io/badge/toolset-JKQ-blue?style=plastic)](https://github.com/iic-jku/jkq)
78

89
# JKQ QCEC - A JKQ tool for **Q**uantum **C**ircuit **E**quivalence **C**hecking
910

@@ -34,59 +35,93 @@ If you have any questions, feel free to contact us via [[email protected]](mail
3435

3536
## Usage
3637

37-
This tool can either be used as a **standalone executable** with command-line interface, or as a **library** for the incorporation in other projects. [Python bindings](#python-bindings) are available since version 1.4.5.
38-
- The standalone executable is launched in the following way:
39-
```commandline
40-
qcec_app <PATH_TO_FILE_1> <PATH_TO_FILE_2> (--method <method>)
38+
JKQ QCEC is mainly developed as a C++ library with a [commandline interface](#command-line-executable). However, using it in Python is as easy as
39+
```bash
40+
pip install jkq.qcec
41+
```
42+
and then in Python
43+
```python
44+
from jkq import qcec
45+
qcec.verify(...)
46+
```
47+
where the `verify` function is defined as follows:
48+
```python
49+
"""
50+
Interface to the JKQ QCEC tool for verifying quantum circuits
51+
52+
Params:
53+
file1 – Path to first file (required)
54+
file2 – Path to second file (required)
55+
method – Equivalence checking method to use (reference | naive | *proportional* | lookahead | simulation | compilation flow)
56+
tolerance – Numerical tolerance used during computation
57+
nsims – Number of simulations to conduct (for simulation method)
58+
fidelity – Fidelity limit for comparison (for simulation method)
59+
csv – Create CSV string for result
60+
statistics – Print statistics
61+
swapGateFusion – Optimization pass reconstructing SWAP operations
62+
singleQubitGateFusion – Optimization pass fusing consecutive single qubit gates
63+
removeDiagonalGatesBeforeMeasure – Optimization pass removing diagonal gates before measurements
64+
Returns:
65+
JSON object containing results
66+
"""
67+
def verify(file1: Union[str, bytes, PathLike],
68+
file2: Union[str, bytes, PathLike],
69+
method: Method = Method.proportional,
70+
tolerance: float = 1e-13,
71+
nsims: int = 16,
72+
fidelity: float = 0.999,
73+
csv: bool = False,
74+
statistics: bool = False,
75+
swapGateFusion: bool = False,
76+
singleQubitGateFusion: bool = False,
77+
removeDiagonalGatesBeforeMeasure: bool = False) -> object
78+
```
79+
### Command-line Executable
80+
JKQ QCEC also provides a **standalone executable** with command-line interface called `qcec_app`.
81+
It provides the same options as the Python module as flags (e.g., `--ps` for printing statistics, or `--method <method>`for setting the method). Per default, this produces JSON formatted output.
82+
If the `--csv` flag is present, a CSV entry according to the following header is printed
83+
```csv
84+
filename1;nqubits1;ngates1;filename2;nqubits2;ngates2;expectedEquivalent;equivalent;method;time;maxActive;nsims
85+
```
86+
For a full list of options, call `qcec_app --help`.
87+
88+
### Library Organisation
89+
Internally the JKQ QCEC library works in the following way
90+
- Import both input files into a `qc::QuantumComputation` object
91+
```c++
92+
std::string file1 = "<PATH_TO_FILE_1>";
93+
qc::QuantumComputation qc1(file1);
94+
95+
std::string file2 = "<PATH_TO_FILE_2>";
96+
qc::QuantumComputation qc2(file2);
4197
```
42-
where *\<method\>* is one of
43-
- reference
44-
- naive
45-
- proportional (**default**)
46-
- lookahead
47-
- simulation
48-
- compilationflow
49-
50-
An optional parameter ```--tol e``` allows to specify the numerical tolerance *e* (default: *1e-13*) used during the computation.
51-
The ```simulation``` method has two optional parameters ```--nsims r``` and ```--fid F```, controlling the maximum number of simulations *r* (default: *16*) and the considered fidelity limit *F* (default *0.999*), respectively.
52-
53-
The executable performs the equivalence check and prints its result to the standard output. Per default, this produces JSON formatted output. Additional statistics (e.g., verification time, maximum number of nodes, required simulations, etc.) can be obtained by additionally providing the `--ps` flag.
54-
If the `--csv` flag is present, a CSV entry according to the following header is printed
55-
```csv
56-
filename1;nqubits1;ngates1;filename2;nqubits2;ngates2;expectedEquivalent;equivalent;method;time;maxActive;nsims
57-
```
58-
59-
- Internally the library works in the following way
60-
- Import both input files into a `qc::QuantumComputation` object
61-
```c++
62-
std::string file1 = "<PATH_TO_FILE_1>";
63-
qc::QuantumComputation qc1(file1);
64-
65-
std::string file2 = "<PATH_TO_FILE_2>";
66-
qc::QuantumComputation qc2(file2);
67-
```
68-
- Instantiate an `ec::EquivalenceChecker` object with both circuits
69-
```c++
70-
ec::Method method = ec::{ Reference | Naive | Proportional | Lookahead };
71-
auto eq = ec::ImprovedDDEquivalenceChecker(qc1, qc2, method);
72-
```
73-
or
74-
```c++
75-
auto eq = ec::PowerOfSimulationEquivalenceChecker(qc1, qc2);
76-
```
77-
or
78-
```c++
79-
auto eq = ec::CompilationFlowEquivalenceChecker(qc1, qc2);
80-
```
81-
- Perform the actual equivalence check
82-
```c++
83-
eq.check();
84-
```
85-
- Print the results
86-
```c++
87-
eq.printResult();
88-
```
89-
or access them through the ```eq.results``` member.
98+
- Instantiate an `ec::EquivalenceChecker` object with both circuits
99+
```c++
100+
ec::Method method = ec::{ Reference | Naive | Proportional | Lookahead };
101+
auto eq = ec::ImprovedDDEquivalenceChecker(qc1, qc2, method);
102+
```
103+
or
104+
```c++
105+
auto eq = ec::PowerOfSimulationEquivalenceChecker(qc1, qc2);
106+
```
107+
or
108+
```c++
109+
auto eq = ec::CompilationFlowEquivalenceChecker(qc1, qc2);
110+
```
111+
- Set configuration options, e.g.,
112+
```c++
113+
ec::Configuration config{};
114+
config.printStatistics = true;
115+
```
116+
- Perform the actual equivalence check
117+
```c++
118+
eq.check(config);
119+
```
120+
- Print the results
121+
```c++
122+
ec.printJSONResult(config.printStatistics);
123+
```
124+
or access them through the ```eq.results``` member.
90125

91126
### System requirements
92127

@@ -132,28 +167,6 @@ In order to build the library execute the following in the project's main direct
132167
target_link_libraries(${TARGET_NAME} PRIVATE JKQ::qcec)
133168
```
134169
135-
### Python Bindings
136-
137-
Running `pip install .` in the main project directory creates Python bindings for the JKQ QCEC tool. Then, using it in Python is as simple as:
138-
```python
139-
from jkq import qcec
140-
qcec.verify({"file1": "<PATH_TO_FILE_1>", "file2:": "<PATH_TO_FILE_2>"})
141-
```
142-
The full list of parameters as described in [Usage](#usage) which can be passed to `qcec.verify(...)` as a Python dictionary, are:
143-
```python
144-
instance = {
145-
"file1": "<PATH_TO_FILE_1>", # required
146-
"file2": "<PATH_TO_FILE_2>", # required
147-
"method": "proportional",
148-
"tolerance": 1e-13,
149-
"nsims": 16,
150-
"fidelity": 0.999,
151-
"statistics": False,
152-
"csv": False,
153-
}
154-
```
155-
156-
157170
## Reference
158171
159172
If you use our tool for your research, we will be thankful if you refer to it by citing the appropriate publication:

Diff for: apps/app.cpp

+30-19
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,30 @@
1414
#include "PowerOfSimulationEquivalenceChecker.hpp"
1515

1616
void show_usage(const std::string& name) {
17-
std::cerr << "Usage: " << name << " <PATH_TO_FILE_1> <PATH_TO_FILE_2> (--method <method>) " << std::endl;
18-
std::cerr << "Supported file formats: " << std::endl;
19-
std::cerr << " .real " << std::endl;
20-
std::cerr << " .qasm " << std::endl;
21-
std::cerr << " .tfc " << std::endl;
22-
std::cerr << " .qc " << std::endl;
23-
std::cerr << "Available methods: " << std::endl;
24-
std::cerr << " reference " << std::endl;
25-
std::cerr << " naive " << std::endl;
26-
std::cerr << " proportional (default) " << std::endl;
27-
std::cerr << " lookahead " << std::endl;
28-
std::cerr << " simulation " << std::endl;
29-
std::cerr << " compilationflow " << std::endl;
30-
std::cerr << "Options: " << std::endl;
31-
std::cerr << " --ps: Print statistics " << std::endl;
32-
std::cerr << " --csv: Print results as csv string " << std::endl;
33-
std::cerr << " --tol e (default 1e-13): Numerical tolerance used during computation " << std::endl;
34-
std::cerr << " --nsims r (default 16): Number of simulations to conduct (for simulation method)" << std::endl;
35-
std::cerr << " --fid F (default 0.999): Fidelity limit for comparison (for simulation method) " << std::endl;
17+
std::cerr << "Usage: " << name << " <PATH_TO_FILE_1> <PATH_TO_FILE_2> (--method <method>) " << std::endl;
18+
std::cerr << "Supported file formats: " << std::endl;
19+
std::cerr << " .real " << std::endl;
20+
std::cerr << " .qasm " << std::endl;
21+
std::cerr << " .tfc " << std::endl;
22+
std::cerr << " .qc " << std::endl;
23+
std::cerr << "Available methods: " << std::endl;
24+
std::cerr << " reference " << std::endl;
25+
std::cerr << " naive " << std::endl;
26+
std::cerr << " proportional (default) " << std::endl;
27+
std::cerr << " lookahead " << std::endl;
28+
std::cerr << " simulation " << std::endl;
29+
std::cerr << " compilationflow " << std::endl;
30+
std::cerr << "Result Options: " << std::endl;
31+
std::cerr << " --ps: Print statistics " << std::endl;
32+
std::cerr << " --csv: Print results as csv string " << std::endl;
33+
std::cerr << "Verification Parameters: " << std::endl;
34+
std::cerr << " --tol e (default 1e-13): Numerical tolerance used during computation " << std::endl;
35+
std::cerr << " --nsims r (default 16): Number of simulations to conduct (for simulation method)" << std::endl;
36+
std::cerr << " --fid F (default 0.999): Fidelity limit for comparison (for simulation method) " << std::endl;
37+
std::cerr << "Optimization Options: " << std::endl;
38+
std::cerr << " --swapGateFusion: reconstruct SWAP operations " << std::endl;
39+
std::cerr << " --singleQubitGateFusion: fuse consecutive single qubit gates " << std::endl;
40+
std::cerr << " --removeDiagonalGatesBeforeMeasure: remove diagonal gates before measurements " << std::endl;
3641
}
3742

3843
int main(int argc, char** argv){
@@ -141,6 +146,12 @@ int main(int argc, char** argv){
141146
show_usage(argv[0]);
142147
return 1;
143148
}
149+
} else if (cmd == "--swapGateFusion") {
150+
config.swapGateFusion = true;
151+
} else if (cmd == "--singleQubitGateFusion") {
152+
config.singleQubitGateFusion = true;
153+
} else if (cmd == "--removeDiagonalGatesBeforeMeasure") {
154+
config.removeDiagonalGatesBeforeMeasure = true;
144155
} else {
145156
show_usage(argv[0]);
146157
return 1;

Diff for: extern/qfr

Submodule qfr updated from fb63868 to aa978ac

Diff for: include/CompilationFlowEquivalenceChecker.hpp

-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <utility>
1212

1313
#include "ImprovedDDEquivalenceChecker.hpp"
14-
#include "CircuitOptimizer.hpp"
1514

1615
namespace ec {
1716
using CostFunction = std::function<unsigned short(const qc::OpType&, unsigned short)>;
@@ -25,11 +24,6 @@ namespace ec {
2524
public:
2625
CompilationFlowEquivalenceChecker(qc::QuantumComputation& qc1, qc::QuantumComputation& qc2, CostFunction costFunction = IBMCostFunction): ImprovedDDEquivalenceChecker(qc1, qc2), costFunction(std::move(costFunction)) {
2726
method = results.method = CompilationFlow;
28-
qc::CircuitOptimizer::swapGateFusion(qc1);
29-
qc::CircuitOptimizer::singleGateFusion(qc1);
30-
31-
qc::CircuitOptimizer::swapGateFusion(qc2);
32-
qc::CircuitOptimizer::singleGateFusion(qc2);
3327
}
3428

3529
void check(const Configuration& config) override;

Diff for: include/EquivalenceChecker.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <chrono>
1212

1313
#include "QuantumComputation.hpp"
14+
#include "CircuitOptimizer.hpp"
1415
#include "EquivalenceCheckingResults.hpp"
1516

1617
#define DEBUG_MODE_EC 0
@@ -23,6 +24,11 @@ namespace ec {
2324
bool printStatistics = false;
2425
fp tolerance = CN::TOLERANCE;
2526

27+
// configuration options for optimizations
28+
bool singleQubitGateFusion = false;
29+
bool swapGateFusion = false;
30+
bool removeDiagonalGatesBeforeMeasure = false;
31+
2632
// configuration options for PowerOfSimulation equivalence checker
2733
double fidelity_limit = 0.999;
2834
unsigned long long max_sims = 16;

Diff for: jkq/qcec/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ add_library(pybind11 ALIAS pybind11::pybind11)
33

44
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/pybind11_json" "extern/pybind11_json")
55

6-
pybind11_add_module(py${PROJECT_NAME} bindings.cpp EXCLUDE_FROM_ALL)
6+
pybind11_add_module(py${PROJECT_NAME} bindings.cpp)
77
target_link_libraries(py${PROJECT_NAME} PUBLIC pybind11_json ${PROJECT_NAME})

0 commit comments

Comments
 (0)