Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into vf2-everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish committed Nov 11, 2021
2 parents f7b3902 + e02119b commit 6d3e2d1
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 4 deletions.
6 changes: 4 additions & 2 deletions qiskit/circuit/library/generalized_gates/pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ def validate_parameter(self, parameter):
return parameter
else:
raise CircuitError(
"Parameter string {0} should contain only 'I', 'X', 'Y', 'Z' characters"
f"Parameter string {parameter} should contain only 'I', 'X', 'Y', 'Z' characters"
)
else:
raise CircuitError("Parameter {0} should be a string of 'I', 'X', 'Y', 'Z' characters")
raise CircuitError(
f"Parameter {parameter} should be a string of 'I', 'X', 'Y', 'Z' characters"
)
2 changes: 1 addition & 1 deletion qiskit/circuit/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def __init__(self, size=None, name=None, bits=None):
if bits is not None:
# pylint: disable=isinstance-second-argument-not-valid-type
if any(not isinstance(bit, self.bit_type) for bit in bits):
raise CircuitError("Provided bits did not all match register type. bits=%s" % bits)
raise CircuitError(f"Provided bits did not all match register type. bits={bits}")
self._bits = list(bits)
self._bit_indices = {bit: idx for idx, bit in enumerate(self._bits)}
else:
Expand Down
22 changes: 22 additions & 0 deletions qiskit/compiler/transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def transpile(
callback: Optional[Callable[[BasePass, DAGCircuit, float, PropertySet, int], Any]] = None,
output_name: Optional[Union[str, List[str]]] = None,
unitary_synthesis_method: str = "default",
unitary_synthesis_plugin_config: dict = None,
) -> Union[QuantumCircuit, List[QuantumCircuit]]:
"""Transpile one or more circuits, according to some desired transpilation targets.
Expand Down Expand Up @@ -220,6 +221,14 @@ def callback_func(**kwargs):
method to use. By default 'default' is used, which is the only
method included with qiskit. If you have installed any unitary
synthesis plugins you can use the name exported by the plugin.
unitary_synthesis_plugin_config: An optional configuration dictionary
that will be passed directly to the unitary synthesis plugin. By
default this setting will have no effect as the default unitary
synthesis method does not take custom configuration. This should
only be necessary when a unitary synthesis plugin is specified with
the ``unitary_synthesis`` argument. As this is custom for each
unitary synthesis plugin refer to the plugin documentation for how
to use this option.
Returns:
The transpiled circuit(s).
Expand Down Expand Up @@ -301,6 +310,7 @@ def callback_func(**kwargs):
output_name,
timing_constraints,
unitary_synthesis_method,
unitary_synthesis_plugin_config,
)

_check_circuits_coupling_map(circuits, transpile_args, backend)
Expand Down Expand Up @@ -484,6 +494,7 @@ def _parse_transpile_args(
output_name,
timing_constraints,
unitary_synthesis_method,
unitary_synthesis_plugin_config,
) -> List[Dict]:
"""Resolve the various types of args allowed to the transpile() function through
duck typing, overriding args, etc. Refer to the transpile() docstring for details on
Expand Down Expand Up @@ -519,6 +530,9 @@ def _parse_transpile_args(
unitary_synthesis_method = _parse_unitary_synthesis_method(
unitary_synthesis_method, num_circuits
)
unitary_synthesis_plugin_config = _parse_unitary_plugin_config(
unitary_synthesis_plugin_config, num_circuits
)
seed_transpiler = _parse_seed_transpiler(seed_transpiler, num_circuits)
optimization_level = _parse_optimization_level(optimization_level, num_circuits)
output_name = _parse_output_name(output_name, circuits)
Expand Down Expand Up @@ -554,6 +568,7 @@ def _parse_transpile_args(
"backend_num_qubits": backend_num_qubits,
"faulty_qubits_map": faulty_qubits_map,
"unitary_synthesis_method": unitary_synthesis_method,
"unitary_synthesis_plugin_config": unitary_synthesis_plugin_config,
}
):
transpile_args = {
Expand All @@ -572,6 +587,7 @@ def _parse_transpile_args(
timing_constraints=kwargs["timing_constraints"],
seed_transpiler=kwargs["seed_transpiler"],
unitary_synthesis_method=kwargs["unitary_synthesis_method"],
unitary_synthesis_plugin_config=kwargs["unitary_synthesis_plugin_config"],
),
"optimization_level": kwargs["optimization_level"],
"output_name": kwargs["output_name"],
Expand Down Expand Up @@ -837,6 +853,12 @@ def _parse_unitary_synthesis_method(unitary_synthesis_method, num_circuits):
return unitary_synthesis_method


def _parse_unitary_plugin_config(unitary_synthesis_plugin_config, num_circuits):
if not isinstance(unitary_synthesis_plugin_config, list):
unitary_synthesis_plugin_config = [unitary_synthesis_plugin_config] * num_circuits
return unitary_synthesis_plugin_config


def _parse_seed_transpiler(seed_transpiler, num_circuits):
if not isinstance(seed_transpiler, list):
seed_transpiler = [seed_transpiler] * num_circuits
Expand Down
10 changes: 10 additions & 0 deletions qiskit/transpiler/passes/synthesis/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ def run(self, unitary, **options):
expose multiple plugins if necessary. The name ``default`` is used by Qiskit
itself and can't be used in a plugin.
Unitary Synthesis Plugin Configuration
''''''''''''''''''''''''''''''''''''''
For some unitary synthesis plugins that expose multiple options and tunables
the plugin interface has an option for users to provide a free form
configuration dictionary. This will be passed through to the ``run()`` method
as the ``config`` kwarg. If your plugin has these configuration options you
should clearly document how a user should specify these configuration options
and how they're used as it's a free form field.
Using Plugins
=============
Expand Down
9 changes: 8 additions & 1 deletion qiskit/transpiler/passes/synthesis/unitary_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def __init__(
synth_gates: Union[List[str], None] = None,
method: str = "default",
min_qubits: int = None,
plugin_config: dict = None,
):
"""Synthesize unitaries over some basis gates.
Expand Down Expand Up @@ -161,6 +162,11 @@ def __init__(
min_qubits: The minimum number of qubits in the unitary to synthesize. If this is set
and the unitary is less than the specified number of qubits it will not be
synthesized.
plugin_config: Optional extra configuration arguments (as a dict)
which are passed directly to the specified unitary synthesis
plugin. By default this will have no effect as the default
plugin has no extra arguments. Refer to the documentation of
your unitary synthesis plugin on how to use this.
"""
super().__init__()
self._basis_gates = set(basis_gates or ())
Expand All @@ -172,6 +178,7 @@ def __init__(
self._backend_props = backend_props
self._pulse_optimize = pulse_optimize
self._natural_direction = natural_direction
self._plugin_config = plugin_config
if synth_gates:
self._synth_gates = synth_gates
else:
Expand Down Expand Up @@ -205,7 +212,7 @@ def run(self, dag: DAGCircuit) -> DAGCircuit:
return dag

plugin_method = self.plugins.ext_plugins[self.method].obj
plugin_kwargs = {}
plugin_kwargs = {"config": self._plugin_config}
_gate_lengths = _gate_errors = None
dag_bit_indices = {}

Expand Down
2 changes: 2 additions & 0 deletions qiskit/transpiler/passmanager_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def __init__(
seed_transpiler=None,
timing_constraints=None,
unitary_synthesis_method="default",
unitary_synthesis_plugin_config=None,
):
"""Initialize a PassManagerConfig object
Expand Down Expand Up @@ -80,6 +81,7 @@ def __init__(
self.seed_transpiler = seed_transpiler
self.timing_constraints = timing_constraints
self.unitary_synthesis_method = unitary_synthesis_method
self.unitary_synthesis_plugin_config = unitary_synthesis_plugin_config

@classmethod
def from_backend(cls, backend, **pass_manager_options):
Expand Down
5 changes: 5 additions & 0 deletions qiskit/transpiler/preset_passmanagers/level0.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
approximation_degree = pass_manager_config.approximation_degree
timing_constraints = pass_manager_config.timing_constraints or TimingConstraints()
unitary_synthesis_method = pass_manager_config.unitary_synthesis_method
unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config

# 1. Choose an initial layout if not set by user (default: trivial layout)
_given_layout = SetLayout(initial_layout)
Expand Down Expand Up @@ -123,6 +124,7 @@ def _choose_layout_condition(property_set):
backend_props=backend_properties,
method=unitary_synthesis_method,
min_qubits=3,
plugin_config=unitary_synthesis_plugin_config,
),
Unroll3qOrMore(),
]
Expand Down Expand Up @@ -166,6 +168,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
UnrollCustomDefinitions(sel, basis_gates),
BasisTranslator(sel, basis_gates),
Expand All @@ -179,6 +182,7 @@ def _swap_condition(property_set):
backend_props=backend_properties,
method=unitary_synthesis_method,
min_qubits=3,
plugin_config=unitary_synthesis_plugin_config,
),
Unroll3qOrMore(),
Collect2qBlocks(),
Expand All @@ -190,6 +194,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
]
else:
Expand Down
4 changes: 4 additions & 0 deletions qiskit/transpiler/preset_passmanagers/level1.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
backend_properties = pass_manager_config.backend_properties
approximation_degree = pass_manager_config.approximation_degree
unitary_synthesis_method = pass_manager_config.unitary_synthesis_method
unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config
timing_constraints = pass_manager_config.timing_constraints or TimingConstraints()

# 1. Use trivial layout if no layout given
Expand Down Expand Up @@ -191,6 +192,7 @@ def _vf2_match_not_found(property_set):
method=unitary_synthesis_method,
backend_props=backend_properties,
min_qubits=3,
plugin_config=unitary_synthesis_plugin_config,
),
Unroll3qOrMore(),
]
Expand Down Expand Up @@ -236,6 +238,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
method=unitary_synthesis_method,
backend_props=backend_properties,
plugin_config=unitary_synthesis_plugin_config,
),
UnrollCustomDefinitions(sel, basis_gates),
BasisTranslator(sel, basis_gates),
Expand All @@ -261,6 +264,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
method=unitary_synthesis_method,
backend_props=backend_properties,
plugin_config=unitary_synthesis_plugin_config,
),
]
else:
Expand Down
5 changes: 5 additions & 0 deletions qiskit/transpiler/preset_passmanagers/level2.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
approximation_degree = pass_manager_config.approximation_degree
unitary_synthesis_method = pass_manager_config.unitary_synthesis_method
timing_constraints = pass_manager_config.timing_constraints or TimingConstraints()
unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config

# 1. Search for a perfect layout, or choose a dense layout, if no layout given
_given_layout = SetLayout(initial_layout)
Expand Down Expand Up @@ -165,6 +166,7 @@ def _vf2_match_not_found(property_set):
backend_props=backend_properties,
method=unitary_synthesis_method,
min_qubits=3,
plugin_config=unitary_synthesis_plugin_config,
),
Unroll3qOrMore(),
]
Expand Down Expand Up @@ -210,6 +212,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
UnrollCustomDefinitions(sel, basis_gates),
BasisTranslator(sel, basis_gates),
Expand All @@ -224,6 +227,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
min_qubits=3,
),
Unroll3qOrMore(),
Expand All @@ -235,6 +239,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
]
else:
Expand Down
6 changes: 6 additions & 0 deletions qiskit/transpiler/preset_passmanagers/level3.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
approximation_degree = pass_manager_config.approximation_degree
unitary_synthesis_method = pass_manager_config.unitary_synthesis_method
timing_constraints = pass_manager_config.timing_constraints or TimingConstraints()
unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config

# 1. Unroll to 1q or 2q gates
_unroll3q = [
Expand All @@ -115,6 +116,7 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
min_qubits=3,
),
Unroll3qOrMore(),
Expand Down Expand Up @@ -210,6 +212,7 @@ def _swap_condition(property_set):
approximation_degree=approximation_degree,
coupling_map=coupling_map,
backend_props=backend_properties,
plugin_config=unitary_synthesis_plugin_config,
method=unitary_synthesis_method,
),
UnrollCustomDefinitions(sel, basis_gates),
Expand All @@ -223,6 +226,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
min_qubits=3,
),
Unroll3qOrMore(),
Expand All @@ -234,6 +238,7 @@ def _swap_condition(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
]
else:
Expand Down Expand Up @@ -267,6 +272,7 @@ def _opt_control(property_set):
coupling_map=coupling_map,
backend_props=backend_properties,
method=unitary_synthesis_method,
plugin_config=unitary_synthesis_plugin_config,
),
Optimize1qGatesDecomposition(basis_gates),
CommutativeCancellation(),
Expand Down
Loading

0 comments on commit 6d3e2d1

Please sign in to comment.