Skip to content

Commit 132284f

Browse files
author
wanhsuan
committed
init
0 parents  commit 132284f

File tree

524 files changed

+315261
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

524 files changed

+315261
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build/*
2+
include/*
3+
lib/*

CMakeLists.txt

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
cmake_minimum_required(VERSION 3.1)
2+
project(OLSQ
3+
VERSION 0.1.0
4+
LANGUAGES CXX)
5+
6+
set(CMAKE_CXX_STANDARD 17)
7+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8+
set(CMAKE_CXX_EXTENSIONS OFF)
9+
10+
11+
set(CMAKE_CXX_FLAGS "-O3")
12+
set(CMAKE_BUILD_TYPE release)
13+
# set(CMAKE_BUILD_TYPE Debug)
14+
15+
############################################################
16+
# Bitwuzla
17+
############################################################
18+
19+
find_library(BITWUZLA_LIBRARY bitwuzla REQUIRED)
20+
find_library(BITWUZLABV_LIBRARY bitwuzlabv REQUIRED)
21+
find_library(BITWUZLABB_LIBRARY bitwuzlabb REQUIRED)
22+
find_library(BITWUZLALS_LIBRARY bitwuzlals REQUIRED)
23+
get_filename_component(BITWUZLA_ROOT ${BITWUZLA_LIBRARY} DIRECTORY)
24+
get_filename_component(BITWUZLA_ROOT ${BITWUZLA_ROOT} DIRECTORY)
25+
get_filename_component(BITWUZLA_ROOT ${BITWUZLA_ROOT} DIRECTORY)
26+
set(BITWUZLA_INCLUDE_DIR "${BITWUZLA_ROOT}/include")
27+
28+
############################################################
29+
# gmp
30+
############################################################
31+
find_library(GMP_LIBRARY gmp REQUIRED)
32+
get_filename_component(GMP_ROOT ${GMP_LIBRARY} DIRECTORY)
33+
set(GMP_INCLUDE_DIR "${GMP_ROOT}/include")
34+
# message(STATUS "Find gmp: ${GMP_ROOT}")
35+
36+
############################################################
37+
# OLSQ library target
38+
############################################################
39+
40+
41+
add_library(olsq
42+
src/cir/circuit.cpp
43+
src/device/device.cpp
44+
src/misc/timeUsage.cpp
45+
src/clusterer/clusterer2.cpp
46+
src/clusterer/clusterer3.cpp
47+
src/placer/initialMapper.cpp
48+
src/molsq/molsq.cpp
49+
src/olsq2/olsq2.cpp
50+
src/stbolsq2/stbolsq2.cpp
51+
src/api/apiPy.cpp
52+
src/placer/placer.cpp
53+
src/placer/placer_dev.cpp
54+
src/router/aRouter.cpp
55+
src/router/aRouter_dev.cpp
56+
src/writer/writer.cpp
57+
src/rolsq2/rolsq2.cpp
58+
)
59+
60+
set(SRC
61+
src/cir/circuit.cpp
62+
src/device/device.cpp
63+
src/misc/timeUsage.cpp
64+
src/clusterer/clusterer2.cpp
65+
src/clusterer/clusterer3.cpp
66+
src/placer/initialMapper.cpp
67+
src/molsq/molsq.cpp
68+
src/olsq2/olsq2.cpp
69+
src/stbolsq2/stbolsq2.cpp
70+
src/api/apiPy.cpp
71+
src/placer/placer.cpp
72+
src/placer/placer_dev.cpp
73+
src/router/aRouter.cpp
74+
src/router/aRouter_dev.cpp
75+
src/writer/writer.cpp
76+
src/rolsq2/rolsq2.cpp
77+
)
78+
79+
set(API
80+
src/api/apiPy.cpp
81+
)
82+
83+
target_include_directories(olsq PUBLIC src include
84+
"$<BUILD_INTERFACE:${BITWUZLA_INCLUDE_DIR}>"
85+
"$<BUILD_INTERFACE:${GMP_INCLUDE_DIR}>"
86+
)
87+
88+
set_property(SOURCE src/router/aRouter_dev.cpp
89+
PROPERTY COMPILE_FLAGS "-Wall -Werror -Wpedantic -Wno-error=unused-variable -Wno-error=format"
90+
)
91+
92+
find_package(PythonInterp REQUIRED)
93+
find_package(PythonLibs REQUIRED)
94+
include_directories(${PYTHON_INCLUDE_DIRS})
95+
96+
97+
############################################################
98+
# Install Boost
99+
############################################################
100+
SET(BASEPATH ${PROJECT_SOURCE_DIR})
101+
#SET(BASEPATH .)
102+
SET(SRCPATH ${BASEPATH}/src)
103+
SET(BINPATH ${BASEPATH}/bin)
104+
SET(INCPATH ${BASEPATH}/include)
105+
SET(LIBPATH ${BASEPATH}/lib)
106+
107+
IF (NOT EXISTS "${INCPATH}")
108+
FILE(MAKE_DIRECTORY ${INCPATH})
109+
ENDIF()
110+
111+
find_package(Boost)
112+
IF (NOT EXISTS "${LIBPATH}")
113+
FILE(MAKE_DIRECTORY ${LIBPATH})
114+
ENDIF()
115+
116+
INCLUDE_DIRECTORIES(${SRCPATH} ${INCPATH})
117+
118+
# Install Boost
119+
SET(BOOST_VERSION 1_82_0)
120+
FIND_PACKAGE(Boost 1.82)
121+
IF(Boost_FOUND)
122+
SET(Boost_USE_STATIC_LIBS ON)
123+
SET(Boost_INCLUDE_DIR ${INCPATH}/boost_${BOOST_VERSION})
124+
SET(Boost_LIBRARY_DIR_RELEASE ${INCPATH}/boost_${BOOST_VERSION})
125+
SET(Boost_USE_STATIC_LIBS ON)
126+
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
127+
ELSE()
128+
IF (NOT EXISTS "${INCPATH}/boost_${BOOST_VERSION}")
129+
execute_process (COMMAND bash -c "wget https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz -P ${INCPATH}")
130+
#execute_process (COMMAND bash -c "wget https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.gz -P ${INCPATH}")
131+
execute_process (COMMAND bash -c "tar zxvf ${INCPATH}/boost_${BOOST_VERSION}.tar.gz -C ${INCPATH}")
132+
execute_process (COMMAND bash -c "rm ${INCPATH}/boost_${BOOST_VERSION}.tar.gz")
133+
ENDIF()
134+
135+
SET(BOOST_ROOT ${INCPATH}/boost_${BOOST_VERSION})
136+
SET(Boost_INCLUDE_DIR ${INCPATH}/boost_${BOOST_VERSION})
137+
SET(Boost_LIBRARY_DIR_RELEASE ${INCPATH}/boost_${BOOST_VERSION})
138+
SET(Boost_USE_STATIC_LIBS ON)
139+
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
140+
ENDIF()
141+
142+
############################################################
143+
# library
144+
############################################################
145+
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
146+
# LIB
147+
file(GLOB LIB ${LIBPATH}/*.a)
148+
149+
150+
set(PYBIND11_ROOT_DIR "include/pybind11")
151+
message(STATUS "Find Pybind11: ${PYBIND11_ROOT_DIR}")
152+
153+
include_directories("${PYBIND11_ROOT_DIR}/include")
154+
add_subdirectory("include/pybind11")
155+
set(PYBIND11_CPP_STANDARD -std=c++14)
156+
157+
#find_package(Bitwuzla REQUIRED)
158+
include_directories(include/pblib/include/pblib)
159+
160+
161+
target_link_libraries(olsq PUBLIC ${PROJECT_SOURCE_DIR}/include/pblib/lib/libpb.a ${GMP_LIBRARY} ${BITWUZLA_LIBRARY} ${BITWUZLABB_LIBRARY} ${BITWUZLABV_LIBRARY} ${BITWUZLALS_LIBRARY} ${CMAKE_DL_LIBS})
162+
163+
add_executable(main app/main.cpp)
164+
target_link_libraries(main olsq ${CMAKE_DL_LIBS})
165+
166+
167+
168+
pybind11_add_module(olsqPy ${SRC} ${API})
169+
target_include_directories(olsqPy PUBLIC
170+
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>"
171+
"$<BUILD_INTERFACE:${BITWUZLA_INCLUDE_DIR}>"
172+
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
173+
target_link_libraries(olsqPy PUBLIC ${PROJECT_SOURCE_DIR}/include/pblib/lib/libpb.a ${GMP_LIBRARY} ${BITWUZLA_LIBRARY} ${BITWUZLABB_LIBRARY} ${BITWUZLABV_LIBRARY} ${BITWUZLALS_LIBRARY} ${CMAKE_DL_LIBS})
174+
175+
# find_package(Python3 REQUIRED COMPONENTS Development)
176+
# find_package(PythonLibs 3)
177+

LICENSE

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2022, UCLA VAST Lab
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# mOLSQ: Multilevel Quantum Layout Synthesis
2+
3+
## Build and Installation Instructions
4+
5+
```
6+
# Clone mOLSQ repository
7+
git clone [email protected]:WanHsuanLin/mOLSQ.git
8+
cd mOLSQ
9+
10+
# Build
11+
cmake . -Bbuild
12+
cd build
13+
make
14+
```
15+
16+
- Required Dependencies:
17+
- GMP: Please install GMP. You may need to compile it with `-fPIC` depending on your system.
18+
- Bitwuzla (https://github.com/bitwuzla/bitwuzla/tree/4eda0536800576cb2531ab9ce13292da8f21f0eb): Please install Bitwuzla.
19+
- pblib (https://github.com/master-keying/pblib): Please intall pblib in the `include/`. You may need to compile it with `-fPIC` depending on your system.
20+
21+
## Create a device from the Input Coupling Graph
22+
23+
To perform QLS, we need to know the connections between the qubits, which is information about the physical device.
24+
We are going to use the `createDevice` function.
25+
26+
```
27+
from olsqPy import Device
28+
from src.pyolsq.apiPy import createDevice
29+
device = createDevice(name="dev", nqubits=5, connection=[(0, 1), (1, 2), (1, 3), (3, 4)])
30+
device.printDevice()
31+
```
32+
33+
We use a minimalist class `qcdevice` to store the properties of the device that we need, which can be constructed with these arguments.
34+
(The last three are only for fidelity optimization.)
35+
- `name`
36+
- `nqubits`: the number of physical qubits
37+
- `connection`: a list of physical qubit pairs corresponding to edges in the coupling graph
38+
- `swap_duration`: number of cycles a SWAP gate takes.
39+
Usually it is either one, or three meaning three CX gates.
40+
- `fmeas`: a list of measurement fidelity
41+
- `fsingle`: a list of single-qubit gate fidelity
42+
- `ftwo`: a list of two-qubit gate fidelity, indices aligned with `connection`
43+
44+
If `name` starts with `"default_"`, a hard-coded device stored in `olsq/devices/` would be loaded.
45+
Other arguments can still be specified, in which case the original device properties would be replaced by the input.
46+
```
47+
# use a hard-coded device in olsq/devices/ called ourense
48+
# which actually has the same properties as the device we constructed above
49+
lsqc_solver.setdevice( qcdevice("default_ourense") )
50+
```
51+
52+
## Create a Circuit from the Input Program
53+
54+
Apart from the device, we need the quantum program/circuit to execute, which can be constructed with the `createCircuit` function.
55+
56+
mOLSQ has an intermediate representation (IR) of quantum programs. (For details, refer to [a later part](#olsq-ir) of this tutorial.)
57+
In general, there are four ways to set the program:
58+
1. Use OLSQ IR
59+
2. Use a string in QASM format
60+
```
61+
from olsqPy import Circuit
62+
from src.pyolsq.apiPy import createCircuit
63+
circuit_name = "toffoli"
64+
circuit_str = "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[3];\nh q[2];\n" \
65+
"cx q[1], q[2];\ntdg q[2];\ncx q[0], q[2];\nt q[2];\n" \
66+
"cx q[1], q[2];\ntdg q[2];\ncx q[0], q[2];\nt q[1];\nt q[2];\n" \
67+
"cx q[0], q[1];\nh q[2];\nt q[0];\ntdg q[1];\ncx q[0], q[1];\n"
68+
69+
# input the quantum program as a QASM string
70+
lsqc_solver.setprogram(circuit_str)
71+
circuit = createCircuit(circuit_name, circuit_str, is_qasm = true)
72+
circuit.printCircuit()
73+
```
74+
75+
76+
## Initialization and solve
77+
78+
```
79+
from olsqPy import Device, Circuit, mOLSQ
80+
81+
# initialize your circuit
82+
# initialize your device
83+
84+
lsqc_solver = mOLSQ(circuit, device)
85+
lsqc_solver.enableAllCommute() # for circuits whose gates are all commutable
86+
# lsqc_solver.disAllCommute() # for circuits whose gates are not commutable (default)
87+
88+
lsqc_solver.run()
89+
```
90+
91+
There are two argument in the constructor of mOLSQ: `Circuit` and `Device`.
92+
The former one stands for the input circuit, and the later one stands for the input device.
93+
Idealy, the `run` method will return three solutions, `${circuit_name}_stage_0.qasm`, `${circuit_name}_stage_1.qasm`, and `${circuit_name}_stage_2.qasm`, from FastQLS (hueristic QLS algorithm), the first multilevel V cycle, and the second multilevel V cycle, respectively.
94+
95+
## OLSQ IR
96+
97+
OLSQ IR contains three things:
98+
1. `count_program_qubit`: the number of qubits in the program.
99+
2. `gates`: a list of tuples representing qubit(s) acted on by a gate, each tuple has one index if it is a single-qubit gate, two indices if it is a two-qubit gate.
100+
3. `gate_spec`: list of type/name of each gate, which is not important to OLSQ, and only needed when generating output.
101+
102+
```
103+
# For the following circuit
104+
# q_0: ───────────────────■───
105+
# │
106+
# q_1: ───────■───────────┼───
107+
# ┌───┐┌─┴─┐┌─────┐┌─┴─┐
108+
# q_2: ┤ H ├┤ X ├┤ TDG ├┤ X ├─
109+
# └───┘└───┘└─────┘└───┘
110+
111+
# count_program_qubit = 3
112+
# gates = ((2,), (1,2), (2,), (0,1))
113+
# gate_spec = ("h", "cx", "tdg", "cx")
114+
```
115+
116+
## Example: run_mlqls.py
117+
118+
run_mlqls.py is an example program to use mOLSQ2 to perform layout synthesis. The output will be stored in under `result/`
119+
```
120+
# compile an qaoa circuit on a 5-by-5 grid quantum device
121+
python3 run_mlqls.py --dt grid --d 4 -qf benchmark/qaoa/qaoa_16_0.qasm
122+
# The output files (Final IR output file and the intermediate qasm file) of running the command are in example/.
123+
124+
# compile an qaoa circuit on sycamore quantum device
125+
python3 run_mlqls.py --dt sycamore --qf benchmark/qaoa/qaoa_16_0.qasm
126+
```
127+
- `--dt $(str)`: Type of the quantum device: ourense, sycamore, rochester, tokyo, aspen-4, eagle, or grid. When using a grid architecure, add `--d $(int)` to specify the grid length.
128+
- `--d $(int)`: Grid length of the grid architecture
129+
- `--qf $(str)`: Input QASM file name

app/main.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <cstdio>
2+
#include "cir/circuit.hpp"
3+
#include "device/device.hpp"
4+
#include "molsq/molsq.hpp"
5+
#include "misc/global.hpp"
6+
7+
using namespace MOLSQ_NAMESPACE;
8+
9+
int main(int argc, char *argv[]) {
10+
printf("hello world!\n");
11+
Circuit cir("test", 4, 4);
12+
vector<unsigned_t> vTargetQubit(2,0);
13+
vTargetQubit[0] = 0;
14+
vTargetQubit[1] = 1;
15+
cir.addGate("cx", vTargetQubit);
16+
vTargetQubit[0] = 0;
17+
vTargetQubit[1] = 2;
18+
cir.addGate("cx", vTargetQubit);
19+
vTargetQubit[0] = 0;
20+
vTargetQubit[1] = 3;
21+
cir.addGate("cx", vTargetQubit);
22+
vTargetQubit[0] = 1;
23+
vTargetQubit[1] = 2;
24+
cir.addGate("cx", vTargetQubit);
25+
cir.printCircuit();
26+
vector<pair<unsigned_t, unsigned_t> > vEdge;
27+
vEdge.emplace_back(make_pair(0,1));
28+
vEdge.emplace_back(make_pair(1,2));
29+
vEdge.emplace_back(make_pair(2,3));
30+
vEdge.emplace_back(make_pair(0,3));
31+
Device device("test", 4, 4);
32+
device.setEdge(vEdge);
33+
device.printDevice();
34+
mOLSQ olsq(cir, device, 100, 100);
35+
olsq.run();
36+
return 0;
37+
}

0 commit comments

Comments
 (0)