# -*- coding: utf-8 -*-
""" run function for IBMQ """
from collections import Counter
import numpy as np
from qiskit import IBMQ, QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute, Aer
from qiskit.providers.ibmq import least_busy
from qiskit.circuit.library.standard_gates import SXdgGate
import qlazy.config as cfg
from qlazy.Result import Result
[docs]def run(qcirc=None, shots=1, cid=None, backend=None, out_state=False, init=None):
""" run the quantum circuit """
if qcirc is None:
raise ValueError("quantum circuit must be specified.")
if out_state is True:
raise ValueError("output option is not supported.")
if init is not None:
raise ValueError("init option is not supported.")
qcirc_tmp = qcirc.clone()
qubit_num = qcirc_tmp.qubit_num
cmem_num = qcirc_tmp.cmem_num
if cid is None:
cid = list(range(cmem_num))
if cmem_num < len(cid):
raise ValueError("length of cid must be less than classical resister size of qcirc")
qubit_reg = QuantumRegister(qubit_num)
cmem_reg = [ClassicalRegister(1, name="c{}".format(i)) for i in range(cmem_num)]
args = [qubit_reg] + cmem_reg
qc = QuantumCircuit(*args)
exist_measurement = False
while True:
kind = qcirc_tmp.kind_first()
if kind is None:
break
(kind, qid, para, c, ctrl, tag) = qcirc_tmp.pop_gate()
if kind == cfg.MEASURE:
exist_measurement = True
if c is None:
raise ValueError("cid (classical register ID) must be specified")
qc.measure(qubit_reg[qid[0]], cmem_reg[c])
elif kind == cfg.RESET:
qc.reset(qubit_reg[qid[0]])
else:
__ibmq_add_qgate(qc, kind, qid, para[0], para[1], para[2], ctrl, cmem_reg)
# set backend
if backend.device == 'aer_simulator':
ibmq_backend = Aer.get_backend("aer_simulator")
elif backend.device == 'aer_simulator_statevector':
ibmq_backend = Aer.get_backend("aer_simulator_statevector")
elif backend.device == 'aer_simulator_matrix_product_state':
ibmq_backend = Aer.get_backend("aer_simulator_matrix_product_state")
else:
provider = IBMQ.load_account()
if backend.device == 'least_busy':
ibmq_backend = least_busy(provider.backends(simulator=False, operational=True))
else:
ibmq_backend_system_names = [b.name() for b in
provider.backends(simulator=False, operational=True)]
if backend.device in ibmq_backend_system_names:
ibmq_backend = provider.get_backend(backend.device)
else:
raise ValueError("unknown device")
# execute the circuit
if exist_measurement is True:
res = execute(qc, ibmq_backend, shots=shots).result()
frq = res.get_counts(qc)
frequency = Counter()
for k, v in frq.items():
bits_list = list(k.replace(' ', ''))
bits_list.reverse()
measured_bits_list = [bits_list[c] for c in cid]
measured_bits = ''.join(measured_bits_list)
if measured_bits != '':
frequency[measured_bits] += v
else:
frequency = None
break
else: # no measurement gates included
cid = []
frequency = None
res = None
info = {'quantum_circuit':qc, 'ibmq':res}
result = Result()
result.backend = backend
result.qubit_num = qubit_num
result.cmem_num = cmem_num
result.cid = cid
result.shots = shots
result.frequency = frequency
result.info = info
return result
def __ibmq_add_qgate(qc, kind, qid, para_phase, para_gphase, para_factor, ctrl, cmem_reg):
phase = para_phase * para_factor * np.pi
# 1-qubit, 0-parameter gate
if kind == cfg.PAULI_X:
if ctrl is None:
qc.x(qid[0])
else:
qc.x(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PAULI_Y:
if ctrl is None:
qc.y(qid[0])
else:
qc.y(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PAULI_Z:
if ctrl is None:
qc.z(qid[0])
else:
qc.z(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.ROOT_PAULI_X:
if ctrl is None:
qc.sx(qid[0])
else:
qc.sx(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.ROOT_PAULI_X_:
if ctrl is None:
qc.sxdg(qid[0])
else:
qc.sxdg(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.HADAMARD:
if ctrl is None:
qc.h(qid[0])
else:
qc.h(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PHASE_SHIFT_S:
if ctrl is None:
qc.s(qid[0])
else:
qc.s(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PHASE_SHIFT_S_:
if ctrl is None:
qc.sdg(qid[0])
else:
qc.sdg(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PHASE_SHIFT_T:
if ctrl is None:
qc.t(qid[0])
else:
qc.t(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PHASE_SHIFT_T_:
if ctrl is None:
qc.tdg(qid[0])
else:
qc.tdg(qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.IDENTITY:
if ctrl is None:
qc.i(qid[0])
else:
qc.i(qid[0]).c_if(cmem_reg[ctrl], 1)
# 1-qubit, 1-parameter gate
elif kind == cfg.ROTATION_X:
if ctrl is None:
qc.rx(phase, qid[0])
else:
qc.rx(phase, qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.ROTATION_Y:
if ctrl is None:
qc.ry(phase, qid[0])
else:
qc.ry(phase, qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.ROTATION_Z:
if ctrl is None:
qc.rz(phase, qid[0])
else:
qc.rz(phase, qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.PHASE_SHIFT:
if ctrl is None:
qc.p(phase, qid[0])
else:
qc.p(phase, qid[0]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_X:
if ctrl is None:
qc.cx(qid[0], qid[1])
else:
qc.cx(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_Y:
if ctrl is None:
qc.cy(qid[0], qid[1])
else:
qc.cy(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_Z:
if ctrl is None:
qc.cz(qid[0], qid[1])
else:
qc.cz(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_XR:
if ctrl is None:
qc.csx(qid[0], qid[1])
else:
qc.csx(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_XR_:
q_csxdg = QuantumRegister(2)
qc_csxdg = QuantumCircuit(q_csxdg)
csxdg_gate = SXdgGate().control(1)
qc_csxdg.append(csxdg_gate, q_csxdg)
if ctrl is None:
qc.append(qc_csxdg, qargs=[qid[0], qid[1]])
else:
qc.append(qc_csxdg, qargs=[qid[0], qid[1]]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_H:
if ctrl is None:
qc.ch(qid[0], qid[1])
else:
qc.ch(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_S:
if ctrl is None:
qc.cp(0.5 * np.pi, qid[0], qid[1])
else:
qc.cp(0.5 * np.pi, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_S_:
if ctrl is None:
qc.cp(-0.5 * np.pi, qid[0], qid[1])
else:
qc.cp(-0.5 * np.pi, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_T:
if ctrl is None:
qc.cp(0.25 * np.pi, qid[0], qid[1])
else:
qc.cp(0.25 * np.pi, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_T_:
if ctrl is None:
qc.cp(-0.25 * np.pi, qid[0], qid[1])
else:
qc.cp(-0.25 * np.pi, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_P:
if ctrl is None:
qc.cp(phase, qid[0], qid[1])
else:
qc.cp(phase, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.SWAP_QUBITS:
if ctrl is None:
qc.swap(qid[0], qid[1])
else:
qc.swap(qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
# 2-qubit, 1-parameters gate
elif kind == cfg.CONTROLLED_RX:
if ctrl is None:
qc.crx(phase, qid[0], qid[1])
else:
qc.crx(phase, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_RY:
if ctrl is None:
qc.cry(phase, qid[0], qid[1])
else:
qc.cry(phase, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
elif kind == cfg.CONTROLLED_RZ:
if ctrl is None:
qc.crz(phase, qid[0], qid[1])
else:
qc.crz(phase, qid[0], qid[1]).c_if(cmem_reg[ctrl], 1)
else:
raise ValueError("unknown gate")