Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add global Molmer-Sorenson gate #3149

Merged
merged 5 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions qiskit/extensions/standard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@
from .cu3 import Cu3Gate
from .rzz import RZZGate
from .rxx import RXXGate
from .ms import MSGate
53 changes: 53 additions & 0 deletions qiskit/extensions/standard/ms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# pylint: disable=invalid-name

"""
Molmer-Sorensen gate.
"""


from qiskit.circuit import Gate
from qiskit.circuit import QuantumCircuit
from qiskit.circuit import QuantumRegister
from qiskit.extensions.standard.rxx import RXXGate


class MSGate(Gate):
"""Global Molmer-Sorensen gate."""

def __init__(self, n_qubits, theta):
"""Create new MS gate."""
super().__init__("ms", n_qubits, [theta])

def _define(self):
definition = []
q = QuantumRegister(self.num_qubits, "q")
rule = []
for i in range(self.num_qubits):
for j in range(i+1, self.num_qubits):
rule += [(RXXGate(self.params[0]), [q[i], q[j]], [])]

for inst in rule:
definition.append(inst)
self.definition = definition


def ms(self, theta, qubits):
"""Apply MS to q1 and q2."""
return self.append(MSGate(len(qubits), theta), qubits)


QuantumCircuit.ms = ms
16 changes: 7 additions & 9 deletions qiskit/transpiler/passes/ms_basis_decomposer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,21 @@ class MSBasisDecomposer(TransformationPass):
"""

supported_input_gates = (U3Gate, CnotGate)
supported_basis_names = ('rx', 'ry', 'rxx')
supported_basis_names = ('rx', 'ry', 'rxx', 'ms')

def __init__(self, basis):
"""
Args:
basis (list[str]): Target basis names, e.g. `['rx', 'ry', 'rxx']` .
basis (list[str]): Target basis names, e.g. `['rx', 'ry', 'rxx', 'ms']` .

Raises:
QiskitError: if target basis is not [ 'rx', 'ry', 'rxx' ]
QiskitError: if target basis is not [ 'rx', 'ry', 'rxx', 'ms' ]

"""
super().__init__()

self.basis = basis
self.requires = [Unroller(['u3', 'cx'])]

if set(basis) != {gate_name for gate_name in self.supported_basis_names}:
raise QiskitError("Cannot unroll the circuit to the given basis, %s. "
% str(self.basis))
self.requires = [Unroller(list(set(basis).union(['u3', 'cx'])))]

def run(self, dag):
"""Replace U3,CX nodes in input dag with equivalent Rx,Ry,Rxx gates.
Expand All @@ -70,10 +66,12 @@ def run(self, dag):
for node in dag.op_nodes():
basic_insts = ['measure', 'reset', 'barrier', 'snapshot']
if node.name in basic_insts:
# TODO: this is legacy behavior.Basis_insts should be removed that these
# TODO: this is legacy behavior. basic_insts should be removed and these
# instructions should be part of the device-reported basis. Currently, no
# backend reports "measure", for example.
continue
if node.name in self.basis: # If already a base, ignore.
continue

if not isinstance(node.op, self.supported_input_gates):
raise QiskitError("Cannot convert the circuit to the given basis, %s. "
Expand Down
9 changes: 4 additions & 5 deletions qiskit/transpiler/transpile_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ def transpile_circuit(circuit, transpile_config):
device_insts = set(transpile_config.basis_gates).union(basic_insts)

ms_basis_swap = None
if (
'rxx' in transpile_config.basis_gates
and not device_insts >= circuit.count_ops().keys()
):
if 'rxx' in transpile_config.basis_gates and \
not device_insts >= circuit.count_ops().keys():
ms_basis_swap = transpile_config.basis_gates
transpile_config.basis_gates = ['u3', 'cx']
transpile_config.basis_gates = list(set(['u3', 'cx']).union(
transpile_config.basis_gates))

level = transpile_config.optimization_level
if level is None:
Expand Down