Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
edyounis committed Sep 8, 2022
1 parent 83b7482 commit ff969f9
Show file tree
Hide file tree
Showing 2 changed files with 269 additions and 24 deletions.
128 changes: 104 additions & 24 deletions 1_comping_with_bqskit.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@
"metadata": {},
"outputs": [],
"source": [
"# Import a circuit from Qiskit\n",
"# Build a circuit in Qiskit\n",
"from qiskit import QuantumCircuit\n",
"qc = QuantumCircuit.from_qasm_file('qasm/heisenberg16.qasm')\n",
"qc = QuantumCircuit(2)\n",
"qc.h(0)\n",
"qc.cnot(0, 1)\n",
"\n",
"# Load it into BQSKit\n",
"from bqskit.ext import qiskit_to_bqskit\n",
"circuit = qiskit_to_bqskit(qc)"
"bqskit_circuit = qiskit_to_bqskit(qc)"
]
},
{
Expand All @@ -86,7 +88,7 @@
"output_type": "stream",
"text": [
"Circuit Statistics\n",
"Gate Counts: {RXGate: 240, RZGate: 180, HGate: 240, CNOTGate: 360, XGate: 8}\n",
"Gate Counts: {HGate: 240, RZGate: 180, XGate: 8, CNOTGate: 360, RXGate: 240}\n",
"Logical Connectivity: CouplingGraph({(0, 1), (9, 10), (13, 14), (1, 2), (10, 11), (3, 4), (12, 13), (2, 3), (6, 7), (4, 5), (8, 9), (11, 12), (5, 6), (14, 15), (7, 8)})\n"
]
}
Expand All @@ -103,7 +105,7 @@
"source": [
"Using the `gate_counts` parameter we can count the number of each gate in the circuit. Additionally, the `coupling_graph` gives us the logical connectivity in this circuit.\n",
"\n",
"### Compile Function\n",
"### The Compile Function\n",
"\n",
"To run a circuit on a specific QPU, we need to ensure the types of gates in the circuit can be executed natively by the QPU and that the logical connectivity in the circuit matches the hardware-provided physical connectivity. More crucially, we must overcome these two restrictions in the fewest number of total operations. Fewer operations mean less error and a greater chance of success.\n",
"\n",
Expand All @@ -120,7 +122,7 @@
"output_type": "stream",
"text": [
"Compiled Circuit Statistics\n",
"Gate Counts: {U3Gate: 978, CNOTGate: 342}\n",
"Gate Counts: {CNOTGate: 342, U3Gate: 923}\n",
"Connectivity: CouplingGraph({(0, 1), (9, 10), (13, 14), (1, 2), (10, 11), (3, 4), (12, 13), (2, 3), (6, 7), (4, 5), (8, 9), (11, 12), (5, 6), (14, 15), (7, 8)})\n"
]
}
Expand Down Expand Up @@ -162,7 +164,7 @@
"output_type": "stream",
"text": [
"Compiled Circuit Statistics\n",
"Gate Counts: {U3Gate: 303, CNOTGate: 352}\n",
"Gate Counts: {CNOTGate: 336, U3Gate: 422}\n",
"Connectivity: CouplingGraph({(0, 1), (9, 10), (13, 14), (1, 2), (10, 11), (3, 4), (12, 13), (2, 3), (6, 7), (4, 5), (8, 9), (11, 12), (5, 6), (14, 15), (7, 8)})\n"
]
}
Expand Down Expand Up @@ -238,7 +240,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Gate Counts: {SqrtXGate: 1016, CZGate: 246, RZGate: 1524}\n"
"Gate Counts: {RZGate: 1464, CZGate: 236, SqrtXGate: 976}\n"
]
}
],
Expand Down Expand Up @@ -273,7 +275,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"{SqrtXGate: 996, ZZGate: 241, RZGate: 1494}\n"
"{ZZGate: 235, RZGate: 1458, SqrtXGate: 972}\n"
]
}
],
Expand Down Expand Up @@ -307,7 +309,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"{RYYGate: 142, SqrtXGate: 600, RZGate: 900}\n"
"{RZGate: 906, RYYGate: 143, SqrtXGate: 604}\n"
]
}
],
Expand Down Expand Up @@ -336,7 +338,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"{SqrtXGate: 1012, CZGate: 245, RZGate: 1518}\n"
"{SycamoreGate: 110, RZGate: 1488, SqrtXGate: 992, CZGate: 123, SqrtISwapGate: 7}\n"
]
}
],
Expand Down Expand Up @@ -380,7 +382,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Gate Counts: {U3Gate: 1237, CNOTGate: 630}\n",
"Gate Counts: {CNOTGate: 597, U3Gate: 1579}\n",
"Connectivity: CouplingGraph({(0, 1), (0, 7), (8, 14), (0, 4), (0, 3), (8, 10), (0, 6), (8, 13), (0, 2), (8, 9), (0, 5), (8, 12), (0, 8), (8, 15), (8, 11)})\n"
]
}
Expand Down Expand Up @@ -468,7 +470,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"{U3Gate: 10, CNOTGate: 6}\n"
"{CNOTGate: 6, U3Gate: 8}\n"
]
}
],
Expand Down Expand Up @@ -497,20 +499,30 @@
"\n",
"![images/instantiation-unpart.png](images/instantiation-unpart.png)\n",
"\n",
"The above circuit is partitioned into three-qubit blocks:\n",
"For example, the above circuit may be partitioned into three-qubit blocks given below:\n",
"\n",
"![images/instantiation-parted.png](images/instantiation-parted.png)\n",
"\n",
"The parameter `max_synthesis_size` determines the maximum width of any block passed to instantiation or synthesis during compilation. It is set to three by default, which is a sweet spot for most use cases. Larger sizes will lead to better results with an exponential time trade-off.\n",
"\n",
"As a note, directly passing unitaries larger than the maximum size to the compile function will log an error. To directly synthesize larger unitaries, you must increase this parameter accordingly."
"As a note, directly passing unitaries larger than the maximum size to the compile function will log an error. To directly synthesize larger unitaries, you must increase this parameter accordingly.\n",
"\n",
"**The block size 4 example below is very computationally intensive.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 14,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Gate Counts: {CNOTGate: 258, U3Gate: 663}\n"
]
}
],
"source": [
"# Block size 4\n",
"out_circuit = compile(circuit, max_synthesis_size=4)\n",
Expand All @@ -519,9 +531,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 15,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Gate Counts: {CNOTGate: 360, U3Gate: 1064}\n"
]
}
],
"source": [
"# Block size 2\n",
"out_circuit = compile(circuit, max_synthesis_size=2)\n",
Expand Down Expand Up @@ -555,9 +575,18 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 16,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/mnt/ed/Workspace/bqskit/bqskit/compiler/compile.py:317: UserWarning: Upper bound on error is greater than set threshold: 1.0 > 0.\n",
" warnings.warn(\n"
]
}
],
"source": [
"# High-error compilation\n",
"out_circuit = compile(circuit, synthesis_epsilon=0.5, error_threshold=0)"
Expand All @@ -572,9 +601,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 17,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{CNOTGate: 342, U3Gate: 917}\n"
]
}
],
"source": [
"out_circuit = compile(circuit, synthesis_epsilon=1e-3, error_threshold=5e-2)\n",
"print(out_circuit.gate_counts)"
Expand Down Expand Up @@ -607,7 +644,50 @@
"The steps are:\n",
"1. Launch your cluster. Refer to the [Dask documentation](https://docs.dask.org/en/stable/deploying.html) for guides. If you plan on using a supercomputer at NERSC, you can also refer to [NERSC's documentation](https://docs.nersc.gov/analytics/dask/) on the topic.\n",
"2. Connect to it. The compile function will pass all extra arguments and keyword arguments to a dask client constructor, which can be used to connect to and configure a dask cluster. Usually, you will either use the `address` or `scheduler_file` keywords to connect to an already running cluster.\n",
"3. Compile. once connected the `compile` function will do the rest."
"3. Compile. once connected the `compile` function will do the rest.\n",
"\n",
"#### Compiling multiple circuits faster\n",
"\n",
"If you plan to compile many inputs one after another on your local machine, you can save a lot of time by caching a `Compiler` object. By default, a new `Compiler` is created every time the `compile` function is called, which has a nontrivial overhead. However, a `Compiler` can be reused without issue. In the below example, we synthesize three single-qubit unitaries one after another. The first attempt doesn't cache the `Compiler` object, while the second does. The compile times are printed:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Synthesized 3 unitaries in 14.125332626979798 seconds.\n",
"After caching a Compiler, synthesized 3 unitaries in 4.921766862971708 seconds.\n"
]
}
],
"source": [
"from timeit import default_timer as timer\n",
"\n",
"from bqskit.compiler import Compiler\n",
"from bqskit.qis import UnitaryMatrix\n",
"\n",
"single_qubit_unitaries = [UnitaryMatrix.random(1) for i in range(3)]\n",
"\n",
"# Synthesize the 3 unitaries\n",
"start = timer()\n",
"for utry in single_qubit_unitaries:\n",
" compile(utry)\n",
"end = timer()\n",
"print(f'Synthesized 3 unitaries in {end - start} seconds.')\n",
"\n",
"# Now synthesize with a cached Compiler\n",
"start = timer()\n",
"compiler = Compiler()\n",
"for utry in single_qubit_unitaries:\n",
" compile(utry, compiler=compiler)\n",
"compiler.close()\n",
"end = timer()\n",
"print(f'After caching a Compiler, synthesized 3 unitaries in {end - start} seconds.')"
]
},
{
Expand Down
Loading

0 comments on commit ff969f9

Please sign in to comment.