def circuit_from_qasm(qasm: str) -> cirq.circuits.Circuit: """Parses an OpenQASM 2.0 program to a Cirq circuit. The OpenQASM language has been extended by the ``ising``, ``xy``, ``iswap`` and ``sqrt_iswap`` gates. Args: qasm: OpenQASM string Returns: parsed circuit """ parser = QasmParser() parser.all_gates['ising'] = QasmGateStatement( qasm_gate='ising', cirq_gate=lambda params: ig.IsingGate(exponent=params[0]), num_params=1, num_args=2) parser.all_gates['xy'] = QasmGateStatement( qasm_gate='xy', cirq_gate=lambda params: ig.XYGate(exponent=params[0]), num_params=1, num_args=2) parser.all_gates['iswap'] = QasmGateStatement(qasm_gate='iswap', cirq_gate=cirq.ops.ISWAP, num_params=0, num_args=2) parser.all_gates['sqrt_iswap'] = QasmGateStatement( qasm_gate='sqrt_iswap', cirq_gate=cirq.ops.ISwapPowGate(exponent=0.5), num_params=0, num_args=2) return parser.parse(qasm).circuit
def operation_decomposer(self, op: ops.Operation): """Decomposes CNOT and the CZPowGate family to Valkmusa native gates.""" if isinstance(op.gate, ops.CXPowGate) and op.gate.exponent == 1.0: # CNOT is a special case, we decompose it using iSWAPs to be able to commute Z rotations through control_qubit = op.qubits[0] target_qubit = op.qubits[1] iSWAP = ig.XYGate(exponent=-1 / 2) return [ ops.XPowGate(exponent=0.5).on(target_qubit), ops.ZPowGate(exponent=-0.5).on(control_qubit), ops.ZPowGate(exponent=0.5).on(target_qubit), iSWAP.on(*op.qubits), ops.XPowGate(exponent=0.5).on(control_qubit), iSWAP.on(*op.qubits), ops.ZPowGate(exponent=0.5).on(target_qubit), ] if isinstance(op.gate, ops.CZPowGate): # the CZ family is decomposed using two applications of the XY interaction s = -op.gate.exponent / 4 r = -2 * s return [ ops.XPowGate(exponent=0.5).on(op.qubits[0]), ops.YPowGate(exponent=-0.5).on(op.qubits[1]), ops.ZPowGate(exponent=0.5).on(op.qubits[1]), ig.XYGate(exponent=s).on(*op.qubits), ops.YPowGate(exponent=1).on(op.qubits[1]), ig.XYGate(exponent=s).on(*op.qubits), ops.XPowGate(exponent=-0.5).on(op.qubits[0]), ops.YPowGate(exponent=0.5).on(op.qubits[1]), ops.XPowGate(exponent=-0.5).on(op.qubits[1]), ops.ZPowGate(exponent=r).on(op.qubits[0]), ops.ZPowGate(exponent=r + 1).on(op.qubits[1]), ] if isinstance(op.gate, ops.ISwapPowGate): # the ISwap family is implemented using the XY interaction return [ig.XYGate(exponent=-0.5 * op.gate.exponent).on(*op.qubits)] return None
def operation_decomposer(self, op): """Decomposes gates into the native Adonis gate set. For now provides a special decomposition for CZPowGate only, which seems to be enough. """ if isinstance(op.gate, ops.CZPowGate): # decompose CZPowGate using IsingGate s = 1 - op.gate.exponent / 2 G = ig.IsingGate(exponent=s) # local Z rotations L = ops.ZPowGate(exponent=-s) return [G.on(*op.qubits), L.on(op.qubits[0]), L.on(op.qubits[1])] if isinstance(op.gate, ops.ISwapPowGate): # the ISwap family is implemented using the XY interaction return [ig.XYGate(exponent=-0.5 * op.gate.exponent).on(*op.qubits)] return None
native_1q_gates = [ cirq.X, cirq.Y, cirq.XPowGate(exponent=0.23), cirq.YPowGate(exponent=0.71), cirq.PhasedXPowGate(phase_exponent=1.7, exponent=-0.58), cirq.Z, cirq.ZPowGate(exponent=-0.23), ] finally_decomposed_1q_gates = [] native_2q_gates = [ ig.IsingGate(exponent=0.45), ig.XYGate(exponent=0.38), ] non_native_1q_gates = [ cirq.H, cirq.HPowGate(exponent=-0.55), cirq.PhasedXZGate(x_exponent=0.2, z_exponent=-0.5, axis_phase_exponent=0.75), ] non_native_2q_gates = [ cirq.ISwapPowGate(exponent=0.27), cirq.ISWAP, cirq.SWAP, cirq.CNOT,
def test_gate_matrices_xy(self, t): """Verify that the XY gates work as expected.""" U = cirq.ISwapPowGate(exponent=t)._unitary_() assert np.allclose(ig.XYGate(exponent=-0.5 * t)._unitary_(), U)