From 5e4c7fe8c4f612b5cb7f16cab72cd08de70527cc Mon Sep 17 00:00:00 2001 From: user <> Date: Tue, 15 Oct 2024 15:25:02 -0500 Subject: [PATCH 01/15] Fixed bug with checkpoint pass --- bqskit/passes/io/checkpoint.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bqskit/passes/io/checkpoint.py b/bqskit/passes/io/checkpoint.py index 7a7dbd776..a374cbb85 100644 --- a/bqskit/passes/io/checkpoint.py +++ b/bqskit/passes/io/checkpoint.py @@ -54,5 +54,6 @@ async def run(self, circuit: Circuit, data: PassData) -> None: with open(self.checkpoint_filename, 'rb') as f: checkpoint = pickle.load(f) circuit.become(checkpoint[0]) - data.clear() - data.update(checkpoint[1]) + new_data = PassData(circuit) + new_data.update(checkpoint[1]) + data.become(new_data) From 8a1b6c32bd2eb1af01049b42b3c8ac3cf780e7f1 Mon Sep 17 00:00:00 2001 From: user <> Date: Wed, 16 Oct 2024 08:12:42 -0500 Subject: [PATCH 02/15] loading/saving from .pkl in build_seqpam --- bqskit/compiler/compile.py | 28 +++++++++++++++++++++------- bqskit/passes/io/checkpoint.py | 5 +++-- bqskit/passes/mapping/pam.py | 8 ++++---- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/bqskit/compiler/compile.py b/bqskit/compiler/compile.py index 4536f0697..475c17ca2 100644 --- a/bqskit/compiler/compile.py +++ b/bqskit/compiler/compile.py @@ -93,6 +93,9 @@ from bqskit.utils.typing import is_iterable from bqskit.utils.typing import is_real_number +from bqskit.passes.io.checkpoint import SaveCheckpointPass +from bqskit.passes.io.checkpoint import LoadCheckpointPass + if TYPE_CHECKING: from bqskit.compiler.basepass import BasePass @@ -1281,6 +1284,10 @@ def build_seqpam_mapping_optimization_workflow( return Workflow( IfThenElsePass( NotPredicate(WidthPredicate(2)), + # Commented out initial block to avoid presynthesis assuming full connectivity + # Full connectivity ensures mapping scores are equivalent, so blocks are chosen + # based solely on synthesis cost. Thus changing the heuristic does not have + # the desired effect. [ LogPass('Caching permutation-aware synthesis results.'), ExtractModelConnectivityPass(), @@ -1308,6 +1315,9 @@ def build_seqpam_mapping_optimization_workflow( UnfoldPass(), RestoreModelConnectivityPass(), + # For testing start here, since this is the first point at which both + # parts of the heuristic come into play. + LogPass('Recaching permutation-aware synthesis results.'), SubtopologySelectionPass(block_size), QuickPartitioner(block_size), @@ -1328,13 +1338,17 @@ def build_seqpam_mapping_optimization_workflow( ), ), ), - LogPass('Performing permutation-aware mapping.'), - ApplyPlacement(), - PAMLayoutPass(num_layout_passes), - PAMRoutingPass(0.1), - post_pam_seq, - ApplyPlacement(), - UnfoldPass(), + SaveCheckpointPass(r'checkpoints/opt_level_1/qaoa12.pkl'), + + #[ + # LoadCheckpointPass(r'checkpoints/opt_level_1/qft4.pkl'), + # LogPass('Performing permutation-aware mapping.'), + # ApplyPlacement(), + # PAMLayoutPass(num_layout_passes), + # PAMRoutingPass(0.1), + # post_pam_seq, + # ApplyPlacement(), + # UnfoldPass(), ], ), name='SeqPAM Mapping', diff --git a/bqskit/passes/io/checkpoint.py b/bqskit/passes/io/checkpoint.py index 7a7dbd776..a374cbb85 100644 --- a/bqskit/passes/io/checkpoint.py +++ b/bqskit/passes/io/checkpoint.py @@ -54,5 +54,6 @@ async def run(self, circuit: Circuit, data: PassData) -> None: with open(self.checkpoint_filename, 'rb') as f: checkpoint = pickle.load(f) circuit.become(checkpoint[0]) - data.clear() - data.update(checkpoint[1]) + new_data = PassData(circuit) + new_data.update(checkpoint[1]) + data.become(new_data) diff --git a/bqskit/passes/mapping/pam.py b/bqskit/passes/mapping/pam.py index 92127a2c3..b8348f6ae 100644 --- a/bqskit/passes/mapping/pam.py +++ b/bqskit/passes/mapping/pam.py @@ -347,14 +347,14 @@ def _get_best_perm( # Calculate best scoring permutation best_triple = pre_circ_post_triples[0] best_perm = (best_triple[0], best_triple[2]) - mapping_score = self._score_perm(circuit, F, pi, D, best_perm, E) + # mapping_score = self._score_perm(circuit, F, pi, D, best_perm, E) gate_score = mq_gate_counts[0] * self.gate_count_weight / len(F) - best_score = mapping_score + gate_score + best_score = gate_score for i in range(1, len(pre_circ_post_triples)): gperm = (pre_circ_post_triples[i][0], pre_circ_post_triples[i][2]) - score = self._score_perm(circuit, F, pi, D, gperm, E) - score = mq_gate_counts[i] * self.gate_count_weight / len(F) + score + # score = self._score_perm(circuit, F, pi, D, gperm, E) + score = mq_gate_counts[i] * self.gate_count_weight / len(F) # + score if score < best_score: best_score = score best_perm = gperm From b786a3a67ac15eeaaf88c2bf1f9a0c4b491776ae Mon Sep 17 00:00:00 2001 From: user <> Date: Wed, 16 Oct 2024 08:19:19 -0500 Subject: [PATCH 03/15] Reset to default PAM (attempt 2) --- bqskit/passes/mapping/pam.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bqskit/passes/mapping/pam.py b/bqskit/passes/mapping/pam.py index b8348f6ae..92127a2c3 100644 --- a/bqskit/passes/mapping/pam.py +++ b/bqskit/passes/mapping/pam.py @@ -347,14 +347,14 @@ def _get_best_perm( # Calculate best scoring permutation best_triple = pre_circ_post_triples[0] best_perm = (best_triple[0], best_triple[2]) - # mapping_score = self._score_perm(circuit, F, pi, D, best_perm, E) + mapping_score = self._score_perm(circuit, F, pi, D, best_perm, E) gate_score = mq_gate_counts[0] * self.gate_count_weight / len(F) - best_score = gate_score + best_score = mapping_score + gate_score for i in range(1, len(pre_circ_post_triples)): gperm = (pre_circ_post_triples[i][0], pre_circ_post_triples[i][2]) - # score = self._score_perm(circuit, F, pi, D, gperm, E) - score = mq_gate_counts[i] * self.gate_count_weight / len(F) # + score + score = self._score_perm(circuit, F, pi, D, gperm, E) + score = mq_gate_counts[i] * self.gate_count_weight / len(F) + score if score < best_score: best_score = score best_perm = gperm From 0e9d321527e3b108d0aa3d31c9cbe535af573e24 Mon Sep 17 00:00:00 2001 From: user <> Date: Wed, 16 Oct 2024 13:40:19 -0500 Subject: [PATCH 04/15] Added save/load modes to build_seqpam --- bqskit/compiler/compile.py | 186 ++++++++++++++++++++++++------------- 1 file changed, 120 insertions(+), 66 deletions(-) diff --git a/bqskit/compiler/compile.py b/bqskit/compiler/compile.py index 475c17ca2..c4d251b71 100644 --- a/bqskit/compiler/compile.py +++ b/bqskit/compiler/compile.py @@ -93,9 +93,12 @@ from bqskit.utils.typing import is_iterable from bqskit.utils.typing import is_real_number +# My additions from bqskit.passes.io.checkpoint import SaveCheckpointPass from bqskit.passes.io.checkpoint import LoadCheckpointPass +import os + if TYPE_CHECKING: from bqskit.compiler.basepass import BasePass @@ -1210,6 +1213,8 @@ def build_seqpam_mapping_optimization_workflow( num_layout_passes: int = 3, block_size: int = 3, error_sim_size: int | None = None, + mode: str | None = None, + checkpoint_path: str = "checkpoint.pkl", ) -> Workflow: """ Build a Sequential-Permutation-Aware Mapping and Optimizing Workflow. @@ -1242,6 +1247,16 @@ def build_seqpam_mapping_optimization_workflow( errors on. If None, then no error analysis is performed. (Default: None) + mode (str | None): The input and output modes for the algorithm. + 'base' applies the typical sequence of pre-optimization, + block synthesis, layout, and routing. 'save' saves a checkpoint + after synthesis.'load' loads that checkpoint and applies + layout and routing. If None, defaults to base. (Default: None) + + checkpoint_path (str | None): The path to write checkpoints to or + read checkpints from, depending on mode + (Default: 'checkpoint.pkl') + Raises: ValueError: If block_size < 2. @@ -1265,6 +1280,21 @@ def build_seqpam_mapping_optimization_workflow( f'Expected error_sim_size >= block_size, got {error_sim_size}.', ) + if mode is not None and not isinstance(mode, str): + raise TypeError( + f'Expected string for mode, got {type(mode)}.', + ) + + if not (mode is None or mode == 'base' or mode == 'save' or mode == 'load'): + raise ValueError( + f'Expected mode None, \'base\', \'save\' or \'load\'; got \'{mode}\'.', + ) + + if checkpoint_path is not None and not isinstance(checkpoint_path, str): + raise TypeError( + f'Expected string for mode, got {type(checkpoint_path)}.', + ) + qsearch = QSearchSynthesisPass( success_threshold=synthesis_epsilon, instantiate_options=get_instantiate_options(optimization_level), @@ -1281,75 +1311,99 @@ def build_seqpam_mapping_optimization_workflow( else: post_pam_seq = NOOPPass() + # Base pass list inside the outermost IfThenElsePass + interior_pass_list = [ + LogPass('Caching permutation-aware synthesis results.'), + ExtractModelConnectivityPass(), + QuickPartitioner(block_size), + ForEachBlockPass( + IfThenElsePass( + WidthPredicate(4), + EmbedAllPermutationsPass( + inner_synthesis=qsearch, + input_perm=True, + output_perm=False, + vary_topology=False, + ), + EmbedAllPermutationsPass( + inner_synthesis=leap, + input_perm=True, + output_perm=False, + vary_topology=False, + ), + ), + ), + LogPass('Preoptimizing with permutation-aware mapping.'), + PAMRoutingPass(), + post_pam_seq, + UnfoldPass(), + RestoreModelConnectivityPass(), + + LogPass('Recaching permutation-aware synthesis results.'), + SubtopologySelectionPass(block_size), + QuickPartitioner(block_size), + ForEachBlockPass( + IfThenElsePass( + WidthPredicate(4), + EmbedAllPermutationsPass( + inner_synthesis=qsearch, + input_perm=False, + output_perm=True, + vary_topology=True, + ), + EmbedAllPermutationsPass( + inner_synthesis=leap, + input_perm=False, + output_perm=True, + vary_topology=True, + ), + ), + ), + ] + + # Build adjustment to base interior_pass_list according to mode + if mode is None or mode == 'base': + + append_pass_list = [ + LogPass('Performing permutation-aware mapping.'), + ApplyPlacement(), + PAMLayoutPass(num_layout_passes), + PAMRoutingPass(0.1), + post_pam_seq, + ApplyPlacement(), + UnfoldPass(), + ] + + elif mode == 'save': + + append_pass_list = [ + LogPass('Saving checkpoint.'), + SaveCheckpointPass(f'{checkpoint_path}') + ] + + elif mode == 'load': + + interior_pass_list.clear() + + append_pass_list = [ + LogPass('Loading checkpoint.'), + LoadCheckpointPass(f'{checkpoint_path}'), + + LogPass('Performing permutation-aware mapping.'), + ApplyPlacement(), + PAMLayoutPass(num_layout_passes), + PAMRoutingPass(0.1), + post_pam_seq, + ApplyPlacement(), + UnfoldPass(), + ] + + interior_pass_list = interior_pass_list + append_pass_list + return Workflow( IfThenElsePass( NotPredicate(WidthPredicate(2)), - # Commented out initial block to avoid presynthesis assuming full connectivity - # Full connectivity ensures mapping scores are equivalent, so blocks are chosen - # based solely on synthesis cost. Thus changing the heuristic does not have - # the desired effect. - [ - LogPass('Caching permutation-aware synthesis results.'), - ExtractModelConnectivityPass(), - QuickPartitioner(block_size), - ForEachBlockPass( - IfThenElsePass( - WidthPredicate(4), - EmbedAllPermutationsPass( - inner_synthesis=qsearch, - input_perm=True, - output_perm=False, - vary_topology=False, - ), - EmbedAllPermutationsPass( - inner_synthesis=leap, - input_perm=True, - output_perm=False, - vary_topology=False, - ), - ), - ), - LogPass('Preoptimizing with permutation-aware mapping.'), - PAMRoutingPass(), - post_pam_seq, - UnfoldPass(), - RestoreModelConnectivityPass(), - - # For testing start here, since this is the first point at which both - # parts of the heuristic come into play. - - LogPass('Recaching permutation-aware synthesis results.'), - SubtopologySelectionPass(block_size), - QuickPartitioner(block_size), - ForEachBlockPass( - IfThenElsePass( - WidthPredicate(4), - EmbedAllPermutationsPass( - inner_synthesis=qsearch, - input_perm=False, - output_perm=True, - vary_topology=True, - ), - EmbedAllPermutationsPass( - inner_synthesis=leap, - input_perm=False, - output_perm=True, - vary_topology=True, - ), - ), - ), - SaveCheckpointPass(r'checkpoints/opt_level_1/qaoa12.pkl'), - - #[ - # LoadCheckpointPass(r'checkpoints/opt_level_1/qft4.pkl'), - # LogPass('Performing permutation-aware mapping.'), - # ApplyPlacement(), - # PAMLayoutPass(num_layout_passes), - # PAMRoutingPass(0.1), - # post_pam_seq, - # ApplyPlacement(), - # UnfoldPass(), - ], + interior_pass_list, ), name='SeqPAM Mapping', ) From 69479ea26fc3bbc87b17b237572cc791243d0d7b Mon Sep 17 00:00:00 2001 From: user <> Date: Tue, 5 Nov 2024 08:18:03 -0600 Subject: [PATCH 05/15] Log panel error in PAMVrificationSequence --- bqskit/passes/mapping/verify.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bqskit/passes/mapping/verify.py b/bqskit/passes/mapping/verify.py index 29c9369ab..600bede2c 100644 --- a/bqskit/passes/mapping/verify.py +++ b/bqskit/passes/mapping/verify.py @@ -1,6 +1,8 @@ """This module implements the PAMVerificationSequence and helper passes.""" from __future__ import annotations +import logging + from bqskit.compiler.basepass import BasePass from bqskit.compiler.passdata import PassData from bqskit.ir.circuit import Circuit @@ -16,6 +18,7 @@ from bqskit.utils.typing import is_integer from bqskit.utils.typing import Sequence +_logger = logging.getLogger(__name__) class TagPAMBlockDataPass(BasePass): """Tag the blocks with the PAM block data.""" @@ -80,6 +83,7 @@ async def run(self, circuit: Circuit, data: PassData) -> None: # calculate error data.update_error_mul(current_unitary.get_distance_from(exact_unitary)) + _logger.info(f' Panel error: {current_unitary.get_distance_from(exact_unitary)}') class UnTagPAMBlockDataPass(BasePass): From 56ef79b1d3885572cc6cc5fad37958143ac94c71 Mon Sep 17 00:00:00 2001 From: user <> Date: Tue, 5 Nov 2024 08:34:46 -0600 Subject: [PATCH 06/15] Log verification info and #CNOT during test_pam_verify --- tests/compiler/compile/test_pam_verify.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/compiler/compile/test_pam_verify.py b/tests/compiler/compile/test_pam_verify.py index 3f49a9439..159409410 100644 --- a/tests/compiler/compile/test_pam_verify.py +++ b/tests/compiler/compile/test_pam_verify.py @@ -7,8 +7,14 @@ from bqskit.passes import SetModelPass from bqskit.qis.permutation import PermutationMatrix +from bqskit.ir.gates import * +import logging +_logger = logging.getLogger(__name__) def test_pam_verify(compiler: Compiler, medium_qasm_file: str) -> None: + + _logger.info(f' Reading from file: {medium_qasm_file}') + circuit = Circuit.from_file(medium_qasm_file) out_circuit, data = compiler.compile( circuit, @@ -18,6 +24,9 @@ def test_pam_verify(compiler: Compiler, medium_qasm_file: str) -> None: ], request_data=True, ) + + _logger.info(f' Finished compiling, CNOT count: {out_circuit.count(CNOTGate())}') + upper_bound_error = data.error pi = data['initial_mapping'] pf = data['final_mapping'] @@ -25,6 +34,11 @@ def test_pam_verify(compiler: Compiler, medium_qasm_file: str) -> None: PI = PermutationMatrix.from_qubit_location(out_circuit.num_qudits, pi) PF = PermutationMatrix.from_qubit_location(out_circuit.num_qudits, pf) exact_error = out_utry.get_distance_from(PF.T @ circuit.get_unitary() @ PI) + + _logger.info(f' Upper bound error: {upper_bound_error}') + _logger.info(f' Exact error: {exact_error}') + _logger.info(f' |upper_bound-exact| : {abs(upper_bound_error - exact_error)}') + assert upper_bound_error >= exact_error or abs( upper_bound_error - exact_error, ) < 5e-7 From 3d1eafa8f6f8dde1786fd704157554ad2ec2f271 Mon Sep 17 00:00:00 2001 From: user <> Date: Tue, 5 Nov 2024 08:35:39 -0600 Subject: [PATCH 07/15] Scripted test_pam_verify for multiple files --- tests/compiler/compile/test_pam_verify_script.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/compiler/compile/test_pam_verify_script.py diff --git a/tests/compiler/compile/test_pam_verify_script.py b/tests/compiler/compile/test_pam_verify_script.py new file mode 100644 index 000000000..1ee6ac3eb --- /dev/null +++ b/tests/compiler/compile/test_pam_verify_script.py @@ -0,0 +1,12 @@ +from bqskit.compiler import Compiler +import test_pam_verify as tpv +import logging + +compiler = Compiler() + +logging.basicConfig(level=logging.INFO) + +# Format +# tpv.test_pam_verify(compiler, 'path/to/qasm/file') + +tpv.test_pam_verify(compiler, 'test/qft4.qasm') \ No newline at end of file From 054f6e13673e05d3349e0b9ef6599b1180bfe9bc Mon Sep 17 00:00:00 2001 From: user <> Date: Fri, 15 Nov 2024 08:46:23 -0600 Subject: [PATCH 08/15] Added SwapToCNOTPass for benchmarking --- bqskit/compiler/compile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bqskit/compiler/compile.py b/bqskit/compiler/compile.py index c4d251b71..413196d75 100644 --- a/bqskit/compiler/compile.py +++ b/bqskit/compiler/compile.py @@ -1369,6 +1369,7 @@ def build_seqpam_mapping_optimization_workflow( ApplyPlacement(), PAMLayoutPass(num_layout_passes), PAMRoutingPass(0.1), + SwapToCNOTPass(), post_pam_seq, ApplyPlacement(), UnfoldPass(), @@ -1393,6 +1394,7 @@ def build_seqpam_mapping_optimization_workflow( ApplyPlacement(), PAMLayoutPass(num_layout_passes), PAMRoutingPass(0.1), + SwapToCNOTPass(), post_pam_seq, ApplyPlacement(), UnfoldPass(), From 79376e5e180b5c9b7a47cef87cd0ceb049de494f Mon Sep 17 00:00:00 2001 From: user <> Date: Fri, 15 Nov 2024 09:54:29 -0600 Subject: [PATCH 09/15] Fixed SwapToCNOT usage --- bqskit/compiler/compile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bqskit/compiler/compile.py b/bqskit/compiler/compile.py index 413196d75..542cee662 100644 --- a/bqskit/compiler/compile.py +++ b/bqskit/compiler/compile.py @@ -96,6 +96,7 @@ # My additions from bqskit.passes.io.checkpoint import SaveCheckpointPass from bqskit.passes.io.checkpoint import LoadCheckpointPass +from bqskit.passes.rules.swap2cnot import SwapToCNOTPass import os @@ -1369,10 +1370,10 @@ def build_seqpam_mapping_optimization_workflow( ApplyPlacement(), PAMLayoutPass(num_layout_passes), PAMRoutingPass(0.1), - SwapToCNOTPass(), post_pam_seq, ApplyPlacement(), UnfoldPass(), + SwapToCNOTPass(), ] elif mode == 'save': @@ -1394,10 +1395,10 @@ def build_seqpam_mapping_optimization_workflow( ApplyPlacement(), PAMLayoutPass(num_layout_passes), PAMRoutingPass(0.1), - SwapToCNOTPass(), post_pam_seq, ApplyPlacement(), UnfoldPass(), + SwapToCNOTPass(), ] interior_pass_list = interior_pass_list + append_pass_list From 914790b319c89e35901d5bd1b66fddb8b5d7d023 Mon Sep 17 00:00:00 2001 From: user <> Date: Fri, 15 Nov 2024 11:31:33 -0600 Subject: [PATCH 10/15] Added CircuitDrawPass for intermediate visualization --- bqskit/passes/io/circdraw.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 bqskit/passes/io/circdraw.py diff --git a/bqskit/passes/io/circdraw.py b/bqskit/passes/io/circdraw.py new file mode 100644 index 000000000..8b8f965ad --- /dev/null +++ b/bqskit/passes/io/circdraw.py @@ -0,0 +1,17 @@ +from bqskit.compiler import BasePass +from bqskit.compiler.passdata import PassData +from bqskit.ir.circuit import Circuit +from bqskit.ext import bqskit_to_qiskit +from qiskit import * + +class CircuitDrawPass(BasePass): + + def __init__( + self, + marker: str = 'circuit', + ) -> None: + self.marker = marker + + async def run(self, circuit: Circuit, data: PassData): + qc = bqskit_to_qiskit(circuit) + qc.draw(output='mpl', filename=self.marker+'.png', fold=-1) From bb0edd0abf197afe2b8bc79d1f7edf6e1433a4ab Mon Sep 17 00:00:00 2001 From: user <> Date: Fri, 15 Nov 2024 12:09:47 -0600 Subject: [PATCH 11/15] Updated CircuitDrawPass --- bqskit/passes/io/circdraw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bqskit/passes/io/circdraw.py b/bqskit/passes/io/circdraw.py index 8b8f965ad..0dfeb2ed8 100644 --- a/bqskit/passes/io/circdraw.py +++ b/bqskit/passes/io/circdraw.py @@ -14,4 +14,4 @@ def __init__( async def run(self, circuit: Circuit, data: PassData): qc = bqskit_to_qiskit(circuit) - qc.draw(output='mpl', filename=self.marker+'.png', fold=-1) + qc.draw(output='mpl', filename=self.marker+'.jpg', scale=0.5, fold=-1) From 54c55aaf4c0b70b130d6ae0604c4885d3505b0c5 Mon Sep 17 00:00:00 2001 From: user <> Date: Tue, 10 Dec 2024 10:55:03 -0600 Subject: [PATCH 12/15] Commented out intermediate CircuitDrawPass in build_seqpam --- bqskit/compiler/compile.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bqskit/compiler/compile.py b/bqskit/compiler/compile.py index 542cee662..b5e269f65 100644 --- a/bqskit/compiler/compile.py +++ b/bqskit/compiler/compile.py @@ -94,11 +94,13 @@ from bqskit.utils.typing import is_real_number # My additions +# ============================================================================ from bqskit.passes.io.checkpoint import SaveCheckpointPass from bqskit.passes.io.checkpoint import LoadCheckpointPass from bqskit.passes.rules.swap2cnot import SwapToCNOTPass +# from bqskit.passes.io.circdraw import CircuitDrawPass +# ============================================================================ -import os if TYPE_CHECKING: from bqskit.compiler.basepass import BasePass @@ -1390,15 +1392,21 @@ def build_seqpam_mapping_optimization_workflow( append_pass_list = [ LogPass('Loading checkpoint.'), LoadCheckpointPass(f'{checkpoint_path}'), - + # CircuitDrawPass('0_pre_opt+block_synth'), LogPass('Performing permutation-aware mapping.'), ApplyPlacement(), + # CircuitDrawPass('1_post_placement_1'), PAMLayoutPass(num_layout_passes), + # CircuitDrawPass('2_post_layout'), PAMRoutingPass(0.1), + # CircuitDrawPass('3_post_routing'), post_pam_seq, ApplyPlacement(), + # CircuitDrawPass('4_post_pacement'), UnfoldPass(), + # CircuitDrawPass('5_post_unfold'), SwapToCNOTPass(), + # CircuitDrawPass('6_post_swap2cnot'), ] interior_pass_list = interior_pass_list + append_pass_list From 3d26dab2420e61ca358066241dccafe4fa977149 Mon Sep 17 00:00:00 2001 From: m-t <99849342+m-tremba@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:33:59 -0600 Subject: [PATCH 13/15] Update README.md --- README.md | 91 ++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index bd2ae61c0..fc950e215 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,64 @@ -# Berkeley Quantum Synthesis Toolkit (BQSKit) +# Berkeley Quantum Synthesis Toolkit (BQSKit) PAM Variants -The Berkeley Quantum Synthesis Toolkit (BQSKit) \[bis • kit\] is a powerful -and portable quantum compiler framework. It can be used with ease to compile -quantum programs to efficient physical circuits for any QPU. +This fork of BQSKit implements variants of Permutation-Aware Mapping (PAM [1]. + +[1] J. Liu, E. Younis, M. Weiden, P. Hovland, J. Kubiatowicz and C. Iancu, +"Tackling the Qubit Mapping Problem with Permutation-Aware Synthesis," 2023 IEEE +International Conference on Quantum Computing and Engineering (QCE), Bellevue, WA, +USA, 2023, pp. 745-756, doi: 10.1109/QCE57702.2023.00090. ## Installation -BQSKit is available for Python 3.8+ on Linux, macOS, and Windows. BQSKit -and its dependencies are listed on the [Python Package Index](https://pypi.org), -and as such, pip can easily install it: +1. Set up a python virtual environment. +2. Install BQSKit using the [Github instructions](https://github.com/BQSKit/bqskit), + to get its dependencies. +3. Clone this repo and perform an editable install of it. ```sh +python -m venv /path/to/venv + +source /path/to/venv/bin/activate + pip install bqskit + +git clone git@github.com:m-tremba/bqskit.git + +pip install -e /path/to/repo ``` ## Basic Usage -A standard BQSKit workflow loads a program into the framework, models the -target QPU, compiles the program, and exports the resulting circuit. The -below example uses BQSKit to optimize an input circuit provided by a qasm -file: +Variants are implemented in different branches of the repo. To change variants, change +branches using git. + +```sh +git checkout branch_name +``` + +To compile circuits using the variants, try building a workflow using the default +PAM workflow builder function included in `bqskit.compiler.compile`{:python}. ```python -from bqskit import compile, Circuit +from bqskit import Circuit +from bqskit.compiler.compiler import Compiler +from bqskit.compiler.workflow import Workflow +from bqskit.compiler.compile import build_seqpam_mapping_optimization_workflow # Load a circuit from QASM circuit = Circuit.from_file("input.qasm") +# Create PAM variant workflow +workflow = build_seqpam_mapping_optimization_workflow() + # Compile the circuit -compiled_circuit = compile(circuit) +with Compiler() as compiler: + compiled_circuit = compiler.compile(circuit.copy(), workflow) # Save output as QASM compiled_circuit.save("output.qasm") ``` -To learn more about BQSKit, follow the -[tutorial series](https://github.com/BQSKit/bqskit-tutorial/) or refer to -the [documentation](https://bqskit.readthedocs.io/en/latest/). - -## How to Cite - -You can use the [software disclosure](https://www.osti.gov/biblio/1785933) -to cite the BQSKit package. - -Additionally, if you used or extended a specific algorithm, you should cite -that individually. BQSKit passes will include a relevant reference in -their documentation. - -## License - -The software in this repository is licensed under a **BSD free software -license** and can be used in source or binary form for any purpose as long -as the simple licensing requirements are followed. See the -**[LICENSE](https://github.com/BQSKit/bqskit/blob/master/LICENSE)** file -for more information. - -## Copyright - -Berkeley Quantum Synthesis Toolkit (BQSKit) Copyright (c) 2021, -The Regents of the University of California, through Lawrence -Berkeley National Laboratory (subject to receipt of any required -approvals from the U.S. Dept. of Energy) and Massachusetts -Institute of Technology (MIT). All rights reserved. - -If you have questions about your rights to use or distribute this software, -please contact Berkeley Lab's Intellectual Property Office at IPO@lbl.gov. +## Other Information -NOTICE. This Software was developed under funding from the U.S. Department -of Energy and the U.S. Government consequently retains certain rights. As -such, the U.S. Government has been granted for itself and others acting on -its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the -Software to reproduce, distribute copies to the public, prepare derivative -works, and perform publicly and display publicly, and to permit others to -do so. +For all other information, including citations, licenses, and copyright, +see the parent BQSKit repo. From 5e07c79c27186d7f61ab71216c2dd6bd5576c1f6 Mon Sep 17 00:00:00 2001 From: m-t <99849342+m-tremba@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:34:28 -0600 Subject: [PATCH 14/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc950e215..3e1aa0794 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Berkeley Quantum Synthesis Toolkit (BQSKit) PAM Variants +# BQSKit Fork - PAM Variants This fork of BQSKit implements variants of Permutation-Aware Mapping (PAM [1]. From ba4a786d30d0bfa6af2240bce6eebb78597b7345 Mon Sep 17 00:00:00 2001 From: m-t <99849342+m-tremba@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:35:09 -0600 Subject: [PATCH 15/15] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3e1aa0794..3dcc69067 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BQSKit Fork - PAM Variants -This fork of BQSKit implements variants of Permutation-Aware Mapping (PAM [1]. +This fork of BQSKit implements variants of Permutation-Aware Mapping (PAM) [1]. [1] J. Liu, E. Younis, M. Weiden, P. Hovland, J. Kubiatowicz and C. Iancu, "Tackling the Qubit Mapping Problem with Permutation-Aware Synthesis," 2023 IEEE @@ -61,4 +61,4 @@ compiled_circuit.save("output.qasm") ## Other Information For all other information, including citations, licenses, and copyright, -see the parent BQSKit repo. +see the parent [BQSKit repo](https://github.com/BQSKit/bqskit),