def test_supported_gates_consistent(self, op_and_sim): """Ensure that supported gates are consistent across backends.""" op = op_and_sim[0] sim = op_and_sim[1] qubits = cirq.GridQubit.rect(1, 5) circuit_batch = [] gate_ref = util.get_supported_gates() for gate in gate_ref: # Create a circuit with non zero entries on real # and imaginary values. c = cirq.Circuit() for qubit in qubits: c += cirq.Circuit(cirq.Y(qubit)**0.125) if gate_ref[gate] == 2: op_qubits = np.random.choice(qubits, size=2, replace=False) c += cirq.Circuit(gate(*op_qubits)) elif gate_ref[gate] == 1: op_qubits = np.random.choice(qubits, size=1, replace=False) c += cirq.Circuit(gate(*op_qubits)) else: raise ValueError( "Unable to test supported gates across all ops." "please update circuit_execution_ops_test.py") circuit_batch.append(c) op_states = op(util.convert_to_tensor(circuit_batch), [], [[]] * len(circuit_batch)).to_list() cirq_states = batch_util.batch_calculate_state( circuit_batch, [cirq.ParamResolver({}) for _ in circuit_batch], sim) self.assertAllClose(cirq_states, op_states, atol=1e-5, rtol=1e-5)
def test_no_circuit(self, sim): """Test functions with no circuits and empty arrays.""" # (1) Test expectation results = batch_util.batch_calculate_expectation([], [], [[]], sim) self.assertDTypeEqual(results, np.float32) self.assertEqual(np.zeros(shape=(0, 0)).shape, results.shape) # (2) Test sampled_expectation results = batch_util.batch_calculate_sampled_expectation([], [], [[]], [[]], sim) self.assertDTypeEqual(results, np.float32) self.assertEqual(np.zeros(shape=(0, 0)).shape, results.shape) # (3) Test state results = batch_util.batch_calculate_state([], [], sim) self.assertDTypeEqual(results, np.complex64) if isinstance(sim, cirq.Simulator): self.assertEqual(np.zeros(shape=(0, 0)).shape, results.shape) else: self.assertEqual(np.zeros(shape=(0, 0, 0)).shape, results.shape) # (4) Test sampling results = batch_util.batch_sample([], [], [], sim) self.assertDTypeEqual(results, np.int8) self.assertEqual(np.zeros(shape=(0, 0, 0)).shape, results.shape)
def cirq_simulate_state(programs, symbol_names, symbol_values): """Simulate the final state of circuits. Calculate the final state of for each `cirq.Circuit` in `programs` with the values in `symbol_values` resolved into the symbols in the circuit (with the ordering defined by `symbol_names`). ```python symbol_names = ['a', 'b', 'c'] programs = tfq.convert_to_tensor( [cirq.Circuit(H(q0) ** sympy.Symbol('a'), X(q1) ** sympy.Symbol('b'), Y(q2) ** sympy.Symbol('c'))] ) symbol_values = [[3,2,1]] cirq_simulate_state(programs, symbol_names, sybmol_values) ``` Would place the values of 3 into the Symbol labeled 'a', 2 into the symbol labeled 'b' and 1 into the symbol labeled 'c'. Then it would simulate the final state of the circuit. Note: In the case of circuits with varying size, all nonexistent amplitudes are padded with -2. Args: programs: `tf.Tensor` of strings with shape [batch_size] containing the string representations of the circuits to be executed. symbol_names: `tf.Tensor` of strings with shape [n_params], which is used to specify the order in which the values in `symbol_values` should be placed inside of the circuits in `programs`. symbol_values: `tf.Tensor` of real numbers with shape [batch_size, n_params] specifying parameter values to resolve into the circuits specified by programs, following the ordering dictated by `symbol_names`. Returns: `tf.Tensor` with shape [batch_size, <size of largest circuit state>] that contains the state information of the circuit. """ def _no_grad(grad): raise RuntimeError( 'Differentiation through states is not supported.') _input_check_helper(programs, symbol_names, symbol_values) states = batch_util.batch_calculate_state( *_batch_deserialize_helper(programs, symbol_names, symbol_values), simulator) return states, _no_grad
def test_empty_circuits(self, sim): """Test functions with empty circuits.""" # Common preparation resolver_batch = [cirq.ParamResolver({}) for _ in range(BATCH_SIZE)] circuit_batch = [cirq.Circuit() for _ in range(BATCH_SIZE)] qubits = cirq.GridQubit.rect(1, N_QUBITS) ops = util.random_pauli_sums(qubits, PAULI_LENGTH, BATCH_SIZE) n_samples = [[1000] for _ in range(len(ops))] # If there is no op on a qubit, the expectation answer is -2.0 true_expectation = (-2.0, ) # (1) Test expectation results = batch_util.batch_calculate_expectation( circuit_batch, resolver_batch, [[x] for x in ops], sim) for _, _, result, _ in zip(circuit_batch, resolver_batch, results, ops): self.assertAllClose(true_expectation, result, rtol=1e-5, atol=1e-5) self.assertDTypeEqual(results, np.float32) # (2) Test sampled_expectation results = batch_util.batch_calculate_sampled_expectation( circuit_batch, resolver_batch, [[x] for x in ops], n_samples, sim) for _, _, result, _ in zip(circuit_batch, resolver_batch, results, ops): self.assertAllClose(true_expectation, result, rtol=1.0, atol=1e-1) self.assertDTypeEqual(results, np.float32) # (3) Test state results = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) for circuit, resolver, result in zip(circuit_batch, resolver_batch, results): r = _pad_state(sim, sim.simulate(circuit, resolver), 0) self.assertAllClose(r, result, rtol=1e-5, atol=1e-5) self.assertDTypeEqual(results, np.complex64) # (4) Test sampling n_samples = 2000 * (2**N_QUBITS) results = batch_util.batch_sample(circuit_batch, resolver_batch, n_samples, sim) for circuit, resolver, a in zip(circuit_batch, resolver_batch, results): state = sim.simulate(circuit, resolver) r = _sample_helper(sim, state, len(circuit.all_qubits()), n_samples) self.assertAllClose(r, a, atol=1e-5) self.assertDTypeEqual(results, np.int32)
def test_simulate_state_no_circuits(self, op_and_sim): """Test no circuits for states using cirq and tfq.""" op = op_and_sim[0] sim = op_and_sim[1] circuit_batch = tf.raw_ops.Empty(shape=(0,), dtype=tf.string) empty_params = tf.raw_ops.Empty(shape=(0, 0), dtype=tf.float32) op_states = op(circuit_batch, [], empty_params).numpy() cirq_states = batch_util.batch_calculate_state([], [], sim) self.assertEqual(op_states.shape, cirq_states.shape)
def test_batch_simulate_state(self, sim): """Test variable sized wavefunction output.""" circuit_batch, resolver_batch = _get_mixed_batch( cirq.GridQubit.rect(1, N_QUBITS), SYMBOLS, BATCH_SIZE) results = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) for circuit, resolver, result in zip(circuit_batch, resolver_batch, results): r = _pad_state(sim, sim.simulate(circuit, resolver), N_QUBITS) self.assertAllClose(r, result, rtol=1e-5, atol=1e-5) self.assertDTypeEqual(results, np.complex64)
def test_simulate_state_empty(self, op_and_sim): """Test empty circuits for states using cirq and tfq.""" op = op_and_sim[0] sim = op_and_sim[1] circuit_batch = [cirq.Circuit() for _ in range(BATCH_SIZE)] resolver_batch = [cirq.ParamResolver({}) for _ in range(BATCH_SIZE)] op_states = op(util.convert_to_tensor(circuit_batch), [], [[]] * BATCH_SIZE).to_list() cirq_states = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) self.assertAllClose(cirq_states, op_states, atol=1e-5, rtol=1e-5)
def test_simulate_state_no_symbols(self, op_and_sim, n_qubits): """Compute states using cirq and tfq without symbols.""" op = op_and_sim[0] sim = op_and_sim[1] circuit_batch, resolver_batch = util.random_circuit_resolver_batch( cirq.GridQubit.rect(1, n_qubits), BATCH_SIZE) op_states = op(util.convert_to_tensor(circuit_batch), [], [[]] * BATCH_SIZE).to_list() cirq_states = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) self.assertAllClose(cirq_states, op_states, atol=1e-5, rtol=1e-5)
def test_simulate_state_large(self, op_and_sim): """Test a reasonably large and complex circuit.""" op, sim = op_and_sim symbol_names = [] circuit_batch, resolver_batch = \ util.random_circuit_resolver_batch( cirq.GridQubit.rect(4, 4), 5) symbol_values_array = np.array( [[resolver[symbol] for symbol in symbol_names] for resolver in resolver_batch]).astype(np.float32) op_states = op(util.convert_to_tensor(circuit_batch), symbol_names, symbol_values_array).to_list() cirq_states = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) self.assertAllClose(cirq_states, op_states, atol=1e-5, rtol=1e-5)
def test_simulate_state_with_symbols(self, op_and_sim, n_qubits, symbol_names): """Compute states using cirq and tfq with symbols.""" op = op_and_sim[0] sim = op_and_sim[1] circuit_batch, resolver_batch = \ util.random_symbol_circuit_resolver_batch( cirq.GridQubit.rect(1, n_qubits), symbol_names, BATCH_SIZE) symbol_values_array = np.array( [[resolver[symbol] for symbol in symbol_names] for resolver in resolver_batch]) op_states = op(util.convert_to_tensor(circuit_batch), symbol_names, symbol_values_array).to_list() cirq_states = batch_util.batch_calculate_state(circuit_batch, resolver_batch, sim) self.assertAllClose(cirq_states, op_states, atol=1e-5, rtol=1e-5)