├── code ├── .gitignore ├── couplings │ ├── 2x2.txt │ ├── 2x3.txt │ ├── qx2.txt │ ├── 2x4.txt │ ├── melbourne.txt │ ├── aspen4.txt │ ├── 4x4.txt │ └── tokyo.txt ├── circuits │ ├── small │ │ ├── qft_4.qasm │ │ ├── 4gt11_84.qasm │ │ ├── ex-1_166.qasm │ │ ├── 4mod5-v0_20.qasm │ │ ├── ham3_102.qasm │ │ ├── 4mod5-v1_22.qasm │ │ ├── mod5d1_63.qasm │ │ ├── 4gt11_82.qasm │ │ ├── rd32-v0_66.qasm │ │ ├── 4mod5-v0_19.qasm │ │ ├── mod5mils_65.qasm │ │ ├── 3_17_13.qasm │ │ ├── 4mod5-v1_24.qasm │ │ ├── rd32-v1_68.qasm │ │ ├── alu-v0_27.qasm │ │ ├── alu-v1_29.qasm │ │ ├── alu-v2_33.qasm │ │ ├── alu-v1_28.qasm │ │ ├── alu-v3_35.qasm │ │ ├── alu-v4_37.qasm │ │ ├── miller_11.qasm │ │ ├── alu-v3_34.qasm │ │ └── 4gt13_92.qasm │ ├── OLSQ │ │ ├── or.qasm │ │ ├── 4mod5-v1_22.qasm │ │ ├── adder.qasm │ │ ├── qaoa5.qasm │ │ ├── mod5mils_65.qasm │ │ ├── 16QBT_05CYC_TFL_0.qasm │ │ ├── tof_4_after_heavy.qasm │ │ ├── 4gt13_92.qasm │ │ ├── barenco_tof_4_after_heavy.qasm │ │ ├── 16QBT_10CYC_TFL_3.qasm │ │ ├── tof_5_after_heavy.qasm │ │ ├── mod_mult_55_after_heavy.qasm │ │ ├── vbe_adder_3_after_heavy.qasm │ │ ├── barenco_tof_5_after_heavy.qasm │ │ ├── 16QBT_15CYC_TFL_1.qasm │ │ └── rc_adder_6_after_heavy.qasm │ └── large │ │ └── qft_10.qasm ├── src │ ├── Latency │ │ ├── Meta.hpp │ │ ├── Latency_1.hpp │ │ ├── Latency_1_3.hpp │ │ ├── Latency_1_2_6.hpp │ │ └── Meta.cpp │ ├── Queue │ │ ├── Meta.hpp │ │ ├── Meta.cpp │ │ ├── DefaultQueue.hpp │ │ └── TrimSlowNodes.hpp │ ├── Filter │ │ ├── Meta.hpp │ │ ├── Meta.cpp │ │ └── HashFilter.hpp │ ├── NodeMod │ │ ├── Meta.hpp │ │ ├── Meta.cpp │ │ └── GreedyMapper.hpp │ ├── Expander │ │ ├── Meta.hpp │ │ ├── Meta.cpp │ │ └── NoSwaps.hpp │ ├── CostFunc │ │ ├── Meta.hpp │ │ ├── Meta.cpp │ │ ├── SimpleCost.hpp │ │ └── CXFrontier.hpp │ ├── full_classes │ │ ├── ScheduledGate.hpp │ │ ├── GateNode.hpp │ │ ├── LinkedStack.hpp │ │ ├── QASMtoken.hpp │ │ ├── Environment.hpp │ │ ├── QASMscanner.hpp │ │ ├── QASMtoken.cpp │ │ ├── Node.hpp │ │ ├── QASMparser.h │ │ ├── Node.cpp │ │ └── QASMscanner.cpp │ ├── Latency.hpp │ ├── NodeMod.hpp │ ├── Expander.hpp │ ├── CostFunc.hpp │ ├── Filter.hpp │ └── Queue.hpp ├── qelib1.inc ├── Makefile └── README.txt ├── data ├── coupling_maps │ ├── 2x3.txt │ ├── 2x4.txt │ ├── qx2.txt │ ├── README.txt │ └── aspen4.txt ├── min-depth │ ├── README.txt │ ├── or_qx2.qasm │ ├── 4mod5-v1_22_qx2.qasm │ ├── 4mod5-v1_22_2x3.qasm │ ├── 4mod5-v1_22_2x4.qasm │ ├── qaoa5_qx2.qasm │ ├── adder_2x3.qasm │ ├── adder_2x4.qasm │ ├── adder_qx2.qasm │ ├── mod5mils_65_qx2.qasm │ ├── 16QBT_05CYC_TFL_0_aspen4.qasm │ ├── 4gt13_92_qx2.qasm │ └── 16QBT_10CYC_TFL_3_aspen4.qasm ├── min-gates │ ├── README.txt │ ├── or_qx2.qasm │ ├── 4mod5-v1_22_qx2.qasm │ ├── 4mod5-v1_22_2x3.qasm │ ├── 4mod5-v1_22_2x4.qasm │ ├── qaoa5_qx2.qasm │ ├── adder_2x3.qasm │ ├── adder_2x4.qasm │ ├── adder_qx2.qasm │ ├── mod5mils_65_qx2.qasm │ ├── 16QBT_05CYC_TFL_0_aspen4.qasm │ ├── 4gt13_92_qx2.qasm │ ├── 16QBT_10CYC_TFL_3_aspen4.qasm │ └── 16QBT_15CYC_TFL_1_aspen4.qasm └── README.txt └── README.md /code/.gitignore: -------------------------------------------------------------------------------- 1 | mapper 2 | objs/*.o 3 | -------------------------------------------------------------------------------- /code/couplings/2x2.txt: -------------------------------------------------------------------------------- 1 | 4 4 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 7 | 0-2 8 | | | 9 | 1-3 10 | -------------------------------------------------------------------------------- /code/couplings/2x3.txt: -------------------------------------------------------------------------------- 1 | 6 7 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 2 4 7 | 3 5 8 | 4 5 9 | 10 | 0-2-4 11 | | | | 12 | 1-3-5 13 | -------------------------------------------------------------------------------- /data/coupling_maps/2x3.txt: -------------------------------------------------------------------------------- 1 | 6 7 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 2 4 7 | 3 5 8 | 4 5 9 | 10 | 0-2-4 11 | | | | 12 | 1-3-5 13 | -------------------------------------------------------------------------------- /code/couplings/qx2.txt: -------------------------------------------------------------------------------- 1 | 5 6 2 | 0 1 3 | 0 2 4 | 1 2 5 | 2 3 6 | 2 4 7 | 3 4 8 | 9 | 4 0 10 | |\ /| 11 | | 2 | 12 | |/ \| 13 | 3 1 14 | -------------------------------------------------------------------------------- /code/couplings/2x4.txt: -------------------------------------------------------------------------------- 1 | 8 10 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 2 4 7 | 3 5 8 | 4 5 9 | 4 6 10 | 5 7 11 | 6 7 12 | 13 | 0-2-4-6 14 | | | | | 15 | 1-3-5-7 16 | -------------------------------------------------------------------------------- /data/coupling_maps/2x4.txt: -------------------------------------------------------------------------------- 1 | 8 10 2 | 0 1 3 | 0 2 4 | 1 3 5 | 2 3 6 | 2 4 7 | 3 5 8 | 4 5 9 | 4 6 10 | 5 7 11 | 6 7 12 | 13 | 0-2-4-6 14 | | | | | 15 | 1-3-5-7 16 | -------------------------------------------------------------------------------- /data/coupling_maps/qx2.txt: -------------------------------------------------------------------------------- 1 | 5 6 2 | 0 1 3 | 0 2 4 | 1 2 5 | 2 3 6 | 2 4 7 | 3 4 8 | 9 | 4 0 10 | |\ /| 11 | | 2 | 12 | |/ \| 13 | 3 1 14 | 15 | This coupling map is based on IBM QX2 architecture. -------------------------------------------------------------------------------- /data/min-depth/README.txt: -------------------------------------------------------------------------------- 1 | This directory has our depth-optimal mappings for the specified circuits. 2 | Comments show the cycle on which each gate is scheduled. 3 | Comments also show the original (logical) gates. 4 | -------------------------------------------------------------------------------- /data/min-gates/README.txt: -------------------------------------------------------------------------------- 1 | This directory has our gate-optimal mappings for the specified circuits. 2 | Comments show the cycle on which each gate is scheduled. 3 | Comments also show the original (logical) gates. 4 | -------------------------------------------------------------------------------- /code/circuits/small/qft_4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[4]; 4 | creg c[4]; 5 | cx q[0],q[1]; 6 | cx q[0],q[2]; 7 | cx q[0],q[3]; 8 | cx q[1],q[2]; 9 | cx q[1],q[3]; 10 | cx q[2],q[3]; 11 | -------------------------------------------------------------------------------- /code/src/Latency/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_LATENCY_HPP 2 | #define META_LATENCY_HPP 3 | 4 | #include 5 | #include "Latency.hpp" 6 | using namespace std; 7 | 8 | extern const int NUMLATENCIES; 9 | extern tuple latencies[]; 10 | 11 | #endif -------------------------------------------------------------------------------- /code/src/Queue/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_QUEUES_HPP 2 | #define META_QUEUES_HPP 3 | 4 | #include "Queue.hpp" 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | extern const int NUMQUEUES; 10 | extern tuple queues[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /code/src/Filter/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_FILTERS_HPP 2 | #define META_FILTERS_HPP 3 | 4 | #include "Filter.hpp" 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | extern const int NUMFILTERS; 10 | extern tuple FILTERS[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /code/src/NodeMod/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_NODEMOD_HPP 2 | #define META_NODEMOD_HPP 3 | 4 | #include "NodeMod.hpp" 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | extern const int NUMNODEMODS; 10 | extern tuple nodeMods[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /code/src/Expander/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_EXPANDERS_HPP 2 | #define META_EXPANDERS_HPP 3 | 4 | #include "Expander.hpp" 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | extern const int NUMEXPANDERS; 10 | extern tuple expanders[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /code/src/CostFunc/Meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef META_COSTFUNC_HPP 2 | #define META_COSTFUNC_HPP 3 | 4 | #include "CostFunc.hpp" 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | extern const int NUMCOSTFUNCTIONS; 10 | extern tuple costFunctions[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /code/src/Latency/Latency_1.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LATENCY_1_HPP 2 | #define LATENCY_1_HPP 3 | 4 | #include "Latency.hpp" 5 | 6 | //Latency example: 1 cycle for EVERY gate 7 | class Latency_1 : public Latency { 8 | public: 9 | int getLatency(string gateName, int control) { 10 | return 1; 11 | } 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /code/couplings/melbourne.txt: -------------------------------------------------------------------------------- 1 | 15 20 2 | 0 1 3 | 0 14 4 | 1 2 5 | 1 13 6 | 2 3 7 | 2 12 8 | 3 4 9 | 3 11 10 | 4 5 11 | 4 10 12 | 5 6 13 | 5 9 14 | 6 8 15 | 7 8 16 | 8 9 17 | 9 10 18 | 10 11 19 | 11 12 20 | 12 13 21 | 13 14 22 | 23 | 0--1--2--3--4--5-6 24 | | | | | | | | 25 | 14-13-12-11-10-9-8-7 26 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/or.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[3]; 4 | x q[0]; 5 | tdg q[1]; 6 | h q[2]; 7 | cx q[2], q[1]; 8 | tdg q[0]; 9 | t q[1]; 10 | tdg q[2]; 11 | cx q[0], q[1]; 12 | sdg q[2]; 13 | cx q[2], q[0]; 14 | t q[1]; 15 | t q[0]; 16 | cx q[2], q[1]; 17 | tdg q[1]; 18 | cx q[2], q[0]; 19 | cx q[0], q[1]; 20 | h q[2]; 21 | -------------------------------------------------------------------------------- /data/coupling_maps/README.txt: -------------------------------------------------------------------------------- 1 | These coupling maps start with two integers, m and n. 2 | The value m is the number of physical qubits on the architecture. 3 | The value n is the number of (bidirectional) edges in the coupling map. 4 | The following n lines describe the edges. 5 | Finally, we include a typographical drawing of the architecture, for convenience. 6 | -------------------------------------------------------------------------------- /code/src/Latency/Latency_1_3.hpp: -------------------------------------------------------------------------------- 1 | #include "Latency.hpp" 2 | 3 | //Latency example: 3 cycles per SWP; 1 cycle otherwise 4 | class Latency_1_3 : public Latency { 5 | public: 6 | int getLatency(string gateName, int control) { 7 | if(!gateName.compare("swp") || !gateName.compare("SWP")) { 8 | return 3; 9 | } else { 10 | return 1; 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /code/circuits/small/4gt11_84.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | h q[0]; 6 | t q[2]; 7 | t q[1]; 8 | t q[0]; 9 | cx q[1],q[2]; 10 | cx q[0],q[1]; 11 | cx q[2],q[0]; 12 | tdg q[1]; 13 | cx q[2],q[1]; 14 | tdg q[2]; 15 | tdg q[1]; 16 | t q[0]; 17 | cx q[0],q[1]; 18 | cx q[2],q[0]; 19 | cx q[1],q[2]; 20 | h q[0]; 21 | cx q[4],q[0]; 22 | cx q[0],q[4]; 23 | -------------------------------------------------------------------------------- /code/circuits/small/ex-1_166.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[3]; 4 | creg c[3]; 5 | cx q[0],q[1]; 6 | h q[0]; 7 | t q[1]; 8 | t q[2]; 9 | t q[0]; 10 | cx q[2],q[1]; 11 | cx q[0],q[2]; 12 | cx q[1],q[0]; 13 | tdg q[2]; 14 | cx q[1],q[2]; 15 | tdg q[1]; 16 | tdg q[2]; 17 | t q[0]; 18 | cx q[0],q[2]; 19 | cx q[1],q[0]; 20 | cx q[2],q[1]; 21 | h q[0]; 22 | cx q[0],q[1]; 23 | x q[0]; 24 | -------------------------------------------------------------------------------- /code/couplings/aspen4.txt: -------------------------------------------------------------------------------- 1 | 16 18 2 | 0 1 3 | 0 7 4 | 1 2 5 | 1 14 6 | 2 3 7 | 2 13 8 | 3 4 9 | 4 5 10 | 5 6 11 | 6 7 12 | 8 9 13 | 8 15 14 | 9 10 15 | 10 11 16 | 11 12 17 | 12 13 18 | 13 14 19 | 14 15 20 | 21 | 4--3 12--11 22 | / \ / \ 23 | 5 2--13 10 24 | | | | | 25 | 6 1--14 9 26 | \ / \ / 27 | 7--0 15---8 -------------------------------------------------------------------------------- /code/circuits/small/4mod5-v0_20.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[1]; 6 | x q[0]; 7 | cx q[0],q[2]; 8 | cx q[2],q[1]; 9 | h q[4]; 10 | t q[2]; 11 | t q[1]; 12 | t q[4]; 13 | cx q[1],q[2]; 14 | cx q[4],q[1]; 15 | cx q[2],q[4]; 16 | tdg q[1]; 17 | cx q[2],q[1]; 18 | tdg q[2]; 19 | tdg q[1]; 20 | t q[4]; 21 | cx q[4],q[1]; 22 | cx q[2],q[4]; 23 | cx q[1],q[2]; 24 | h q[4]; 25 | -------------------------------------------------------------------------------- /code/circuits/small/ham3_102.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[3]; 4 | creg c[3]; 5 | h q[0]; 6 | t q[1]; 7 | t q[2]; 8 | t q[0]; 9 | cx q[2],q[1]; 10 | cx q[0],q[2]; 11 | cx q[1],q[0]; 12 | tdg q[2]; 13 | cx q[1],q[2]; 14 | tdg q[1]; 15 | tdg q[2]; 16 | t q[0]; 17 | cx q[0],q[2]; 18 | cx q[1],q[0]; 19 | cx q[2],q[1]; 20 | h q[0]; 21 | cx q[2],q[1]; 22 | cx q[1],q[2]; 23 | cx q[0],q[2]; 24 | cx q[2],q[1]; 25 | -------------------------------------------------------------------------------- /code/couplings/4x4.txt: -------------------------------------------------------------------------------- 1 | 16 24 2 | 0 1 3 | 0 4 4 | 1 2 5 | 1 5 6 | 2 3 7 | 2 6 8 | 3 7 9 | 4 5 10 | 4 8 11 | 5 6 12 | 5 9 13 | 6 7 14 | 6 10 15 | 7 11 16 | 8 9 17 | 8 12 18 | 9 10 19 | 9 13 20 | 10 11 21 | 10 14 22 | 11 15 23 | 12 13 24 | 13 14 25 | 14 15 26 | 27 | Visual coupling graph: 28 | 0--1--2--3 29 | | | | | 30 | 4--5--6--7 31 | | | | | 32 | 8--9-10-11 33 | | | | | 34 | 12-13-14-15 35 | -------------------------------------------------------------------------------- /code/circuits/small/4mod5-v1_22.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | x q[4]; 6 | cx q[0],q[2]; 7 | cx q[1],q[3]; 8 | h q[4]; 9 | t q[2]; 10 | t q[3]; 11 | t q[4]; 12 | cx q[3],q[2]; 13 | cx q[4],q[3]; 14 | cx q[2],q[4]; 15 | tdg q[3]; 16 | cx q[2],q[3]; 17 | tdg q[2]; 18 | tdg q[3]; 19 | t q[4]; 20 | cx q[4],q[3]; 21 | cx q[2],q[4]; 22 | cx q[3],q[2]; 23 | h q[4]; 24 | cx q[2],q[3]; 25 | cx q[3],q[4]; 26 | -------------------------------------------------------------------------------- /code/src/Latency/Latency_1_2_6.hpp: -------------------------------------------------------------------------------- 1 | #include "Latency.hpp" 2 | 3 | //Latency example: 6 cycles per SWP; 2 cycles per 2-qubit gate; 1 cycle otherwise 4 | class Latency_1_2_6 : public Latency { 5 | public: 6 | int getLatency(string gateName, int control) { 7 | if(!gateName.compare("swp") || !gateName.compare("SWP")) { 8 | return 6; 9 | } else if(control >= 0) { 10 | return 2; 11 | } else { 12 | return 1; 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/4mod5-v1_22.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | x q[4]; 6 | cx q[0], q[2]; 7 | cx q[1], q[3]; 8 | h q[4]; 9 | t q[2]; 10 | t q[3]; 11 | t q[4]; 12 | cx q[3], q[2]; 13 | cx q[4], q[3]; 14 | cx q[2], q[4]; 15 | tdg q[3]; 16 | cx q[2], q[3]; 17 | tdg q[2]; 18 | tdg q[3]; 19 | t q[4]; 20 | cx q[4], q[3]; 21 | cx q[2], q[4]; 22 | cx q[3], q[2]; 23 | h q[4]; 24 | cx q[2], q[3]; 25 | cx q[3], q[4]; 26 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/adder.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[4]; 4 | x q[0]; 5 | x q[1]; 6 | h q[3]; 7 | cx q[2], q[3]; 8 | t q[0]; 9 | t q[1]; 10 | t q[2]; 11 | tdg q[3]; 12 | cx q[0], q[1]; 13 | cx q[2], q[3]; 14 | cx q[3], q[0]; 15 | cx q[1], q[2]; 16 | cx q[0], q[1]; 17 | cx q[2], q[3]; 18 | tdg q[0]; 19 | tdg q[1]; 20 | tdg q[2]; 21 | t q[3]; 22 | cx q[0], q[1]; 23 | cx q[2], q[3]; 24 | s q[3]; 25 | cx q[3], q[0]; 26 | h q[3]; 27 | -------------------------------------------------------------------------------- /code/circuits/small/mod5d1_63.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[1]; 6 | cx q[2],q[0]; 7 | cx q[1],q[4]; 8 | cx q[0],q[4]; 9 | h q[4]; 10 | t q[1]; 11 | t q[0]; 12 | t q[4]; 13 | cx q[0],q[1]; 14 | cx q[4],q[0]; 15 | cx q[1],q[4]; 16 | tdg q[0]; 17 | cx q[1],q[0]; 18 | tdg q[1]; 19 | tdg q[0]; 20 | t q[4]; 21 | cx q[4],q[0]; 22 | cx q[1],q[4]; 23 | cx q[0],q[1]; 24 | h q[4]; 25 | cx q[3],q[1]; 26 | cx q[2],q[0]; 27 | -------------------------------------------------------------------------------- /data/coupling_maps/aspen4.txt: -------------------------------------------------------------------------------- 1 | 16 18 2 | 0 1 3 | 0 7 4 | 1 2 5 | 1 14 6 | 2 3 7 | 2 13 8 | 3 4 9 | 4 5 10 | 5 6 11 | 6 7 12 | 8 9 13 | 8 15 14 | 9 10 15 | 10 11 16 | 11 12 17 | 12 13 18 | 13 14 19 | 14 15 20 | 21 | 4--3 12--11 22 | / \ / \ 23 | 5 2--13 10 24 | | | | | 25 | 6 1--14 9 26 | \ / \ / 27 | 7--0 15---8 28 | 29 | This coupling map is based on Rigetti Aspen-4 architecture. -------------------------------------------------------------------------------- /code/circuits/OLSQ/qaoa5.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | 5 | h q[0]; 6 | h q[1]; 7 | h q[2]; 8 | h q[3]; 9 | h q[4]; 10 | cx q[0], q[1]; 11 | rz(1.571) q[1]; 12 | cx q[0], q[1]; 13 | cx q[1], q[2]; 14 | rz(1.571) q[2]; 15 | cx q[1], q[2]; 16 | cx q[2], q[3]; 17 | rz(1.571) q[3]; 18 | cx q[2], q[3]; 19 | cx q[3], q[4]; 20 | rz(1.571) q[4]; 21 | cx q[3], q[4]; 22 | rx(2.356) q[0]; 23 | rx(2.356) q[1]; 24 | rx(2.356) q[2]; 25 | rx(2.356) q[3]; 26 | rx(2.356) q[4]; 27 | -------------------------------------------------------------------------------- /code/src/NodeMod/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_NODEMOD_CPP 2 | #define META_NODEMOD_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "NodeMod.hpp" 6 | #include "GreedyMapper.hpp" 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | const int NUMNODEMODS = 1; 12 | tuple nodeMods[NUMNODEMODS] = { 13 | make_tuple(new GreedyMapper(), 14 | "GreedyMapper", 15 | "Deletes default initial mapping, and greedily maps qubits in ready CX gates"), 16 | }; 17 | 18 | #endif -------------------------------------------------------------------------------- /code/src/full_classes/ScheduledGate.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCHEDULEDGATE_HPP 2 | #define SCHEDULEDGATE_HPP 3 | 4 | #include "GateNode.hpp" 5 | using namespace std; 6 | 7 | class ScheduledGate { 8 | public: 9 | GateNode * gate; 10 | int cycle;//cycle when this gate started 11 | int physicalControl; 12 | int physicalTarget; 13 | 14 | ScheduledGate(GateNode * gate, int cycle) { 15 | this->gate = gate; 16 | this->cycle = cycle; 17 | this->physicalControl = -1; 18 | this->physicalTarget = -1; 19 | } 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | If you are using TOQM for your research, it will be greatly appreciated if you cite this publication: 3 | 4 | @inproceedings{zhang2021time, 5 | title={Time-optimal Qubit mapping}, 6 | author={Zhang, Chi and Hayes, Ari B and Qiu, Longfei and Jin, Yuwei and Chen, Yanhao and Zhang, Eddy Z}, 7 | booktitle={Proceedings of the 26th ACM International Conference on Architectural Support for Programming Languages and Operating Systems}, 8 | pages={360--374}, 9 | year={2021} 10 | } 11 | -------------------------------------------------------------------------------- /code/circuits/small/4gt11_82.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[2],q[1]; 6 | cx q[1],q[2]; 7 | cx q[3],q[2]; 8 | cx q[2],q[3]; 9 | cx q[4],q[3]; 10 | cx q[3],q[4]; 11 | h q[0]; 12 | t q[1]; 13 | t q[4]; 14 | t q[0]; 15 | cx q[4],q[1]; 16 | cx q[0],q[4]; 17 | cx q[1],q[0]; 18 | tdg q[4]; 19 | cx q[1],q[4]; 20 | tdg q[1]; 21 | tdg q[4]; 22 | t q[0]; 23 | cx q[0],q[4]; 24 | cx q[1],q[0]; 25 | cx q[4],q[1]; 26 | h q[0]; 27 | cx q[4],q[3]; 28 | cx q[4],q[2]; 29 | cx q[4],q[1]; 30 | cx q[0],q[4]; 31 | cx q[4],q[0]; 32 | -------------------------------------------------------------------------------- /code/src/Latency.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LATENCY_HPP 2 | #define LATENCY_HPP 3 | 4 | #include 5 | using namespace std; 6 | 7 | class Latency { 8 | public: 9 | virtual ~Latency() {}; 10 | virtual int getLatency(string gateName, int control) =0; 11 | 12 | virtual int setArgs(char** argv) { 13 | //used to set the queue's parameters via command-line 14 | //return number of args consumed 15 | 16 | return 0; 17 | } 18 | 19 | virtual int setArgs() { 20 | //used to set the queue's parameters via std::cin 21 | //return number of args consumed 22 | 23 | return 0; 24 | } 25 | }; 26 | 27 | #endif -------------------------------------------------------------------------------- /code/src/NodeMod.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NODEMOD_HPP 2 | #define NODEMOD_HPP 3 | 4 | class Node; 5 | 6 | #define MOD_TYPE_BEFORECOST 1 7 | 8 | class NodeMod { 9 | public: 10 | virtual ~NodeMod() {}; 11 | 12 | virtual void mod(Node * node, int flag) = 0; 13 | 14 | virtual int setArgs(char** argv) { 15 | //used to set the queue's parameters via command-line 16 | //return number of args consumed 17 | 18 | return 0; 19 | } 20 | 21 | virtual int setArgs() { 22 | //used to set the queue's parameters via std::cin 23 | //return number of args consumed 24 | 25 | return 0; 26 | } 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /code/src/Queue/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_QUEUES_CPP 2 | #define META_QUEUES_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "Queue.hpp" 6 | #include "DefaultQueue.hpp" 7 | #include "TrimSlowNodes.hpp" 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | const int NUMQUEUES = 2; 13 | tuple queues[NUMQUEUES] = { 14 | make_tuple(new DefaultQueue(), 15 | "DefaultQueue", 16 | "uses std priority_queue."), 17 | make_tuple(new TrimSlowNodes(), 18 | "TrimSlowNodes", 19 | "Takes 2 params; when reaching max # nodes it removes slowest until it reaches target # nodes."), 20 | }; 21 | 22 | #endif -------------------------------------------------------------------------------- /code/circuits/small/rd32-v0_66.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[4]; 4 | creg c[4]; 5 | h q[3]; 6 | t q[1]; 7 | t q[0]; 8 | t q[3]; 9 | cx q[0],q[1]; 10 | cx q[3],q[0]; 11 | cx q[1],q[3]; 12 | tdg q[0]; 13 | cx q[1],q[0]; 14 | tdg q[1]; 15 | tdg q[0]; 16 | t q[3]; 17 | cx q[3],q[0]; 18 | cx q[1],q[3]; 19 | cx q[0],q[1]; 20 | h q[3]; 21 | cx q[0],q[1]; 22 | h q[3]; 23 | t q[2]; 24 | t q[1]; 25 | t q[3]; 26 | cx q[1],q[2]; 27 | cx q[3],q[1]; 28 | cx q[2],q[3]; 29 | tdg q[1]; 30 | cx q[2],q[1]; 31 | tdg q[2]; 32 | tdg q[1]; 33 | t q[3]; 34 | cx q[3],q[1]; 35 | cx q[2],q[3]; 36 | cx q[1],q[2]; 37 | h q[3]; 38 | cx q[1],q[2]; 39 | -------------------------------------------------------------------------------- /code/circuits/small/4mod5-v0_19.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | x q[3]; 6 | cx q[1],q[3]; 7 | cx q[3],q[4]; 8 | h q[4]; 9 | t q[3]; 10 | t q[2]; 11 | t q[4]; 12 | cx q[2],q[3]; 13 | cx q[4],q[2]; 14 | cx q[3],q[4]; 15 | tdg q[2]; 16 | cx q[3],q[2]; 17 | tdg q[3]; 18 | tdg q[2]; 19 | t q[4]; 20 | cx q[4],q[2]; 21 | cx q[3],q[4]; 22 | cx q[2],q[3]; 23 | h q[4]; 24 | h q[4]; 25 | t q[3]; 26 | t q[0]; 27 | t q[4]; 28 | cx q[0],q[3]; 29 | cx q[4],q[0]; 30 | cx q[3],q[4]; 31 | tdg q[0]; 32 | cx q[3],q[0]; 33 | tdg q[3]; 34 | tdg q[0]; 35 | t q[4]; 36 | cx q[4],q[0]; 37 | cx q[3],q[4]; 38 | cx q[0],q[3]; 39 | h q[4]; 40 | -------------------------------------------------------------------------------- /code/circuits/small/mod5mils_65.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[1],q[3]; 6 | x q[3]; 7 | h q[4]; 8 | t q[3]; 9 | t q[0]; 10 | t q[4]; 11 | cx q[0],q[3]; 12 | cx q[4],q[0]; 13 | cx q[3],q[4]; 14 | tdg q[0]; 15 | cx q[3],q[0]; 16 | tdg q[3]; 17 | tdg q[0]; 18 | t q[4]; 19 | cx q[4],q[0]; 20 | cx q[3],q[4]; 21 | cx q[0],q[3]; 22 | h q[4]; 23 | h q[4]; 24 | t q[3]; 25 | t q[2]; 26 | t q[4]; 27 | cx q[2],q[3]; 28 | cx q[4],q[2]; 29 | cx q[3],q[4]; 30 | tdg q[2]; 31 | cx q[3],q[2]; 32 | tdg q[3]; 33 | tdg q[2]; 34 | t q[4]; 35 | cx q[4],q[2]; 36 | cx q[3],q[4]; 37 | cx q[2],q[3]; 38 | h q[4]; 39 | cx q[3],q[4]; 40 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/mod5mils_65.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[1], q[3]; 6 | x q[3]; 7 | h q[4]; 8 | t q[3]; 9 | t q[0]; 10 | t q[4]; 11 | cx q[0], q[3]; 12 | cx q[4], q[0]; 13 | cx q[3], q[4]; 14 | tdg q[0]; 15 | cx q[3], q[0]; 16 | tdg q[3]; 17 | tdg q[0]; 18 | t q[4]; 19 | cx q[4], q[0]; 20 | cx q[3], q[4]; 21 | cx q[0], q[3]; 22 | h q[4]; 23 | h q[4]; 24 | t q[3]; 25 | t q[2]; 26 | t q[4]; 27 | cx q[2], q[3]; 28 | cx q[4], q[2]; 29 | cx q[3], q[4]; 30 | tdg q[2]; 31 | cx q[3], q[2]; 32 | tdg q[3]; 33 | tdg q[2]; 34 | t q[4]; 35 | cx q[4], q[2]; 36 | cx q[3], q[4]; 37 | cx q[2], q[3]; 38 | h q[4]; 39 | cx q[3], q[4]; 40 | -------------------------------------------------------------------------------- /code/circuits/small/3_17_13.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[3]; 4 | creg c[3]; 5 | x q[2]; 6 | cx q[0],q[2]; 7 | cx q[2],q[1]; 8 | h q[0]; 9 | t q[1]; 10 | t q[2]; 11 | t q[0]; 12 | cx q[2],q[1]; 13 | cx q[0],q[2]; 14 | cx q[1],q[0]; 15 | tdg q[2]; 16 | cx q[1],q[2]; 17 | tdg q[1]; 18 | tdg q[2]; 19 | t q[0]; 20 | cx q[0],q[2]; 21 | cx q[1],q[0]; 22 | cx q[2],q[1]; 23 | h q[0]; 24 | h q[2]; 25 | t q[0]; 26 | t q[1]; 27 | t q[2]; 28 | cx q[1],q[0]; 29 | cx q[2],q[1]; 30 | cx q[0],q[2]; 31 | tdg q[1]; 32 | cx q[0],q[1]; 33 | tdg q[0]; 34 | tdg q[1]; 35 | t q[2]; 36 | cx q[2],q[1]; 37 | cx q[0],q[2]; 38 | cx q[1],q[0]; 39 | h q[2]; 40 | cx q[1],q[2]; 41 | -------------------------------------------------------------------------------- /code/circuits/small/4mod5-v1_24.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | x q[4]; 6 | cx q[3],q[1]; 7 | h q[0]; 8 | t q[4]; 9 | t q[2]; 10 | t q[0]; 11 | cx q[2],q[4]; 12 | cx q[0],q[2]; 13 | cx q[4],q[0]; 14 | tdg q[2]; 15 | cx q[4],q[2]; 16 | tdg q[4]; 17 | tdg q[2]; 18 | t q[0]; 19 | cx q[0],q[2]; 20 | cx q[4],q[0]; 21 | cx q[2],q[4]; 22 | h q[0]; 23 | cx q[1],q[4]; 24 | x q[1]; 25 | h q[4]; 26 | t q[1]; 27 | t q[0]; 28 | t q[4]; 29 | cx q[0],q[1]; 30 | cx q[4],q[0]; 31 | cx q[1],q[4]; 32 | tdg q[0]; 33 | cx q[1],q[0]; 34 | tdg q[1]; 35 | tdg q[0]; 36 | t q[4]; 37 | cx q[4],q[0]; 38 | cx q[1],q[4]; 39 | cx q[0],q[1]; 40 | h q[4]; 41 | -------------------------------------------------------------------------------- /code/circuits/small/rd32-v1_68.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[4]; 4 | creg c[4]; 5 | x q[3]; 6 | h q[3]; 7 | t q[1]; 8 | t q[0]; 9 | t q[3]; 10 | cx q[0],q[1]; 11 | cx q[3],q[0]; 12 | cx q[1],q[3]; 13 | tdg q[0]; 14 | cx q[1],q[0]; 15 | tdg q[1]; 16 | tdg q[0]; 17 | t q[3]; 18 | cx q[3],q[0]; 19 | cx q[1],q[3]; 20 | cx q[0],q[1]; 21 | h q[3]; 22 | cx q[0],q[1]; 23 | h q[3]; 24 | t q[2]; 25 | t q[1]; 26 | t q[3]; 27 | cx q[1],q[2]; 28 | cx q[3],q[1]; 29 | cx q[2],q[3]; 30 | tdg q[1]; 31 | cx q[2],q[1]; 32 | tdg q[2]; 33 | tdg q[1]; 34 | t q[3]; 35 | cx q[3],q[1]; 36 | cx q[2],q[3]; 37 | cx q[1],q[2]; 38 | h q[3]; 39 | x q[3]; 40 | cx q[1],q[2]; 41 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v0_27.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[4]; 6 | cx q[2],q[1]; 7 | h q[2]; 8 | t q[3]; 9 | t q[1]; 10 | t q[2]; 11 | cx q[1],q[3]; 12 | cx q[2],q[1]; 13 | cx q[3],q[2]; 14 | tdg q[1]; 15 | cx q[3],q[1]; 16 | tdg q[3]; 17 | tdg q[1]; 18 | t q[2]; 19 | cx q[2],q[1]; 20 | cx q[3],q[2]; 21 | cx q[1],q[3]; 22 | h q[2]; 23 | cx q[2],q[0]; 24 | x q[2]; 25 | h q[2]; 26 | t q[4]; 27 | t q[0]; 28 | t q[2]; 29 | cx q[0],q[4]; 30 | cx q[2],q[0]; 31 | cx q[4],q[2]; 32 | tdg q[0]; 33 | cx q[4],q[0]; 34 | tdg q[4]; 35 | tdg q[0]; 36 | t q[2]; 37 | cx q[2],q[0]; 38 | cx q[4],q[2]; 39 | cx q[0],q[4]; 40 | h q[2]; 41 | -------------------------------------------------------------------------------- /code/src/Filter/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_FILTERS_CPP 2 | #define META_FILTERS_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "Filter.hpp" 6 | #include "HashFilter.hpp" 7 | #include "HashFilter2.hpp" 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | const int NUMFILTERS = 2; 13 | tuple FILTERS[NUMFILTERS] = { 14 | make_tuple(new HashFilter(), 15 | "HashFilter", 16 | "using hash, this tries to filter out worse nodes."), 17 | make_tuple(new HashFilter2(), 18 | "HashFilter2", 19 | "using hash, this tries to filter out worse nodes, or mark old nodes as dead if a new node is strictly-better."), 20 | }; 21 | 22 | #endif -------------------------------------------------------------------------------- /code/circuits/small/alu-v1_29.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[4]; 6 | x q[3]; 7 | cx q[1],q[2]; 8 | h q[1]; 9 | t q[3]; 10 | t q[2]; 11 | t q[1]; 12 | cx q[2],q[3]; 13 | cx q[1],q[2]; 14 | cx q[3],q[1]; 15 | tdg q[2]; 16 | cx q[3],q[2]; 17 | tdg q[3]; 18 | tdg q[2]; 19 | t q[1]; 20 | cx q[1],q[2]; 21 | cx q[3],q[1]; 22 | cx q[2],q[3]; 23 | h q[1]; 24 | cx q[1],q[0]; 25 | x q[1]; 26 | h q[1]; 27 | t q[4]; 28 | t q[0]; 29 | t q[1]; 30 | cx q[0],q[4]; 31 | cx q[1],q[0]; 32 | cx q[4],q[1]; 33 | tdg q[0]; 34 | cx q[4],q[0]; 35 | tdg q[4]; 36 | tdg q[0]; 37 | t q[1]; 38 | cx q[1],q[0]; 39 | cx q[4],q[1]; 40 | cx q[0],q[4]; 41 | h q[1]; 42 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v2_33.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | x q[4]; 6 | cx q[3],q[4]; 7 | cx q[2],q[1]; 8 | h q[2]; 9 | t q[3]; 10 | t q[1]; 11 | t q[2]; 12 | cx q[1],q[3]; 13 | cx q[2],q[1]; 14 | cx q[3],q[2]; 15 | tdg q[1]; 16 | cx q[3],q[1]; 17 | tdg q[3]; 18 | tdg q[1]; 19 | t q[2]; 20 | cx q[2],q[1]; 21 | cx q[3],q[2]; 22 | cx q[1],q[3]; 23 | h q[2]; 24 | cx q[0],q[2]; 25 | x q[0]; 26 | h q[0]; 27 | t q[4]; 28 | t q[2]; 29 | t q[0]; 30 | cx q[2],q[4]; 31 | cx q[0],q[2]; 32 | cx q[4],q[0]; 33 | tdg q[2]; 34 | cx q[4],q[2]; 35 | tdg q[4]; 36 | tdg q[2]; 37 | t q[0]; 38 | cx q[0],q[2]; 39 | cx q[4],q[0]; 40 | cx q[2],q[4]; 41 | h q[0]; 42 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/16QBT_05CYC_TFL_0.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | x q[2]; 5 | x q[11]; 6 | x q[1]; 7 | x q[13]; 8 | x q[0]; 9 | x q[14]; 10 | x q[6]; 11 | cx q[3], q[9]; 12 | cx q[8], q[12]; 13 | x q[2]; 14 | x q[9]; 15 | x q[7]; 16 | x q[3]; 17 | x q[4]; 18 | x q[1]; 19 | x q[15]; 20 | cx q[10], q[11]; 21 | cx q[8], q[12]; 22 | cx q[14], q[6]; 23 | x q[1]; 24 | x q[12]; 25 | cx q[8], q[2]; 26 | cx q[3], q[9]; 27 | cx q[5], q[4]; 28 | cx q[6], q[0]; 29 | cx q[14], q[10]; 30 | x q[10]; 31 | cx q[8], q[12]; 32 | cx q[14], q[6]; 33 | cx q[1], q[4]; 34 | x q[15]; 35 | x q[1]; 36 | x q[6]; 37 | x q[9]; 38 | x q[0]; 39 | cx q[8], q[12]; 40 | cx q[14], q[10]; 41 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v1_28.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[4],q[3]; 6 | cx q[1],q[2]; 7 | cx q[2],q[4]; 8 | h q[1]; 9 | t q[4]; 10 | t q[2]; 11 | t q[1]; 12 | cx q[2],q[4]; 13 | cx q[1],q[2]; 14 | cx q[4],q[1]; 15 | tdg q[2]; 16 | cx q[4],q[2]; 17 | tdg q[4]; 18 | tdg q[2]; 19 | t q[1]; 20 | cx q[1],q[2]; 21 | cx q[4],q[1]; 22 | cx q[2],q[4]; 23 | h q[1]; 24 | cx q[1],q[0]; 25 | h q[1]; 26 | t q[0]; 27 | t q[3]; 28 | t q[1]; 29 | cx q[3],q[0]; 30 | cx q[1],q[3]; 31 | cx q[0],q[1]; 32 | tdg q[3]; 33 | cx q[0],q[3]; 34 | tdg q[0]; 35 | tdg q[3]; 36 | t q[1]; 37 | cx q[1],q[3]; 38 | cx q[0],q[1]; 39 | cx q[3],q[0]; 40 | h q[1]; 41 | x q[1]; 42 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v3_35.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[4],q[3]; 6 | cx q[2],q[1]; 7 | x q[2]; 8 | h q[2]; 9 | t q[4]; 10 | t q[1]; 11 | t q[2]; 12 | cx q[1],q[4]; 13 | cx q[2],q[1]; 14 | cx q[4],q[2]; 15 | tdg q[1]; 16 | cx q[4],q[1]; 17 | tdg q[4]; 18 | tdg q[1]; 19 | t q[2]; 20 | cx q[2],q[1]; 21 | cx q[4],q[2]; 22 | cx q[1],q[4]; 23 | h q[2]; 24 | cx q[2],q[0]; 25 | h q[2]; 26 | t q[3]; 27 | t q[0]; 28 | t q[2]; 29 | cx q[0],q[3]; 30 | cx q[2],q[0]; 31 | cx q[3],q[2]; 32 | tdg q[0]; 33 | cx q[3],q[0]; 34 | tdg q[3]; 35 | tdg q[0]; 36 | t q[2]; 37 | cx q[2],q[0]; 38 | cx q[3],q[2]; 39 | cx q[0],q[3]; 40 | h q[2]; 41 | cx q[2],q[3]; 42 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v4_37.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[4]; 6 | cx q[2],q[1]; 7 | x q[2]; 8 | h q[2]; 9 | t q[3]; 10 | t q[1]; 11 | t q[2]; 12 | cx q[1],q[3]; 13 | cx q[2],q[1]; 14 | cx q[3],q[2]; 15 | tdg q[1]; 16 | cx q[3],q[1]; 17 | tdg q[3]; 18 | tdg q[1]; 19 | t q[2]; 20 | cx q[2],q[1]; 21 | cx q[3],q[2]; 22 | cx q[1],q[3]; 23 | h q[2]; 24 | cx q[2],q[0]; 25 | h q[2]; 26 | t q[4]; 27 | t q[0]; 28 | t q[2]; 29 | cx q[0],q[4]; 30 | cx q[2],q[0]; 31 | cx q[4],q[2]; 32 | tdg q[0]; 33 | cx q[4],q[0]; 34 | tdg q[4]; 35 | tdg q[0]; 36 | t q[2]; 37 | cx q[2],q[0]; 38 | cx q[4],q[2]; 39 | cx q[0],q[4]; 40 | h q[2]; 41 | cx q[2],q[4]; 42 | -------------------------------------------------------------------------------- /code/couplings/tokyo.txt: -------------------------------------------------------------------------------- 1 | 20 43 2 | 0 1 3 | 0 5 4 | 1 2 5 | 1 6 6 | 1 7 7 | 2 3 8 | 2 6 9 | 2 7 10 | 3 4 11 | 3 8 12 | 3 9 13 | 4 8 14 | 4 9 15 | 5 6 16 | 5 10 17 | 5 11 18 | 6 7 19 | 6 10 20 | 6 11 21 | 7 8 22 | 7 12 23 | 7 13 24 | 8 9 25 | 8 12 26 | 8 13 27 | 9 14 28 | 10 11 29 | 10 15 30 | 11 12 31 | 11 16 32 | 11 17 33 | 12 13 34 | 12 16 35 | 12 17 36 | 13 14 37 | 13 18 38 | 13 19 39 | 14 18 40 | 14 19 41 | 15 16 42 | 16 17 43 | 17 18 44 | 18 19 45 | 46 | 0--1--2--3--4 47 | | |\/| |\/| 48 | | |/\| |/\| 49 | 5--6--7--8--9 50 | |\/| |\/| | 51 | |/\| |/\| | 52 | 10-11-12-13-14 53 | | |\/| |\/| 54 | | |/\| |/\| 55 | 15-16-17-18-19 56 | -------------------------------------------------------------------------------- /code/src/Latency/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_LATENCY_CPP 2 | #define META_LATENCY_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "Latency.hpp" 6 | #include "Latency_1_2_6.hpp" 7 | #include "Latency_1_3.hpp" 8 | #include "Latency_1.hpp" 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int NUMLATENCIES = 3; 14 | tuple latencies[NUMLATENCIES] = { 15 | make_tuple(new Latency_1_2_6(), 16 | "Latency_1_2_6", 17 | "swap cost 6, 2-bit gate cost 2, 1-bit gate cost 1."), 18 | make_tuple(new Latency_1_3(), 19 | "Latency_1_3", 20 | "swap cost 3, all else cost 1."), 21 | make_tuple(new Latency_1(), 22 | "Latency_1", 23 | "every gate takes 1 cycle."), 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /code/src/Expander.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXPAND_HPP 2 | #define EXPAND_HPP 3 | 4 | class Node; 5 | class Queue; 6 | 7 | class Expander { 8 | public: 9 | virtual ~Expander() {}; 10 | 11 | //expands given node, unless it has same-or-worse cost than best final node 12 | //returns false iff given node's cost >= best final node's cost 13 | virtual bool expand(Queue * nodes, Node * node) =0; 14 | 15 | virtual int setArgs(char** argv) { 16 | //used to set the expander's parameters via command-line 17 | //return number of args consumed 18 | 19 | return 0; 20 | } 21 | 22 | virtual int setArgs() { 23 | //used to set the expander's parameters via-cin 24 | //return number of args consumed 25 | 26 | return 0; 27 | } 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /code/src/CostFunc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COSTFUNC_HPP 2 | #define COSTFUNC_HPP 3 | 4 | #include "Node.hpp" 5 | #include "NodeMod.hpp" 6 | 7 | class CostFunc { 8 | public: 9 | virtual ~CostFunc() {}; 10 | virtual int _getCost(Node * node) = 0; 11 | 12 | int getCost(Node * node) { 13 | Environment * env = node->env; 14 | env->runNodeModifiers(node, MOD_TYPE_BEFORECOST); 15 | return _getCost(node); 16 | } 17 | 18 | virtual int setArgs(char** argv) { 19 | //used to set the queue's parameters via command-line 20 | //return number of args consumed 21 | 22 | return 0; 23 | } 24 | 25 | virtual int setArgs() { 26 | //used to set the queue's parameters via std::cin 27 | //return number of args consumed 28 | 29 | return 0; 30 | } 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /code/src/Expander/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_EXPANDERS_CPP 2 | #define META_EXPANDERS_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "Expander.hpp" 6 | #include "DefaultExpander.hpp" 7 | #include "GreedyTopK.hpp" 8 | #include "NoSwaps.hpp" 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int NUMEXPANDERS = 3; 14 | tuple expanders[NUMEXPANDERS] = { 15 | make_tuple(new DefaultExpander(), 16 | "DefaultExpander", 17 | "The default expander. Includes acyclic swap and dependent state optimizations."), 18 | make_tuple(new GreedyTopK(), 19 | "GreedyTopK", 20 | "Keep only top K nodes; avoids some swaps and schedules original gates ASAP [non-optimal!]"), 21 | make_tuple(new NoSwaps(), 22 | "NoSwaps", 23 | "Cannot insert swaps."), 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /code/src/CostFunc/Meta.cpp: -------------------------------------------------------------------------------- 1 | #ifndef META_COSTFUNC_CPP 2 | #define META_COSTFUNC_CPP 3 | 4 | #include "Meta.hpp" 5 | #include "CostFunc.hpp" 6 | #include "CXFull.hpp" 7 | #include "CXFrontier.hpp" 8 | #include "SimpleCost.hpp" 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int NUMCOSTFUNCTIONS = 5; 14 | tuple costFunctions[NUMCOSTFUNCTIONS] = { 15 | make_tuple(new CXFrontier(), 16 | "CXFrontier", 17 | "Calculates lower-bound cost, including swaps to enable gates in the CX frontier"), 18 | make_tuple(new CXFull(), 19 | "CXFull", 20 | "Calculates lower-bound cost, including swaps to enable CX gates in remaining circuit"), 21 | make_tuple(new SimpleCost(), 22 | "SimpleCost", 23 | "Calculates lower-bound cost, assuming no more swaps will be inserted"), 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /code/circuits/small/miller_11.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[3]; 4 | creg c[3]; 5 | cx q[2],q[1]; 6 | h q[2]; 7 | t q[1]; 8 | t q[0]; 9 | t q[2]; 10 | cx q[0],q[1]; 11 | cx q[2],q[0]; 12 | cx q[1],q[2]; 13 | tdg q[0]; 14 | cx q[1],q[0]; 15 | tdg q[1]; 16 | tdg q[0]; 17 | t q[2]; 18 | cx q[2],q[0]; 19 | cx q[1],q[2]; 20 | cx q[0],q[1]; 21 | h q[2]; 22 | h q[0]; 23 | t q[2]; 24 | t q[1]; 25 | t q[0]; 26 | cx q[1],q[2]; 27 | cx q[0],q[1]; 28 | cx q[2],q[0]; 29 | tdg q[1]; 30 | cx q[2],q[1]; 31 | tdg q[2]; 32 | tdg q[1]; 33 | t q[0]; 34 | cx q[0],q[1]; 35 | cx q[2],q[0]; 36 | cx q[1],q[2]; 37 | h q[0]; 38 | h q[2]; 39 | t q[1]; 40 | t q[0]; 41 | t q[2]; 42 | cx q[0],q[1]; 43 | cx q[2],q[0]; 44 | cx q[1],q[2]; 45 | tdg q[0]; 46 | cx q[1],q[0]; 47 | tdg q[1]; 48 | tdg q[0]; 49 | t q[2]; 50 | cx q[2],q[0]; 51 | cx q[1],q[2]; 52 | cx q[0],q[1]; 53 | h q[2]; 54 | cx q[2],q[1]; 55 | -------------------------------------------------------------------------------- /code/circuits/small/alu-v3_34.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | h q[1]; 6 | t q[4]; 7 | t q[2]; 8 | t q[1]; 9 | cx q[2],q[4]; 10 | cx q[1],q[2]; 11 | cx q[4],q[1]; 12 | tdg q[2]; 13 | cx q[4],q[2]; 14 | tdg q[4]; 15 | tdg q[2]; 16 | t q[1]; 17 | cx q[1],q[2]; 18 | cx q[4],q[1]; 19 | cx q[2],q[4]; 20 | h q[1]; 21 | x q[2]; 22 | cx q[4],q[3]; 23 | h q[2]; 24 | t q[1]; 25 | t q[4]; 26 | t q[2]; 27 | cx q[4],q[1]; 28 | cx q[2],q[4]; 29 | cx q[1],q[2]; 30 | tdg q[4]; 31 | cx q[1],q[4]; 32 | tdg q[1]; 33 | tdg q[4]; 34 | t q[2]; 35 | cx q[2],q[4]; 36 | cx q[1],q[2]; 37 | cx q[4],q[1]; 38 | h q[2]; 39 | cx q[2],q[0]; 40 | h q[2]; 41 | t q[0]; 42 | t q[3]; 43 | t q[2]; 44 | cx q[3],q[0]; 45 | cx q[2],q[3]; 46 | cx q[0],q[2]; 47 | tdg q[3]; 48 | cx q[0],q[3]; 49 | tdg q[0]; 50 | tdg q[3]; 51 | t q[2]; 52 | cx q[2],q[3]; 53 | cx q[0],q[2]; 54 | cx q[3],q[0]; 55 | h q[2]; 56 | cx q[2],q[3]; 57 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/tof_4_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[7]; 5 | h q[4]; 6 | h q[5]; 7 | h q[6]; 8 | cx q[1],q[4]; 9 | tdg q[4]; 10 | cx q[0],q[4]; 11 | t q[4]; 12 | cx q[1],q[4]; 13 | tdg q[4]; 14 | cx q[0],q[4]; 15 | t q[4]; 16 | h q[4]; 17 | cx q[4],q[5]; 18 | tdg q[5]; 19 | cx q[2],q[5]; 20 | t q[5]; 21 | cx q[4],q[5]; 22 | tdg q[5]; 23 | cx q[2],q[5]; 24 | t q[5]; 25 | h q[5]; 26 | cx q[5],q[6]; 27 | tdg q[6]; 28 | cx q[3],q[6]; 29 | t q[6]; 30 | cx q[5],q[6]; 31 | tdg q[6]; 32 | cx q[3],q[6]; 33 | cx q[3],q[5]; 34 | t q[6]; 35 | tdg q[5]; 36 | h q[6]; 37 | cx q[3],q[5]; 38 | t q[3]; 39 | t q[5]; 40 | h q[5]; 41 | cx q[4],q[5]; 42 | t q[5]; 43 | cx q[2],q[5]; 44 | tdg q[5]; 45 | cx q[4],q[5]; 46 | h q[4]; 47 | t q[5]; 48 | cx q[1],q[4]; 49 | cx q[2],q[5]; 50 | t q[4]; 51 | tdg q[5]; 52 | cx q[0],q[4]; 53 | h q[5]; 54 | tdg q[4]; 55 | cx q[1],q[4]; 56 | t q[4]; 57 | cx q[0],q[4]; 58 | tdg q[4]; 59 | h q[4]; 60 | -------------------------------------------------------------------------------- /data/README.txt: -------------------------------------------------------------------------------- 1 | README 2 | ## Resulted qasm files 3 | 4 | * min-depth is for all benchmarks in OLSQ depth optimality testing 5 | * min-gate is for all benchmarks in OLSQ gate optimality testing 6 | * coupling-graph is for all the hardware coupling graphs used 7 | 8 | In the output .qasm files, each original instruction is placed as comments to the right of its transformed one such that the qubit location for each gate is described. For instance in the following instruction: 9 | 10 | “u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1]” 11 | 12 | It means the original logical_q[1] is mapped to the physical qubit q[0]. 13 | 14 | We provide hardware coupling graphs in the coupling graphs folder. 15 | 16 | Example: 17 | 18 | 6 7 19 | 0 1 20 | 0 2 21 | 1 3 22 | 2 3 23 | 2 4 24 | 3 5 25 | 4 5 26 | 27 | 0-2-4 28 | | | | 29 | 1-3-5 30 | 31 | The first number describes the number of vertices. The second number describes the number of edges. Then it describes the adjacency list, followed by a pictorial description of the hardware. 32 | 33 | 34 | -------------------------------------------------------------------------------- /code/src/Filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_HPP 2 | #define FILTER_HPP 3 | 4 | class Node; 5 | class Queue; 6 | #include 7 | 8 | class Filter { 9 | public: 10 | virtual ~Filter() {}; 11 | 12 | //this should be called after we're done scheduling gates in newNode 13 | //return true iff we don't want to add newNode to the nodes list 14 | virtual bool filter(Node * newNode) = 0; 15 | 16 | virtual void printStatistics(std::ostream & stream) { 17 | //this function should print info such as how many nodes have been filtered out 18 | } 19 | 20 | virtual void deleteRecord(Node * n) { 21 | //if this filter retains node info, delete the filter's records of node n 22 | } 23 | 24 | virtual Filter * createEmptyCopy() = 0; 25 | 26 | virtual int setArgs(char** argv) { 27 | //used to set the queue's parameters via command-line 28 | //return number of args consumed 29 | 30 | return 0; 31 | } 32 | 33 | virtual int setArgs() { 34 | //used to set the queue's parameters via std::cin 35 | //return number of args consumed 36 | 37 | return 0; 38 | } 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /code/src/full_classes/GateNode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GATENODE_HPP 2 | #define GATENODE_HPP 3 | 4 | #include 5 | using namespace std; 6 | 7 | class GateNode { //part of a DAG of nodes 8 | public: 9 | string name; 10 | int control;//control qubit, or -1 11 | int target;//target qubit 12 | 13 | int latency;//how many cycles this gate takes 14 | int criticality;//length (time) of circuit from here until furthest leaf 15 | 16 | //note that the following variables will not take into account inserted SWP gates 17 | GateNode * controlChild = 0;//gate which depends on this one's control qubit, or NULL 18 | GateNode * targetChild = 0;//gate which depends on this one's target qubit, or NULL 19 | GateNode * controlParent = 0;//prior gate which this control qubit depends on, or NULL 20 | GateNode * targetParent = 0;//prior gate which this target qubit depends on, or NULL 21 | 22 | GateNode * nextControlCNOT = 0;//next 2-qubit gate which depends on this one's control, or -1 23 | GateNode * nextTargetCNOT = 0;//next 2-qubit gate which depends on this one's target, or -1 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /code/circuits/small/4gt13_92.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[4],q[0]; 6 | h q[0]; 7 | t q[1]; 8 | t q[4]; 9 | t q[0]; 10 | cx q[4],q[1]; 11 | cx q[0],q[4]; 12 | cx q[1],q[0]; 13 | tdg q[4]; 14 | cx q[1],q[4]; 15 | tdg q[1]; 16 | tdg q[4]; 17 | t q[0]; 18 | cx q[0],q[4]; 19 | cx q[1],q[0]; 20 | cx q[4],q[1]; 21 | h q[0]; 22 | h q[4]; 23 | t q[3]; 24 | t q[2]; 25 | t q[4]; 26 | cx q[2],q[3]; 27 | cx q[4],q[2]; 28 | cx q[3],q[4]; 29 | tdg q[2]; 30 | cx q[3],q[2]; 31 | tdg q[3]; 32 | tdg q[2]; 33 | t q[4]; 34 | cx q[4],q[2]; 35 | cx q[3],q[4]; 36 | cx q[2],q[3]; 37 | h q[4]; 38 | h q[0]; 39 | t q[1]; 40 | t q[4]; 41 | t q[0]; 42 | cx q[4],q[1]; 43 | cx q[0],q[4]; 44 | cx q[1],q[0]; 45 | tdg q[4]; 46 | cx q[1],q[4]; 47 | tdg q[1]; 48 | tdg q[4]; 49 | t q[0]; 50 | cx q[0],q[4]; 51 | cx q[1],q[0]; 52 | cx q[4],q[1]; 53 | h q[0]; 54 | h q[4]; 55 | t q[3]; 56 | t q[2]; 57 | t q[4]; 58 | cx q[2],q[3]; 59 | cx q[4],q[2]; 60 | cx q[3],q[4]; 61 | tdg q[2]; 62 | cx q[3],q[2]; 63 | tdg q[3]; 64 | tdg q[2]; 65 | t q[4]; 66 | cx q[4],q[2]; 67 | cx q[3],q[4]; 68 | cx q[2],q[3]; 69 | h q[4]; 70 | cx q[0],q[4]; 71 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/4gt13_92.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[4], q[0]; 6 | h q[0]; 7 | t q[1]; 8 | t q[4]; 9 | t q[0]; 10 | cx q[4], q[1]; 11 | cx q[0], q[4]; 12 | cx q[1], q[0]; 13 | tdg q[4]; 14 | cx q[1], q[4]; 15 | tdg q[1]; 16 | tdg q[4]; 17 | t q[0]; 18 | cx q[0], q[4]; 19 | cx q[1], q[0]; 20 | cx q[4], q[1]; 21 | h q[0]; 22 | h q[4]; 23 | t q[3]; 24 | t q[2]; 25 | t q[4]; 26 | cx q[2], q[3]; 27 | cx q[4], q[2]; 28 | cx q[3], q[4]; 29 | tdg q[2]; 30 | cx q[3], q[2]; 31 | tdg q[3]; 32 | tdg q[2]; 33 | t q[4]; 34 | cx q[4], q[2]; 35 | cx q[3], q[4]; 36 | cx q[2], q[3]; 37 | h q[4]; 38 | h q[0]; 39 | t q[1]; 40 | t q[4]; 41 | t q[0]; 42 | cx q[4], q[1]; 43 | cx q[0], q[4]; 44 | cx q[1], q[0]; 45 | tdg q[4]; 46 | cx q[1], q[4]; 47 | tdg q[1]; 48 | tdg q[4]; 49 | t q[0]; 50 | cx q[0], q[4]; 51 | cx q[1], q[0]; 52 | cx q[4], q[1]; 53 | h q[0]; 54 | h q[4]; 55 | t q[3]; 56 | t q[2]; 57 | t q[4]; 58 | cx q[2], q[3]; 59 | cx q[4], q[2]; 60 | cx q[3], q[4]; 61 | tdg q[2]; 62 | cx q[3], q[2]; 63 | tdg q[3]; 64 | tdg q[2]; 65 | t q[4]; 66 | cx q[4], q[2]; 67 | cx q[3], q[4]; 68 | cx q[2], q[3]; 69 | h q[4]; 70 | cx q[0], q[4]; 71 | -------------------------------------------------------------------------------- /code/src/full_classes/LinkedStack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LINKEDSTACK_HPP 2 | #define LINKEDSTACK_HPP 3 | 4 | template 5 | class LinkedStack { 6 | public: 7 | T value; 8 | LinkedStack * next; 9 | int size; 10 | int numRefs; //will be used to help with garbage collection 11 | 12 | LinkedStack() { 13 | this->value = NULL; 14 | this->size = 0; 15 | this->next = NULL; 16 | this->numRefs = 1; 17 | } 18 | 19 | //Create a new LinkedStack such that this one is its second element 20 | //Sets new node's reference count to 1 21 | //Returns the new LinkedStack 22 | LinkedStack * push(T newVal) { 23 | LinkedStack * ret = new LinkedStack; 24 | ret->next = this; 25 | ret->size = this->size + 1; 26 | ret->value = newVal; 27 | ret->numRefs = 1; 28 | return ret; 29 | } 30 | 31 | LinkedStack * newRef() { 32 | numRefs++; 33 | return this; 34 | } 35 | 36 | void clean() { 37 | this->numRefs--; 38 | if(this->numRefs > 0) { 39 | return; 40 | } 41 | 42 | if(this->next) { 43 | this->next->clean(); 44 | } 45 | 46 | if(this->value) { 47 | delete this->value; 48 | } 49 | delete this; 50 | } 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/barenco_tof_4_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[7]; 5 | t q[4]; 6 | t q[5]; 7 | h q[6]; 8 | cx q[5],q[6]; 9 | tdg q[6]; 10 | cx q[3],q[6]; 11 | t q[6]; 12 | cx q[5],q[6]; 13 | cx q[3],q[5]; 14 | tdg q[5]; 15 | cx q[3],q[5]; 16 | h q[5]; 17 | cx q[4],q[5]; 18 | tdg q[5]; 19 | cx q[2],q[5]; 20 | t q[5]; 21 | cx q[4],q[5]; 22 | cx q[2],q[4]; 23 | tdg q[4]; 24 | cx q[2],q[4]; 25 | h q[4]; 26 | cx q[1],q[4]; 27 | tdg q[4]; 28 | cx q[0],q[4]; 29 | t q[4]; 30 | cx q[1],q[4]; 31 | tdg q[4]; 32 | cx q[0],q[4]; 33 | t q[4]; 34 | h q[4]; 35 | cx q[4],q[5]; 36 | tdg q[5]; 37 | cx q[2],q[5]; 38 | t q[5]; 39 | cx q[4],q[5]; 40 | h q[5]; 41 | cx q[5],q[6]; 42 | tdg q[6]; 43 | cx q[3],q[6]; 44 | t q[6]; 45 | cx q[5],q[6]; 46 | cx q[3],q[5]; 47 | h q[6]; 48 | t q[5]; 49 | cx q[3],q[5]; 50 | tdg q[5]; 51 | h q[5]; 52 | cx q[4],q[5]; 53 | tdg q[5]; 54 | cx q[2],q[5]; 55 | t q[5]; 56 | cx q[4],q[5]; 57 | h q[4]; 58 | cx q[1],q[4]; 59 | t q[4]; 60 | cx q[0],q[4]; 61 | tdg q[4]; 62 | cx q[1],q[4]; 63 | t q[4]; 64 | cx q[0],q[4]; 65 | tdg q[4]; 66 | h q[4]; 67 | cx q[4],q[5]; 68 | tdg q[5]; 69 | cx q[2],q[5]; 70 | t q[5]; 71 | cx q[4],q[5]; 72 | cx q[2],q[4]; 73 | h q[5]; 74 | t q[4]; 75 | cx q[2],q[4]; 76 | tdg q[4]; 77 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/16QBT_10CYC_TFL_3.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | x q[0]; 5 | x q[2]; 6 | x q[10]; 7 | x q[9]; 8 | x q[7]; 9 | cx q[14], q[12]; 10 | cx q[13], q[6]; 11 | x q[0]; 12 | x q[7]; 13 | x q[11]; 14 | x q[4]; 15 | x q[5]; 16 | cx q[12], q[1]; 17 | cx q[6], q[10]; 18 | x q[7]; 19 | cx q[0], q[11]; 20 | cx q[12], q[1]; 21 | cx q[9], q[5]; 22 | cx q[2], q[8]; 23 | x q[10]; 24 | x q[9]; 25 | x q[4]; 26 | x q[8]; 27 | x q[3]; 28 | cx q[11], q[14]; 29 | cx q[15], q[2]; 30 | cx q[12], q[7]; 31 | cx q[13], q[0]; 32 | x q[11]; 33 | x q[7]; 34 | x q[3]; 35 | x q[12]; 36 | x q[14]; 37 | x q[8]; 38 | cx q[6], q[10]; 39 | cx q[13], q[0]; 40 | x q[11]; 41 | x q[8]; 42 | x q[1]; 43 | x q[14]; 44 | x q[13]; 45 | cx q[12], q[7]; 46 | cx q[3], q[5]; 47 | x q[9]; 48 | x q[10]; 49 | cx q[11], q[14]; 50 | cx q[12], q[1]; 51 | cx q[2], q[8]; 52 | x q[11]; 53 | x q[2]; 54 | x q[4]; 55 | x q[15]; 56 | x q[8]; 57 | x q[14]; 58 | cx q[13], q[6]; 59 | cx q[7], q[9]; 60 | cx q[12], q[1]; 61 | x q[11]; 62 | x q[7]; 63 | x q[9]; 64 | x q[1]; 65 | cx q[14], q[12]; 66 | cx q[13], q[6]; 67 | cx q[3], q[5]; 68 | cx q[8], q[4]; 69 | x q[11]; 70 | x q[12]; 71 | x q[0]; 72 | x q[10]; 73 | x q[14]; 74 | cx q[7], q[9]; 75 | cx q[3], q[5]; 76 | cx q[8], q[4]; 77 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/tof_5_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[9]; 5 | h q[5]; 6 | h q[6]; 7 | h q[7]; 8 | h q[8]; 9 | cx q[1],q[5]; 10 | tdg q[5]; 11 | cx q[0],q[5]; 12 | t q[5]; 13 | cx q[1],q[5]; 14 | tdg q[5]; 15 | cx q[0],q[5]; 16 | t q[5]; 17 | h q[5]; 18 | cx q[5],q[6]; 19 | tdg q[6]; 20 | cx q[2],q[6]; 21 | t q[6]; 22 | cx q[5],q[6]; 23 | tdg q[6]; 24 | cx q[2],q[6]; 25 | t q[6]; 26 | h q[6]; 27 | cx q[6],q[7]; 28 | tdg q[7]; 29 | cx q[3],q[7]; 30 | t q[7]; 31 | cx q[6],q[7]; 32 | tdg q[7]; 33 | cx q[3],q[7]; 34 | t q[7]; 35 | h q[7]; 36 | cx q[7],q[8]; 37 | tdg q[8]; 38 | cx q[4],q[8]; 39 | t q[8]; 40 | cx q[7],q[8]; 41 | tdg q[8]; 42 | cx q[4],q[8]; 43 | cx q[4],q[7]; 44 | t q[8]; 45 | tdg q[7]; 46 | h q[8]; 47 | cx q[4],q[7]; 48 | t q[4]; 49 | t q[7]; 50 | h q[7]; 51 | cx q[6],q[7]; 52 | t q[7]; 53 | cx q[3],q[7]; 54 | tdg q[7]; 55 | cx q[6],q[7]; 56 | h q[6]; 57 | t q[7]; 58 | cx q[3],q[7]; 59 | cx q[5],q[6]; 60 | t q[6]; 61 | tdg q[7]; 62 | cx q[2],q[6]; 63 | h q[7]; 64 | tdg q[6]; 65 | cx q[5],q[6]; 66 | h q[5]; 67 | t q[6]; 68 | cx q[1],q[5]; 69 | cx q[2],q[6]; 70 | t q[5]; 71 | tdg q[6]; 72 | cx q[0],q[5]; 73 | h q[6]; 74 | tdg q[5]; 75 | cx q[1],q[5]; 76 | t q[5]; 77 | cx q[0],q[5]; 78 | tdg q[5]; 79 | h q[5]; 80 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/mod_mult_55_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[9]; 5 | h q[6]; 6 | h q[7]; 7 | h q[8]; 8 | cx q[0],q[7]; 9 | t q[7]; 10 | cx q[2],q[7]; 11 | t q[7]; 12 | cx q[0],q[7]; 13 | tdg q[7]; 14 | cx q[2],q[7]; 15 | cx q[2],q[0]; 16 | tdg q[7]; 17 | sdg q[0]; 18 | h q[7]; 19 | tdg q[0]; 20 | cx q[7],q[6]; 21 | cx q[2],q[0]; 22 | t q[6]; 23 | cx q[1],q[6]; 24 | cx q[2],q[8]; 25 | tdg q[6]; 26 | t q[8]; 27 | cx q[0],q[8]; 28 | cx q[7],q[6]; 29 | t q[6]; 30 | t q[8]; 31 | cx q[1],q[6]; 32 | cx q[2],q[8]; 33 | cx q[1],q[7]; 34 | tdg q[6]; 35 | tdg q[8]; 36 | cx q[0],q[8]; 37 | h q[6]; 38 | t q[7]; 39 | cx q[1],q[7]; 40 | cx q[6],q[5]; 41 | tdg q[8]; 42 | cx q[6],q[3]; 43 | tdg q[7]; 44 | h q[8]; 45 | h q[3]; 46 | h q[6]; 47 | cx q[8],q[7]; 48 | cx q[7],q[3]; 49 | cx q[8],q[6]; 50 | t q[3]; 51 | t q[6]; 52 | cx q[1],q[6]; 53 | t q[6]; 54 | cx q[8],q[6]; 55 | tdg q[6]; 56 | cx q[1],q[6]; 57 | cx q[1],q[8]; 58 | tdg q[6]; 59 | h q[6]; 60 | tdg q[8]; 61 | cx q[1],q[8]; 62 | cx q[6],q[4]; 63 | cx q[1],q[3]; 64 | tdg q[8]; 65 | t q[3]; 66 | cx q[5],q[8]; 67 | cx q[7],q[3]; 68 | h q[5]; 69 | h q[8]; 70 | cx q[2],q[8]; 71 | t q[3]; 72 | cx q[1],q[3]; 73 | t q[8]; 74 | cx q[0],q[8]; 75 | cx q[1],q[5]; 76 | t q[3]; 77 | h q[3]; 78 | tdg q[5]; 79 | t q[8]; 80 | cx q[2],q[8]; 81 | cx q[7],q[5]; 82 | tdg q[2]; 83 | tdg q[5]; 84 | tdg q[8]; 85 | cx q[0],q[8]; 86 | cx q[1],q[5]; 87 | t q[0]; 88 | t q[5]; 89 | tdg q[8]; 90 | cx q[7],q[5]; 91 | h q[8]; 92 | t q[5]; 93 | sdg q[7]; 94 | h q[5]; 95 | cx q[5],q[8]; 96 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/vbe_adder_3_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[10]; 5 | h q[3]; 6 | h q[6]; 7 | t q[7]; 8 | t q[8]; 9 | h q[9]; 10 | cx q[2],q[3]; 11 | cx q[5],q[6]; 12 | cx q[8],q[9]; 13 | tdg q[3]; 14 | tdg q[6]; 15 | tdg q[9]; 16 | cx q[1],q[3]; 17 | cx q[4],q[6]; 18 | cx q[7],q[9]; 19 | cx q[2],q[3]; 20 | cx q[5],q[6]; 21 | cx q[8],q[9]; 22 | tdg q[3]; 23 | tdg q[6]; 24 | tdg q[9]; 25 | cx q[1],q[3]; 26 | cx q[4],q[6]; 27 | cx q[7],q[9]; 28 | cx q[1],q[2]; 29 | cx q[4],q[5]; 30 | cx q[7],q[8]; 31 | cx q[2],q[3]; 32 | cx q[5],q[6]; 33 | cx q[8],q[9]; 34 | cx q[0],q[3]; 35 | t q[3]; 36 | cx q[2],q[3]; 37 | tdg q[3]; 38 | cx q[0],q[3]; 39 | s q[3]; 40 | h q[3]; 41 | cx q[3],q[6]; 42 | t q[6]; 43 | cx q[5],q[6]; 44 | tdg q[6]; 45 | cx q[3],q[6]; 46 | s q[6]; 47 | h q[6]; 48 | t q[6]; 49 | cx q[6],q[9]; 50 | t q[9]; 51 | cx q[8],q[9]; 52 | tdg q[9]; 53 | cx q[6],q[9]; 54 | cx q[6],q[8]; 55 | s q[9]; 56 | h q[6]; 57 | tdg q[8]; 58 | h q[9]; 59 | sdg q[6]; 60 | cx q[5],q[6]; 61 | cx q[3],q[6]; 62 | tdg q[6]; 63 | cx q[5],q[6]; 64 | cx q[4],q[5]; 65 | t q[6]; 66 | cx q[3],q[6]; 67 | cx q[5],q[6]; 68 | t q[6]; 69 | cx q[4],q[6]; 70 | cx q[5],q[6]; 71 | cx q[3],q[5]; 72 | t q[6]; 73 | h q[3]; 74 | cx q[4],q[6]; 75 | sdg q[3]; 76 | cx q[4],q[5]; 77 | h q[6]; 78 | cx q[2],q[3]; 79 | cx q[0],q[3]; 80 | tdg q[3]; 81 | cx q[2],q[3]; 82 | cx q[1],q[2]; 83 | t q[3]; 84 | cx q[0],q[3]; 85 | cx q[2],q[3]; 86 | t q[3]; 87 | cx q[1],q[3]; 88 | cx q[2],q[3]; 89 | cx q[0],q[2]; 90 | t q[3]; 91 | cx q[1],q[3]; 92 | cx q[1],q[2]; 93 | h q[3]; 94 | -------------------------------------------------------------------------------- /data/min-gates/or_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 6 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 8 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 9 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[1] 10 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 11 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 12 | u3(0.000000, 0.000000, -1.570796) q[0]; //cycle: 3 //u3(0.000000, 0.000000, -1.570796) logical_q[2] 13 | cx q[2],q[1]; //cycle: 3 //cx logical_q[0],logical_q[1] 14 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 4 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 15 | cx q[0],q[2]; //cycle: 4 //cx logical_q[2],logical_q[0] 16 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 5 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 17 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[1] 18 | cx q[0],q[2]; //cycle: 6 //cx logical_q[2],logical_q[0] 19 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 20 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 7 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 21 | cx q[2],q[1]; //cycle: 7 //cx logical_q[0],logical_q[1] 22 | //17 original gates 23 | //17 final gates 24 | //10 nodes expanded (popped from queue). 25 | //11 nodes remain in queue. 26 | -------------------------------------------------------------------------------- /code/src/Queue.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_HPP 2 | #define QUEUE_HPP 3 | 4 | #include "Node.hpp" 5 | #include "Environment.hpp" 6 | #include "Filter.hpp" 7 | #include 8 | 9 | class Queue { 10 | private: 11 | //push a node into the priority queue 12 | //return false iff this fails for any reason 13 | //pre-condition: our filters have already said this node is good 14 | //pre-condition: newNode.cost has already been set 15 | virtual bool pushNode(Node * newNode) = 0; 16 | 17 | protected: 18 | Node * bestFinalNode = 0; 19 | int numPushed=0,numFiltered=0,numPopped=0; 20 | 21 | public: 22 | virtual ~Queue() {}; 23 | 24 | virtual int setArgs(char** argv) { 25 | //used to set the queue's parameters via command-line 26 | //return number of args consumed 27 | 28 | return 0; 29 | } 30 | 31 | virtual int setArgs() { 32 | //used to set the queue's parameters via std::cin 33 | //return number of args consumed 34 | 35 | return 0; 36 | } 37 | 38 | //pop a node and return it 39 | virtual Node* pop() = 0; 40 | 41 | //return number of elements in queue 42 | virtual int size() = 0; 43 | 44 | //push a node into the priority queue 45 | //return false iff this fails for any reason 46 | //pre-condition: newNode.cost has already been set 47 | bool push(Node * newNode) { 48 | numPushed++; 49 | if(!newNode->env->filter(newNode)) { 50 | bool success = this->pushNode(newNode); 51 | if(success) { 52 | return true; 53 | } else { 54 | std::cerr << "WARNING: pushNode(Node*) failed somehow.\n"; 55 | return false; 56 | } 57 | } 58 | numFiltered++; 59 | return false; 60 | } 61 | 62 | inline Node * getBestFinalNode() { 63 | return bestFinalNode; 64 | } 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /data/min-depth/or_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 6 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 8 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 9 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[1] 10 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 11 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 12 | u3(0.000000, 0.000000, -1.570796) q[0]; //cycle: 3 //u3(0.000000, 0.000000, -1.570796) logical_q[2] 13 | cx q[2],q[1]; //cycle: 3 //cx logical_q[0],logical_q[1] 14 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 4 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 15 | cx q[0],q[2]; //cycle: 4 //cx logical_q[2],logical_q[0] 16 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 5 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 17 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[1] 18 | cx q[0],q[2]; //cycle: 6 //cx logical_q[2],logical_q[0] 19 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 20 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 7 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 21 | cx q[2],q[1]; //cycle: 7 //cx logical_q[0],logical_q[1] 22 | //17 original gates 23 | //17 final gates 24 | //8 original depth (cycles) 25 | //8 cycles in selected mapping 26 | //10 nodes expanded (popped from queue). 27 | //11 nodes remain in queue. 28 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/barenco_tof_5_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[9]; 5 | t q[5]; 6 | t q[6]; 7 | t q[7]; 8 | h q[8]; 9 | cx q[7],q[8]; 10 | tdg q[8]; 11 | cx q[4],q[8]; 12 | t q[8]; 13 | cx q[7],q[8]; 14 | cx q[4],q[7]; 15 | tdg q[7]; 16 | cx q[4],q[7]; 17 | h q[7]; 18 | cx q[6],q[7]; 19 | tdg q[7]; 20 | cx q[3],q[7]; 21 | t q[7]; 22 | cx q[6],q[7]; 23 | cx q[3],q[6]; 24 | tdg q[6]; 25 | cx q[3],q[6]; 26 | h q[6]; 27 | cx q[5],q[6]; 28 | tdg q[6]; 29 | cx q[2],q[6]; 30 | t q[6]; 31 | cx q[5],q[6]; 32 | cx q[2],q[5]; 33 | tdg q[5]; 34 | cx q[2],q[5]; 35 | h q[5]; 36 | cx q[1],q[5]; 37 | tdg q[5]; 38 | cx q[0],q[5]; 39 | t q[5]; 40 | cx q[1],q[5]; 41 | tdg q[5]; 42 | cx q[0],q[5]; 43 | t q[5]; 44 | h q[5]; 45 | cx q[5],q[6]; 46 | tdg q[6]; 47 | cx q[2],q[6]; 48 | t q[6]; 49 | cx q[5],q[6]; 50 | h q[6]; 51 | cx q[6],q[7]; 52 | tdg q[7]; 53 | cx q[3],q[7]; 54 | t q[7]; 55 | cx q[6],q[7]; 56 | h q[7]; 57 | cx q[7],q[8]; 58 | tdg q[8]; 59 | cx q[4],q[8]; 60 | t q[8]; 61 | cx q[7],q[8]; 62 | cx q[4],q[7]; 63 | h q[8]; 64 | t q[7]; 65 | cx q[4],q[7]; 66 | tdg q[7]; 67 | h q[7]; 68 | cx q[6],q[7]; 69 | tdg q[7]; 70 | cx q[3],q[7]; 71 | t q[7]; 72 | cx q[6],q[7]; 73 | h q[6]; 74 | cx q[5],q[6]; 75 | tdg q[6]; 76 | cx q[2],q[6]; 77 | t q[6]; 78 | cx q[5],q[6]; 79 | h q[5]; 80 | cx q[1],q[5]; 81 | t q[5]; 82 | cx q[0],q[5]; 83 | tdg q[5]; 84 | cx q[1],q[5]; 85 | t q[5]; 86 | cx q[0],q[5]; 87 | tdg q[5]; 88 | h q[5]; 89 | cx q[5],q[6]; 90 | tdg q[6]; 91 | cx q[2],q[6]; 92 | t q[6]; 93 | cx q[5],q[6]; 94 | cx q[2],q[5]; 95 | h q[6]; 96 | t q[5]; 97 | cx q[6],q[7]; 98 | cx q[2],q[5]; 99 | tdg q[7]; 100 | cx q[3],q[7]; 101 | tdg q[5]; 102 | t q[7]; 103 | cx q[6],q[7]; 104 | cx q[3],q[6]; 105 | h q[7]; 106 | t q[6]; 107 | cx q[3],q[6]; 108 | tdg q[6]; 109 | -------------------------------------------------------------------------------- /code/src/full_classes/QASMtoken.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | DD-based simulator by JKU Linz, Austria 3 | 4 | Developer: Alwin Zulehner, Robert Wille 5 | 6 | With code from the QMDD implementation provided by Michael Miller (University of Victoria, Canada) 7 | and Philipp Niemann (University of Bremen, Germany). 8 | 9 | For more information, please visit http://iic.jku.at/eda/research/quantum_simulation 10 | 11 | If you have any questions feel free to contact us using 12 | alwin.zulehner@jku.at or robert.wille@jku.at 13 | 14 | If you use the quantum simulator for your research, we would be thankful if you referred to it 15 | by citing the following publication: 16 | 17 | @article{zulehner2018simulation, 18 | title={Advanced Simulation of Quantum Computations}, 19 | author={Zulehner, Alwin and Wille, Robert}, 20 | journal={IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)}, 21 | year={2018}, 22 | eprint = {arXiv:1707.00865} 23 | } 24 | */ 25 | 26 | #ifndef TOKEN_H_ 27 | #define TOKEN_H_ 28 | 29 | #include 30 | #include 31 | 32 | class Token { 33 | public: 34 | 35 | enum class Kind {include, none, identifier, number, plus, semicolon, eof, lpar, rpar, lbrack, rbrack, lbrace, rbrace, comma, minus, times, nninteger, real, qreg, creg, ugate, cxgate, gate, pi, measure, openqasm, probabilities, sin, cos, tan, exp, ln, sqrt, div, power, string, gt, barrier, opaque, _if, eq, reset, snapshot, swapgate}; 36 | 37 | Token(Kind kind, int line, int col) { 38 | this->kind = kind; 39 | this->line = line; 40 | this->col = col; 41 | this->val = 0; 42 | this->valReal = 0.0; 43 | } 44 | 45 | Token() : Token(Kind::none, 0, 0) { 46 | } 47 | 48 | static std::map KindNames; 49 | Kind kind; 50 | int line; 51 | int col; 52 | int val; 53 | double valReal; 54 | std::string str; 55 | 56 | }; 57 | 58 | #endif /* TOKEN_H_ */ 59 | -------------------------------------------------------------------------------- /data/min-gates/4mod5-v1_22_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[3],q[4]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[2],q[1]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 9 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | swp q[2],q[4]; //cycle: 2 12 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 13 | cx q[2],q[1]; //cycle: 3 //cx logical_q[3],logical_q[2] 14 | cx q[0],q[2]; //cycle: 4 //cx logical_q[4],logical_q[3] 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 5 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[1],q[0]; //cycle: 5 //cx logical_q[2],logical_q[4] 17 | cx q[1],q[2]; //cycle: 6 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 21 | cx q[0],q[2]; //cycle: 8 //cx logical_q[4],logical_q[3] 22 | cx q[1],q[0]; //cycle: 9 //cx logical_q[2],logical_q[4] 23 | cx q[2],q[1]; //cycle: 10 //cx logical_q[3],logical_q[2] 24 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 25 | cx q[1],q[2]; //cycle: 11 //cx logical_q[2],logical_q[3] 26 | cx q[2],q[0]; //cycle: 12 //cx logical_q[3],logical_q[4] 27 | //21 original gates 28 | //22 final gates 29 | //1101 nodes expanded (popped from queue). 30 | //906 nodes remain in queue. 31 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/16QBT_15CYC_TFL_1.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | x q[15]; 5 | x q[5]; 6 | x q[2]; 7 | cx q[13], q[10]; 8 | x q[15]; 9 | x q[11]; 10 | cx q[14], q[8]; 11 | cx q[6], q[7]; 12 | cx q[10], q[4]; 13 | cx q[5], q[3]; 14 | x q[15]; 15 | x q[1]; 16 | x q[14]; 17 | x q[8]; 18 | x q[11]; 19 | cx q[9], q[0]; 20 | x q[15]; 21 | x q[13]; 22 | x q[5]; 23 | x q[1]; 24 | cx q[4], q[11]; 25 | cx q[10], q[2]; 26 | x q[15]; 27 | x q[6]; 28 | x q[10]; 29 | x q[9]; 30 | x q[13]; 31 | cx q[2], q[12]; 32 | cx q[0], q[8]; 33 | cx q[11], q[7]; 34 | cx q[14], q[4]; 35 | cx q[1], q[5]; 36 | x q[15]; 37 | x q[7]; 38 | x q[13]; 39 | x q[9]; 40 | x q[2]; 41 | cx q[1], q[5]; 42 | cx q[4], q[11]; 43 | x q[3]; 44 | x q[13]; 45 | x q[8]; 46 | cx q[15], q[6]; 47 | cx q[9], q[0]; 48 | cx q[1], q[5]; 49 | cx q[4], q[11]; 50 | x q[2]; 51 | x q[6]; 52 | x q[10]; 53 | x q[13]; 54 | cx q[12], q[15]; 55 | cx q[5], q[3]; 56 | cx q[0], q[8]; 57 | cx q[14], q[4]; 58 | cx q[11], q[7]; 59 | x q[15]; 60 | x q[6]; 61 | x q[12]; 62 | x q[2]; 63 | x q[1]; 64 | cx q[14], q[8]; 65 | cx q[4], q[11]; 66 | cx q[9], q[0]; 67 | x q[9]; 68 | x q[11]; 69 | x q[13]; 70 | x q[4]; 71 | x q[8]; 72 | x q[12]; 73 | x q[2]; 74 | x q[10]; 75 | x q[0]; 76 | cx q[15], q[6]; 77 | cx q[1], q[5]; 78 | x q[5]; 79 | x q[8]; 80 | x q[2]; 81 | cx q[12], q[15]; 82 | cx q[13], q[10]; 83 | cx q[6], q[7]; 84 | cx q[4], q[11]; 85 | x q[1]; 86 | x q[13]; 87 | x q[8]; 88 | x q[4]; 89 | cx q[12], q[15]; 90 | cx q[5], q[3]; 91 | cx q[9], q[0]; 92 | x q[15]; 93 | x q[5]; 94 | cx q[0], q[8]; 95 | cx q[1], q[9]; 96 | cx q[13], q[10]; 97 | cx q[4], q[11]; 98 | cx q[2], q[12]; 99 | x q[15]; 100 | x q[14]; 101 | x q[2]; 102 | x q[5]; 103 | x q[3]; 104 | cx q[10], q[4]; 105 | cx q[11], q[7]; 106 | x q[15]; 107 | x q[11]; 108 | x q[6]; 109 | x q[4]; 110 | x q[0]; 111 | x q[8]; 112 | cx q[5], q[3]; 113 | -------------------------------------------------------------------------------- /data/min-gates/4mod5-v1_22_2x3.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[6]; 4 | creg c[6]; 5 | cx q[0],q[2]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[5],q[4]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 9 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | cx q[2],q[4]; //cycle: 2 //cx logical_q[3],logical_q[2] 13 | cx q[3],q[2]; //cycle: 3 //cx logical_q[4],logical_q[3] 14 | swp q[2],q[4]; //cycle: 4 15 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 5 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[2],q[3]; //cycle: 5 //cx logical_q[2],logical_q[4] 17 | cx q[2],q[4]; //cycle: 6 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 21 | swp q[2],q[3]; //cycle: 8 22 | cx q[2],q[4]; //cycle: 9 //cx logical_q[4],logical_q[3] 23 | cx q[3],q[2]; //cycle: 10 //cx logical_q[2],logical_q[4] 24 | swp q[3],q[5]; //cycle: 11 25 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 11 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 26 | cx q[4],q[5]; //cycle: 12 //cx logical_q[3],logical_q[2] 27 | cx q[5],q[4]; //cycle: 13 //cx logical_q[2],logical_q[3] 28 | cx q[4],q[2]; //cycle: 14 //cx logical_q[3],logical_q[4] 29 | //21 original gates 30 | //24 final gates 31 | //5778 nodes expanded (popped). 32 | //5888 nodes remain in queue. 33 | -------------------------------------------------------------------------------- /data/min-gates/4mod5-v1_22_2x4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[8]; 4 | creg c[8]; 5 | cx q[6],q[4]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[3],q[2]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 9 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[5]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | cx q[4],q[2]; //cycle: 2 //cx logical_q[3],logical_q[2] 13 | cx q[5],q[4]; //cycle: 3 //cx logical_q[4],logical_q[3] 14 | swp q[2],q[4]; //cycle: 4 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 5 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[4],q[5]; //cycle: 5 //cx logical_q[2],logical_q[4] 17 | cx q[4],q[2]; //cycle: 6 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[5]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | swp q[4],q[5]; //cycle: 7 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[5]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | cx q[4],q[2]; //cycle: 8 //cx logical_q[4],logical_q[3] 23 | cx q[5],q[4]; //cycle: 9 //cx logical_q[2],logical_q[4] 24 | swp q[3],q[5]; //cycle: 10 25 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 26 | cx q[2],q[3]; //cycle: 11 //cx logical_q[3],logical_q[2] 27 | cx q[3],q[2]; //cycle: 12 //cx logical_q[2],logical_q[3] 28 | cx q[2],q[4]; //cycle: 13 //cx logical_q[3],logical_q[4] 29 | //21 original gates 30 | //24 final gates 31 | //34340 nodes expanded (popped from queue). 32 | //54550 nodes remain in queue. 33 | -------------------------------------------------------------------------------- /data/min-depth/4mod5-v1_22_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | cx q[1],q[0]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[2],q[3]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | swp q[0],q[2]; //cycle: 1 9 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 4 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 13 | cx q[2],q[3]; //cycle: 5 //cx logical_q[3],logical_q[2] 14 | cx q[4],q[2]; //cycle: 6 //cx logical_q[4],logical_q[3] 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[3],q[4]; //cycle: 7 //cx logical_q[2],logical_q[4] 17 | cx q[3],q[2]; //cycle: 8 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 8 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 9 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 9 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 21 | cx q[4],q[2]; //cycle: 10 //cx logical_q[4],logical_q[3] 22 | cx q[3],q[4]; //cycle: 11 //cx logical_q[2],logical_q[4] 23 | cx q[2],q[3]; //cycle: 12 //cx logical_q[3],logical_q[2] 24 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 12 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 25 | cx q[3],q[2]; //cycle: 13 //cx logical_q[2],logical_q[3] 26 | cx q[2],q[4]; //cycle: 14 //cx logical_q[3],logical_q[4] 27 | //21 original gates 28 | //22 final gates 29 | //12 original depth (cycles) 30 | //15 cycles in selected mapping 31 | //26392 nodes expanded (popped from queue). 32 | //159 nodes remain in queue. 33 | -------------------------------------------------------------------------------- /data/min-depth/4mod5-v1_22_2x3.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[6]; 4 | creg c[6]; 5 | cx q[1],q[3]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[0],q[2]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 9 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[5]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[3],logical_q[2] 13 | cx q[5],q[3]; //cycle: 3 //cx logical_q[4],logical_q[3] 14 | swp q[4],q[5]; //cycle: 4 15 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 4 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[2],q[4]; //cycle: 7 //cx logical_q[2],logical_q[4] 17 | cx q[2],q[3]; //cycle: 8 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 8 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | swp q[2],q[4]; //cycle: 9 20 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 9 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 12 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | cx q[2],q[3]; //cycle: 12 //cx logical_q[4],logical_q[3] 23 | cx q[4],q[2]; //cycle: 13 //cx logical_q[2],logical_q[4] 24 | swp q[4],q[5]; //cycle: 14 25 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 14 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 26 | cx q[3],q[5]; //cycle: 17 //cx logical_q[3],logical_q[2] 27 | cx q[5],q[3]; //cycle: 18 //cx logical_q[2],logical_q[3] 28 | cx q[3],q[2]; //cycle: 19 //cx logical_q[3],logical_q[4] 29 | //21 original gates 30 | //24 final gates 31 | //12 original depth (cycles) 32 | //20 cycles in selected mapping 33 | //1731 nodes expanded (popped from queue). 34 | //1640 nodes remain in queue. 35 | -------------------------------------------------------------------------------- /code/src/full_classes/Environment.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENVIRONMENT_HPP 2 | #define ENVIRONMENT_HPP 3 | 4 | class GateNode; 5 | class CostFunc; 6 | class Latency; 7 | #include "Filter.hpp" 8 | #include "NodeMod.hpp" 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | class Environment {//for data shared across all nodes 14 | public: 15 | vector nodeMods; 16 | vector filters; 17 | CostFunc * cost;//contains function to calculate a node's cost 18 | Latency * latency;//contains function to calculate a gate's latency 19 | set > couplings; //the coupling map (as a list of qubit-pairs) 20 | GateNode ** possibleSwaps; 21 | 22 | int numLogicalQubits; 23 | int numPhysicalQubits; 24 | int * couplingDistances;//array of size (numPhysicalQubits*numPhysicalQubits) 25 | int swapCost; //should be set by main using the latency function 26 | int numGates; 27 | 28 | GateNode ** firstCXPerQubit = 0; 29 | 30 | void runNodeModifiers(Node * node, int flag) { 31 | for(unsigned int x = 0; x < this->nodeMods.size(); x++) { 32 | this->nodeMods[x]->mod(node, flag); 33 | } 34 | } 35 | 36 | bool filter(Node * newNode) { 37 | for(unsigned int x = 0; x < this->filters.size(); x++) { 38 | if(this->filters[x]->filter(newNode)) { 39 | for(unsigned int y = 0; y < x; y++) { 40 | this->filters[y]->deleteRecord(newNode); 41 | } 42 | return true; 43 | } 44 | } 45 | 46 | return false; 47 | } 48 | 49 | void deleteRecord(Node * oldNode) { 50 | for(unsigned int x = 0; x < this->filters.size(); x++) { 51 | this->filters[x]->deleteRecord(oldNode); 52 | } 53 | } 54 | 55 | void resetFilters() { 56 | for(unsigned int x = 0; x < this->filters.size(); x++) { 57 | Filter * old = this->filters[x]; 58 | this->filters[x] = old->createEmptyCopy(); 59 | delete old; 60 | } 61 | } 62 | 63 | void printFilterStats(std::ostream & stream) { 64 | for(unsigned int x = 0; x < this->filters.size(); x++) { 65 | this->filters[x]->printStatistics(stream); 66 | } 67 | } 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /data/min-depth/4mod5-v1_22_2x4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[8]; 4 | creg c[8]; 5 | cx q[1],q[3]; //cycle: 0 //cx logical_q[1],logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | cx q[0],q[2]; //cycle: 0 //cx logical_q[0],logical_q[2] 8 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 9 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 10 | u3(1.570796, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[5]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[3],logical_q[2] 13 | cx q[5],q[3]; //cycle: 3 //cx logical_q[4],logical_q[3] 14 | swp q[2],q[3]; //cycle: 4 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 16 | cx q[3],q[5]; //cycle: 7 //cx logical_q[2],logical_q[4] 17 | cx q[3],q[2]; //cycle: 8 //cx logical_q[2],logical_q[3] 18 | u3(0.000000, 0.000000, 0.785398) q[5]; //cycle: 8 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | swp q[3],q[5]; //cycle: 9 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 9 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[5]; //cycle: 12 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | cx q[3],q[2]; //cycle: 12 //cx logical_q[4],logical_q[3] 23 | swp q[2],q[4]; //cycle: 13 24 | cx q[5],q[3]; //cycle: 13 //cx logical_q[2],logical_q[4] 25 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 14 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 26 | swp q[2],q[3]; //cycle: 16 27 | cx q[4],q[5]; //cycle: 16 //cx logical_q[3],logical_q[2] 28 | cx q[5],q[4]; //cycle: 17 //cx logical_q[2],logical_q[3] 29 | cx q[4],q[2]; //cycle: 19 //cx logical_q[3],logical_q[4] 30 | //21 original gates 31 | //25 final gates 32 | //12 original depth (cycles) 33 | //20 cycles in selected mapping 34 | //2746 nodes expanded (popped from queue). 35 | //3948 nodes remain in queue. 36 | -------------------------------------------------------------------------------- /data/min-gates/qaoa5_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 6 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 7 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 8 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[1] 9 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 10 | cx q[4],q[3]; //cycle: 1 //cx logical_q[0],logical_q[1] 11 | u3(0.000000, 0.000000, 1.571000) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 1.571000) logical_q[1] 12 | cx q[4],q[3]; //cycle: 3 //cx logical_q[0],logical_q[1] 13 | u3(2.356000, -1.570796, 1.570796) q[4]; //cycle: 4 //u3(2.356000, -1.570796, 1.570796) logical_q[0] 14 | cx q[3],q[2]; //cycle: 4 //cx logical_q[1],logical_q[2] 15 | u3(0.000000, 0.000000, 1.571000) q[2]; //cycle: 5 //u3(0.000000, 0.000000, 1.571000) logical_q[2] 16 | cx q[3],q[2]; //cycle: 6 //cx logical_q[1],logical_q[2] 17 | cx q[2],q[0]; //cycle: 7 //cx logical_q[2],logical_q[3] 18 | u3(2.356000, -1.570796, 1.570796) q[3]; //cycle: 7 //u3(2.356000, -1.570796, 1.570796) logical_q[1] 19 | u3(0.000000, 0.000000, 1.571000) q[0]; //cycle: 8 //u3(0.000000, 0.000000, 1.571000) logical_q[3] 20 | cx q[2],q[0]; //cycle: 9 //cx logical_q[2],logical_q[3] 21 | u3(2.356000, -1.570796, 1.570796) q[2]; //cycle: 10 //u3(2.356000, -1.570796, 1.570796) logical_q[2] 22 | cx q[0],q[1]; //cycle: 10 //cx logical_q[3],logical_q[4] 23 | u3(0.000000, 0.000000, 1.571000) q[1]; //cycle: 11 //u3(0.000000, 0.000000, 1.571000) logical_q[4] 24 | cx q[0],q[1]; //cycle: 12 //cx logical_q[3],logical_q[4] 25 | u3(2.356000, -1.570796, 1.570796) q[1]; //cycle: 13 //u3(2.356000, -1.570796, 1.570796) logical_q[4] 26 | u3(2.356000, -1.570796, 1.570796) q[0]; //cycle: 13 //u3(2.356000, -1.570796, 1.570796) logical_q[3] 27 | //22 original gates 28 | //22 final gates 29 | //37 nodes expanded (popped from queue). 30 | //14 nodes remain in queue. 31 | -------------------------------------------------------------------------------- /code/src/full_classes/QASMscanner.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | DD-based simulator by JKU Linz, Austria 3 | 4 | Developer: Alwin Zulehner, Robert Wille 5 | 6 | With code from the QMDD implementation provided by Michael Miller (University of Victoria, Canada) 7 | and Philipp Niemann (University of Bremen, Germany). 8 | 9 | For more information, please visit http://iic.jku.at/eda/research/quantum_simulation 10 | 11 | If you have any questions feel free to contact us using 12 | alwin.zulehner@jku.at or robert.wille@jku.at 13 | 14 | If you use the quantum simulator for your research, we would be thankful if you referred to it 15 | by citing the following publication: 16 | 17 | @article{zulehner2018simulation, 18 | title={Advanced Simulation of Quantum Computations}, 19 | author={Zulehner, Alwin and Wille, Robert}, 20 | journal={IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)}, 21 | year={2018}, 22 | eprint = {arXiv:1707.00865} 23 | } 24 | */ 25 | 26 | #ifndef QASMSCANNER_HPP_ 27 | #define QASMSCANNER_HPP_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "QASMtoken.hpp" 36 | #include 37 | #include 38 | 39 | 40 | class QASMscanner { 41 | 42 | 43 | public: 44 | QASMscanner(std::istream& in_stream); 45 | Token next(); 46 | void addFileInput(std::string fname); 47 | 48 | private: 49 | std::istream& in; 50 | std::stack streams; 51 | char ch; 52 | std::map keywords; 53 | int line; 54 | int col; 55 | void nextCh(); 56 | void readName(Token& t); 57 | void readNumber(Token& t); 58 | void readString(Token& t); 59 | void skipComment(); 60 | 61 | class LineInfo { 62 | public: 63 | char ch; 64 | int line, col; 65 | 66 | LineInfo(char ch, int line, int col) { 67 | this->ch = ch; 68 | this->line = line; 69 | this->col = col; 70 | } 71 | }; 72 | 73 | std::stack lines; 74 | 75 | }; 76 | 77 | #endif /* QASMSCANNER_HPP_ */ 78 | -------------------------------------------------------------------------------- /data/min-gates/adder_2x3.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[6]; 4 | creg c[6]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[0],q[1]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[1],q[3]; //cycle: 4 //cx logical_q[3],logical_q[0] 16 | cx q[2],q[0]; //cycle: 4 //cx logical_q[1],logical_q[2] 17 | cx q[3],q[2]; //cycle: 5 //cx logical_q[0],logical_q[1] 18 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[3] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 20 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 23 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[1] 24 | cx q[0],q[1]; //cycle: 7 //cx logical_q[2],logical_q[3] 25 | u3(0.000000, 0.000000, 1.570796) q[1]; //cycle: 8 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 26 | cx q[1],q[3]; //cycle: 9 //cx logical_q[3],logical_q[0] 27 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 28 | //23 original gates 29 | //23 final gates 30 | //18 nodes expanded (popped from queue). 31 | //19 nodes remain in queue. 32 | -------------------------------------------------------------------------------- /data/min-gates/adder_2x4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[8]; 4 | creg c[8]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[0],q[1]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[1],q[3]; //cycle: 4 //cx logical_q[3],logical_q[0] 16 | cx q[2],q[0]; //cycle: 4 //cx logical_q[1],logical_q[2] 17 | cx q[3],q[2]; //cycle: 5 //cx logical_q[0],logical_q[1] 18 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[3] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 20 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 23 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[1] 24 | cx q[0],q[1]; //cycle: 7 //cx logical_q[2],logical_q[3] 25 | u3(0.000000, 0.000000, 1.570796) q[1]; //cycle: 8 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 26 | cx q[1],q[3]; //cycle: 9 //cx logical_q[3],logical_q[0] 27 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 28 | //23 original gates 29 | //23 final gates 30 | //70 nodes expanded (popped from queue). 31 | //21 nodes remain in queue. 32 | -------------------------------------------------------------------------------- /data/min-gates/adder_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[2],q[3]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[1],q[0]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[2],q[3]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[0],q[2]; //cycle: 4 //cx logical_q[1],logical_q[2] 16 | swp q[2],q[3]; //cycle: 5 17 | cx q[2],q[1]; //cycle: 6 //cx logical_q[3],logical_q[0] 18 | cx q[1],q[0]; //cycle: 7 //cx logical_q[0],logical_q[1] 19 | cx q[3],q[2]; //cycle: 7 //cx logical_q[2],logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 21 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 8 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 22 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 23 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 24 | cx q[1],q[0]; //cycle: 9 //cx logical_q[0],logical_q[1] 25 | cx q[3],q[2]; //cycle: 9 //cx logical_q[2],logical_q[3] 26 | u3(0.000000, 0.000000, 1.570796) q[2]; //cycle: 10 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 27 | cx q[2],q[1]; //cycle: 11 //cx logical_q[3],logical_q[0] 28 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 12 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 29 | //23 original gates 30 | //24 final gates 31 | //757 nodes expanded (popped). 32 | //901 nodes remain in queue. 33 | -------------------------------------------------------------------------------- /data/min-depth/qaoa5_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 6 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[2] 7 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 8 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[1] 9 | u3(1.570796, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 10 | cx q[4],q[3]; //cycle: 1 //cx logical_q[0],logical_q[1] 11 | u3(0.000000, 0.000000, 1.571000) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 1.571000) logical_q[1] 12 | cx q[4],q[3]; //cycle: 3 //cx logical_q[0],logical_q[1] 13 | u3(2.356000, -1.570796, 1.570796) q[4]; //cycle: 4 //u3(2.356000, -1.570796, 1.570796) logical_q[0] 14 | cx q[3],q[2]; //cycle: 4 //cx logical_q[1],logical_q[2] 15 | u3(0.000000, 0.000000, 1.571000) q[2]; //cycle: 5 //u3(0.000000, 0.000000, 1.571000) logical_q[2] 16 | cx q[3],q[2]; //cycle: 6 //cx logical_q[1],logical_q[2] 17 | cx q[2],q[0]; //cycle: 7 //cx logical_q[2],logical_q[3] 18 | u3(2.356000, -1.570796, 1.570796) q[3]; //cycle: 7 //u3(2.356000, -1.570796, 1.570796) logical_q[1] 19 | u3(0.000000, 0.000000, 1.571000) q[0]; //cycle: 8 //u3(0.000000, 0.000000, 1.571000) logical_q[3] 20 | cx q[2],q[0]; //cycle: 9 //cx logical_q[2],logical_q[3] 21 | u3(2.356000, -1.570796, 1.570796) q[2]; //cycle: 10 //u3(2.356000, -1.570796, 1.570796) logical_q[2] 22 | cx q[0],q[1]; //cycle: 10 //cx logical_q[3],logical_q[4] 23 | u3(0.000000, 0.000000, 1.571000) q[1]; //cycle: 11 //u3(0.000000, 0.000000, 1.571000) logical_q[4] 24 | cx q[0],q[1]; //cycle: 12 //cx logical_q[3],logical_q[4] 25 | u3(2.356000, -1.570796, 1.570796) q[1]; //cycle: 13 //u3(2.356000, -1.570796, 1.570796) logical_q[4] 26 | u3(2.356000, -1.570796, 1.570796) q[0]; //cycle: 13 //u3(2.356000, -1.570796, 1.570796) logical_q[3] 27 | //22 original gates 28 | //22 final gates 29 | //14 original depth (cycles) 30 | //14 cycles in selected mapping 31 | //37 nodes expanded (popped from queue). 32 | //14 nodes remain in queue. 33 | -------------------------------------------------------------------------------- /data/min-depth/adder_2x3.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[6]; 4 | creg c[6]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[0],q[1]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[1],q[3]; //cycle: 4 //cx logical_q[3],logical_q[0] 16 | cx q[2],q[0]; //cycle: 4 //cx logical_q[1],logical_q[2] 17 | cx q[3],q[2]; //cycle: 5 //cx logical_q[0],logical_q[1] 18 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[3] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 20 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 23 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[1] 24 | cx q[0],q[1]; //cycle: 7 //cx logical_q[2],logical_q[3] 25 | u3(0.000000, 0.000000, 1.570796) q[1]; //cycle: 8 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 26 | cx q[1],q[3]; //cycle: 9 //cx logical_q[3],logical_q[0] 27 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 28 | //23 original gates 29 | //23 final gates 30 | //11 original depth (cycles) 31 | //11 cycles in selected mapping 32 | //18 nodes expanded (popped from queue). 33 | //19 nodes remain in queue. 34 | -------------------------------------------------------------------------------- /data/min-depth/adder_2x4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[8]; 4 | creg c[8]; 5 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[3],q[2]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[0],q[1]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[1],q[3]; //cycle: 4 //cx logical_q[3],logical_q[0] 16 | cx q[2],q[0]; //cycle: 4 //cx logical_q[1],logical_q[2] 17 | cx q[3],q[2]; //cycle: 5 //cx logical_q[0],logical_q[1] 18 | cx q[0],q[1]; //cycle: 5 //cx logical_q[2],logical_q[3] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 20 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 21 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 22 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 23 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[1] 24 | cx q[0],q[1]; //cycle: 7 //cx logical_q[2],logical_q[3] 25 | u3(0.000000, 0.000000, 1.570796) q[1]; //cycle: 8 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 26 | cx q[1],q[3]; //cycle: 9 //cx logical_q[3],logical_q[0] 27 | u3(1.570796, 0.000000, 3.141593) q[1]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 28 | //23 original gates 29 | //23 final gates 30 | //11 original depth (cycles) 31 | //11 cycles in selected mapping 32 | //70 nodes expanded (popped from queue). 33 | //21 nodes remain in queue. 34 | -------------------------------------------------------------------------------- /data/min-depth/adder_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 6 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 7 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 9 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 10 | cx q[2],q[3]; //cycle: 1 //cx logical_q[2],logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 12 | cx q[0],q[1]; //cycle: 2 //cx logical_q[0],logical_q[1] 13 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 14 | cx q[2],q[3]; //cycle: 3 //cx logical_q[2],logical_q[3] 15 | cx q[1],q[2]; //cycle: 4 //cx logical_q[1],logical_q[2] 16 | swp q[2],q[3]; //cycle: 5 17 | cx q[2],q[0]; //cycle: 8 //cx logical_q[3],logical_q[0] 18 | cx q[0],q[1]; //cycle: 9 //cx logical_q[0],logical_q[1] 19 | cx q[3],q[2]; //cycle: 9 //cx logical_q[2],logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 10 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 21 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 10 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 22 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 10 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 23 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 10 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 24 | cx q[0],q[1]; //cycle: 11 //cx logical_q[0],logical_q[1] 25 | cx q[3],q[2]; //cycle: 11 //cx logical_q[2],logical_q[3] 26 | u3(0.000000, 0.000000, 1.570796) q[2]; //cycle: 12 //u3(0.000000, 0.000000, 1.570796) logical_q[3] 27 | cx q[2],q[0]; //cycle: 13 //cx logical_q[3],logical_q[0] 28 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 14 //u3(1.570796, 0.000000, 3.141593) logical_q[3] 29 | //23 original gates 30 | //24 final gates 31 | //11 original depth (cycles) 32 | //15 cycles in selected mapping 33 | //90 nodes expanded (popped from queue). 34 | //221 nodes remain in queue. 35 | -------------------------------------------------------------------------------- /code/src/full_classes/QASMtoken.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | DD-based simulator by JKU Linz, Austria 3 | 4 | Developer: Alwin Zulehner, Robert Wille 5 | 6 | With code from the QMDD implementation provided by Michael Miller (University of Victoria, Canada) 7 | and Philipp Niemann (University of Bremen, Germany). 8 | 9 | For more information, please visit http://iic.jku.at/eda/research/quantum_simulation 10 | 11 | If you have any questions feel free to contact us using 12 | alwin.zulehner@jku.at or robert.wille@jku.at 13 | 14 | If you use the quantum simulator for your research, we would be thankful if you referred to it 15 | by citing the following publication: 16 | 17 | @article{zulehner2018simulation, 18 | title={Advanced Simulation of Quantum Computations}, 19 | author={Zulehner, Alwin and Wille, Robert}, 20 | journal={IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)}, 21 | year={2018}, 22 | eprint = {arXiv:1707.00865} 23 | } 24 | */ 25 | 26 | #include 27 | 28 | std::map Token::KindNames = { 29 | {Kind::none,"none"}, 30 | {Kind::include,"include"}, 31 | {Kind::identifier,""}, 32 | {Kind::number,""}, 33 | {Kind::plus,"+"}, 34 | {Kind::semicolon,";"}, 35 | {Kind::eof,"EOF"}, 36 | {Kind::lpar,"("}, 37 | {Kind::rpar,")"}, 38 | {Kind::lbrack,"["}, 39 | {Kind::rbrack,"]"}, 40 | {Kind::lbrace,"{"}, 41 | {Kind::rbrace,"}"}, 42 | {Kind::comma,","}, 43 | {Kind::minus,"-"}, 44 | {Kind::times,"*"}, 45 | {Kind::nninteger,""}, 46 | {Kind::real,""}, 47 | {Kind::qreg,"qreg"}, 48 | {Kind::creg,"creg"}, 49 | {Kind::ugate,"U"}, 50 | {Kind::cxgate,"CX"}, 51 | {Kind::gate,"gate"}, 52 | {Kind::pi,"pi"}, 53 | {Kind::measure,"measure"}, 54 | {Kind::openqasm,"openqasm"}, 55 | {Kind::probabilities,"probabilities"}, 56 | {Kind::opaque,"opaque"}, 57 | {Kind::sin,"sin"}, 58 | {Kind::cos,"cos"}, 59 | {Kind::tan,"tan"}, 60 | {Kind::exp,"exp"}, 61 | {Kind::ln,"ln"}, 62 | {Kind::sqrt,"sqrt"}, 63 | {Kind::div,"/"}, 64 | {Kind::power,"^"}, 65 | {Kind::string,"string"}, 66 | {Kind::gt,">"}, 67 | {Kind::barrier,"barrier"}, 68 | {Kind::_if,"if"}, 69 | {Kind::eq,"=="}, 70 | {Kind::reset,"reset"}, 71 | {Kind::swapgate,"SWP"} 72 | }; 73 | -------------------------------------------------------------------------------- /code/circuits/OLSQ/rc_adder_6_after_heavy.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | 4 | qreg q[14]; 5 | cx q[4],q[3]; 6 | cx q[6],q[5]; 7 | cx q[8],q[7]; 8 | cx q[10],q[9]; 9 | cx q[12],q[11]; 10 | cx q[4],q[2]; 11 | t q[11]; 12 | h q[2]; 13 | cx q[6],q[4]; 14 | cx q[1],q[2]; 15 | h q[4]; 16 | cx q[8],q[6]; 17 | tdg q[2]; 18 | cx q[3],q[4]; 19 | h q[6]; 20 | cx q[10],q[8]; 21 | cx q[0],q[2]; 22 | tdg q[4]; 23 | cx q[5],q[6]; 24 | h q[8]; 25 | cx q[12],q[10]; 26 | t q[2]; 27 | tdg q[6]; 28 | cx q[7],q[8]; 29 | h q[10]; 30 | cx q[12],q[13]; 31 | cx q[1],q[2]; 32 | tdg q[8]; 33 | cx q[9],q[10]; 34 | h q[13]; 35 | tdg q[2]; 36 | tdg q[10]; 37 | cx q[11],q[13]; 38 | cx q[0],q[2]; 39 | tdg q[13]; 40 | t q[2]; 41 | h q[2]; 42 | cx q[2],q[4]; 43 | t q[4]; 44 | cx q[3],q[4]; 45 | tdg q[4]; 46 | cx q[2],q[4]; 47 | cx q[2],q[3]; 48 | t q[4]; 49 | h q[4]; 50 | cx q[4],q[6]; 51 | t q[6]; 52 | cx q[5],q[6]; 53 | tdg q[6]; 54 | cx q[4],q[6]; 55 | cx q[4],q[5]; 56 | t q[6]; 57 | h q[6]; 58 | cx q[6],q[8]; 59 | t q[8]; 60 | cx q[7],q[8]; 61 | tdg q[8]; 62 | cx q[6],q[8]; 63 | cx q[6],q[7]; 64 | t q[8]; 65 | h q[8]; 66 | cx q[8],q[10]; 67 | t q[10]; 68 | cx q[9],q[10]; 69 | tdg q[10]; 70 | cx q[8],q[10]; 71 | cx q[8],q[9]; 72 | t q[10]; 73 | h q[10]; 74 | t q[10]; 75 | cx q[10],q[13]; 76 | t q[13]; 77 | cx q[11],q[13]; 78 | tdg q[13]; 79 | cx q[10],q[13]; 80 | cx q[10],q[11]; 81 | t q[13]; 82 | h q[10]; 83 | tdg q[11]; 84 | h q[13]; 85 | cx q[8],q[10]; 86 | t q[10]; 87 | cx q[9],q[10]; 88 | t q[10]; 89 | cx q[8],q[10]; 90 | h q[8]; 91 | tdg q[10]; 92 | cx q[6],q[8]; 93 | cx q[9],q[10]; 94 | t q[8]; 95 | tdg q[10]; 96 | cx q[7],q[8]; 97 | h q[10]; 98 | t q[8]; 99 | cx q[12],q[10]; 100 | cx q[6],q[8]; 101 | cx q[12],q[11]; 102 | h q[6]; 103 | tdg q[8]; 104 | cx q[4],q[6]; 105 | cx q[7],q[8]; 106 | t q[6]; 107 | tdg q[8]; 108 | cx q[5],q[6]; 109 | h q[8]; 110 | t q[6]; 111 | cx q[10],q[8]; 112 | cx q[4],q[6]; 113 | cx q[10],q[9]; 114 | h q[4]; 115 | tdg q[6]; 116 | cx q[2],q[4]; 117 | cx q[5],q[6]; 118 | t q[4]; 119 | tdg q[6]; 120 | cx q[3],q[4]; 121 | h q[6]; 122 | t q[4]; 123 | cx q[8],q[6]; 124 | cx q[2],q[4]; 125 | cx q[8],q[7]; 126 | h q[2]; 127 | tdg q[4]; 128 | cx q[1],q[2]; 129 | cx q[3],q[4]; 130 | t q[2]; 131 | tdg q[4]; 132 | cx q[0],q[2]; 133 | h q[4]; 134 | tdg q[2]; 135 | cx q[6],q[4]; 136 | cx q[1],q[2]; 137 | cx q[6],q[5]; 138 | t q[2]; 139 | cx q[0],q[2]; 140 | cx q[1],q[0]; 141 | tdg q[2]; 142 | h q[2]; 143 | cx q[4],q[2]; 144 | cx q[4],q[3]; 145 | -------------------------------------------------------------------------------- /code/qelib1.inc: -------------------------------------------------------------------------------- 1 | // Quantum Experience (QE) Standard Header 2 | // file: qelib1.inc 3 | 4 | // --- QE Hardware primitives --- 5 | 6 | // 3-parameter 2-pulse single qubit gate 7 | gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; } 8 | // 2-parameter 1-pulse single qubit gate 9 | gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; } 10 | // 1-parameter 0-pulse single qubit gate 11 | gate u1(lambda) q { U(0,0,lambda) q; } 12 | // controlled-NOT 13 | gate cx c,t { CX c,t; } 14 | // idle gate (identity) 15 | gate id a { U(0,0,0) a; } 16 | 17 | // --- QE Standard Gates --- 18 | 19 | // Pauli gate: bit-flip 20 | gate x a { u3(pi,0,pi) a; } 21 | // Pauli gate: bit and phase flip 22 | gate y a { u3(pi,pi/2,pi/2) a; } 23 | // Pauli gate: phase flip 24 | gate z a { u1(pi) a; } 25 | // Clifford gate: Hadamard 26 | gate h a { u2(0,pi) a; } 27 | // Clifford gate: sqrt(Z) phase gate 28 | gate s a { u1(pi/2) a; } 29 | // Clifford gate: conjugate of sqrt(Z) 30 | gate sdg a { u1(-pi/2) a; } 31 | // C3 gate: sqrt(S) phase gate 32 | gate t a { u1(pi/4) a; } 33 | // C3 gate: conjugate of sqrt(S) 34 | gate tdg a { u1(-pi/4) a; } 35 | 36 | // --- Standard rotations --- 37 | // Rotation around X-axis 38 | gate rx(theta) a { u3(theta,-pi/2,pi/2) a; } 39 | // rotation around Y-axis 40 | gate ry(theta) a { u3(theta,0,0) a; } 41 | // rotation around Z axis 42 | gate rz(phi) a { u1(phi) a; } 43 | 44 | // --- QE Standard User-Defined Gates --- 45 | 46 | // controlled-Phase 47 | gate cz a,b { h b; cx a,b; h b; } 48 | // controlled-Y 49 | gate cy a,b { sdg b; cx a,b; s b; } 50 | // controlled-H 51 | gate ch a,b { 52 | h b; sdg b; 53 | cx a,b; 54 | h b; t b; 55 | cx a,b; 56 | t b; h b; s b; x b; s a; 57 | } 58 | // C3 gate: Toffoli 59 | gate ccx a,b,c 60 | { 61 | h c; 62 | cx b,c; tdg c; 63 | cx a,c; t c; 64 | cx b,c; tdg c; 65 | cx a,c; t b; t c; h c; 66 | cx a,b; t a; tdg b; 67 | cx a,b; 68 | } 69 | // controlled rz rotation 70 | gate crz(lambda) a,b 71 | { 72 | u1(lambda/2) b; 73 | cx a,b; 74 | u1(-lambda/2) b; 75 | cx a,b; 76 | } 77 | // controlled phase rotation 78 | gate cu1(lambda) a,b 79 | { 80 | u1(lambda/2) a; 81 | cx a,b; 82 | u1(-lambda/2) b; 83 | cx a,b; 84 | u1(lambda/2) b; 85 | } 86 | // controlled-U 87 | gate cu3(theta,phi,lambda) c, t 88 | { 89 | // implements controlled-U(theta,phi,lambda) with target t and control c 90 | u1((lambda-phi)/2) t; 91 | cx c,t; 92 | u3(-theta/2,0,-(phi+lambda)/2) t; 93 | cx c,t; 94 | u3(theta/2,phi,0) t; 95 | } 96 | -------------------------------------------------------------------------------- /code/src/Queue/DefaultQueue.hpp: -------------------------------------------------------------------------------- 1 | #include "Queue.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | extern bool _verbose; 7 | 8 | //Queue example: this queue uses std::priority_queue 9 | class DefaultQueue : public Queue { 10 | private: 11 | struct CmpDefaultQueue 12 | { 13 | bool operator()(const Node* lhs, const Node* rhs) const 14 | { 15 | //tiebreaker: 16 | if(lhs->cost == rhs->cost) { 17 | //return lhs->scheduled->size > rhs->scheduled->size; 18 | //return lhs->numUnscheduledGates > rhs->numUnscheduledGates; 19 | //return lhs->cycle < rhs->cycle; 20 | } 21 | 22 | //lower cost is better 23 | return lhs->cost > rhs->cost; 24 | } 25 | }; 26 | 27 | std::priority_queue, CmpDefaultQueue> nodes; 28 | 29 | bool pushNode(Node * newNode) { 30 | //std::cerr << "Debug message: pushed node with cost " << newNode->cost << "\n"; 31 | nodes.push(newNode); 32 | if(_verbose) { 33 | if(newNode->numUnscheduledGates < garbage) { 34 | garbage = newNode->numUnscheduledGates; 35 | garbage2 = newNode->cost; 36 | 37 | std::cerr << "dbg More progress!\n"; 38 | std::cerr << " " << garbage << " gates remain!\n"; 39 | std::cerr << " cost is " << newNode->cost << "\n"; 40 | if(newNode->parent) 41 | std::cerr << " parent cost is " << newNode->parent->cost << "\n"; 42 | else 43 | std::cerr << " root node!\n"; 44 | std::cerr << " num ready gates is " << newNode->readyGates.size() << "\n"; 45 | } else if(newNode->numUnscheduledGates == garbage) { 46 | if(newNode->cost < garbage2) { 47 | garbage2 = newNode->cost; 48 | std::cerr << "dbg Better progress!\n"; 49 | std::cerr << " new cost is " << newNode->cost << "\n"; 50 | } 51 | } 52 | } 53 | return true; 54 | } 55 | 56 | int garbage = 9999999; 57 | int garbage2 = 9999999; 58 | 59 | public: 60 | Node * pop() { 61 | numPopped++; 62 | 63 | Node * ret = nodes.top(); 64 | nodes.pop(); 65 | 66 | //std::cerr << "Debug message: popped node with cost " << ret->cost << "\n"; 67 | //std::cerr << "Debug message: queue has size " << nodes.size() << " now.\n"; 68 | 69 | if(!ret->readyGates.size()) { 70 | assert(ret->numUnscheduledGates == 0); 71 | bool done = true; 72 | if(done) { 73 | if(!bestFinalNode) { 74 | if(_verbose) std::cerr << "dbg msg: found a final node.\n"; 75 | bestFinalNode = ret; 76 | } else if(ret->cost < bestFinalNode->cost) { 77 | if(_verbose) std::cerr << "dbg msg: found a better final node.\n"; 78 | //delete bestFinalNode; 79 | bestFinalNode = ret; 80 | } 81 | } 82 | } 83 | 84 | return ret; 85 | } 86 | 87 | int size() { 88 | return nodes.size(); 89 | } 90 | }; 91 | -------------------------------------------------------------------------------- /code/src/full_classes/Node.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NODE_HPP 2 | #define NODE_HPP 3 | 4 | #include "Environment.hpp" 5 | #include "GateNode.hpp" 6 | #include "LinkedStack.hpp" 7 | #include "ScheduledGate.hpp" 8 | #include 9 | #include 10 | #include 11 | class Queue; 12 | using namespace std; 13 | 14 | //Warning: you may need to run make clean after changing MAX_QUBITS 15 | const int MAX_QUBITS = 20; 16 | extern int GLOBALCOUNTER; 17 | 18 | class Node { 19 | public: 20 | Node * parent;//node from which this one expanded 21 | Environment * env;//object with functions/data shared by all nodes 22 | int cycle;//current cycle 23 | int cost; 24 | int cost2 = 0;//used as tiebreaker in some places 25 | 26 | int numUnscheduledGates; 27 | bool expanded = false; 28 | bool dead = false; 29 | 30 | int debugID = GLOBALCOUNTER++; 31 | 32 | char qal[MAX_QUBITS];//qubit mapping 33 | char laq[MAX_QUBITS];//qubit mapping (inverted) 34 | 35 | ScheduledGate * lastNonSwapGate[MAX_QUBITS];//last scheduled non-swap gate per LOGICAL qubit 36 | ScheduledGate * lastGate[MAX_QUBITS];//last scheduled gate per PHYSICAL qubit 37 | //ScheduledGate * busy[MAX_QUBITS];//gate with which PHYSICAL qubit is busy, or NULL 38 | inline int busyCycles(int physicalQubit) { 39 | if(!this->lastGate[physicalQubit]) return 0; 40 | int cycles = this->lastGate[physicalQubit]->cycle + this->lastGate[physicalQubit]->gate->latency - this->cycle; 41 | if(cycles < 0) return 0; 42 | return cycles; 43 | } 44 | 45 | std::set readyGates;//set of gates in DAG whose parents have already been scheduled 46 | 47 | LinkedStack * scheduled;//list of scheduled gates. Warning: this linked list's data overlaps with the same list in parent node 48 | 49 | Node(); 50 | 51 | ~Node(); 52 | 53 | //swap two physical qubits in qubit map, without scheduling a gate 54 | inline bool swapQubits(int physicalControl, int physicalTarget) { 55 | if(qal[physicalControl] < 0 && qal[physicalTarget] < 0) { 56 | return false; 57 | } else if(qal[physicalTarget] < 0) { 58 | laq[(int)qal[physicalControl]] = physicalTarget; 59 | } else if(qal[physicalControl] < 0) { 60 | laq[(int)qal[physicalTarget]] = physicalControl; 61 | } else { 62 | std::swap(laq[(int)qal[physicalControl]], laq[(int)qal[physicalTarget]]); 63 | } 64 | std::swap(qal[physicalControl], qal[physicalTarget]); 65 | return true; 66 | } 67 | 68 | //schedule a gate, or return false if it conflicts with an active gate 69 | //the gate parameter uses logical qubits (except in swaps); this function determines physical locations based on prior swaps 70 | //the timeOffset can be used if we want to schedule a gate to start X cycles in the future 71 | //this function adjusts qubit map when scheduling a swap 72 | bool scheduleGate(GateNode * gate, unsigned int timeOffset = 0); 73 | 74 | //prepares a new child node (without scheduling any more gates) 75 | Node * prepChild(); 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /data/min-gates/mod5mils_65_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 6 | cx q[0],q[2]; //cycle: 0 //cx logical_q[1],logical_q[3] 7 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 8 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 9 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 10 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 11 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 12 | cx q[3],q[2]; //cycle: 3 //cx logical_q[0],logical_q[3] 13 | cx q[4],q[3]; //cycle: 4 //cx logical_q[4],logical_q[0] 14 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 5 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 15 | cx q[2],q[4]; //cycle: 5 //cx logical_q[3],logical_q[4] 16 | cx q[2],q[3]; //cycle: 6 //cx logical_q[3],logical_q[0] 17 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 6 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 18 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 7 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 20 | cx q[4],q[3]; //cycle: 8 //cx logical_q[4],logical_q[0] 21 | cx q[2],q[4]; //cycle: 9 //cx logical_q[3],logical_q[4] 22 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 23 | cx q[3],q[2]; //cycle: 10 //cx logical_q[0],logical_q[3] 24 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 11 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 25 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 11 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 26 | swp q[0],q[2]; //cycle: 12 27 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 12 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 28 | swp q[2],q[4]; //cycle: 13 29 | cx q[1],q[0]; //cycle: 13 //cx logical_q[2],logical_q[3] 30 | cx q[2],q[1]; //cycle: 14 //cx logical_q[4],logical_q[2] 31 | cx q[0],q[2]; //cycle: 15 //cx logical_q[3],logical_q[4] 32 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 15 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 33 | cx q[0],q[1]; //cycle: 16 //cx logical_q[3],logical_q[2] 34 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 16 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 35 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 17 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 36 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 17 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 37 | cx q[2],q[1]; //cycle: 18 //cx logical_q[4],logical_q[2] 38 | cx q[0],q[2]; //cycle: 19 //cx logical_q[3],logical_q[4] 39 | cx q[1],q[0]; //cycle: 20 //cx logical_q[2],logical_q[3] 40 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 20 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 41 | cx q[0],q[2]; //cycle: 21 //cx logical_q[3],logical_q[4] 42 | //35 original gates 43 | //37 final gates 44 | //9332 nodes expanded (popped from queue). 45 | //1387 nodes remain in queue. 46 | -------------------------------------------------------------------------------- /code/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | CFLAGS = -Isrc -Isrc/full_classes -O3 -Wall -std=c++11 3 | rm = @rm 4 | mkdir = @mkdir 5 | exe = mapper 6 | OBJs = objs/CostFunc.o \ 7 | objs/Expander.o \ 8 | objs/Filter.o \ 9 | objs/NodeMod.o \ 10 | objs/Latency.o \ 11 | objs/Queue.o \ 12 | objs/QASMparser.o \ 13 | objs/QASMscanner.o \ 14 | objs/QASMtoken.o \ 15 | objs/Node.o 16 | HPPs = src/CostFunc.hpp \ 17 | src/Expander.hpp \ 18 | src/Filter.hpp \ 19 | src/NodeMod.hpp \ 20 | src/Latency.hpp \ 21 | src/Queue.hpp \ 22 | src/CostFunc/Meta.hpp \ 23 | src/Expander/Meta.hpp \ 24 | src/Filter/Meta.hpp \ 25 | src/NodeMod/Meta.hpp \ 26 | src/Latency/Meta.hpp \ 27 | src/Queue/Meta.hpp \ 28 | src/full_classes/Environment.hpp \ 29 | src/full_classes/GateNode.hpp \ 30 | src/full_classes/LinkedStack.hpp \ 31 | src/full_classes/Node.hpp \ 32 | src/full_classes/ScheduledGate.hpp \ 33 | src/full_classes/QASMparser.h 34 | 35 | ifeq ($(OS),Windows_NT) 36 | rm = @del /F /Q 37 | CFLAGS += -D WINDOWS 38 | exe = mapper.exe 39 | else 40 | mkdir += -p 41 | rm += -f -r 42 | UNAME_S := $(shell uname -s) 43 | UNAME_P := $(shell uname -p) 44 | 45 | ifeq ($(UNAME_S),Linux) 46 | CFLAGS += -D LINUX 47 | ifeq ($(UNAME_P),x86_64) 48 | CFLAGS += -D AMD64 49 | CFLAGS += -D LINUX64 50 | endif 51 | else ifeq ($(UNAME_P),x86_64) 52 | CFLAGS += -D AMD64 53 | endif 54 | endif 55 | 56 | default: objs ${exe} 57 | 58 | debug: CFLAGS += -g -O0 59 | debug: default 60 | prof: CFLAGS += -pg -fno-inline 61 | prof: default 62 | 63 | 64 | mapper: src/main.cpp ${OBJs} ${HPPs} 65 | ${CC} ${CFLAGS} ${OBJs} $< -o $@ 66 | 67 | mapper.exe: src/main.cpp ${OBJs} ${HPPs} 68 | ${CC} ${CFLAGS} ${OBJs} $< -o $@ 69 | 70 | objs: 71 | ${mkdir} objs 72 | 73 | objs/CostFunc.o: $(wildcard src/CostFunc/*) src/CostFunc.hpp src/full_classes/Node.hpp 74 | ${CC} ${CFLAGS} -c src/CostFunc/Meta.cpp -o $@ 75 | 76 | objs/Expander.o: $(wildcard src/Expander/*) src/Expander.hpp src/full_classes/Node.hpp 77 | ${CC} ${CFLAGS} -c src/Expander/Meta.cpp -o $@ 78 | 79 | objs/Filter.o: $(wildcard src/Filter/*) src/Filter.hpp src/full_classes/Node.hpp 80 | ${CC} ${CFLAGS} -c src/Filter/Meta.cpp -o $@ 81 | 82 | objs/NodeMod.o: $(wildcard src/NodeMod/*) src/NodeMod.hpp src/full_classes/Node.hpp 83 | ${CC} ${CFLAGS} -c src/NodeMod/Meta.cpp -o $@ 84 | 85 | objs/Latency.o: $(wildcard src/Latency/*) src/Latency.hpp 86 | ${CC} ${CFLAGS} -c src/Latency/Meta.cpp -o $@ 87 | 88 | objs/Queue.o: $(wildcard src/Queue/*) src/Queue.hpp src/full_classes/Node.hpp 89 | ${CC} ${CFLAGS} -c src/Queue/Meta.cpp -o $@ 90 | 91 | objs/Node.o: src/full_classes/Node.cpp $(wildcard src/full_classes/*.hpp) 92 | ${CC} ${CFLAGS} -c $< -o $@ 93 | 94 | objs/QASMparser.o: src/full_classes/QASMparser.cpp src/full_classes/QASMparser.h 95 | ${CC} ${CFLAGS} -c $< -o $@ 96 | 97 | objs/QASMscanner.o: src/full_classes/QASMscanner.cpp src/full_classes/QASMscanner.hpp 98 | ${CC} ${CFLAGS} -c $< -o $@ 99 | 100 | objs/QASMtoken.o: src/full_classes/QASMtoken.cpp src/full_classes/QASMtoken.hpp 101 | ${CC} ${CFLAGS} -c $< -o $@ 102 | 103 | 104 | clean: 105 | ${rm} mapper mapper.exe objs 106 | -------------------------------------------------------------------------------- /data/min-depth/mod5mils_65_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 6 | cx q[2],q[3]; //cycle: 0 //cx logical_q[1],logical_q[3] 7 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 8 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 9 | swp q[1],q[2]; //cycle: 1 10 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 11 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 12 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 13 | cx q[2],q[3]; //cycle: 4 //cx logical_q[0],logical_q[3] 14 | cx q[4],q[2]; //cycle: 5 //cx logical_q[4],logical_q[0] 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 16 | cx q[3],q[4]; //cycle: 6 //cx logical_q[3],logical_q[4] 17 | cx q[3],q[2]; //cycle: 7 //cx logical_q[3],logical_q[0] 18 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 7 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 19 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 8 //u3(0.000000, 0.000000, -0.785398) logical_q[0] 21 | cx q[4],q[2]; //cycle: 9 //cx logical_q[4],logical_q[0] 22 | cx q[3],q[4]; //cycle: 10 //cx logical_q[3],logical_q[4] 23 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 11 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 24 | cx q[2],q[3]; //cycle: 11 //cx logical_q[0],logical_q[3] 25 | swp q[0],q[2]; //cycle: 12 26 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 12 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 27 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 12 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 28 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 13 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 29 | cx q[2],q[3]; //cycle: 15 //cx logical_q[2],logical_q[3] 30 | cx q[4],q[2]; //cycle: 16 //cx logical_q[4],logical_q[2] 31 | cx q[3],q[4]; //cycle: 17 //cx logical_q[3],logical_q[4] 32 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 17 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 33 | cx q[3],q[2]; //cycle: 18 //cx logical_q[3],logical_q[2] 34 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 18 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 35 | u3(0.000000, 0.000000, -0.785398) q[3]; //cycle: 19 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 36 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 19 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 37 | cx q[4],q[2]; //cycle: 20 //cx logical_q[4],logical_q[2] 38 | cx q[3],q[4]; //cycle: 21 //cx logical_q[3],logical_q[4] 39 | cx q[2],q[3]; //cycle: 22 //cx logical_q[2],logical_q[3] 40 | u3(1.570796, 0.000000, 3.141593) q[4]; //cycle: 22 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 41 | cx q[3],q[4]; //cycle: 23 //cx logical_q[3],logical_q[4] 42 | //35 original gates 43 | //37 final gates 44 | //21 original depth (cycles) 45 | //24 cycles in selected mapping 46 | //156 nodes expanded (popped from queue). 47 | //393 nodes remain in queue. 48 | -------------------------------------------------------------------------------- /data/min-gates/16QBT_05CYC_TFL_0_aspen4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 6 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 8 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 9 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 10 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 11 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 12 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 13 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 14 | cx q[10],q[11]; //cycle: 0 //cx logical_q[8],logical_q[12] 15 | cx q[5],q[6]; //cycle: 0 //cx logical_q[3],logical_q[9] 16 | u3(3.141593, 0.000000, 3.141593) q[7]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 17 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 18 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 19 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 20 | cx q[14],q[15]; //cycle: 1 //cx logical_q[14],logical_q[6] 21 | cx q[2],q[1]; //cycle: 1 //cx logical_q[5],logical_q[4] 22 | cx q[10],q[11]; //cycle: 1 //cx logical_q[8],logical_q[12] 23 | cx q[13],q[12]; //cycle: 1 //cx logical_q[10],logical_q[11] 24 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 25 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 26 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 27 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 28 | cx q[10],q[9]; //cycle: 2 //cx logical_q[8],logical_q[2] 29 | cx q[5],q[6]; //cycle: 2 //cx logical_q[3],logical_q[9] 30 | cx q[15],q[8]; //cycle: 2 //cx logical_q[6],logical_q[0] 31 | cx q[14],q[13]; //cycle: 2 //cx logical_q[14],logical_q[10] 32 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 33 | cx q[10],q[11]; //cycle: 3 //cx logical_q[8],logical_q[12] 34 | cx q[14],q[15]; //cycle: 3 //cx logical_q[14],logical_q[6] 35 | cx q[0],q[1]; //cycle: 3 //cx logical_q[1],logical_q[4] 36 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 37 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 38 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 39 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 40 | cx q[10],q[11]; //cycle: 4 //cx logical_q[8],logical_q[12] 41 | cx q[14],q[13]; //cycle: 4 //cx logical_q[14],logical_q[10] 42 | //37 original gates 43 | //37 final gates 44 | //13240 nodes expanded (popped from queue). 45 | //91 nodes remain in queue. 46 | -------------------------------------------------------------------------------- /data/min-depth/16QBT_05CYC_TFL_0_aspen4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 6 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 7 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 8 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 9 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 10 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 11 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 12 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 13 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 14 | cx q[10],q[11]; //cycle: 0 //cx logical_q[8],logical_q[12] 15 | cx q[5],q[6]; //cycle: 0 //cx logical_q[3],logical_q[9] 16 | u3(3.141593, 0.000000, 3.141593) q[7]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 17 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 18 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 19 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 20 | cx q[14],q[15]; //cycle: 1 //cx logical_q[14],logical_q[6] 21 | cx q[2],q[1]; //cycle: 1 //cx logical_q[5],logical_q[4] 22 | cx q[10],q[11]; //cycle: 1 //cx logical_q[8],logical_q[12] 23 | cx q[13],q[12]; //cycle: 1 //cx logical_q[10],logical_q[11] 24 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 25 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 26 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 27 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 28 | cx q[10],q[9]; //cycle: 2 //cx logical_q[8],logical_q[2] 29 | cx q[5],q[6]; //cycle: 2 //cx logical_q[3],logical_q[9] 30 | cx q[15],q[8]; //cycle: 2 //cx logical_q[6],logical_q[0] 31 | cx q[14],q[13]; //cycle: 2 //cx logical_q[14],logical_q[10] 32 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 33 | cx q[10],q[11]; //cycle: 3 //cx logical_q[8],logical_q[12] 34 | cx q[14],q[15]; //cycle: 3 //cx logical_q[14],logical_q[6] 35 | cx q[0],q[1]; //cycle: 3 //cx logical_q[1],logical_q[4] 36 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 37 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 38 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 39 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 40 | cx q[10],q[11]; //cycle: 4 //cx logical_q[8],logical_q[12] 41 | cx q[14],q[13]; //cycle: 4 //cx logical_q[14],logical_q[10] 42 | //37 original gates 43 | //37 final gates 44 | //5 original depth (cycles) 45 | //5 cycles in selected mapping 46 | //13240 nodes expanded (popped from queue). 47 | //91 nodes remain in queue. 48 | -------------------------------------------------------------------------------- /code/src/CostFunc/SimpleCost.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLECOST_HPP 2 | #define SIMPLECOST_HPP 3 | 4 | #include "CostFunc.hpp" 5 | #include "Node.hpp" 6 | #include 7 | 8 | //CostFunc example 9 | class SimpleCost : public CostFunc { 10 | public: 11 | int _getCost(Node * node) { 12 | bool debug = node->cost > 0; 13 | 14 | int cost = 0; 15 | int costT = 99999; 16 | Environment * env = node->env; 17 | 18 | //Calculate remaining cost of scheduled gates that haven't finished 19 | int busyCyclesRemaining[env->numPhysicalQubits]; 20 | for(int x = 0; x < env->numPhysicalQubits; x++) { 21 | busyCyclesRemaining[x] = node->busyCycles(x); 22 | if(debug) { 23 | //std::cerr << x << " busy for " << busyCyclesRemaining[x] << "\n"; 24 | } 25 | if(busyCyclesRemaining[x] > cost) { 26 | cost = busyCyclesRemaining[x]; 27 | } 28 | } 29 | 30 | //Consider cost of unscheduled gates 31 | auto iter = node->readyGates.begin(); 32 | while(iter != node->readyGates.end()) { 33 | GateNode * g = *iter; 34 | 35 | int tempcost = g->criticality + g->latency; 36 | int tempcost2 = tempcost; 37 | 38 | int control = -1; 39 | if(g->control >= 0) { 40 | control = node->laq[g->control]; 41 | } 42 | int target = -1; 43 | if(g->target >= 0) { 44 | target = node->laq[g->target]; 45 | } 46 | 47 | if(control >= 0) { 48 | if(busyCyclesRemaining[control]) { 49 | tempcost += busyCyclesRemaining[control]; 50 | } else { 51 | tempcost += 1;//take into account that we're not scheduling any more gates this cycle 52 | } 53 | } 54 | if(target >= 0) { 55 | if(busyCyclesRemaining[target]) { 56 | tempcost2 += busyCyclesRemaining[target]; 57 | } else { 58 | tempcost2 += 1;//take into account that we're not scheduling any more gates this cycle 59 | } 60 | } 61 | 62 | if(control >= 0 && target >= 0) { 63 | int dist = env->couplingDistances[control*env->numPhysicalQubits + target]; 64 | if(dist < costT) costT = dist - 1; 65 | int minSwapCost = env->swapCost * (dist / 2); 66 | assert(minSwapCost >= 0); 67 | 68 | if(debug) { 69 | std::cerr << target << " busy for " << busyCyclesRemaining[target] << "\n"; 70 | std::cerr << control << " busy for " << busyCyclesRemaining[control] << "\n"; 71 | std::cerr << "dist: " << dist << ", swapCostPerQ: " << minSwapCost << "\n"; 72 | } 73 | 74 | if(dist > 1) {//at least one node between target and control 75 | if(dist & 0x1) {//odd dist; therefore even nodes between target and control 76 | tempcost += minSwapCost; 77 | tempcost2 += minSwapCost; 78 | } else if(tempcost < tempcost2) { 79 | tempcost += minSwapCost; 80 | tempcost2 += minSwapCost - env->swapCost; 81 | } else { 82 | tempcost2 += minSwapCost; 83 | tempcost += minSwapCost - env->swapCost; 84 | } 85 | } 86 | } 87 | 88 | if(tempcost > cost) { 89 | cost = tempcost; 90 | } 91 | if(tempcost2 > cost) { 92 | cost = tempcost2; 93 | } 94 | 95 | if(debug) { 96 | std::cerr << control << "," << target << ":" << g->criticality + g->latency << ":" << "\t" << tempcost << " or " << tempcost2 << "\n"; 97 | } 98 | 99 | iter++; 100 | } 101 | 102 | //Consider cost of completed gates 103 | cost += node->cycle; 104 | 105 | if(debug) std::cerr << " COST: " << cost << " (" << node->cycle << " + " << (cost-node->cycle) << ")" << "\n"; 106 | 107 | if(costT == 99999) costT = 0; 108 | node->cost2 = costT; 109 | 110 | return cost; 111 | } 112 | }; 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /code/README.txt: -------------------------------------------------------------------------------- 1 | ******************** 2 | **DIRECTORY LAYOUT** 3 | ******************** 4 | 5 | The 'src' folder contains our source code. 6 | The 'couplings' folder contains the coupling maps for architectures used in our paper. 7 | The 'circuits' folder contains circuits we used in our paper and/or our response to reviewers. 8 | 9 | Within the circuits folder: 10 | -The 'small' folder contains a set of small benchmarks (3 to 5 qubits) used by Robert Wille et. al. 11 | -The 'large' folder contains a set of larger benchmarks (8 to 16 qubits). 12 | -The 'OLSQ' folder contains a set of benchmarks from the OLSQ paper. 13 | 14 | 15 | ******************** 16 | *****COMPILATION**** 17 | ******************** 18 | 19 | Compile by running 'make'. This will produce the executable 'mapper'. 20 | 21 | Note that compilation has been tested successfully on systems with the following setups: 22 | -Linux (Ubuntu 18.04 LTS) with version 7.5.0 of the GNU Compiler Collection. 23 | -Windows 10 with version 5.3.0 of the GNU Compiler Collection. 24 | 25 | 26 | ******************** 27 | ***** RUNNING ****** 28 | ***** (small) ****** 29 | ******************** 30 | 31 | The small circuits were mapped on the IBM QX2 coupling map, with latencies of 1 cycle for 1 qubit gates, 2 cycles for CX gates, and 6 cycles for swaps. 32 | 33 | We ran the program twice: once to try to find a mapping without swaps, and a second time with swaps if that failed. For example to reproduce our results for qft_4, you would use the following two commands (since the first one fails) and add up their runtimes: 34 | 35 | ./mapper ./circuits/small/qft_4.qasm couplings/qx2.txt -defaults -latency Latency_1_2_6 -expander noSwaps 36 | ./mapper ./circuits/small/qft_4.qasm couplings/qx2.txt -defaults -latency Latency_1_2_6 -filter HashFilter -filter HashFilter2 -pureSwapDiameter 37 | 38 | In that example, the first command results in the program aborting when it fails to map the circuit without swap gates, and the second command finds an optimal mapping (with one swap gate). An example where mapping without swaps is possible would be the 3_17_13 circuit. 39 | 40 | 41 | ******************** 42 | ***** RUNNING ****** 43 | ***** (large) ****** 44 | ******************** 45 | 46 | The large circuits were mapped on the IBM Tokyo coupling map, with latencies of 1 cycle for 1 qubit gates, 2 cycles for CX gates, and 6 cycles for swaps. 47 | 48 | For example to reproduce our results for qft_10, you could use the following command: 49 | 50 | ./mapper ./circuits/large/qft_10.qasm couplings/tokyo.txt -defaults -latency Latency_1_2_6 -expander GreedyTopK 10 -queue TrimSlowNodes 2000 1000 -nodeMod GreedyMapper -retain 1 51 | 52 | This quickly produces a (non-optimal) mapping for the benchmark. 53 | 54 | 55 | ******************** 56 | ***** RUNNING ****** 57 | ***** (OLSQ) ****** 58 | ******************** 59 | 60 | The OLSQ circuits were mapped on the IBM QX2, Rigetti Aspen-4, 2x3, and/or 2x4 coupling maps, with latencies of 3 cycles for swaps and 1 cycle for other gates. 61 | 62 | We ran the program twice: once to try to find a mapping without swaps, and a second time with swaps if that failed. For example to reproduce our results for mod5mils_65 on QX2, you would use the following two commands (since the first one fails) and add up their runtimes: 63 | 64 | ./mapper ./circuits/OLSQ/mod5mils_65.qasm couplings/qx2.txt -defaults -latency Latency_1_3 -expander noswaps 65 | ./mapper ./circuits/OLSQ/mod5mils_65.qasm couplings/qx2.txt -defaults -latency Latency_1_3 -filter HashFilter -filter HashFilter2 -pureSwapDiameter 66 | 67 | In that example, the first command results in the program aborting when it fails to map the circuit without swap gates, and the second command finds an optimal mapping (with three swap gates). An example where mapping without swaps is possible would be the 16QBT_05CYC_TFL_0 circuit with the aspen4 coupling map. 68 | -------------------------------------------------------------------------------- /code/src/NodeMod/GreedyMapper.hpp: -------------------------------------------------------------------------------- 1 | #include "NodeMod.hpp" 2 | #include "Node.hpp" 3 | #include 4 | 5 | class GreedyMapper : public NodeMod { 6 | private: 7 | 8 | public: 9 | 10 | void mod(Node * node, int flag) { 11 | //Return unless this was called before calculating node's cost 12 | if(flag != MOD_TYPE_BEFORECOST) { 13 | return; 14 | } 15 | 16 | Environment * env = node->env; 17 | 18 | //if this is the root node, unmap the qubits 19 | if(node->cycle < 0 && node->parent == NULL) { 20 | for(int x = 0; x < env->numPhysicalQubits; x++) { 21 | node->laq[x] = -1; 22 | node->qal[x] = -1; 23 | } 24 | } 25 | 26 | //return unless there are unmapped qubits 27 | bool mayNeedAssignment = false; 28 | for(int x = 0; x < env->numLogicalQubits; x++) { 29 | if(node->laq[x] < 0) { 30 | mayNeedAssignment = true; 31 | break; 32 | } 33 | } 34 | if(!mayNeedAssignment) { 35 | return; 36 | } 37 | 38 | for(auto iter = node->readyGates.begin(); iter != node->readyGates.end(); iter++) { 39 | GateNode * g = *iter; 40 | 41 | if(g && g->control < 0) { 42 | //g = g->nextTargetCNOT ? g->nextTargetCNOT : g; 43 | } 44 | 45 | if(g && g->control >= 0) { 46 | int physC = node->laq[g->control]; 47 | int physT = node->laq[g->target]; 48 | if(physC < 0 && physT < 0) { 49 | int bestTarget = -1; 50 | int bestControl = -1; 51 | int bestDistance = 2 * env->numPhysicalQubits * env->numPhysicalQubits; 52 | for(int x = 0; x < env->numPhysicalQubits - 1; x++) { 53 | if(node->qal[x] < 0) { 54 | for(int y = x + 1; y < env->numPhysicalQubits; y++) { 55 | if(node->qal[y] < 0) { 56 | int dist = env->couplingDistances[x * env->numPhysicalQubits + y]; 57 | if(dist < bestDistance) { 58 | bestTarget = x; 59 | bestControl = y; 60 | bestDistance = dist; 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | //cerr << bestTarget << " "; 68 | //std::swap(bestTarget, bestControl); 69 | //cerr << bestTarget << "\n"; 70 | 71 | assert(bestTarget >= 0); 72 | node->laq[g->control] = bestControl; 73 | node->laq[g->target] = bestTarget; 74 | node->qal[bestControl] = g->control; 75 | node->qal[bestTarget] = g->target; 76 | 77 | } else if(physC < 0) { 78 | int bestBit = -1; 79 | int bestDistance = 2 * env->numPhysicalQubits * env->numPhysicalQubits; 80 | for(int x = 0; x < env->numPhysicalQubits; x++) { 81 | if(x != physT) { 82 | if(node->qal[x] < 0) { 83 | int dist = env->couplingDistances[x * env->numPhysicalQubits + physT]; 84 | if(dist < bestDistance) { 85 | bestBit = x; 86 | bestDistance = dist; 87 | } 88 | } 89 | } 90 | } 91 | 92 | assert(bestBit >= 0); 93 | node->laq[g->control] = bestBit; 94 | node->qal[bestBit] = g->control; 95 | } else if(physT < 0) { 96 | int bestBit = -1; 97 | int bestDistance = 2 * env->numPhysicalQubits * env->numPhysicalQubits; 98 | for(int x = 0; x < env->numPhysicalQubits; x++) { 99 | if(x != physC) { 100 | if(node->qal[x] < 0) { 101 | int dist = env->couplingDistances[x * env->numPhysicalQubits + physC]; 102 | if(dist < bestDistance) { 103 | bestBit = x; 104 | bestDistance = dist; 105 | } 106 | } 107 | } 108 | } 109 | 110 | assert(bestBit >= 0); 111 | node->laq[g->target] = bestBit; 112 | node->qal[bestBit] = g->target; 113 | } 114 | } else if(false && g) { 115 | for(int x = 0; x < env->numPhysicalQubits; x++) { 116 | if(node->qal[x] < 0) { 117 | node->laq[g->target] = x; 118 | node->qal[x] = g->target; 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | } 125 | }; 126 | -------------------------------------------------------------------------------- /code/circuits/large/qft_10.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | h q[0]; 6 | rz(-0.7854) q[0]; 7 | cx q[0],q[1]; 8 | rz(0.7854) q[0]; 9 | cx q[0],q[1]; 10 | rz(-0.3927) q[0]; 11 | cx q[0],q[2]; 12 | rz(0.3927) q[0]; 13 | cx q[0],q[2]; 14 | rz(-0.19635) q[0]; 15 | cx q[0],q[3]; 16 | rz(0.19635) q[0]; 17 | cx q[0],q[3]; 18 | rz(-0.09815) q[0]; 19 | cx q[0],q[4]; 20 | rz(0.09815) q[0]; 21 | cx q[0],q[4]; 22 | rz(-0.0491) q[0]; 23 | cx q[0],q[5]; 24 | rz(0.0491) q[0]; 25 | cx q[0],q[5]; 26 | rz(-0.02455) q[0]; 27 | cx q[0],q[6]; 28 | rz(0.02455) q[0]; 29 | cx q[0],q[6]; 30 | rz(-0.01225) q[0]; 31 | cx q[0],q[7]; 32 | rz(0.01225) q[0]; 33 | cx q[0],q[7]; 34 | rz(-0.00615) q[0]; 35 | cx q[0],q[8]; 36 | rz(0.00615) q[0]; 37 | cx q[0],q[8]; 38 | rz(-0.00305) q[0]; 39 | cx q[0],q[9]; 40 | rz(0.00305) q[0]; 41 | cx q[0],q[9]; 42 | h q[1]; 43 | rz(-0.7854) q[1]; 44 | cx q[1],q[2]; 45 | rz(0.7854) q[1]; 46 | cx q[1],q[2]; 47 | rz(-0.3927) q[1]; 48 | cx q[1],q[3]; 49 | rz(0.3927) q[1]; 50 | cx q[1],q[3]; 51 | rz(-0.19635) q[1]; 52 | cx q[1],q[4]; 53 | rz(0.19635) q[1]; 54 | cx q[1],q[4]; 55 | rz(-0.09815) q[1]; 56 | cx q[1],q[5]; 57 | rz(0.09815) q[1]; 58 | cx q[1],q[5]; 59 | rz(-0.0491) q[1]; 60 | cx q[1],q[6]; 61 | rz(0.0491) q[1]; 62 | cx q[1],q[6]; 63 | rz(-0.02455) q[1]; 64 | cx q[1],q[7]; 65 | rz(0.02455) q[1]; 66 | cx q[1],q[7]; 67 | rz(-0.01225) q[1]; 68 | cx q[1],q[8]; 69 | rz(0.01225) q[1]; 70 | cx q[1],q[8]; 71 | rz(-0.00615) q[1]; 72 | cx q[1],q[9]; 73 | rz(0.00615) q[1]; 74 | cx q[1],q[9]; 75 | h q[2]; 76 | rz(-0.7854) q[2]; 77 | cx q[2],q[3]; 78 | rz(0.7854) q[2]; 79 | cx q[2],q[3]; 80 | rz(-0.3927) q[2]; 81 | cx q[2],q[4]; 82 | rz(0.3927) q[2]; 83 | cx q[2],q[4]; 84 | rz(-0.19635) q[2]; 85 | cx q[2],q[5]; 86 | rz(0.19635) q[2]; 87 | cx q[2],q[5]; 88 | rz(-0.09815) q[2]; 89 | cx q[2],q[6]; 90 | rz(0.09815) q[2]; 91 | cx q[2],q[6]; 92 | rz(-0.0491) q[2]; 93 | cx q[2],q[7]; 94 | rz(0.0491) q[2]; 95 | cx q[2],q[7]; 96 | rz(-0.02455) q[2]; 97 | cx q[2],q[8]; 98 | rz(0.02455) q[2]; 99 | cx q[2],q[8]; 100 | rz(-0.01225) q[2]; 101 | cx q[2],q[9]; 102 | rz(0.01225) q[2]; 103 | cx q[2],q[9]; 104 | h q[3]; 105 | rz(-0.7854) q[3]; 106 | cx q[3],q[4]; 107 | rz(0.7854) q[3]; 108 | cx q[3],q[4]; 109 | rz(-0.3927) q[3]; 110 | cx q[3],q[5]; 111 | rz(0.3927) q[3]; 112 | cx q[3],q[5]; 113 | rz(-0.19635) q[3]; 114 | cx q[3],q[6]; 115 | rz(0.19635) q[3]; 116 | cx q[3],q[6]; 117 | rz(-0.09815) q[3]; 118 | cx q[3],q[7]; 119 | rz(0.09815) q[3]; 120 | cx q[3],q[7]; 121 | rz(-0.0491) q[3]; 122 | cx q[3],q[8]; 123 | rz(0.0491) q[3]; 124 | cx q[3],q[8]; 125 | rz(-0.02455) q[3]; 126 | cx q[3],q[9]; 127 | rz(0.02455) q[3]; 128 | cx q[3],q[9]; 129 | h q[4]; 130 | rz(-0.7854) q[4]; 131 | cx q[4],q[5]; 132 | rz(0.7854) q[4]; 133 | cx q[4],q[5]; 134 | rz(-0.3927) q[4]; 135 | cx q[4],q[6]; 136 | rz(0.3927) q[4]; 137 | cx q[4],q[6]; 138 | rz(-0.19635) q[4]; 139 | cx q[4],q[7]; 140 | rz(0.19635) q[4]; 141 | cx q[4],q[7]; 142 | rz(-0.09815) q[4]; 143 | cx q[4],q[8]; 144 | rz(0.09815) q[4]; 145 | cx q[4],q[8]; 146 | rz(-0.0491) q[4]; 147 | cx q[4],q[9]; 148 | rz(0.0491) q[4]; 149 | cx q[4],q[9]; 150 | h q[5]; 151 | rz(-0.7854) q[5]; 152 | cx q[5],q[6]; 153 | rz(0.7854) q[5]; 154 | cx q[5],q[6]; 155 | rz(-0.3927) q[5]; 156 | cx q[5],q[7]; 157 | rz(0.3927) q[5]; 158 | cx q[5],q[7]; 159 | rz(-0.19635) q[5]; 160 | cx q[5],q[8]; 161 | rz(0.19635) q[5]; 162 | cx q[5],q[8]; 163 | rz(-0.09815) q[5]; 164 | cx q[5],q[9]; 165 | rz(0.09815) q[5]; 166 | cx q[5],q[9]; 167 | h q[6]; 168 | rz(-0.7854) q[6]; 169 | cx q[6],q[7]; 170 | rz(0.7854) q[6]; 171 | cx q[6],q[7]; 172 | rz(-0.3927) q[6]; 173 | cx q[6],q[8]; 174 | rz(0.3927) q[6]; 175 | cx q[6],q[8]; 176 | rz(-0.19635) q[6]; 177 | cx q[6],q[9]; 178 | rz(0.19635) q[6]; 179 | cx q[6],q[9]; 180 | h q[7]; 181 | rz(-0.7854) q[7]; 182 | cx q[7],q[8]; 183 | rz(0.7854) q[7]; 184 | cx q[7],q[8]; 185 | rz(-0.3927) q[7]; 186 | cx q[7],q[9]; 187 | rz(0.3927) q[7]; 188 | cx q[7],q[9]; 189 | h q[8]; 190 | rz(-0.7854) q[8]; 191 | cx q[8],q[9]; 192 | rz(0.7854) q[8]; 193 | cx q[8],q[9]; 194 | h q[9]; 195 | h q[0]; 196 | h q[1]; 197 | h q[2]; 198 | h q[3]; 199 | h q[4]; 200 | h q[5]; 201 | h q[6]; 202 | h q[7]; 203 | h q[8]; 204 | h q[9]; 205 | -------------------------------------------------------------------------------- /code/src/Filter/HashFilter.hpp: -------------------------------------------------------------------------------- 1 | #include "Filter.hpp" 2 | #include "Node.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef HASH_COMBINE_FUNCTION 9 | #define HASH_COMBINE_FUNCTION 10 | //based on hash_combine from Boost libraries 11 | template 12 | inline void hash_combine(std::size_t& seed, const T& v) 13 | { 14 | std::hash hasher; 15 | seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); 16 | } 17 | #endif 18 | 19 | inline std::size_t hashFunc1(Node * n) { 20 | std::size_t hash_result = 0; 21 | int numQubits = n->env->numPhysicalQubits; 22 | 23 | //combine into hash: qubit map (array of integers) 24 | for(int x = 0; x < numQubits; x++) { 25 | hash_combine(hash_result, n->laq[x]); 26 | } 27 | 28 | //combine into hash: ready gate (set of pointers) 29 | for(auto x = n->readyGates.begin(); x != n->readyGates.end(); x++) { 30 | hash_combine(hash_result, (std::uintptr_t) (*x)); 31 | } 32 | 33 | return hash_result; 34 | } 35 | 36 | class HashFilter : public Filter { 37 | private: 38 | int numFiltered = 0; 39 | std::unordered_map > hashmap; 40 | 41 | public: 42 | Filter * createEmptyCopy() { 43 | HashFilter * f = new HashFilter(); 44 | f->numFiltered = this->numFiltered; 45 | return f; 46 | } 47 | 48 | void deleteRecord(Node * n) { 49 | std::size_t hash_result = hashFunc1(n); 50 | vector * mapValue = &this->hashmap[hash_result];//Note: I'm terrified of accidentally making an actual copy of the vector here 51 | for(unsigned int blah = 0; blah < mapValue->size(); blah++) { 52 | Node * n2 = (*mapValue)[blah]; 53 | if(n2 == n) { 54 | if(mapValue->size() > 1 && blah < mapValue->size() - 1) { 55 | std::swap((*mapValue)[blah],(*mapValue)[mapValue->size()-1]); 56 | } 57 | mapValue->pop_back(); 58 | return; 59 | } 60 | } 61 | } 62 | 63 | bool filter(Node * newNode) { 64 | int numQubits = newNode->env->numPhysicalQubits; 65 | std::size_t hash_result = hashFunc1(newNode); 66 | 67 | //auto findNode = this->hashmap.find(hash_result); 68 | //if(findNode != this->hashmap.end()) { 69 | for(Node * candidate : this->hashmap[hash_result]) { 70 | //Node * candidate = findNode->second; 71 | bool willFilter = true; 72 | 73 | for(int x = 0; x < numQubits; x++) { 74 | if(candidate->laq[x] != newNode->laq[x]) { 75 | //std::cerr << "Warning: duplicate hash values.\n"; 76 | willFilter = false; 77 | break; 78 | } 79 | } 80 | if(newNode->readyGates.size() != candidate->readyGates.size()) { 81 | //std::cerr << "Warning: duplicate hash values.\n"; 82 | willFilter = false; 83 | } else if(willFilter) { 84 | for(auto x = newNode->readyGates.begin(), y = candidate->readyGates.begin(); x != newNode->readyGates.end(); x++, y++) { 85 | if((*x) != (*y)) { 86 | //std::cerr << "Warning: duplicate hash values.\n"; 87 | willFilter = false; 88 | break; 89 | } 90 | } 91 | } 92 | bool allEqual = willFilter; 93 | for(int x = 0; willFilter && x < numQubits; x++) { 94 | int time = 0; 95 | int newBusy = newNode->busyCycles(x); 96 | if(newBusy) { 97 | int temp = newBusy + newNode->cycle; 98 | assert(temp > time); 99 | time = temp; 100 | } 101 | int time2 = 0; 102 | int canBusy = candidate->busyCycles(x); 103 | if(canBusy) { 104 | int temp = canBusy + candidate->cycle; 105 | assert(temp > time2); 106 | time2 = temp; 107 | } 108 | if(time < time2) { 109 | //std::cerr << "Warning: duplicate hash values.\n"; 110 | willFilter = false; 111 | allEqual = false; 112 | break; 113 | } else if(time > time2) { 114 | allEqual = false; 115 | } 116 | } 117 | 118 | if(willFilter && (newNode->cycle == candidate->cycle || !allEqual)) { 119 | numFiltered++; 120 | return true; 121 | } 122 | } 123 | this->hashmap[hash_result].push_back(newNode); 124 | 125 | return false; 126 | } 127 | 128 | virtual void printStatistics(std::ostream & stream) { 129 | stream << "//HashFilter filtered " << numFiltered << " total nodes.\n"; 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /code/src/Queue/TrimSlowNodes.hpp: -------------------------------------------------------------------------------- 1 | #include "Queue.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | extern bool _verbose; 7 | 8 | class TrimSlowNodes : public Queue { 9 | private: 10 | unsigned int maxSize = 1000; 11 | unsigned int targetSize = 500; 12 | 13 | struct CmpCost { 14 | bool operator()(const Node* lhs, const Node* rhs) const 15 | { 16 | //tiebreaker: 17 | if(lhs->cost == rhs->cost) { 18 | //return lhs->scheduled->size > rhs->scheduled->size; 19 | //return lhs->numUnscheduledGates > rhs->numUnscheduledGates; 20 | //return lhs->cycle < rhs->cycle; 21 | return lhs->debugID < rhs->debugID; 22 | } 23 | 24 | //lower cost is better 25 | return lhs->cost > rhs->cost; 26 | } 27 | }; 28 | 29 | struct CmpProgress { 30 | bool operator()(const Node* lhs, const Node* rhs) const 31 | { 32 | //tiebreaker: 33 | if(lhs->numUnscheduledGates == rhs->numUnscheduledGates) { 34 | if(lhs->cost ==- rhs->cost) { 35 | return lhs->debugID < rhs->debugID; 36 | } else { 37 | return lhs->cost > rhs->cost; 38 | } 39 | } 40 | 41 | //fewer not-yet-scheduled gates is better 42 | return lhs->numUnscheduledGates > rhs->numUnscheduledGates; 43 | } 44 | }; 45 | 46 | /** 47 | * The queue containing the nodes 48 | */ 49 | std::priority_queue, CmpCost> nodes; 50 | 51 | /** 52 | * A temporary queue used to organize nodes by progress through the original circuit 53 | */ 54 | std::priority_queue, CmpProgress> tempQueue; 55 | 56 | bool pushNode(Node * newNode) { 57 | nodes.push(newNode); 58 | if(_verbose) { 59 | if(newNode->numUnscheduledGates < garbage) { 60 | garbage = newNode->numUnscheduledGates; 61 | garbage2 = newNode->cost; 62 | 63 | std::cerr << "dbg More progress!\n"; 64 | std::cerr << " " << garbage << " gates remain!\n"; 65 | std::cerr << " cost is " << newNode->cost << "\n"; 66 | if(newNode->parent) 67 | std::cerr << " parent cost is " << newNode->parent->cost << "\n"; 68 | else 69 | std::cerr << " root node!\n"; 70 | std::cerr << " num ready gates is " << newNode->readyGates.size() << "\n"; 71 | } else if(newNode->numUnscheduledGates == garbage) { 72 | if(newNode->cost < garbage2) { 73 | garbage2 = newNode->cost; 74 | std::cerr << "dbg Better progress!\n"; 75 | std::cerr << " new cost is " << newNode->cost << "\n"; 76 | } 77 | } 78 | } 79 | 80 | if(nodes.size() > maxSize) { 81 | if(_verbose) { 82 | std::cerr << "dbg Queue needs trimming...\n"; 83 | } 84 | 85 | //Move all nodes to queue that sorts them by progress 86 | while(nodes.size() > 0) { 87 | tempQueue.push(nodes.top()); 88 | nodes.pop(); 89 | } 90 | //Move top nodes back to main queue 91 | for(unsigned int x = 0; x < this->targetSize; x++) { 92 | nodes.push(tempQueue.top()); 93 | tempQueue.pop(); 94 | } 95 | //Delete the rest of the nodes 96 | while(tempQueue.size() > 0) { 97 | Node * n = tempQueue.top(); 98 | tempQueue.pop(); 99 | n->env->deleteRecord(n); 100 | delete n; 101 | } 102 | } 103 | 104 | return true; 105 | } 106 | 107 | int garbage = 9999999; 108 | int garbage2 = 9999999; 109 | 110 | public: 111 | int setArgs(char** argv) { 112 | this->maxSize = atoi(argv[0]); 113 | this->targetSize = atoi(argv[1]); 114 | if(this->maxSize < this->targetSize) { 115 | std::swap(this->maxSize, this->targetSize); 116 | } 117 | assert(this->maxSize != this->targetSize); 118 | return 2; 119 | } 120 | 121 | int setArgs() { 122 | std::cerr << "Enter max size and then target size for queue:\n"; 123 | std::cin >> this->maxSize; 124 | std::cin >> this->targetSize; 125 | if(this->maxSize < this->targetSize) { 126 | std::swap(this->maxSize, this->targetSize); 127 | } 128 | assert(this->maxSize != this->targetSize); 129 | return 2; 130 | } 131 | 132 | Node * pop() { 133 | numPopped++; 134 | 135 | Node * ret = nodes.top(); 136 | nodes.pop(); 137 | 138 | //std::cerr << "Debug message: popped node with cost " << ret->cost << "\n"; 139 | //std::cerr << "Debug message: queue has size " << nodes.size() << " now.\n"; 140 | 141 | if(!ret->readyGates.size()) { 142 | assert(ret->numUnscheduledGates == 0); 143 | bool done = true; 144 | if(done) { 145 | if(!bestFinalNode) { 146 | if(_verbose) std::cerr << "dbg msg: found a final node.\n"; 147 | bestFinalNode = ret; 148 | } else if(ret->cost < bestFinalNode->cost) { 149 | if(_verbose) std::cerr << "dbg msg: found a better final node.\n"; 150 | //delete bestFinalNode; 151 | bestFinalNode = ret; 152 | } 153 | } 154 | } 155 | 156 | return ret; 157 | } 158 | 159 | int size() { 160 | return nodes.size(); 161 | } 162 | }; 163 | -------------------------------------------------------------------------------- /data/min-gates/4gt13_92_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 6 | cx q[2],q[3]; //cycle: 0 //cx logical_q[4],logical_q[0] 7 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 9 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 10 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 11 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 12 | cx q[2],q[4]; //cycle: 2 //cx logical_q[4],logical_q[1] 13 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 14 | cx q[3],q[2]; //cycle: 3 //cx logical_q[0],logical_q[4] 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 4 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 16 | cx q[4],q[3]; //cycle: 4 //cx logical_q[1],logical_q[0] 17 | cx q[4],q[2]; //cycle: 5 //cx logical_q[1],logical_q[4] 18 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 5 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 19 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 21 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[4] 22 | cx q[4],q[3]; //cycle: 8 //cx logical_q[1],logical_q[0] 23 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 9 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 24 | cx q[2],q[4]; //cycle: 9 //cx logical_q[4],logical_q[1] 25 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 26 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 10 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 27 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 28 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 11 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 29 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 11 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 30 | cx q[2],q[0]; //cycle: 12 //cx logical_q[4],logical_q[2] 31 | cx q[1],q[2]; //cycle: 13 //cx logical_q[3],logical_q[4] 32 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 13 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 33 | cx q[1],q[0]; //cycle: 14 //cx logical_q[3],logical_q[2] 34 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 14 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 35 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 15 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 36 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 15 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 37 | cx q[2],q[0]; //cycle: 16 //cx logical_q[4],logical_q[2] 38 | cx q[1],q[2]; //cycle: 17 //cx logical_q[3],logical_q[4] 39 | cx q[0],q[1]; //cycle: 18 //cx logical_q[2],logical_q[3] 40 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 18 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 41 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 42 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 43 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 44 | cx q[2],q[4]; //cycle: 20 //cx logical_q[4],logical_q[1] 45 | cx q[0],q[1]; //cycle: 20 //cx logical_q[2],logical_q[3] 46 | cx q[3],q[2]; //cycle: 21 //cx logical_q[0],logical_q[4] 47 | cx q[4],q[3]; //cycle: 22 //cx logical_q[1],logical_q[0] 48 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 22 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 49 | cx q[4],q[2]; //cycle: 23 //cx logical_q[1],logical_q[4] 50 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 23 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 51 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 24 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 52 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 24 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 53 | cx q[3],q[2]; //cycle: 25 //cx logical_q[0],logical_q[4] 54 | cx q[4],q[3]; //cycle: 26 //cx logical_q[1],logical_q[0] 55 | cx q[2],q[4]; //cycle: 27 //cx logical_q[4],logical_q[1] 56 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 27 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 57 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 28 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 58 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 29 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 59 | cx q[2],q[0]; //cycle: 30 //cx logical_q[4],logical_q[2] 60 | cx q[1],q[2]; //cycle: 31 //cx logical_q[3],logical_q[4] 61 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 31 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 62 | cx q[1],q[0]; //cycle: 32 //cx logical_q[3],logical_q[2] 63 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 32 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 64 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 33 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 65 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 33 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 66 | cx q[2],q[0]; //cycle: 34 //cx logical_q[4],logical_q[2] 67 | cx q[1],q[2]; //cycle: 35 //cx logical_q[3],logical_q[4] 68 | cx q[0],q[1]; //cycle: 36 //cx logical_q[2],logical_q[3] 69 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 36 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 70 | cx q[3],q[2]; //cycle: 37 //cx logical_q[0],logical_q[4] 71 | //66 original gates 72 | //66 final gates 73 | //41 nodes expanded (popped from queue). 74 | //16 nodes remain in queue. 75 | -------------------------------------------------------------------------------- /data/min-depth/4gt13_92_qx2.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[5]; 4 | creg c[5]; 5 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 6 | cx q[2],q[3]; //cycle: 0 //cx logical_q[4],logical_q[0] 7 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 8 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 0 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 9 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 10 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 1 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 11 | cx q[0],q[1]; //cycle: 1 //cx logical_q[2],logical_q[3] 12 | cx q[2],q[4]; //cycle: 2 //cx logical_q[4],logical_q[1] 13 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 2 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 14 | cx q[3],q[2]; //cycle: 3 //cx logical_q[0],logical_q[4] 15 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 4 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 16 | cx q[4],q[3]; //cycle: 4 //cx logical_q[1],logical_q[0] 17 | cx q[4],q[2]; //cycle: 5 //cx logical_q[1],logical_q[4] 18 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 5 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 19 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 20 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 6 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 21 | cx q[3],q[2]; //cycle: 7 //cx logical_q[0],logical_q[4] 22 | cx q[4],q[3]; //cycle: 8 //cx logical_q[1],logical_q[0] 23 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 9 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 24 | cx q[2],q[4]; //cycle: 9 //cx logical_q[4],logical_q[1] 25 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 26 | u3(0.000000, 0.000000, 0.785398) q[4]; //cycle: 10 //u3(0.000000, 0.000000, 0.785398) logical_q[1] 27 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 10 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 28 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 11 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 29 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 11 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 30 | cx q[2],q[0]; //cycle: 12 //cx logical_q[4],logical_q[2] 31 | cx q[1],q[2]; //cycle: 13 //cx logical_q[3],logical_q[4] 32 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 13 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 33 | cx q[1],q[0]; //cycle: 14 //cx logical_q[3],logical_q[2] 34 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 14 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 35 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 15 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 36 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 15 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 37 | cx q[2],q[0]; //cycle: 16 //cx logical_q[4],logical_q[2] 38 | cx q[1],q[2]; //cycle: 17 //cx logical_q[3],logical_q[4] 39 | cx q[0],q[1]; //cycle: 18 //cx logical_q[2],logical_q[3] 40 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 18 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 41 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 42 | u3(0.000000, 0.000000, 0.785398) q[1]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[3] 43 | u3(0.000000, 0.000000, 0.785398) q[0]; //cycle: 19 //u3(0.000000, 0.000000, 0.785398) logical_q[2] 44 | cx q[2],q[4]; //cycle: 20 //cx logical_q[4],logical_q[1] 45 | cx q[0],q[1]; //cycle: 20 //cx logical_q[2],logical_q[3] 46 | cx q[3],q[2]; //cycle: 21 //cx logical_q[0],logical_q[4] 47 | cx q[4],q[3]; //cycle: 22 //cx logical_q[1],logical_q[0] 48 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 22 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 49 | cx q[4],q[2]; //cycle: 23 //cx logical_q[1],logical_q[4] 50 | u3(0.000000, 0.000000, 0.785398) q[3]; //cycle: 23 //u3(0.000000, 0.000000, 0.785398) logical_q[0] 51 | u3(0.000000, 0.000000, -0.785398) q[4]; //cycle: 24 //u3(0.000000, 0.000000, -0.785398) logical_q[1] 52 | u3(0.000000, 0.000000, -0.785398) q[2]; //cycle: 24 //u3(0.000000, 0.000000, -0.785398) logical_q[4] 53 | cx q[3],q[2]; //cycle: 25 //cx logical_q[0],logical_q[4] 54 | cx q[4],q[3]; //cycle: 26 //cx logical_q[1],logical_q[0] 55 | cx q[2],q[4]; //cycle: 27 //cx logical_q[4],logical_q[1] 56 | u3(1.570796, 0.000000, 3.141593) q[3]; //cycle: 27 //u3(1.570796, 0.000000, 3.141593) logical_q[0] 57 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 28 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 58 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 29 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 59 | cx q[2],q[0]; //cycle: 30 //cx logical_q[4],logical_q[2] 60 | cx q[1],q[2]; //cycle: 31 //cx logical_q[3],logical_q[4] 61 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 31 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 62 | cx q[1],q[0]; //cycle: 32 //cx logical_q[3],logical_q[2] 63 | u3(0.000000, 0.000000, 0.785398) q[2]; //cycle: 32 //u3(0.000000, 0.000000, 0.785398) logical_q[4] 64 | u3(0.000000, 0.000000, -0.785398) q[1]; //cycle: 33 //u3(0.000000, 0.000000, -0.785398) logical_q[3] 65 | u3(0.000000, 0.000000, -0.785398) q[0]; //cycle: 33 //u3(0.000000, 0.000000, -0.785398) logical_q[2] 66 | cx q[2],q[0]; //cycle: 34 //cx logical_q[4],logical_q[2] 67 | cx q[1],q[2]; //cycle: 35 //cx logical_q[3],logical_q[4] 68 | cx q[0],q[1]; //cycle: 36 //cx logical_q[2],logical_q[3] 69 | u3(1.570796, 0.000000, 3.141593) q[2]; //cycle: 36 //u3(1.570796, 0.000000, 3.141593) logical_q[4] 70 | cx q[3],q[2]; //cycle: 37 //cx logical_q[0],logical_q[4] 71 | //66 original gates 72 | //66 final gates 73 | //38 original depth (cycles) 74 | //38 cycles in selected mapping 75 | //41 nodes expanded (popped from queue). 76 | //16 nodes remain in queue. 77 | -------------------------------------------------------------------------------- /code/src/full_classes/QASMparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | DD-based simulator by JKU Linz, Austria 3 | 4 | Developer: Alwin Zulehner, Robert Wille 5 | 6 | With code from the QMDD implementation provided by Michael Miller (University of Victoria, Canada) 7 | and Philipp Niemann (University of Bremen, Germany). 8 | 9 | For more information, please visit http://iic.jku.at/eda/research/quantum_simulation 10 | 11 | If you have any questions feel free to contact us using 12 | alwin.zulehner@jku.at or robert.wille@jku.at 13 | 14 | If you use the quantum simulator for your research, we would be thankful if you referred to it 15 | by citing the following publication: 16 | 17 | @article{zulehner2018simulation, 18 | title={Advanced Simulation of Quantum Computations}, 19 | author={Zulehner, Alwin and Wille, Robert}, 20 | journal={IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)}, 21 | year={2018}, 22 | eprint = {arXiv:1707.00865} 23 | } 24 | */ 25 | 26 | #ifndef QASM_SIMULATOR_H_ 27 | #define QASM_SIMULATOR_H_ 28 | 29 | #include "QASMscanner.hpp" 30 | #include "QASMtoken.hpp" 31 | #include 32 | #include 33 | 34 | class QASMparser { 35 | public: 36 | QASMparser(std::string fname); 37 | virtual ~QASMparser(); 38 | 39 | void Parse(); 40 | 41 | struct gate { 42 | int target; 43 | int control; 44 | char type[128]; 45 | }; 46 | 47 | std::vector > getLayers() { 48 | return layers; 49 | } 50 | 51 | int getNqubits() { 52 | return nqubits; 53 | } 54 | 55 | int getNgates() { 56 | return ngates; 57 | } 58 | 59 | private: 60 | class Expr { 61 | public: 62 | enum class Kind {number, plus, minus, sign, times, sin, cos, tan, exp, ln, sqrt, div, power, id}; 63 | double num; 64 | Kind kind; 65 | Expr* op1 = NULL; 66 | Expr* op2 = NULL; 67 | std::string id; 68 | 69 | Expr(Kind kind, Expr* op1, Expr* op2, double num, std::string id) { 70 | this->kind = kind; 71 | this->op1 = op1; 72 | this->op2 = op2; 73 | this->num = num; 74 | this->id = id; 75 | } 76 | 77 | Expr(const Expr& expr) { 78 | this->kind = expr.kind; 79 | this->num = expr.num; 80 | this->id = expr.id; 81 | if(expr.op1 != NULL) { 82 | this->op1 = new Expr(*expr.op1); 83 | } 84 | if(expr.op2 != NULL) { 85 | this->op2 = new Expr(*expr.op2); 86 | } 87 | } 88 | 89 | ~Expr() { 90 | if(op1 != NULL) { 91 | delete op1; 92 | } 93 | if(op2 != NULL) { 94 | delete op2; 95 | } 96 | } 97 | }; 98 | 99 | class BasisGate { 100 | public: 101 | virtual ~BasisGate() = default; 102 | }; 103 | 104 | class Ugate : public BasisGate { 105 | public: 106 | Expr* theta; 107 | Expr* phi; 108 | Expr* lambda; 109 | std::string target; 110 | 111 | Ugate(Expr* theta, Expr* phi, Expr* lambda, std::string target) { 112 | this->theta = theta; 113 | this->phi = phi; 114 | this->lambda = lambda; 115 | this->target = target; 116 | } 117 | 118 | ~Ugate() { 119 | if(theta != NULL) { 120 | delete theta; 121 | } 122 | if(phi != NULL) { 123 | delete phi; 124 | } 125 | if(lambda != NULL) { 126 | delete lambda; 127 | } 128 | } 129 | }; 130 | 131 | class CXgate : public BasisGate { 132 | public: 133 | std::string control; 134 | std::string target; 135 | 136 | CXgate(std::string control, std::string target) { 137 | this->control = control; 138 | this->target = target; 139 | } 140 | }; 141 | 142 | class SWPgate : public BasisGate { 143 | public: 144 | std::string control; 145 | std::string target; 146 | 147 | SWPgate(std::string control, std::string target) { 148 | this->control = control; 149 | this->target = target; 150 | } 151 | }; 152 | 153 | class CompoundGate { 154 | public: 155 | std::vector parameterNames; 156 | std::vector argumentNames; 157 | std::vector gates; 158 | bool opaque; 159 | }; 160 | 161 | class Snapshot { 162 | public: 163 | ~Snapshot() { 164 | if(probabilities != NULL) { 165 | delete[] probabilities; 166 | } 167 | if(statevector != NULL) { 168 | delete[] statevector; 169 | } 170 | } 171 | 172 | unsigned long long len; 173 | double* probabilities; 174 | std::string* statevector; 175 | std::map probabilities_ket; 176 | }; 177 | 178 | void scan(); 179 | void check(Token::Kind expected); 180 | 181 | Token la,t; 182 | Token::Kind sym = Token::Kind::none; 183 | 184 | std::string fname; 185 | std::istream* in; 186 | QASMscanner* scanner; 187 | std::map > qregs; 188 | std::map > cregs; 189 | std::pair QASMargumentQreg(); 190 | std::pair QASMargumentCreg(); 191 | Expr* QASMexponentiation(); 192 | Expr* QASMfactor(); 193 | Expr* QASMterm(); 194 | Expr* QASMexp(); 195 | void QASMgateDecl(); 196 | void QASMopaqueGateDecl(); 197 | void QASMgate(bool execute = true); 198 | void QASMqop(bool execute = true); 199 | void QASMexpList(std::vector& expressions); 200 | void QASMidList(std::vector& identifiers); 201 | void QASMargsList(std::vector >& arguments); 202 | std::set unaryops {Token::Kind::sin,Token::Kind::cos,Token::Kind::tan,Token::Kind::exp,Token::Kind::ln,Token::Kind::sqrt}; 203 | 204 | std::map compoundGates; 205 | Expr* RewriteExpr(Expr* expr, std::map& exprMap); 206 | void printExpr(Expr* expr); 207 | 208 | std::vector > layers; 209 | 210 | unsigned int nqubits = 0; 211 | int* last_layer; 212 | unsigned int ngates = 0; 213 | 214 | void addUgate(int target, double theta, double phi, double lambda); 215 | void addCXgate(int target, int control); 216 | void addSWPgate(int target, int control); 217 | }; 218 | 219 | #endif /* QASM_SIMULATOR_H_ */ 220 | -------------------------------------------------------------------------------- /data/min-gates/16QBT_10CYC_TFL_3_aspen4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 6 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 7 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 8 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 9 | cx q[6],q[7]; //cycle: 0 //cx logical_q[13],logical_q[6] 10 | cx q[3],q[2]; //cycle: 0 //cx logical_q[14],logical_q[12] 11 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 12 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 13 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 14 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 15 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 16 | cx q[7],q[0]; //cycle: 1 //cx logical_q[6],logical_q[10] 17 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 18 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 19 | cx q[2],q[1]; //cycle: 1 //cx logical_q[12],logical_q[1] 20 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 21 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 22 | cx q[8],q[15]; //cycle: 1 //cx logical_q[2],logical_q[8] 23 | cx q[12],q[11]; //cycle: 1 //cx logical_q[9],logical_q[5] 24 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 25 | cx q[5],q[4]; //cycle: 2 //cx logical_q[0],logical_q[11] 26 | cx q[2],q[1]; //cycle: 2 //cx logical_q[12],logical_q[1] 27 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 28 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 29 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 30 | cx q[9],q[8]; //cycle: 2 //cx logical_q[15],logical_q[2] 31 | cx q[10],q[11]; //cycle: 2 //cx logical_q[3],logical_q[5] 32 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 33 | cx q[4],q[3]; //cycle: 3 //cx logical_q[11],logical_q[14] 34 | cx q[2],q[13]; //cycle: 3 //cx logical_q[12],logical_q[7] 35 | cx q[6],q[5]; //cycle: 3 //cx logical_q[13],logical_q[0] 36 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 37 | cx q[7],q[0]; //cycle: 3 //cx logical_q[6],logical_q[10] 38 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 39 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 40 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 41 | cx q[10],q[11]; //cycle: 3 //cx logical_q[3],logical_q[5] 42 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 43 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 44 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 45 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 46 | cx q[6],q[5]; //cycle: 4 //cx logical_q[13],logical_q[0] 47 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 48 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 49 | cx q[10],q[11]; //cycle: 4 //cx logical_q[3],logical_q[5] 50 | cx q[2],q[13]; //cycle: 5 //cx logical_q[12],logical_q[7] 51 | cx q[8],q[15]; //cycle: 5 //cx logical_q[2],logical_q[8] 52 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 53 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 54 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 55 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 56 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 57 | cx q[4],q[3]; //cycle: 6 //cx logical_q[11],logical_q[14] 58 | cx q[2],q[1]; //cycle: 6 //cx logical_q[12],logical_q[1] 59 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 60 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 61 | cx q[6],q[7]; //cycle: 6 //cx logical_q[13],logical_q[6] 62 | cx q[13],q[12]; //cycle: 6 //cx logical_q[7],logical_q[9] 63 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 64 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 65 | cx q[2],q[1]; //cycle: 7 //cx logical_q[12],logical_q[1] 66 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 67 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 68 | cx q[6],q[7]; //cycle: 7 //cx logical_q[13],logical_q[6] 69 | cx q[15],q[14]; //cycle: 7 //cx logical_q[8],logical_q[4] 70 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 71 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 72 | cx q[3],q[2]; //cycle: 8 //cx logical_q[14],logical_q[12] 73 | cx q[13],q[12]; //cycle: 8 //cx logical_q[7],logical_q[9] 74 | cx q[15],q[14]; //cycle: 8 //cx logical_q[8],logical_q[4] 75 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 76 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 77 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 78 | //73 original gates 79 | //73 final gates 80 | //392622 nodes expanded (popped from queue). 81 | //78 nodes remain in queue. 82 | -------------------------------------------------------------------------------- /data/min-depth/16QBT_10CYC_TFL_3_aspen4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 6 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 7 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 8 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 9 | cx q[6],q[7]; //cycle: 0 //cx logical_q[13],logical_q[6] 10 | cx q[3],q[2]; //cycle: 0 //cx logical_q[14],logical_q[12] 11 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 12 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 13 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 14 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 15 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 16 | cx q[7],q[0]; //cycle: 1 //cx logical_q[6],logical_q[10] 17 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 18 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 19 | cx q[2],q[1]; //cycle: 1 //cx logical_q[12],logical_q[1] 20 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 21 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 22 | cx q[8],q[15]; //cycle: 1 //cx logical_q[2],logical_q[8] 23 | cx q[12],q[11]; //cycle: 1 //cx logical_q[9],logical_q[5] 24 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 25 | cx q[5],q[4]; //cycle: 2 //cx logical_q[0],logical_q[11] 26 | cx q[2],q[1]; //cycle: 2 //cx logical_q[12],logical_q[1] 27 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 28 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 29 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 30 | cx q[9],q[8]; //cycle: 2 //cx logical_q[15],logical_q[2] 31 | cx q[10],q[11]; //cycle: 2 //cx logical_q[3],logical_q[5] 32 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 33 | cx q[4],q[3]; //cycle: 3 //cx logical_q[11],logical_q[14] 34 | cx q[2],q[13]; //cycle: 3 //cx logical_q[12],logical_q[7] 35 | cx q[6],q[5]; //cycle: 3 //cx logical_q[13],logical_q[0] 36 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 37 | cx q[7],q[0]; //cycle: 3 //cx logical_q[6],logical_q[10] 38 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 39 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 40 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 41 | cx q[10],q[11]; //cycle: 3 //cx logical_q[3],logical_q[5] 42 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 43 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 44 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 45 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 46 | cx q[6],q[5]; //cycle: 4 //cx logical_q[13],logical_q[0] 47 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 48 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 49 | cx q[10],q[11]; //cycle: 4 //cx logical_q[3],logical_q[5] 50 | cx q[2],q[13]; //cycle: 5 //cx logical_q[12],logical_q[7] 51 | cx q[8],q[15]; //cycle: 5 //cx logical_q[2],logical_q[8] 52 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 53 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 54 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 55 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 56 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 57 | cx q[4],q[3]; //cycle: 6 //cx logical_q[11],logical_q[14] 58 | cx q[2],q[1]; //cycle: 6 //cx logical_q[12],logical_q[1] 59 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 60 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 61 | cx q[6],q[7]; //cycle: 6 //cx logical_q[13],logical_q[6] 62 | cx q[13],q[12]; //cycle: 6 //cx logical_q[7],logical_q[9] 63 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 64 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 65 | cx q[2],q[1]; //cycle: 7 //cx logical_q[12],logical_q[1] 66 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 67 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 68 | cx q[6],q[7]; //cycle: 7 //cx logical_q[13],logical_q[6] 69 | cx q[15],q[14]; //cycle: 7 //cx logical_q[8],logical_q[4] 70 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 71 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 72 | cx q[3],q[2]; //cycle: 8 //cx logical_q[14],logical_q[12] 73 | cx q[13],q[12]; //cycle: 8 //cx logical_q[7],logical_q[9] 74 | cx q[15],q[14]; //cycle: 8 //cx logical_q[8],logical_q[4] 75 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 76 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 77 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 78 | //73 original gates 79 | //73 final gates 80 | //10 original depth (cycles) 81 | //10 cycles in selected mapping 82 | //392622 nodes expanded (popped from queue). 83 | //78 nodes remain in queue. 84 | -------------------------------------------------------------------------------- /code/src/full_classes/Node.cpp: -------------------------------------------------------------------------------- 1 | #include "Node.hpp" 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | //const int MAX_QUBITS = 20; 8 | int GLOBALCOUNTER=0; 9 | 10 | Node::Node() { 11 | for(int x = 0; x < MAX_QUBITS; x++) { 12 | qal[x] = x; 13 | laq[x] = x; 14 | lastNonSwapGate[x] = NULL; 15 | lastGate[x] = NULL; 16 | } 17 | this->cost = 0; 18 | this->dead = false; 19 | } 20 | 21 | Node::~Node() { 22 | scheduled->clean(); 23 | } 24 | 25 | //schedule a gate, or return false if it conflicts with an active gate 26 | //the gate parameter uses logical qubits (except in swaps); this function determines physical locations based on prior swaps 27 | //the timeOffset can be used if we want to schedule a gate to start X cycles in the future 28 | //this function adjusts qubit map when scheduling a swap 29 | bool Node::scheduleGate(GateNode * gate, unsigned int timeOffset) { 30 | bool isSwap = !gate->name.compare("swp"); 31 | isSwap = isSwap || !gate->name.compare("swp"); 32 | 33 | int physicalControl = gate->control; 34 | int physicalTarget = gate->target; 35 | if(!isSwap) { 36 | if(physicalControl >= 0) { 37 | physicalControl = laq[physicalControl]; 38 | } 39 | if(physicalTarget >= 0) { 40 | physicalTarget = laq[physicalTarget]; 41 | } 42 | } 43 | 44 | int busyControl = this->busyCycles(physicalControl); 45 | if(physicalControl >= 0 && busyControl > 0 && busyControl > (int) timeOffset) { 46 | return false; 47 | } 48 | int busyTarget = this->busyCycles(physicalTarget); 49 | if(physicalTarget >= 0 && busyTarget > 0 && busyTarget > (int) timeOffset) { 50 | return false; 51 | } 52 | 53 | if(!isSwap) { 54 | //if appropriate, add double-child to ready gates 55 | if(gate->controlChild && gate->controlChild == gate->targetChild) { 56 | readyGates.insert(gate->controlChild); 57 | } 58 | //if appropriate, add control child to ready gates 59 | if(gate->controlChild && gate->controlChild != gate->targetChild) { 60 | if(gate->controlChild->control < 0) {//single-qubit gate 61 | readyGates.insert(gate->controlChild); 62 | } else { 63 | int childParentBit; 64 | GateNode * otherParent; 65 | if(gate->controlChild->controlParent == gate) { 66 | otherParent = gate->controlChild->targetParent; 67 | if(gate->controlChild->targetParent) { 68 | childParentBit = gate->controlChild->target; 69 | } else { 70 | childParentBit = -1; 71 | } 72 | } else { 73 | assert(gate->controlChild->targetParent == gate); 74 | otherParent = gate->controlChild->controlParent; 75 | if(gate->controlChild->controlParent) { 76 | childParentBit = gate->controlChild->control; 77 | } else { 78 | childParentBit = -1; 79 | } 80 | } 81 | if(childParentBit < 0 || (this->lastNonSwapGate[childParentBit] && this->lastNonSwapGate[childParentBit]->gate == otherParent)) { 82 | readyGates.insert(gate->controlChild); 83 | } 84 | } 85 | } 86 | //if appropriate, add target child to ready gates 87 | if(gate->targetChild && gate->controlChild != gate->targetChild) { 88 | if(gate->targetChild->control < 0) {//single-qubit gate 89 | readyGates.insert(gate->targetChild); 90 | } else { 91 | int childParentBit; 92 | GateNode * otherParent; 93 | if(gate->targetChild->controlParent == gate) { 94 | otherParent = gate->targetChild->targetParent; 95 | if(gate->targetChild->targetParent) { 96 | childParentBit = gate->targetChild->target; 97 | } else { 98 | childParentBit = -1; 99 | } 100 | } else { 101 | assert(gate->targetChild->targetParent == gate); 102 | otherParent = gate->targetChild->controlParent; 103 | if(gate->targetChild->controlParent) { 104 | childParentBit = gate->targetChild->control; 105 | } else { 106 | childParentBit = -1; 107 | } 108 | } 109 | if(childParentBit < 0 || (this->lastNonSwapGate[childParentBit] && this->lastNonSwapGate[childParentBit]->gate == otherParent)) { 110 | readyGates.insert(gate->targetChild); 111 | } 112 | } 113 | } 114 | } 115 | 116 | ScheduledGate * sg = new ScheduledGate(gate, this->cycle + timeOffset); 117 | sg->physicalControl = physicalControl; 118 | sg->physicalTarget = physicalTarget; 119 | 120 | if(physicalControl >= 0) { 121 | this->lastGate[physicalControl] = sg; 122 | } 123 | if(sg->gate->control >= 0 && !isSwap) { 124 | this->lastNonSwapGate[sg->gate->control] = sg; 125 | } 126 | 127 | if(physicalTarget >= 0) { 128 | this->lastGate[physicalTarget] = sg; 129 | } 130 | if(sg->gate->target >= 0 && !isSwap) { 131 | this->lastNonSwapGate[sg->gate->target] = sg; 132 | } 133 | 134 | if(!isSwap) { 135 | if(this->readyGates.erase(gate) != 1) { 136 | std::cerr << "FATAL ERROR: unable to remove scheduled gate from ready list.\n"; 137 | std::cerr << "\tGate name: " << gate->name << "\n"; 138 | std::cerr << "\tTime offset: " << timeOffset << "\n"; 139 | assert(false); 140 | } 141 | this->numUnscheduledGates--; 142 | } 143 | 144 | this->scheduled = this->scheduled->push(sg); 145 | 146 | //adjust qubit map 147 | if(isSwap) { 148 | if(qal[physicalControl] >= 0 && qal[physicalTarget] >= 0) { 149 | std::swap(laq[(int)qal[physicalControl]], laq[(int)qal[physicalTarget]]); 150 | } else if(qal[physicalControl] >= 0) { 151 | laq[(int)qal[physicalControl]] = physicalTarget; 152 | } else if(qal[physicalTarget] >= 0) { 153 | laq[(int)qal[physicalTarget]] = physicalControl; 154 | } else { 155 | assert(false); 156 | } 157 | std::swap(qal[physicalControl], qal[physicalTarget]); 158 | } 159 | 160 | return true; 161 | } 162 | 163 | //prepares a new child node (without scheduling any more gates) 164 | Node * Node::prepChild() { 165 | Node * child = new Node; 166 | child->numUnscheduledGates = this->numUnscheduledGates; 167 | child->env = this->env; 168 | child->parent = this; 169 | child->cycle = this->cycle + 1; 170 | child->readyGates = this->readyGates;//note: this actually produces a separate copy 171 | child->scheduled = scheduled->newRef(); 172 | for(int x = 0; x < env->numPhysicalQubits; x++) { 173 | child->qal[x] = this->qal[x]; 174 | child->laq[x] = this->laq[x]; 175 | child->lastNonSwapGate[x] = this->lastNonSwapGate[x]; 176 | child->lastGate[x] = this->lastGate[x]; 177 | } 178 | child->cost = 0;//Remember to calculate cost in expander, *after* it's done scheduling new gates for this node //child->cost = env->cost->getCost(child); 179 | 180 | return child; 181 | } 182 | -------------------------------------------------------------------------------- /code/src/Expander/NoSwaps.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEFAULTPLUSINITIAL_HPP 2 | #define DEFAULTPLUSINITIAL_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "Expander.hpp" 8 | #include "Queue.hpp" 9 | #include "CostFunc.hpp" 10 | 11 | class NoSwaps : public Expander { 12 | private: 13 | int busyCycles(Node * n, int logicalQubit) { 14 | if(!n->lastNonSwapGate[logicalQubit]) return 0; 15 | int cycles = n->lastNonSwapGate[logicalQubit]->cycle + n->lastNonSwapGate[logicalQubit]->gate->latency - n->cycle; 16 | if(cycles < 0) return 0; 17 | return cycles; 18 | } 19 | public: 20 | bool expand(Queue * nodes, Node * node) { 21 | //return false if we're done expanding 22 | if(nodes->getBestFinalNode() && node->cost >= nodes->getBestFinalNode()->cost) { 23 | return false; 24 | } 25 | 26 | //unset initial mapping for root node 27 | if(node->parent == NULL) { 28 | for(int x = 0; x < node->env->numLogicalQubits; x++) { 29 | node->laq[x] = -1; 30 | node->qal[x] = -1; 31 | } 32 | } 33 | 34 | //if this node has any unmapped qubits affecting frontier, make alternate nodes where they're mapped: 35 | bool addedNodes = false; 36 | Node * n = node; 37 | Environment * env = node->env; 38 | for(auto iter = n->readyGates.begin(); iter != n->readyGates.end(); iter++) { 39 | if(addedNodes) { 40 | //just let the child nodes handle the next one: 41 | break; 42 | } 43 | 44 | int numAdded = 0; 45 | 46 | GateNode * g = *iter; 47 | //GateNode * g = env->firstCXPerQubit[z]; 48 | 49 | if(g && g->control < 0) { 50 | g = g->nextTargetCNOT ? g->nextTargetCNOT : g; 51 | } 52 | 53 | if(g && g->control >= 0) { 54 | int physC = n->laq[g->control]; 55 | int physT = n->laq[g->target]; 56 | if(physC < 0 && physT < 0) { 57 | addedNodes = true; 58 | for(unsigned int x = 0; x < env->couplings.size(); x++) { 59 | GateNode * sw = env->possibleSwaps[x]; 60 | if(n->qal[sw->control] < 0 && n->qal[sw->target] < 0) { 61 | Node * n1 = n->prepChild(); 62 | n1->cycle--; 63 | n1->laq[g->control] = sw->control; 64 | n1->laq[g->target] = sw->target; 65 | n1->qal[sw->control] = g->control; 66 | n1->qal[sw->target] = g->target; 67 | n1->cost = n->cost-1;//env->cost->getCost(n1); 68 | if(nodes->push(n1)) { 69 | //cerr << "//try " << g->control <<"<->" << g->target << " assigned to physical " << sw->control << "<->" << sw->target << "\n"; 70 | numAdded++; 71 | } else { 72 | delete n1; 73 | } 74 | 75 | Node * n2 = n->prepChild(); 76 | n2->cycle--; 77 | n2->laq[g->control] = sw->target; 78 | n2->laq[g->target] = sw->control; 79 | n2->qal[sw->control] = g->target; 80 | n2->qal[sw->target] = g->control; 81 | n2->cost = n->cost-1;//env->cost->getCost(n2); 82 | if(nodes->push(n2)) { 83 | numAdded++; 84 | } else { 85 | delete n2; 86 | } 87 | } 88 | } 89 | } else if(physC < 0) { 90 | addedNodes = true; 91 | for(unsigned int x = 0; x < env->couplings.size(); x++) { 92 | GateNode * sw = env->possibleSwaps[x]; 93 | if(n->qal[sw->control] < 0 && n->qal[sw->target] == g->target) { 94 | Node * n1 = n->prepChild(); 95 | n1->cycle--; 96 | n1->laq[g->control] = sw->control; 97 | n1->qal[sw->control] = g->control; 98 | assert(n1->laq[g->target] == sw->target); 99 | n1->cost = n->cost-1;//env->cost->getCost(n1); 100 | if(nodes->push(n1)) { 101 | numAdded++; 102 | } else { 103 | delete n1; 104 | } 105 | } else if(n->qal[sw->target] < 0 && n->qal[sw->control] == g->target) { 106 | Node * n1 = n->prepChild(); 107 | n1->cycle--; 108 | n1->laq[g->control] = sw->target; 109 | n1->qal[sw->target] = g->control; 110 | assert(n1->laq[g->target] == sw->control); 111 | n1->cost = n->cost-1;//env->cost->getCost(n1); 112 | if(nodes->push(n1)) { 113 | numAdded++; 114 | } else { 115 | delete n1; 116 | } 117 | } 118 | } 119 | } else if(physT < 0) { 120 | addedNodes = true; 121 | for(unsigned int x = 0; x < env->couplings.size(); x++) { 122 | GateNode * sw = env->possibleSwaps[x]; 123 | if(n->qal[sw->control] < 0 && n->qal[sw->target] == g->control) { 124 | Node * n1 = n->prepChild(); 125 | n1->cycle--; 126 | n1->laq[g->target] = sw->control; 127 | n1->qal[sw->control] = g->target; 128 | assert(n1->laq[g->control] == sw->target); 129 | n1->cost = n->cost-1;//env->cost->getCost(n1); 130 | if(nodes->push(n1)) { 131 | numAdded++; 132 | } else { 133 | delete n1; 134 | } 135 | } else if(n->qal[sw->target] < 0 && n->qal[sw->control] == g->control) { 136 | Node * n1 = n->prepChild(); 137 | n1->cycle--; 138 | n1->laq[g->target] = sw->target; 139 | n1->qal[sw->target] = g->target; 140 | assert(n1->laq[g->control] == sw->control); 141 | n1->cost = n->cost-1;//env->cost->getCost(n1); 142 | if(nodes->push(n1)) { 143 | numAdded++; 144 | } else { 145 | delete n1; 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | if(addedNodes) { 153 | return true; 154 | } 155 | 156 | vector possibleGates;//executable ready gates 157 | for(auto iter = node->readyGates.begin(); iter != node->readyGates.end(); iter++) { 158 | GateNode * g = *iter; 159 | int target = g->target; 160 | int control = g->control; 161 | 162 | bool good = (node->cycle >= -1); 163 | 164 | if(good && target >= 0 && node->lastNonSwapGate[target]) { 165 | if(busyCycles(node, target) > 1) { 166 | good = false; 167 | } 168 | } 169 | 170 | if(good && control >= 0 && node->lastNonSwapGate[control]) { 171 | if(busyCycles(node, control) > 1) { 172 | good = false; 173 | } 174 | } 175 | 176 | //make sure CX is actually executable 177 | if(good && control >= 0 && target >= 0) {//gate has 2 qubits 178 | int physicalTarget = node->laq[target]; 179 | int physicalControl = node->laq[control]; 180 | if(node->env->couplings.count(make_pair(physicalTarget,physicalControl)) <= 0) { 181 | if(node->env->couplings.count(make_pair(physicalControl,physicalTarget)) <= 0) { 182 | good = false; 183 | } 184 | } 185 | } 186 | 187 | if(good) { 188 | possibleGates.push_back(g); 189 | } 190 | } 191 | 192 | Node * child = node->prepChild(); 193 | int numgatesscheduled = 0; 194 | 195 | //schedule the gates 196 | for(unsigned int y = 0; y < possibleGates.size(); y++) { 197 | if(node->cycle >= -1) { 198 | assert(child->scheduleGate(possibleGates[y])); 199 | numgatesscheduled++; 200 | } else { 201 | assert(false); 202 | } 203 | } 204 | 205 | bool good = true; 206 | if(!numgatesscheduled) { 207 | int numbusy = 0; 208 | for(int x = 0; x < node->env->numLogicalQubits; x++) { 209 | if(busyCycles(child, x) > 0) { 210 | numbusy++; 211 | } 212 | } 213 | if(!numbusy) { 214 | good = false; 215 | } 216 | } 217 | 218 | if(good) { 219 | child->cost = node->cost-numgatesscheduled;//node->env->cost->getCost(child); 220 | 221 | if(!nodes->push(child)) { 222 | delete child; 223 | } 224 | } else { 225 | delete child; 226 | } 227 | 228 | return true; 229 | } 230 | }; 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /code/src/full_classes/QASMscanner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | DD-based simulator by JKU Linz, Austria 3 | 4 | Developer: Alwin Zulehner, Robert Wille 5 | 6 | With code from the QMDD implementation provided by Michael Miller (University of Victoria, Canada) 7 | and Philipp Niemann (University of Bremen, Germany). 8 | 9 | For more information, please visit http://iic.jku.at/eda/research/quantum_simulation 10 | 11 | If you have any questions feel free to contact us using 12 | alwin.zulehner@jku.at or robert.wille@jku.at 13 | 14 | If you use the quantum simulator for your research, we would be thankful if you referred to it 15 | by citing the following publication: 16 | 17 | @article{zulehner2018simulation, 18 | title={Advanced Simulation of Quantum Computations}, 19 | author={Zulehner, Alwin and Wille, Robert}, 20 | journal={IEEE Transactions on Computer Aided Design of Integrated Circuits and Systems (TCAD)}, 21 | year={2018}, 22 | eprint = {arXiv:1707.00865} 23 | } 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "QASMscanner.hpp" 35 | 36 | QASMscanner::QASMscanner(std::istream& in_stream) : in(in_stream) { 37 | // initialize error handling support 38 | keywords["qreg"] = Token::Kind::qreg; 39 | keywords["creg"] = Token::Kind::creg; 40 | keywords["gate"] = Token::Kind::gate; 41 | keywords["measure"] = Token::Kind::measure; 42 | keywords["U"] = Token::Kind::ugate; 43 | keywords["CX"] = Token::Kind::cxgate; 44 | keywords["pi"] = Token::Kind::pi; 45 | keywords["OPENQASM"] = Token::Kind::openqasm; 46 | keywords["show_probabilities"] = Token::Kind::probabilities; 47 | keywords["sin"] = Token::Kind::sin; 48 | keywords["cos"] = Token::Kind::cos; 49 | keywords["tan"] = Token::Kind::tan; 50 | keywords["exp"] = Token::Kind::exp; 51 | keywords["ln"] = Token::Kind::ln; 52 | keywords["sqrt"] = Token::Kind::sqrt; 53 | keywords["include"] = Token::Kind::include; 54 | keywords["barrier"] = Token::Kind::barrier; 55 | keywords["opaque"] = Token::Kind::opaque; 56 | keywords["if"] = Token::Kind::_if; 57 | keywords["reset"] = Token::Kind::reset; 58 | keywords["snapshot"] = Token::Kind::snapshot; 59 | keywords["SWP"] = Token::Kind::swapgate; 60 | line = 1; 61 | col = 0; 62 | ch = 0; 63 | nextCh(); 64 | } 65 | 66 | void QASMscanner::addFileInput(std::string fname) { 67 | std::ifstream* in = new std::ifstream (fname, std::ifstream::in); 68 | if(in->fail()) { 69 | std::cerr << "Failed to open file '" << fname << "'!" << std::endl; 70 | } else { 71 | streams.push(in); 72 | lines.push(LineInfo(ch, line, col)); 73 | line = 0; 74 | col = 0; 75 | } 76 | nextCh(); 77 | } 78 | 79 | void QASMscanner::nextCh() { 80 | if(!streams.empty() && streams.top()->eof()) { 81 | delete streams.top(); 82 | streams.pop(); 83 | ch = lines.top().ch; 84 | col = lines.top().col; 85 | line = lines.top().line; 86 | lines.pop(); 87 | return; 88 | } 89 | if(!streams.empty()) { 90 | col++; 91 | streams.top()->get(ch); 92 | } else { 93 | if(!in.eof()) { 94 | col++; 95 | in.get(ch); 96 | } else { 97 | ch = (char) -1; 98 | } 99 | } 100 | if(ch == '\n') { 101 | col = 0; 102 | line++; 103 | } 104 | } 105 | 106 | Token QASMscanner::next() { 107 | while(iswspace(ch)) { 108 | nextCh(); 109 | } 110 | 111 | Token t = Token(Token::Kind::none, line, col); 112 | 113 | switch(ch) { 114 | case 'a': 115 | case 'b': 116 | case 'c': 117 | case 'd': 118 | case 'e': 119 | case 'f': 120 | case 'g': 121 | case 'h': 122 | case 'i': 123 | case 'j': 124 | case 'k': 125 | case 'l': 126 | case 'm': 127 | case 'n': 128 | case 'o': 129 | case 'p': 130 | case 'q': 131 | case 'r': 132 | case 's': 133 | case 't': 134 | case 'u': 135 | case 'v': 136 | case 'w': 137 | case 'x': 138 | case 'y': 139 | case 'z': 140 | case 'A': 141 | case 'B': 142 | case 'C': 143 | case 'D': 144 | case 'E': 145 | case 'F': 146 | case 'G': 147 | case 'H': 148 | case 'I': 149 | case 'J': 150 | case 'K': 151 | case 'L': 152 | case 'M': 153 | case 'N': 154 | case 'O': 155 | case 'P': 156 | case 'Q': 157 | case 'R': 158 | case 'S': 159 | case 'T': 160 | case 'U': 161 | case 'V': 162 | case 'W': 163 | case 'X': 164 | case 'Y': 165 | case 'Z': 166 | readName(t);break; 167 | case '0': 168 | case '1': 169 | case '2': 170 | case '3': 171 | case '4': 172 | case '5': 173 | case '6': 174 | case '7': 175 | case '8': 176 | case '9': 177 | case '.': 178 | readNumber(t);break; 179 | case ';': t.kind = Token::Kind::semicolon; nextCh(); break; 180 | case (char) -1: t.kind = Token::Kind::eof; break; 181 | case '(': t.kind = Token::Kind::lpar; nextCh(); break; 182 | case ')': t.kind = Token::Kind::rpar; nextCh(); break; 183 | case '[': t.kind = Token::Kind::lbrack; nextCh(); break; 184 | case ']': t.kind = Token::Kind::rbrack; nextCh(); break; 185 | case '{': t.kind = Token::Kind::lbrace; nextCh(); break; 186 | case '}': t.kind = Token::Kind::rbrace; nextCh(); break; 187 | case ',': t.kind = Token::Kind::comma; nextCh(); break; 188 | case '+': nextCh(); t.kind = Token::Kind::plus; break; 189 | case '-': nextCh(); t.kind = Token::Kind::minus; break; 190 | case '*': nextCh(); t.kind = Token::Kind::times; break; 191 | case '/': nextCh(); if(ch == '/') { 192 | skipComment(); 193 | t = next(); 194 | } else { 195 | t.kind = Token::Kind::div; 196 | } 197 | break; 198 | case '^': nextCh(); t.kind = Token::Kind::power; break; 199 | case '"': nextCh(); readString(t); nextCh(); break; 200 | case '>': nextCh(); t.kind = Token::Kind::gt; break; 201 | case '=': nextCh(); if(ch == '=') { 202 | nextCh(); 203 | t.kind = Token::Kind::eq; 204 | } else { 205 | std::cerr << "ERROR: UNEXPECTED CHARACTER: '" << ch << "'! " << std::endl; 206 | } 207 | break; 208 | default: 209 | std::cerr << "ERROR: UNEXPECTED CHARACTER: '" << ch << "'! " << std::endl; 210 | nextCh(); 211 | } 212 | 213 | return t; 214 | } 215 | 216 | void QASMscanner::readString(Token& t) { 217 | std::stringstream ss; 218 | while(ch != '"') { 219 | ss << ch; 220 | nextCh(); 221 | } 222 | t.str = ss.str(); 223 | t.kind = Token::Kind::string; 224 | } 225 | 226 | void QASMscanner::skipComment() { 227 | while(ch != '\n' && ch != (char) -1) { 228 | nextCh(); 229 | } 230 | } 231 | 232 | void QASMscanner::readName(Token& t) { 233 | std::stringstream ss; 234 | while(isdigit(ch) || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_') { 235 | ss << ch; 236 | nextCh(); 237 | } 238 | t.str = ss.str(); 239 | std::map::iterator it = keywords.find(t.str); 240 | if(it != keywords.end()) { 241 | t.kind = it->second; 242 | } else { 243 | t.kind = Token::Kind::identifier; 244 | } 245 | } 246 | 247 | void QASMscanner::readNumber(Token& t) { 248 | std::stringstream ss; 249 | while(isdigit(ch)) { 250 | ss << ch; 251 | nextCh(); 252 | } 253 | t.kind = Token::Kind::nninteger; 254 | t.str = ss.str(); 255 | if(ch != '.') { 256 | ss >> t.val; 257 | return; 258 | } 259 | t.kind = Token::Kind::real; 260 | ss << ch; 261 | nextCh(); 262 | while(isdigit(ch)) { 263 | ss << ch; 264 | nextCh(); 265 | } 266 | if(ch != 'e' && ch != 'E') { 267 | ss >> t.valReal; 268 | return; 269 | } 270 | ss << ch; 271 | nextCh(); 272 | if(ch == '-' || ch == '+') { 273 | ss << ch; 274 | nextCh(); 275 | } 276 | while(isdigit(ch)) { 277 | ss << ch; 278 | nextCh(); 279 | } 280 | ss >> t.valReal; 281 | } 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /code/src/CostFunc/CXFrontier.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CXFRONTIER_HPP 2 | #define CXFRONTIER_HPP 3 | 4 | #include "CostFunc.hpp" 5 | #include "Node.hpp" 6 | #include 7 | 8 | class CXFrontier : public CostFunc { 9 | public: 10 | int _getCost(Node * node) { 11 | bool debug = node->cost > 0;//called getCost for second time on this node 12 | 13 | int cost = 0; 14 | int costT = 99999; 15 | Environment * env = node->env; 16 | GateNode * next2BitGate[env->numPhysicalQubits]; 17 | int pathLength[env->numPhysicalQubits]; 18 | for(int x = 0; x < env->numPhysicalQubits; x++) { 19 | next2BitGate[x] = NULL; 20 | pathLength[x] = 0; 21 | int busy = node->busyCycles(x); 22 | if(busy > cost) { 23 | cost = busy; 24 | } 25 | } 26 | 27 | //search from last scheduled (non-swap) gates 28 | for(int x = 0; x < env->numPhysicalQubits; x++) { 29 | ScheduledGate * sg = node->lastNonSwapGate[x]; 30 | if(sg) { 31 | //get latest physical location of logical qubit x: 32 | int actualQubit; 33 | if(sg->gate->target == x) { 34 | actualQubit = node->laq[sg->gate->target]; 35 | } else { 36 | assert(sg->gate->control == x); 37 | actualQubit = node->laq[sg->gate->control]; 38 | } 39 | 40 | //get path length to next 2-qubit gate along this qubit: 41 | pathLength[actualQubit] = node->busyCycles(actualQubit); 42 | if(!pathLength[actualQubit]) { 43 | pathLength[actualQubit] = 1;//since we won't schedule any more gates this cycle 44 | } 45 | GateNode * temp; 46 | if(sg->gate->target == x) { 47 | temp = sg->gate->targetChild; 48 | } else { 49 | assert(sg->gate->control == x); 50 | temp = sg->gate->controlChild; 51 | } 52 | 53 | while(temp && temp->control < 0) { 54 | pathLength[actualQubit] += temp->latency; 55 | temp = temp->targetChild; 56 | } 57 | next2BitGate[actualQubit] = temp; 58 | } 59 | } 60 | 61 | //also search from ready gates, in case some qubits haven't scheduled gates yet 62 | auto iter = node->readyGates.begin(); 63 | while(iter != node->readyGates.end()) { 64 | GateNode * g = *iter; 65 | int physicalTarget = node->laq[g->target]; 66 | 67 | if(physicalTarget < 0) { 68 | iter++; 69 | continue; 70 | } 71 | 72 | if(g->control < 0) { 73 | //if(next2BitGate[physicalTarget] == NULL) { 74 | pathLength[physicalTarget] = node->busyCycles(physicalTarget); 75 | if(!pathLength[physicalTarget]) { 76 | pathLength[physicalTarget] = 1;//since we won't schedule any more gates this cycle 77 | } 78 | GateNode * temp = g; 79 | while(temp && temp->control < 0) { 80 | pathLength[physicalTarget] += temp->latency; 81 | temp = temp->targetChild; 82 | } 83 | next2BitGate[physicalTarget] = temp; 84 | 85 | if(temp) { 86 | int otherBit; 87 | bool noOtherParent = false; 88 | if(temp->target == g->target) { 89 | noOtherParent = temp->controlParent == NULL; 90 | otherBit = node->laq[temp->control]; 91 | } else { 92 | assert(temp->control == g->target); 93 | noOtherParent = temp->targetParent == NULL; 94 | otherBit = node->laq[temp->target]; 95 | } 96 | if(noOtherParent && next2BitGate[otherBit] == NULL) { 97 | next2BitGate[otherBit] = temp; 98 | pathLength[otherBit] = node->busyCycles(otherBit); 99 | if(!pathLength[otherBit]) { 100 | pathLength[otherBit] = 1;//since we won't schedule any more gates this cycle 101 | } 102 | } 103 | } 104 | //} 105 | } else { 106 | int physicalControl = node->laq[g->control]; 107 | if(physicalControl < 0) { 108 | iter++; 109 | continue; 110 | } 111 | assert(next2BitGate[physicalControl] == g || next2BitGate[physicalControl] == NULL); 112 | assert(next2BitGate[physicalTarget] == g || next2BitGate[physicalTarget] == NULL); 113 | 114 | pathLength[physicalTarget] = node->busyCycles(physicalTarget); 115 | if(!pathLength[physicalTarget]) { 116 | pathLength[physicalTarget] = 1;//since we won't schedule any more gates this cycle 117 | } 118 | next2BitGate[physicalTarget] = g; 119 | 120 | pathLength[physicalControl] = node->busyCycles(physicalControl); 121 | if(!pathLength[physicalControl]) { 122 | pathLength[physicalControl] = 1;//since we won't schedule any more gates this cycle 123 | } 124 | next2BitGate[physicalControl] = g; 125 | } 126 | 127 | /* 128 | int cost1 = g->criticality + g->latency + node->busyCycles(physicalTarget); 129 | if(cost1 > cost) { 130 | if(debug) std::cerr << " up subcircuit cost to " << cost1 << " based on ready " << physicalTarget << " gate" << "\n"; 131 | cost = cost1; 132 | } 133 | */ 134 | 135 | iter++; 136 | } 137 | 138 | //analyze cnot frontier 139 | for(int x = 0; x < env->numPhysicalQubits - 1; x++) { 140 | GateNode * g = next2BitGate[x]; 141 | if(g) { 142 | if(debug) std::cerr << " considering next gate for physical qubit " << x << "\n"; 143 | if(debug) std::cerr << " logical qubits: " << g->control << "," << g->target << "\n"; 144 | int physicalTarget = node->laq[g->target]; 145 | int physicalControl = node->laq[g->control]; 146 | 147 | if(debug) std::cerr << " physical qubits: " << physicalControl << "," << physicalTarget << "\n"; 148 | 149 | assert(physicalTarget == x || physicalControl == x); 150 | assert(physicalTarget != physicalControl); 151 | //assert(physicalTarget >= 0 && physicalControl >= 0); 152 | if(physicalTarget < 0 || physicalControl < 0) { 153 | continue; 154 | } 155 | 156 | int length1 = pathLength[physicalTarget]; 157 | int length2 = pathLength[physicalControl]; 158 | 159 | bool skipCheckedCheck = false; 160 | 161 | if(next2BitGate[physicalTarget] == NULL && g->targetParent == NULL) { 162 | next2BitGate[physicalTarget] = g; 163 | length1 = node->busyCycles(physicalTarget); 164 | if(!length1) { 165 | length1 = 1;//since we won't schedule any more gates this cycle 166 | } 167 | skipCheckedCheck = true; 168 | } 169 | 170 | if(next2BitGate[physicalControl] == NULL && g->controlParent == NULL) { 171 | next2BitGate[physicalControl] = g; 172 | length2 = node->busyCycles(physicalControl); 173 | if(!length2) { 174 | length2 = 1;//since we won't schedule any more gates this cycle 175 | } 176 | skipCheckedCheck = true; 177 | } 178 | 179 | //skip if this cnot depends on another unscheduled cnot 180 | if(next2BitGate[physicalTarget] != next2BitGate[physicalControl]) { 181 | if(debug) std::cerr << " skipping (non-frontier)\n"; 182 | continue; 183 | } 184 | 185 | //skip if we already processed this in earlier iteration: 186 | if(!skipCheckedCheck && physicalTarget <= x && physicalControl <= x) { 187 | if(debug) std::cerr << " skipping (already checked)\n"; 188 | continue; 189 | } 190 | 191 | int minSwaps = env->couplingDistances[physicalControl*env->numPhysicalQubits + physicalTarget] - 1; 192 | if(minSwaps < costT) costT = minSwaps; 193 | int totalSwapCost = env->swapCost * minSwaps; 194 | 195 | if(length1 < length2) { 196 | std::swap(length1, length2); 197 | } 198 | 199 | if(debug) std::cerr << " path lengths: " << length1 << "," << length2 << "\n"; 200 | if(debug) std::cerr << " swaps needed at least: " << minSwaps << "\n"; 201 | 202 | int slack = length1-length2; 203 | int effectiveSlack = (slack/env->swapCost) * env->swapCost; 204 | if(effectiveSlack > totalSwapCost) { 205 | effectiveSlack = totalSwapCost; 206 | } 207 | 208 | if(debug) std::cerr << " effective slack cycles: " << effectiveSlack << "\n"; 209 | 210 | int mutualSwapCost = totalSwapCost - effectiveSlack; 211 | int extraSwapCost = (0x1 & (mutualSwapCost/env->swapCost)) * env->swapCost; 212 | mutualSwapCost -= extraSwapCost; 213 | assert((mutualSwapCost % env->swapCost) == 0); 214 | mutualSwapCost = mutualSwapCost >> 1; 215 | 216 | int cost1 = g->latency + g->criticality + length1 + mutualSwapCost; 217 | int cost2 = g->latency + g->criticality + length2 + mutualSwapCost + effectiveSlack; 218 | 219 | if(cost1 < cost2) { 220 | cost1 += extraSwapCost; 221 | } else { 222 | cost2 += extraSwapCost; 223 | } 224 | 225 | if(debug) std::cerr << " shared swap cycles: " << mutualSwapCost << "\n"; 226 | if(debug) std::cerr << " criticality: " << g->criticality << "\n"; 227 | 228 | if(debug) std::cerr << " subcircuit cost: " << cost1 << " vs " << cost2 << "\n"; 229 | 230 | if(cost1 > cost) { 231 | cost = cost1; 232 | } 233 | if(cost2 > cost) { 234 | cost = cost2; 235 | } 236 | } 237 | } 238 | 239 | //add old cycles to cost 240 | cost += node->cycle; 241 | 242 | /* 243 | //Since this function is either buggy or CANNOT overestimate cost, use parent cost if larger 244 | if(node->parent && node->parent->cost > cost) { 245 | cost = node->parent->cost; 246 | } 247 | */ 248 | 249 | if(costT == 99999) costT = 0; 250 | node->cost2 = costT; 251 | 252 | return cost; 253 | } 254 | }; 255 | 256 | #endif 257 | -------------------------------------------------------------------------------- /data/min-gates/16QBT_15CYC_TFL_1_aspen4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q[16]; 4 | creg c[16]; 5 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 6 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 7 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 8 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 9 | cx q[5],q[4]; //cycle: 0 //cx logical_q[6],logical_q[7] 10 | cx q[13],q[12]; //cycle: 0 //cx logical_q[14],logical_q[8] 11 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 0 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 12 | cx q[10],q[11]; //cycle: 0 //cx logical_q[9],logical_q[0] 13 | cx q[14],q[1]; //cycle: 0 //cx logical_q[13],logical_q[10] 14 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 15 | cx q[8],q[15]; //cycle: 1 //cx logical_q[5],logical_q[3] 16 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 17 | cx q[1],q[2]; //cycle: 1 //cx logical_q[10],logical_q[4] 18 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 19 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 20 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 21 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 22 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 23 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 1 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 24 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 25 | cx q[2],q[3]; //cycle: 2 //cx logical_q[4],logical_q[11] 26 | cx q[1],q[0]; //cycle: 2 //cx logical_q[10],logical_q[2] 27 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 28 | cx q[11],q[12]; //cycle: 2 //cx logical_q[0],logical_q[8] 29 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 30 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 31 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 2 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 32 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 33 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 34 | cx q[0],q[7]; //cycle: 3 //cx logical_q[2],logical_q[12] 35 | cx q[3],q[4]; //cycle: 3 //cx logical_q[11],logical_q[7] 36 | cx q[13],q[2]; //cycle: 3 //cx logical_q[14],logical_q[4] 37 | cx q[9],q[8]; //cycle: 3 //cx logical_q[1],logical_q[5] 38 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 39 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 3 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 40 | cx q[10],q[11]; //cycle: 3 //cx logical_q[9],logical_q[0] 41 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 42 | u3(3.141593, 0.000000, 3.141593) q[4]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[7] 43 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 44 | cx q[9],q[8]; //cycle: 4 //cx logical_q[1],logical_q[5] 45 | cx q[2],q[3]; //cycle: 4 //cx logical_q[4],logical_q[11] 46 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 47 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 4 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 48 | cx q[11],q[12]; //cycle: 4 //cx logical_q[0],logical_q[8] 49 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 50 | cx q[10],q[11]; //cycle: 5 //cx logical_q[9],logical_q[0] 51 | u3(3.141593, 0.000000, 3.141593) q[1]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[10] 52 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 53 | cx q[9],q[8]; //cycle: 5 //cx logical_q[1],logical_q[5] 54 | cx q[2],q[3]; //cycle: 5 //cx logical_q[4],logical_q[11] 55 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 5 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 56 | cx q[6],q[5]; //cycle: 6 //cx logical_q[15],logical_q[6] 57 | cx q[8],q[15]; //cycle: 6 //cx logical_q[5],logical_q[3] 58 | cx q[13],q[2]; //cycle: 6 //cx logical_q[14],logical_q[4] 59 | cx q[3],q[4]; //cycle: 6 //cx logical_q[11],logical_q[7] 60 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 61 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 62 | u3(3.141593, 0.000000, 3.141593) q[10]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[9] 63 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 64 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 6 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 65 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 66 | cx q[7],q[6]; //cycle: 7 //cx logical_q[12],logical_q[15] 67 | cx q[13],q[12]; //cycle: 7 //cx logical_q[14],logical_q[8] 68 | cx q[2],q[3]; //cycle: 7 //cx logical_q[4],logical_q[11] 69 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 7 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 70 | cx q[9],q[8]; //cycle: 7 //cx logical_q[1],logical_q[5] 71 | cx q[14],q[1]; //cycle: 7 //cx logical_q[13],logical_q[10] 72 | cx q[10],q[11]; //cycle: 7 //cx logical_q[9],logical_q[0] 73 | u3(3.141593, 0.000000, 3.141593) q[9]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[1] 74 | u3(3.141593, 0.000000, 3.141593) q[14]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[13] 75 | u3(3.141593, 0.000000, 3.141593) q[13]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[14] 76 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 77 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 78 | u3(3.141593, 0.000000, 3.141593) q[7]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 79 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 80 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 81 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 82 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 83 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 8 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 84 | u3(3.141593, 0.000000, 3.141593) q[7]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[12] 85 | cx q[6],q[5]; //cycle: 9 //cx logical_q[15],logical_q[6] 86 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 9 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 87 | cx q[2],q[3]; //cycle: 9 //cx logical_q[4],logical_q[11] 88 | cx q[8],q[15]; //cycle: 9 //cx logical_q[5],logical_q[3] 89 | cx q[9],q[10]; //cycle: 9 //cx logical_q[1],logical_q[9] 90 | cx q[14],q[1]; //cycle: 9 //cx logical_q[13],logical_q[10] 91 | cx q[7],q[6]; //cycle: 10 //cx logical_q[12],logical_q[15] 92 | cx q[5],q[4]; //cycle: 10 //cx logical_q[6],logical_q[7] 93 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 10 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 94 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 10 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 95 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 10 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 96 | u3(3.141593, 0.000000, 3.141593) q[15]; //cycle: 10 //u3(3.141593, 0.000000, 3.141593) logical_q[3] 97 | cx q[7],q[6]; //cycle: 11 //cx logical_q[12],logical_q[15] 98 | cx q[11],q[12]; //cycle: 11 //cx logical_q[0],logical_q[8] 99 | cx q[2],q[3]; //cycle: 11 //cx logical_q[4],logical_q[11] 100 | u3(3.141593, 0.000000, 3.141593) q[8]; //cycle: 11 //u3(3.141593, 0.000000, 3.141593) logical_q[5] 101 | u3(3.141593, 0.000000, 3.141593) q[5]; //cycle: 11 //u3(3.141593, 0.000000, 3.141593) logical_q[6] 102 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 12 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 103 | cx q[0],q[7]; //cycle: 12 //cx logical_q[2],logical_q[12] 104 | cx q[1],q[2]; //cycle: 12 //cx logical_q[10],logical_q[4] 105 | cx q[3],q[4]; //cycle: 12 //cx logical_q[11],logical_q[7] 106 | u3(3.141593, 0.000000, 3.141593) q[11]; //cycle: 12 //u3(3.141593, 0.000000, 3.141593) logical_q[0] 107 | u3(3.141593, 0.000000, 3.141593) q[12]; //cycle: 12 //u3(3.141593, 0.000000, 3.141593) logical_q[8] 108 | cx q[8],q[15]; //cycle: 12 //cx logical_q[5],logical_q[3] 109 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 13 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 110 | u3(3.141593, 0.000000, 3.141593) q[0]; //cycle: 13 //u3(3.141593, 0.000000, 3.141593) logical_q[2] 111 | u3(3.141593, 0.000000, 3.141593) q[3]; //cycle: 13 //u3(3.141593, 0.000000, 3.141593) logical_q[11] 112 | u3(3.141593, 0.000000, 3.141593) q[2]; //cycle: 13 //u3(3.141593, 0.000000, 3.141593) logical_q[4] 113 | u3(3.141593, 0.000000, 3.141593) q[6]; //cycle: 14 //u3(3.141593, 0.000000, 3.141593) logical_q[15] 114 | //109 original gates 115 | //109 final gates 116 | //10421180 nodes expanded (popped from queue). 117 | //46 nodes remain in queue. 118 | --------------------------------------------------------------------------------