Beispiel #1
0
    def _write_operations(self,
                          op_tree: ops.OP_TREE,
                          output: Callable[[str], None],
                          output_line_gap: Callable[[int], None],
                          top=True) -> None:
        for op in ops.flatten_op_tree(op_tree):
            out = protocols.qasm(op, args=self.args, default=None)
            if out is not None:
                output(out)
                continue

            if isinstance(op, ops.GateOperation):
                comment = 'Gate: {!s}'.format(op.gate)
            else:
                comment = 'Operation: {!s}'.format(op)

            decomp = protocols.decompose_once(op, None)
            if decomp is not None:
                if top:
                    output_line_gap(1)
                    output('// {}\n'.format(comment))
                self._write_operations(decomp,
                                       output,
                                       output_line_gap,
                                       top=False)
                if top:
                    output_line_gap(1)
                continue

            mat = protocols.unitary(op, None) if len(op.qubits) <= 2 else None
            if mat is not None and len(op.qubits) == 1:
                u_op = QasmUGate.from_matrix(mat).on(*op.qubits)
                if top:
                    output_line_gap(1)
                    output('// {}\n'.format(comment))
                output(cast(str, protocols.qasm(u_op, args=self.args)))
                if top:
                    output_line_gap(1)
                continue

            if mat is not None and len(op.qubits) == 2:
                u_op = QasmTwoQubitGate.from_matrix(mat).on(*op.qubits)
                if top:
                    output_line_gap(1)
                    output('// {}\n'.format(comment))
                self._write_operations((u_op,),
                                       output,
                                       output_line_gap,
                                       top=False)
                if top:
                    output_line_gap(1)
                continue

            raise ValueError('Cannot output operation as QASM: {!r}'.format(op))
Beispiel #2
0
 def _qasm_(self, args: 'cirq.QasmArgs',
            qubits: Tuple['cirq.Qid', ...]) -> Optional[str]:
     from cirq.circuits import qasm_output
     qasm_gate = qasm_output.QasmUGate(lmda=0.5 - self._axis_phase_exponent,
                                       theta=self._x_exponent,
                                       phi=self._z_exponent +
                                       self._axis_phase_exponent - 0.5)
     return protocols.qasm(qasm_gate, args=args, qubits=qubits)
 def _qasm_(self, args: 'cirq.QasmArgs') -> Optional[str]:
     args.validate_version('2.0')
     if len(self._conditions) > 1:
         raise ValueError('QASM does not support multiple conditions.')
     subop_qasm = protocols.qasm(self._sub_operation, args=args)
     if not self._conditions:
         return subop_qasm
     return f'if ({self._conditions[0].qasm}) {subop_qasm}'
    def _write_operations(
        self,
        op_tree: 'cirq.OP_TREE',
        output: Callable[[str], None],
        output_line_gap: Callable[[int], None],
    ) -> None:
        def keep(op: 'cirq.Operation') -> bool:
            return protocols.qasm(op, args=self.args, default=None) is not None

        def fallback(op):
            if len(op.qubits) not in [1, 2]:
                return NotImplemented

            mat = protocols.unitary(op, None)
            if mat is None:
                return NotImplemented

            if len(op.qubits) == 1:
                return QasmUGate.from_matrix(mat).on(*op.qubits)
            return QasmTwoQubitGate.from_matrix(mat).on(*op.qubits)

        def on_stuck(bad_op):
            return ValueError(
                'Cannot output operation as QASM: {!r}'.format(bad_op))

        for main_op in ops.flatten_op_tree(op_tree):
            decomposed = protocols.decompose(main_op,
                                             keep=keep,
                                             fallback_decomposer=fallback,
                                             on_stuck_raise=on_stuck)

            qasms = [protocols.qasm(op, args=self.args) for op in decomposed]

            should_annotate = decomposed != [main_op
                                             ] or qasms[0].count('\n') > 1
            if should_annotate:
                output_line_gap(1)
                if isinstance(main_op, ops.GateOperation):
                    x = str(main_op.gate).replace('\n', '\n //')
                    output('// Gate: {!s}\n'.format(x))
                else:
                    x = str(main_op).replace('\n', '\n //')
                    output('// Operation: {!s}\n'.format(x))

            for qasm in qasms:
                output(qasm)

            if should_annotate:
                output_line_gap(1)
Beispiel #5
0
 def keep(op: ops.Operation) -> bool:
     return protocols.qasm(op, args=self.args, default=None) is not None
Beispiel #6
0
 def _qasm_(self, args: 'protocols.QasmArgs') -> Optional[str]:
     return protocols.qasm(self.sub_operation, args=args, default=None)
Beispiel #7
0
 def _qasm_(self, args: 'protocols.QasmArgs') -> Optional[str]:
     return protocols.qasm(self.gate,
                           args=args,
                           qubits=self.qubits,
                           default=None)
Beispiel #8
0
def assert_qasm_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._qasm_`'s behavior."""

    # Only test if qiskit is installed.
    try:
        import qiskit
    except ImportError:
        # coverage: ignore
        warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
                      "qiskit isn't installed to verify against.")
        return

    unitary = protocols.unitary(val, None)
    if unitary is None:
        # Vacuous consistency.
        return

    controls = getattr(val, 'control_qubits', None)
    if controls is None:
        qubit_count = len(unitary).bit_length() - 1
    else:
        qubit_count = len(unitary).bit_length() - 1 - (len(controls) -
                                                       controls.count(None))
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        op = val
    elif isinstance(val, ops.Gate):
        qubits = tuple(line.LineQubit.range(qubit_count))
        op = val.on(*qubits)
    else:
        raise NotImplementedError("Don't know how to test {!r}".format(val))

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

    header = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[{}];
""".format(len(qubits))
    qasm = header + qasm

    qasm_unitary = None
    try:
        result = qiskit.execute(
            qiskit.load_qasm_string(qasm),
            backend=qiskit.Aer.get_backend('unitary_simulator'))
        qasm_unitary = result.result().get_unitary()
        qasm_unitary = _reorder_indices_of_matrix(
            qasm_unitary, list(reversed(range(len(qubits)))))

        lin_alg_utils.assert_allclose_up_to_global_phase(qasm_unitary,
                                                         unitary,
                                                         rtol=1e-8,
                                                         atol=1e-8)
    except Exception as ex:
        if qasm_unitary is not None:
            p_unitary, p_qasm_unitary = linalg.match_global_phase(
                unitary, qasm_unitary)
        else:
            p_unitary = None
            p_qasm_unitary = None
        raise AssertionError(
            'QASM be consistent with cirq.unitary(op) up to global phase.\n\n'
            'op:\n{}\n\n'
            'cirq.unitary(op):\n{}\n\n'
            'Generated QASM:\n\n{}\n\n'
            'Unitary of generated QASM:\n{}\n\n'
            'Phased matched cirq.unitary(op):\n{}\n\n'
            'Phased matched unitary of generated QASM:\n{}\n\n'
            'Underlying error:\n{}'.format(_indent(repr(op)),
                                           _indent(repr(unitary)),
                                           _indent(qasm),
                                           _indent(repr(qasm_unitary)),
                                           _indent(repr(p_unitary)),
                                           _indent(repr(p_qasm_unitary)),
                                           _indent(str(ex))))
Beispiel #9
0
def assert_qasm_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._qasm_`'s behavior."""

    # Only test if qiskit is installed.
    try:
        import qiskit
    except ImportError:
        # coverage: ignore
        warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
                      "qiskit isn't installed to verify against.")
        return

    unitary = protocols.unitary(val, None)
    if unitary is None:
        # Vacuous consistency.
        return

    if isinstance(val, ops.Operation):
        qubits: Sequence[ops.Qid] = val.qubits
        op = val
    elif isinstance(val, ops.Gate):
        qid_shape = protocols.qid_shape(val)
        remaining_shape = list(qid_shape)
        controls = getattr(val, 'control_qubits', None)
        if controls is not None:
            for i, q in zip(reversed(range(len(controls))),
                            reversed(controls)):
                if q is not None:
                    remaining_shape.pop(i)
        qubits = devices.LineQid.for_qid_shape(remaining_shape)
        op = val.on(*qubits)
    else:
        raise NotImplementedError(f"Don't know how to test {val!r}")

    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:
        return

    num_qubits = len(qubits)
    header = f"""
OPENQASM 2.0;
include "qelib1.inc";
qreg q[{num_qubits}];
"""
    qasm = header + qasm

    qasm_unitary = None
    try:
        result = qiskit.execute(
            qiskit.QuantumCircuit.from_qasm_str(qasm),
            backend=qiskit.Aer.get_backend('unitary_simulator'),
        )
        qasm_unitary = result.result().get_unitary()
        qasm_unitary = _reorder_indices_of_matrix(
            qasm_unitary, list(reversed(range(num_qubits))))

        lin_alg_utils.assert_allclose_up_to_global_phase(qasm_unitary,
                                                         unitary,
                                                         rtol=1e-8,
                                                         atol=1e-8)
    except Exception as ex:
        if qasm_unitary is not None:
            p_unitary, p_qasm_unitary = linalg.match_global_phase(
                unitary, qasm_unitary)
        else:
            p_unitary = None
            p_qasm_unitary = None
        raise AssertionError(
            'QASM not consistent with cirq.unitary(op) up to global phase.\n\n'
            'op:\n{}\n\n'
            'cirq.unitary(op):\n{}\n\n'
            'Generated QASM:\n\n{}\n\n'
            'Unitary of generated QASM:\n{}\n\n'
            'Phased matched cirq.unitary(op):\n{}\n\n'
            'Phased matched unitary of generated QASM:\n{}\n\n'
            'Underlying error:\n{}'.format(
                _indent(repr(op)),
                _indent(repr(unitary)),
                _indent(qasm),
                _indent(repr(qasm_unitary)),
                _indent(repr(p_unitary)),
                _indent(repr(p_qasm_unitary)),
                _indent(str(ex)),
            ))
Beispiel #10
0
 def _qasm_(self, args: 'cirq.QasmArgs') -> Optional[str]:
     args.validate_version('2.0')
     all_keys = " && ".join(c.qasm for c in self._conditions)
     return args.format('if ({0}) {1}', all_keys,
                        protocols.qasm(self._sub_operation, args=args))