Skip to content

Commit

Permalink
improved to_bracket qiskit-community#176
Browse files Browse the repository at this point in the history
  • Loading branch information
monika-sahay committed Jun 8, 2024
1 parent 99bad32 commit 78d89d3
Showing 1 changed file with 183 additions and 0 deletions.
183 changes: 183 additions & 0 deletions qiskit_braket_provider/providers/braket_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import warnings

from braket.aws import AwsDevice
from braket.circuits import Circuit as BraketCircuit
from braket.device_schema.dwave import DwaveDeviceCapabilities
from braket.device_schema.quera import QueraDeviceCapabilities
from braket.device_schema.xanadu import XanaduDeviceCapabilities
from qiskit.circuit import Gate
from qiskit.providers import ProviderV1
from qiskit.transpiler import CouplingMap, PassManager
from qiskit.transpiler.passes import BasicSwap

from .braket_backend import BraketAwsBackend, BraketLocalBackend

Expand Down Expand Up @@ -82,3 +86,182 @@ def __init__(self):
stacklevel=2,
)
super().__init__()

def to_braket(self, circuit, backend, native=True, topology=True):
"""
Convert a Qiskit circuit to a Braket circuit respecting backend restrictions.
Args:
circuit (QuantumCircuit): The input Qiskit circuit.
backend (BraketBackend): The backend to which the circuit will be transpiled.
native (bool): Whether to use only native gates of the backend.
topology (bool): Whether to respect the device topology.
Returns:
BraketCircuit: The converted Braket circuit.
"""
if native:
# Adjust angles and gate types based on backend restrictions
circuit = self.adjust_angles(circuit, backend)
if topology:
circuit = self.adjust_topology(circuit, backend)

# Convert the adjusted Qiskit circuit to a Braket circuit
braket_circuit = self.convert_to_braket(circuit)

return braket_circuit

def adjust_angles(self, circuit, backend):
"""
Adjust angles in the Qiskit circuit based on backend angle restrictions.
Args:
circuit (QuantumCircuit): The input Qiskit circuit.
backend (BraketBackend): The backend to which the circuit will be transpiled.
Returns:
QuantumCircuit: The adjusted Qiskit circuit.
"""
if backend.name.startswith("rigetti"):
# Adjust angles for Rigetti backends
for instr, _, _ in circuit.data:
if isinstance(instr, Gate) and instr.name == "rx":
# Adjust angles to supported values
theta = instr.params[0]
new_theta = self.adjust_angle(theta)
instr.params[0] = new_theta
# Add more angle adjustments for other backends as needed
return circuit

def adjust_angle(self, theta):
"""
Adjust the angle to be within the supported range of the backend.
Args:
theta (float): The original angle.
Returns:
float: The adjusted angle.
"""
# Adjust the angle to supported values
supported_angles = [0, -1 / 2, 1 / 2, -1, 1] # Example for Rigetti backend
closest_angle = min(supported_angles, key=lambda x: abs(x - theta))
return closest_angle

def adjust_topology(self, circuit, backend):
"""
Adjust the Qiskit circuit to respect the device topology of the backend.
Args:
circuit (QuantumCircuit): The input Qiskit circuit.
backend (BraketBackend): The backend to which the circuit will be transpiled.
Returns:
QuantumCircuit: The adjusted Qiskit circuit.
"""
# Get the coupling map of the backend
coupling_map = CouplingMap(backend.configuration().coupling_map)

# Create a pass manager with the BasicSwap pass to adjust for the topology
pass_manager = PassManager()
pass_manager.append(BasicSwap(coupling_map))

# Run the pass manager on the circuit
adjusted_circuit = pass_manager.run(circuit)

return adjusted_circuit

def convert_to_braket(self, circuit):
"""
Convert the Qiskit circuit to a Braket circuit.
Args:
circuit (QuantumCircuit): The input Qiskit circuit.
Returns:
BraketCircuit: The converted Braket circuit.
"""
braket_circuit = BraketCircuit()

for instr, qargs, _ in circuit.data:
if isinstance(instr, Gate):
if instr.name == "h":
braket_circuit.h(qargs[0].index)
elif instr.name == "x":
braket_circuit.x(qargs[0].index)
elif instr.name == "y":
braket_circuit.y(qargs[0].index)
elif instr.name == "z":
braket_circuit.z(qargs[0].index)
elif instr.name == "s":
braket_circuit.s(qargs[0].index)
elif instr.name == "sdg":
braket_circuit.si(qargs[0].index)
elif instr.name == "t":
braket_circuit.t(qargs[0].index)
elif instr.name == "tdg":
braket_circuit.ti(qargs[0].index)
elif instr.name == "rx":
theta = instr.params[0]
braket_circuit.rx(theta, qargs[0].index)
elif instr.name == "ry":
theta = instr.params[0]
braket_circuit.ry(theta, qargs[0].index)
elif instr.name == "rz":
theta = instr.params[0]
braket_circuit.rz(theta, qargs[0].index)
elif instr.name == "u1":
lambda_ = instr.params[0]
braket_circuit.phaseshift(lambda_, qargs[0].index)
elif instr.name == "u2":
phi, lambda_ = instr.params
braket_circuit.u2(phi, lambda_, qargs[0].index)
elif instr.name == "u3":
theta, phi, lambda_ = instr.params
braket_circuit.u3(theta, phi, lambda_, qargs[0].index)
elif instr.name == "cx":
control, target = qargs
braket_circuit.cnot(control.index, target.index)
elif instr.name == "cy":
control, target = qargs
braket_circuit.cy(control.index, target.index)
elif instr.name == "cz":
control, target = qargs
braket_circuit.cz(control.index, target.index)
elif instr.name == "ch":
control, target = qargs
braket_circuit.ch(control.index, target.index)
elif instr.name == "crx":
theta = instr.params[0]
control, target = qargs
braket_circuit.crx(theta, control.index, target.index)
elif instr.name == "cry":
theta = instr.params[0]
control, target = qargs
braket_circuit.cry(theta, control.index, target.index)
elif instr.name == "crz":
theta = instr.params[0]
control, target = qargs
braket_circuit.crz(theta, control.index, target.index)
elif instr.name == "cp":
lambda_ = instr.params[0]
control, target = qargs
braket_circuit.cphaseshift(lambda_, control.index, target.index)
elif instr.name == "cu1":
lambda_ = instr.params[0]
control, target = qargs
braket_circuit.cphaseshift(lambda_, control.index, target.index)
elif instr.name == "cu3":
theta, phi, lambda_ = instr.params
control, target = qargs
braket_circuit.cu3(theta, phi, lambda_, control.index, target.index)
elif instr.name == "swap":
q0, q1 = qargs
braket_circuit.swap(q0.index, q1.index)
elif instr.name == "ccx":
control1, control2, target = qargs
braket_circuit.ccnot(control1.index, control2.index, target.index)
else:
raise ValueError(f"Unsupported gate: {instr.name}")

return braket_circuit

0 comments on commit 78d89d3

Please sign in to comment.