def test_to_sweep_resolver_list(r_list_gen): sweep = cirq.to_sweep(r_list_gen()) assert isinstance(sweep, cirq.Sweep) assert list(sweep) == [ cirq.ParamResolver({'a': 1}), cirq.ParamResolver({'a': 1.5}) ]
def test_to_sweep_type_error(): with pytest.raises(TypeError, match='Unexpected sweep'): cirq.to_sweep(5)
def test_to_sweep_sweep(): sweep = cirq.Linspace('a', 0, 1, 10) assert cirq.to_sweep(sweep) is sweep
def timeit_n_rounds_k_updates(qubits, depth, sim_trials, n_param_updates): """ Args: qubits: QubitId representation of circuit qubits depth (int): Circuit depth. sim_trials (int): Number of trials to run each simulation for the purpose of averaging n_param_updates (int): Number of updates to invoke per trial. Returns: Array of shape (sim_trials, ) containing times for each trial """ """ TIMING: Op placeholder resolution: Each trial consists of the time to run all of: 1. call to TFWaveFunctionSimulator().simulate with feed_dict kwarg 2. put a random wavefunction element to outcomes[v_ind] note that the feed dicts are constructed ahead of time, which is actually generous to the timing. circuit reconstructions: Each trial consists of the time to run all of: 1. Iteratively copy the existing circuit op-wise, inserting new angles according to randomly generated params 2. call to cirq.Simulator() using this new state 3. put a random wavefunction element to outcomes[v_ind] """ tfcirq_times = [] float_times = [] n_qubits = len(qubits) for k in range(sim_trials): """ VERIFICATION: Results between two resolved circuits will be compared according to the amplitude of the wavefunction at a random index `v_ind`, for every trial, for every parameter in the param updates. """ tfcirq_outcomes = np.zeros(n_param_updates).astype(np.complex64) float_outcomes = np.zeros(n_param_updates).astype(np.complex64) v_ind = np.random.randint(2**n_qubits - 1) # precompute all parameter updates to apply to both circuits all_params = np.random.rand(n_param_updates, n_qubits*depth) all_params = np.ones((n_param_updates, n_qubits*depth)) # initialize a persistent sympy-parametrized circuit symbol_strings = [] for i in range(n_qubits*depth): symbol_strings.append("{}".format(i) ) layer_symbols = [sympy.Symbol(s) for s in symbol_strings] global trial layers = trial(depth, qubits, layer_symbols) base_circuit = cirq.Circuit.from_ops([g for l in layers for g in l]) # consistent initial state prep x = np.ones(2**n_qubits, dtype=np.complex64) / np.sqrt(2**n_qubits) # Convert circuit parameters over to placeholders placeholders = [tf.placeholder(tf.complex64, shape=(), name=s) for s in symbol_strings] placeholder_names = ["{}:0".format(s) for s in symbol_strings] tfcirq_circuit = update_params(base_circuit, placeholders) feed_dicts = [dict(zip(placeholder_names, all_params[j][:])) for j in range(n_param_updates)] start = timer() for j in range(n_param_updates): final_state = TFWaveFunctionSimulator(dtype=tf.complex64).simulate( tfcirq_circuit, initial_state=np.copy(x)) tfcirq_outcomes[j] = final_state[v_ind] tfcirq_times_trial_time = timer() - start tfcirq_times.append(tfcirq_times_trial_time) # TODO: need to port everything over to tf2 # initialize a copy of the circuit, this time using hard-coded angles # the symbols will be overwritten with the first update. float_circuit = base_circuit.copy() resolver = cirq.to_sweep({}) start = timer() for j in range(n_param_updates): # Regenerate _entire_ circuit with updates to float values # each time includes the circuit construction time float_circuit = update_params(float_circuit, all_params[j][:]) float_outcomes[j] = cirq.Simulator().simulate_sweep(float_circuit, initial_state=np.copy(x), params=resolver).final_state[v_ind] float_trial_time = timer() - start float_times.append(float_trial_time) np.testing.assert_array_almost_equal(float_outcomes, sympy_outcomes) print("trial {}:") print(" cirq-tf: ", sympy_trial_time) print(" float: ", float_trial_time) return np.asarray(sympy_times), np.asarray(float_times)