Skip to content

Commit

Permalink
Add warning when converting global phase operator to OpenQASM 2.0 (#6476
Browse files Browse the repository at this point in the history
)
  • Loading branch information
kenya-sk authored Feb 29, 2024
1 parent eef7c5c commit d75d43f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
6 changes: 5 additions & 1 deletion cirq-core/cirq/circuits/qasm_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ def output(text):
output(f'creg {meas_id}[{len(meas.qubits)}];\n')
else:
output(f'creg {meas_id}[{len(meas.qubits)}]; // Measurement: {comment}\n')
output_line_gap(2)
# In OpenQASM 2.0, the transformation of global phase gates is ignored.
# Therefore, no newline is created when the operations contained in
# a circuit consist only of global phase gates.
if any(not isinstance(op.gate, ops.GlobalPhaseGate) for op in self.operations):
output_line_gap(2)

# Operations
self._write_operations(self.operations, output, output_line_gap)
Expand Down
13 changes: 13 additions & 0 deletions cirq-core/cirq/circuits/qasm_output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ def test_h_gate_with_parameter():
)


def test_qasm_global_pahse():
output = cirq.QasmOutput((cirq.global_phase_operation(np.exp(1j * 5))), ())
assert (
str(output)
== """OPENQASM 2.0;
include "qelib1.inc";
// Qubits: []
"""
)


def test_precision():
(q0,) = _make_qubits(1)
output = cirq.QasmOutput((cirq.X(q0) ** 0.1234567,), (q0,), precision=3)
Expand Down
11 changes: 10 additions & 1 deletion cirq-core/cirq/ops/gate_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""Basic types defining qubits, gates, and operations."""

import re
import warnings
from typing import (
AbstractSet,
Any,
Expand All @@ -35,7 +36,7 @@

import numpy as np

from cirq import protocols, value
from cirq import ops, protocols, value
from cirq.ops import raw_types, gate_features, control_values as cv
from cirq.type_workarounds import NotImplementedType

Expand Down Expand Up @@ -348,6 +349,14 @@ def __rmul__(self, other: Any) -> Any:
return self.gate._rmul_with_qubits(self._qubits, other)

def _qasm_(self, args: 'protocols.QasmArgs') -> Optional[str]:
if isinstance(self.gate, ops.GlobalPhaseGate):
warnings.warn(
"OpenQASM 2.0 does not support global phase."
"Since the global phase does not affect the measurement results, "
"the conversion to QASM is disregarded."
)
return ""

return protocols.qasm(self.gate, args=args, qubits=self.qubits, default=None)

def _equal_up_to_global_phase_(
Expand Down
6 changes: 6 additions & 0 deletions cirq-core/cirq/testing/consistent_qasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def assert_qasm_is_consistent_with_unitary(val: Any):
if isinstance(val, ops.Operation):
qubits: Sequence[ops.Qid] = val.qubits
op = val
gate = val.gate
elif isinstance(val, ops.Gate):
qid_shape = protocols.qid_shape(val)
remaining_shape = list(qid_shape)
Expand All @@ -52,9 +53,14 @@ def assert_qasm_is_consistent_with_unitary(val: Any):
remaining_shape.pop(i)
qubits = devices.LineQid.for_qid_shape(remaining_shape)
op = val.on(*qubits)
gate = val
else:
raise NotImplementedError(f"Don't know how to test {val!r}")

if isinstance(gate, ops.GlobalPhaseGate):
# OpenQASM 2.0 does not support global phase gates.
return

args = protocols.QasmArgs(qubit_id_map={q: f'q[{i}]' for i, q in enumerate(qubits)})
qasm = protocols.qasm(op, args=args, default=None)
if qasm is None:
Expand Down

0 comments on commit d75d43f

Please sign in to comment.