Example #1
0
    def test_append_circuit(self, max_n_bits, symbols, n_circuits):
        """Generate a bunch of circuits of different lengths acting on different
        numbers of qubits and append them using our op, checking that results
        are consistant with the native cirq method.
        """
        base_circuits = []
        circuits_to_append = []
        qubits = cirq.GridQubit.rect(1, max_n_bits)
        other_qubits = cirq.GridQubit.rect(2, max_n_bits)

        base_circuits, _ = util.random_symbol_circuit_resolver_batch(
            qubits, symbols, n_circuits, include_scalars=False)

        circuits_to_append, _ = util.random_symbol_circuit_resolver_batch(
            other_qubits, symbols, n_circuits, include_scalars=False)

        serialized_base_circuits = util.convert_to_tensor(base_circuits)
        serialized_circuits_to_append = util.convert_to_tensor(
            circuits_to_append)

        tfq_results = tfq_utility_ops.append_circuit(
            serialized_base_circuits, serialized_circuits_to_append)

        tfq_results = util.from_tensor(tfq_results)
        cirq_results = [
            a + b for a, b in zip(base_circuits, circuits_to_append)
        ]
        self.assertAllEqual(util.convert_to_tensor(tfq_results),
                            util.convert_to_tensor(cirq_results))
Example #2
0
    def test_append_input_checking(self):
        """Check that the append op has correct input checking."""
        test_circuit = serializer.serialize_circuit(
            cirq.Circuit(cirq.X.on(cirq.GridQubit(0, 0)))).SerializeToString()
        with self.assertRaisesRegex(TypeError, 'Cannot convert \\[1\\]'):
            tfq_utility_ops.append_circuit([test_circuit], [1])
        with self.assertRaisesRegex(TypeError, 'Cannot convert \\[1\\]'):
            tfq_utility_ops.append_circuit([1], [test_circuit])
        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'Unparseable proto'):
            tfq_utility_ops.append_circuit(['wrong'], ['wrong'])
        with self.assertRaisesRegex(
                tf.errors.InvalidArgumentError,
                'programs and programs_to_append must have matching sizes.'):
            tfq_utility_ops.append_circuit([test_circuit],
                                           [test_circuit, test_circuit])
        with self.assertRaisesRegex(
                tf.errors.InvalidArgumentError,
                'programs and programs_to_append must have matching sizes.'):
            tfq_utility_ops.append_circuit([test_circuit, test_circuit],
                                           [test_circuit])
        with self.assertRaisesRegex(
                tf.errors.InvalidArgumentError,
                'programs and programs_to_append must have matching sizes'):
            tfq_utility_ops.append_circuit([], [test_circuit])

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'programs must be rank 1. Got rank 2'):
            tfq_utility_ops.append_circuit([[test_circuit, test_circuit]],
                                           [[test_circuit, test_circuit]])

        with self.assertRaisesRegex(TypeError,
                                    'missing 1 required positional argument'):
            # pylint: disable=no-value-for-parameter
            tfq_utility_ops.append_circuit([test_circuit])
            # pylint: enable=no-value-for-parameter

        with self.assertRaisesRegex(TypeError,
                                    '2 positional arguments but 3 were given'):
            # pylint: disable=too-many-function-args
            tfq_utility_ops.append_circuit([test_circuit], [test_circuit],
                                           [test_circuit])
            # pylint: enable=too-many-function-args

        # These tests really just makes sure we can cast output
        res = tfq_utility_ops.append_circuit([], [])

        self.assertDTypeEqual(res.numpy().astype(np.str), np.dtype('<U1'))
Example #3
0
    def call(self, inputs, *, append=None, prepend=None):
        """Keras call method.

        Input options:

            1. `inputs` can be a single `cirq.Circuit`, a Python `list` of
                `cirq.Circuit`s or a pre-converted `tf.Tensor` of
                `cirq.Circuit`s.

            2. `append` can be a Python `list` of `cirq.Circuit`s or a
                pre-converted `tf.Tensor` of type `str` (containing circuits).

            3. `prepend` can be a Python `list` of `cirq.Circuit`s or a
                pre-converted `tf.Tensor` of type `str` (containing circuits).

        Output shape:
            `tf.Tensor` of shape [input size] containing circuits with append
            circuits appended or prepend circuits prepended.

        """
        # inputs is circuit.

        if append is None and prepend is None:
            raise ValueError("Values must be provided for append or prepend.")

        if append is not None and prepend is not None:
            raise ValueError(
                "Values cannot be given for both append and prepend.")

        # Ingest input circuit(s).
        if isinstance(inputs, cirq.Circuit):
            inputs = util.convert_to_tensor([inputs])

        if isinstance(inputs, (tuple, list, np.ndarray)):
            inputs = util.convert_to_tensor(inputs)

        if not tf.is_tensor(inputs):
            raise TypeError("Circuits cannot be parsed with given input:"
                            " ".format(inputs))

        batch_dim = tf.gather(tf.shape(inputs), 0)

        # Ingest append circuit(s):
        if append is not None:
            if isinstance(append, cirq.Circuit):
                append = tf.tile(util.convert_to_tensor([append]), [batch_dim])
            if isinstance(append, (tuple, list, np.ndarray)):
                append = util.convert_to_tensor(append)
            if not tf.is_tensor(append):
                raise TypeError(
                    "Append circuits cannot be parsed with given input:"
                    " ".format(append))

            return tfq_utility_ops.append_circuit(inputs, append)

        # Otherwise ingest prepend circuits.
        if isinstance(prepend, cirq.Circuit):
            prepend = tf.tile(util.convert_to_tensor([prepend]), [batch_dim])
        if isinstance(prepend, (tuple, list, np.ndarray)):
            prepend = util.convert_to_tensor(prepend)
        if not tf.is_tensor(prepend):
            raise TypeError(
                "Prepend circuits cannot be parsed with given input:"
                " ".format(prepend))

        return tfq_utility_ops.append_circuit(prepend, inputs)