def test_resolve_parameters_consistency_basic(self): """Compare tfq op to cirq resolving.""" qubits = cirq.GridQubit.rect(1, 4) circuit = cirq.Circuit() symbols = [] for n, q in enumerate(qubits): new_bit = sympy.Symbol("bit_{}".format(n)) circuit += cirq.X(q)**new_bit symbols.append(new_bit) symbol_names = [str(s) for s in symbols] bitstring_list = [[0, 0, 0, 0], [0, 1, 0, 1], [1, 0, 1, 1]] circuit_list = [] resolver_list = [] for bitstring in bitstring_list: resolve_dict = {} for s, b in zip(symbols, bitstring): resolve_dict[s] = b resolver_list.append(cirq.ParamResolver(resolve_dict)) circuit_list.append(circuit) test_resolved_circuits = util.from_tensor( tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_list), symbol_names, np.asarray(bitstring_list))) expected_resolved_circuits = [] for circuit, resolver in zip(circuit_list, resolver_list): expected_resolved_circuits.append( cirq.resolve_parameters(circuit, resolver)) for exp_c, test_c in zip(expected_resolved_circuits, test_resolved_circuits): self.assertAllEqual(exp_c, test_c)
def test_resolve_parameters_consistency(self, n_qubits, symbol_names): """Compare tfq op to cirq resolving for randomized circuits.""" # Get random circuit batches qubits = cirq.GridQubit.rect(1, n_qubits) batch_size = 15 n_moments = 15 circuit_batch, resolver_batch = \ util.random_symbol_circuit_resolver_batch( qubits, symbol_names, batch_size, n_moments=n_moments, include_channels=True, include_scalars=True) # Remove one of the symbols from the resolvers symbol_names_partial = symbol_names[1:] symbol_values_array_partial = np.array( [[resolver[symbol] for symbol in symbol_names_partial] for resolver in resolver_batch]) resolver_batch_partial = [ cirq.ParamResolver( {symbol: resolver[symbol] for symbol in symbol_names_partial}) for resolver in resolver_batch ] # Resolve in two ways and compare results test_resolved_circuits = util.from_tensor( tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names_partial, symbol_values_array_partial)) expected_resolved_circuits = [] for circuit, resolver in zip(circuit_batch, resolver_batch_partial): expected_resolved_circuits.append( cirq.resolve_parameters(circuit, resolver)) # TODO(zaqqwerty): Find a way to eliminate parsing. for test_c, exp_c in zip(test_resolved_circuits, expected_resolved_circuits): for test_m, exp_m in zip(test_c, exp_c): for test_o, exp_o in zip(test_m, exp_m): self.assertTrue( util.gate_approx_eq(test_o.gate, exp_o.gate))
def test_resolve_parameters_input_checking(self): """Check that the resolve parameters op has correct input checking.""" 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]) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'must be rank 1'): # programs tensor has the wrong shape (too many dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor([circuit_batch]), symbol_names, symbol_values_array) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'must be rank 1'): # programs tensor has the wrong shape (too few dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch)[0], symbol_names, symbol_values_array) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'must be rank 1'): # symbol_names tensor has the wrong shape (too many dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), np.array([symbol_names]), symbol_values_array) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'must be rank 1'): # symbol_names tensor has the wrong shape (too few dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names[0], symbol_values_array) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'symbol_values must be rank 2'): # symbol_values tensor has the wrong shape (too many dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names, np.array([symbol_values_array])) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'symbol_values must be rank 2'): # symbol_values tensor has the wrong shape (too few dims). tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names, symbol_values_array[0]) with self.assertRaisesRegex(tf.errors.InvalidArgumentError, 'Unparseable proto'): # programs tensor has the right type, but invalid value. tfq_utility_ops.resolve_parameters(['junk'] * batch_size, symbol_names, symbol_values_array) with self.assertRaisesRegex(TypeError, 'Cannot convert'): # programs tensor has the wrong type. tfq_utility_ops.resolve_parameters([1] * batch_size, symbol_names, symbol_values_array) with self.assertRaisesRegex(TypeError, 'Cannot convert'): # symbol_names tensor has the wrong type. tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), [1], symbol_values_array) with self.assertRaisesRegex(tf.errors.UnimplementedError, 'Cast string to float is not supported'): # symbol_values tensor has the wrong type. tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names, [['junk']] * batch_size) with self.assertRaisesRegex(TypeError, 'missing'): # too few tensors. # pylint: disable=no-value-for-parameter tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names)
def test_resolve_parameters_consistency(self, n_qubits, symbol_names): """Compare tfq op to cirq resolving for randomized circuits.""" # Get random circuit batches qubits = cirq.GridQubit.rect(1, n_qubits) batch_size = 15 n_moments = 15 circuit_batch, resolver_batch = \ util.random_symbol_circuit_resolver_batch( qubits, symbol_names, batch_size, n_moments) # Remove one of the symbols from the resolvers symbol_names_partial = symbol_names[1:] symbol_values_array_partial = np.array( [[resolver[symbol] for symbol in symbol_names_partial] for resolver in resolver_batch]) resolver_batch_partial = [ cirq.ParamResolver( {symbol: resolver[symbol] for symbol in symbol_names_partial}) for resolver in resolver_batch ] # Resolve in two ways and compare results test_resolved_circuits = util.from_tensor( tfq_utility_ops.resolve_parameters( util.convert_to_tensor(circuit_batch), symbol_names_partial, symbol_values_array_partial)) expected_resolved_circuits = [] for circuit, resolver in zip(circuit_batch, resolver_batch_partial): expected_resolved_circuits.append( cirq.resolve_parameters(circuit, resolver)) # TODO(zaqqwerty): Find a way to eliminate parsing. for test_c, exp_c in zip(test_resolved_circuits, expected_resolved_circuits): for test_m, exp_m in zip(test_c, exp_c): for test_o, exp_o in zip(test_m, exp_m): tg = test_o.gate eg = exp_o.gate self.assertEqual(type(tg), type(eg)) # TODO(zaqqwerty): simplify parsing when cirq build parser # see core/serialize/serializer.py if isinstance(tg, cirq.IdentityGate): # all identity gates are the same continue elif isinstance(tg, cirq.EigenGate): self._compare_gate_parameters(tg._global_shift, eg._global_shift) self._compare_gate_parameters(tg._exponent, eg._exponent) elif isinstance(tg, cirq.FSimGate): self._compare_gate_parameters(tg.theta, eg.theta) self._compare_gate_parameters(tg.phi, eg.phi) elif isinstance( tg, (cirq.PhasedXPowGate, cirq.PhasedISwapPowGate)): self._compare_gate_parameters(tg._global_shift, eg._global_shift) self._compare_gate_parameters(tg._exponent, eg._exponent) self._compare_gate_parameters(tg._phase_exponent, eg._phase_exponent) else: self.assertTrue(False, msg="Some gate in the randomizer " "is not being checked: " "{}".format(type(tg)))