Пример #1
0
    def test_calculate_adj_grad_simple_case_single(self):
        """Make sure the adjoint gradient works on a one symbol for all gate."""
        n_qubits = 2
        batch_size = 1
        symbol_names = ['alpha', 'beta', 'gamma']
        qubits = cirq.GridQubit.rect(1, n_qubits)
        circuit_batch, resolver_batch = \
        [cirq.Circuit(cirq.X(qubits[0]) ** sympy.Symbol('alpha'),
            cirq.Y(qubits[1]) ** sympy.Symbol('alpha'),
            cirq.CNOT(qubits[0], qubits[1]),
            cirq.FSimGate(
                -0.56,
                sympy.Symbol('alpha'))(qubits[0], qubits[1]))
        ], [{'alpha': 0.123, 'beta': 0.456, 'gamma': 0.789}]

        op_batch = [[cirq.Z(qubits[0]), cirq.X(qubits[1])]
                    for _ in range(batch_size)]

        symbol_values_array = np.array(
            [[resolver[symbol] for symbol in symbol_names]
             for resolver in resolver_batch])

        prev_grads = tf.ones([batch_size, len(op_batch[0])])

        out = tfq_adj_grad_op.tfq_adj_grad(
            util.convert_to_tensor(circuit_batch),
            tf.convert_to_tensor(symbol_names),
            tf.convert_to_tensor(symbol_values_array),
            util.convert_to_tensor(op_batch), prev_grads)

        self.assertAllClose(out, np.array([[1.2993, 0, 0]]), atol=1e-3)
Пример #2
0
 def test_calculate_adj_grad_empty(self):
     """Verify that the empty case is handled gracefully."""
     out = tfq_adj_grad_op.tfq_adj_grad(
         util.convert_to_tensor([cirq.Circuit()]),
         tf.convert_to_tensor([], dtype=tf.dtypes.string),
         tf.convert_to_tensor([[]]),
         tf.convert_to_tensor([[]], dtype=tf.dtypes.string),
         tf.convert_to_tensor([[]]))
     self.assertShapeEqual(np.zeros((1, 0)), out)
Пример #3
0
 def test_calculate_adj_grad_no_circuit(self):
     """Verify that the no circuit case is handled gracefully."""
     out = tfq_adj_grad_op.tfq_adj_grad(
         tf.raw_ops.Empty(shape=(0, ), dtype=tf.string),
         tf.raw_ops.Empty(shape=(0, ), dtype=tf.string),
         tf.raw_ops.Empty(shape=(0, 0), dtype=tf.float32),
         tf.raw_ops.Empty(shape=(0, 0), dtype=tf.string),
         tf.raw_ops.Empty(shape=(0, 0), dtype=tf.float32),
     )
     self.assertShapeEqual(np.zeros((0, 0)), out)
Пример #4
0
    def test_adj_grad_inputs(self):
        """Make sure that the expectation op fails gracefully on bad inputs."""
        n_qubits = 5
        batch_size = 5
        symbol_names = ['alpha']
        qubits = cirq.GridQubit.rect(1, n_qubits)
        circuit_batch, resolver_batch = \
            util.random_symbol_circuit_resolver_batch(
                qubits, symbol_names, batch_size)

        symbol_values_array = np.array(
            [[resolver[symbol] for symbol in symbol_names]
             for resolver in resolver_batch])

        pauli_sums = util.random_pauli_sums(qubits, 3, batch_size)
        upstream_grads = np.ones((batch_size, len(symbol_names)))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'programs must be rank 1'):
            # Circuit tensor has too many dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor([circuit_batch]), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'symbol_names must be rank 1.'):
            # symbol_names tensor has too many dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch),
                np.array([symbol_names]),
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'symbol_values must be rank 2.'):
            # symbol_values_array tensor has too many dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(np.array([symbol_values_array])),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'symbol_values must be rank 2.'):
            # symbol_values_array tensor has too few dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array[0]),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'pauli_sums must be rank 2.'):
            # pauli_sums tensor has too few dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([x for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'pauli_sums must be rank 2.'):
            # pauli_sums tensor has too many dimensions.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[[x]] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'Unparseable proto'):
            # circuit tensor has the right type but invalid values.
            tfq_adj_grad_op.tfq_adj_grad(
                ['junk'] * batch_size, symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'Could not find symbol in parameter map'):
            # symbol_names tensor has the right type but invalid values.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), ['junk'],
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'qubits not found in circuit'):
            # pauli_sums tensor has the right type but invalid values.
            new_qubits = [cirq.GridQubit(5, 5), cirq.GridQubit(9, 9)]
            new_pauli_sums = util.random_pauli_sums(new_qubits, 2, batch_size)
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in new_pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    'Unparseable proto'):
            # pauli_sums tensor has the right type but invalid values 2.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                [['junk']] * batch_size, tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(TypeError, 'Cannot convert'):
            # circuits tensor has the wrong type.
            tfq_adj_grad_op.tfq_adj_grad(
                [1.0] * batch_size, symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(TypeError, 'Cannot convert'):
            # symbol_names tensor has the wrong type.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), [0.1234],
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.UnimplementedError, ''):
            # symbol_values tensor has the wrong type.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                [['junk']] * batch_size,
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(TypeError, 'Cannot convert'):
            # pauli_sums tensor has the wrong type.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                [[1.0]] * batch_size, tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(TypeError, 'missing'):
            # we are missing an argument.
            # pylint: disable=no-value-for-parameter
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                tf.convert_to_tensor(upstream_grads))
            # pylint: enable=no-value-for-parameter

        with self.assertRaisesRegex(TypeError, 'positional arguments'):
            # pylint: disable=too-many-function-args
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads), [])

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    expected_regex='do not match'):
            # wrong op size.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor([cirq.Circuit()]), symbol_names,
                symbol_values_array.astype(np.float64),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor(upstream_grads))

        with self.assertRaisesRegex(tf.errors.InvalidArgumentError,
                                    expected_regex='rank 2'):
            # wrong grad shape.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor([upstream_grads]))

        with self.assertRaisesRegex(
                tf.errors.InvalidArgumentError,
                expected_regex='gradients and circuits do not match'):
            # wrong grad batch size.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor([[0 for i in range(len(symbol_names))]]))

        with self.assertRaisesRegex(
                tf.errors.InvalidArgumentError,
                expected_regex='gradients and pauli sum dimension do not match'
        ):
            # wrong grad inner size.
            tfq_adj_grad_op.tfq_adj_grad(
                util.convert_to_tensor(circuit_batch), symbol_names,
                tf.convert_to_tensor(symbol_values_array),
                util.convert_to_tensor([[x] for x in pauli_sums]),
                tf.convert_to_tensor([[0, 0]
                                      for _ in range(len(circuit_batch))]))
Пример #5
0
 def differentiate_analytic(self, programs, symbol_names, symbol_values,
                            pauli_sums, forward_pass_vals, grad):
     return tfq_adj_grad_op.tfq_adj_grad(programs, symbol_names,
                                         symbol_values, pauli_sums, grad)