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))
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'))
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)