gaialive's picture
Upload 170 files
227c43a verified
"""
IBM Quantum Cloud Integration Plugin
This module implements a robust Cirq → Qiskit conversion utility that handles
a broad set of common gates (including parameterized rotations) and measurements.
It then authenticates with IBM Quantum using qiskit-ibm-provider, transpiles the
converted circuit, submits the job to an IBM backend, and returns the results.
Provider Setup Guidance:
1. Create an IBM Quantum account and retrieve your API token.
2. Save your token by calling:
from qiskit_ibm_provider import IBMProvider
IBMProvider.save_account(token='MY_API_TOKEN')
(This stores your credentials in $HOME/.qiskit/qiskit-ibm.json.)
3. Alternatively, set the environment variable QISKIT_IBM_TOKEN.
4. Or, for a single session, pass the token when instantiating the provider.
Requirements:
- cirq
- qiskit
- qiskit-ibm-provider
- sympy
"""
import cirq
import sympy
from qiskit import transpile
from qiskit_ibm_provider import IBMProvider
#############################################
# Part 1: Robust Cirq to Qiskit Conversion #
#############################################
def _handle_rx(rads):
from qiskit.circuit.library import RXGate
if isinstance(rads, sympy.Basic):
from qiskit.circuit import Parameter
return RXGate(Parameter(str(rads)))
elif isinstance(rads, (float, int)):
return RXGate(rads)
else:
return RXGate(rads)
def _handle_ry(rads):
from qiskit.circuit.library import RYGate
if isinstance(rads, sympy.Basic):
from qiskit.circuit import Parameter
return RYGate(Parameter(str(rads)))
else:
return RYGate(rads)
def _handle_rz(rads):
from qiskit.circuit.library import RZGate
if isinstance(rads, sympy.Basic):
from qiskit.circuit import Parameter
return RZGate(Parameter(str(rads)))
else:
return RZGate(rads)
def cirq_to_qiskit(cirq_circuit: cirq.Circuit):
"""
Converts a Cirq circuit into a Qiskit QuantumCircuit.
Supports:
- Single-qubit gates: X, Y, Z, S, T, H, and parameterized rotations (Rx, Ry, Rz).
- Two-qubit gates: CNOT, CZ, SWAP.
- Measurements.
Symbolic parameters in Cirq become Qiskit Parameter objects.
Returns:
A Qiskit QuantumCircuit.
"""
# Collect and sort qubits
all_qubits = sorted(cirq_circuit.all_qubits(), key=lambda q: str(q))
num_qubits = len(all_qubits)
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qreg = QuantumRegister(num_qubits, 'q')
creg = ClassicalRegister(num_qubits, 'c')
qc = QuantumCircuit(qreg, creg)
qubit_map = {q: i for i, q in enumerate(all_qubits)}
for moment in cirq_circuit:
for op in moment.operations:
gate = op.gate
qubits = op.qubits
# Handle measurement
if isinstance(gate, cirq.MeasurementGate):
for q in qubits:
idx = qubit_map[q]
qc.measure(qreg[idx], creg[idx])
# Single-qubit operations
elif len(qubits) == 1:
idx = qubit_map[qubits[0]]
if isinstance(gate, cirq.XPowGate) and gate.exponent == 1 and gate.global_shift == 0:
qc.x(qreg[idx])
elif isinstance(gate, cirq.YPowGate) and gate.exponent == 1 and gate.global_shift == 0:
qc.y(qreg[idx])
elif isinstance(gate, cirq.ZPowGate) and gate.exponent == 1 and gate.global_shift == 0:
qc.z(qreg[idx])
# For constant gates, compare directly
elif gate == cirq.S:
qc.s(qreg[idx])
elif gate == cirq.T:
qc.t(qreg[idx])
elif gate == cirq.H:
qc.h(qreg[idx])
# Parametric rotations
elif isinstance(gate, cirq.XPowGate) and gate.global_shift == 0:
angle = sympy.pi * gate.exponent
qc.append(_handle_rx(angle), [qreg[idx]])
elif isinstance(gate, cirq.YPowGate) and gate.global_shift == 0:
angle = sympy.pi * gate.exponent
qc.append(_handle_ry(angle), [qreg[idx]])
elif isinstance(gate, cirq.ZPowGate) and gate.global_shift == 0:
angle = sympy.pi * gate.exponent
qc.append(_handle_rz(angle), [qreg[idx]])
else:
continue
# Two-qubit operations
elif len(qubits) == 2:
idx0 = qubit_map[qubits[0]]
idx1 = qubit_map[qubits[1]]
if isinstance(gate, cirq.CNOT):
qc.cx(qreg[idx0], qreg[idx1])
elif isinstance(gate, cirq.CZ):
qc.cz(qreg[idx0], qreg[idx1])
elif isinstance(gate, cirq.SWAP):
qc.swap(qreg[idx0], qreg[idx1])
else:
continue
else:
continue
return qc
###########################################
# Part 2: IBM Quantum Integration #
###########################################
def authenticate_ibm(token: str = None):
"""
Authenticates with IBM Quantum using the provided token.
If token is None, attempts to load credentials from the environment or saved file.
Returns the IBMProvider instance.
"""
if token:
return IBMProvider(token=token)
else:
return IBMProvider()
def submit_cirq_to_ibm(cirq_circuit: cirq.Circuit, token: str = None, shots: int = 1024, backend_name: str = None):
"""
Converts a Cirq circuit to a Qiskit circuit, transpiles it for an IBM backend,
submits the job, and returns the job ID and results.
"""
provider = authenticate_ibm(token)
qiskit_circ = cirq_to_qiskit(cirq_circuit)
if qiskit_circ is None:
raise ValueError("Conversion from Cirq to Qiskit failed.")
if backend_name:
backend = provider.get_backend(backend_name)
else:
simulator_backends = provider.backends(filters=lambda b: b.configuration().simulator)
if not simulator_backends:
raise ValueError("No simulator backends available.")
from qiskit_ibm_provider import least_busy
backend = least_busy(simulator_backends)
transpiled_circ = transpile(qiskit_circ, backend=backend)
job = backend.run(transpiled_circ, shots=shots)
job_id = job.job_id()
result = job.result()
counts = result.get_counts()
return job_id, counts
def demo_hardware_integration_real(token: str, cirq_circuit: cirq.Circuit):
"""
Demonstrates real integration by converting a Cirq circuit to Qiskit,
submitting it to IBM Quantum, and returning job results.
"""
try:
job_id, counts = submit_cirq_to_ibm(cirq_circuit, token, shots=1024)
return {
"success": True,
"job_id": job_id,
"status": "Completed",
"results": counts
}
except Exception as e:
return {
"success": False,
"message": str(e)
}
if __name__ == "__main__":
# Example demonstration:
q0, q1 = cirq.LineQubit.range(2)
demo_circuit = cirq.Circuit(
cirq.H(q0),
cirq.CNOT(q0, q1),
cirq.measure(q0, key='m0'),
cirq.measure(q1, key='m1')
)
# Replace "YOUR_TOKEN_HERE" with your actual IBM Quantum API token.
token = "5930ef6e6c64d2c69651052ee317561b8f64a6ff614e051f8053eb8a3b813e864b7ac94e2d52f97ac487953419e7d62416379a99e0902a0a24b5842c8a2b9e16"
try:
job_id, counts = submit_cirq_to_ibm(demo_circuit, token, shots=1024)
print("IBM Quantum Job submitted successfully!")
print("Job ID:", job_id)
print("Counts:", counts)
except Exception as error:
print("Error during IBM Quantum integration:")
print(error)