def test_get_sampled_expectation_inputs(self): """Test that get expectation only accepts inputs it should.""" circuit_execution_ops.get_sampled_expectation_op() circuit_execution_ops.get_sampled_expectation_op( backend=cirq.Simulator()) circuit_execution_ops.get_sampled_expectation_op( backend=cirq.DensityMatrixSimulator()) mock_engine = mock.Mock() circuit_execution_ops.get_sampled_expectation_op( cirq.google.QuantumEngineSampler(engine=mock_engine, processor_id='test', gate_set=cirq.google.XMON)) with self.assertRaisesRegex(TypeError, expected_regex="a Cirq.Sampler"): circuit_execution_ops.get_sampled_expectation_op(backend="junk")
def __init__(self, backend='noiseless', differentiator=None, **kwargs): """Instantiate this Layer. Create a layer that will output expectation values gained from simulating a quantum circuit. Args: backend: Optional Backend to use to simulate states. Can be either {'noiseless', 'noisy'} users may also specify a preconfigured cirq simulation object to use instead, which must inherit `cirq.Sampler`. differentiator: Optional Differentiator to use to calculate analytic derivative values of given operators_to_measure and circuit, which must inherit `tfq.differentiators.Differentiator`. Defaults to `parameter_shift.ParameterShift()` (None argument). """ super().__init__(**kwargs) # Ingest differentiator. if differentiator is None: differentiator = parameter_shift.ParameterShift() if not isinstance(differentiator, diff.Differentiator): raise TypeError("Differentiator must inherit from " "tfq.differentiators.Differentiator") # Ingest backend. if not isinstance(backend, cirq.Sampler) and \ isinstance(backend, cirq.SimulatesFinalState): raise TypeError( "Backend implements cirq.SimulatesFinalState but " "not cirq.Sampler. Please use Expectation instead.") used_op = None if backend == 'noiseless': used_op = circuit_execution_ops.get_sampled_expectation_op( backend=None) elif backend == 'noisy': used_op = noisy_sampled_expectation_op.sampled_expectation else: used_op = circuit_execution_ops.get_sampled_expectation_op( backend=backend) self._expectation_op = differentiator.generate_differentiable_op( sampled_op=used_op) self._w = None
def test_sample_errors(self): """Ensure that the adjoint method won't attach to sample ops.""" dif = adjoint.Adjoint() op = circuit_execution_ops.get_sampled_expectation_op() with self.assertRaisesRegex(ValueError, expected_regex='not supported'): dif.generate_differentiable_op(sampled_op=op)
def test_parameter_shift_sampled(self): """Test if ParameterShift.differentiate_sampled doesn't crash before running.""" programs, names, values, ops, n_samples, true_f, true_g = \ _simple_op_inputs() ps = parameter_shift.ParameterShift() op = ps.generate_differentiable_op( sampled_op=circuit_execution_ops.get_sampled_expectation_op()) with tf.GradientTape() as g: g.watch(values) expectations = op(programs, names, values, ops, n_samples) grads = g.gradient(expectations, values) self.assertAllClose(expectations, true_f, atol=1e-1, rtol=1e-1) self.assertAllClose(grads, true_g, atol=1e-1, rtol=1e-1)
def test_sampled_functional(self, diff): """Test that the differentiate_sampled function WORKS.""" differentiable_op = diff.generate_differentiable_op( sampled_op=circuit_execution_ops.get_sampled_expectation_op()) circuit, names, values, ops, n_samples, true_f, true_g = \ _simple_op_inputs() with tf.GradientTape() as g: g.watch(values) res = differentiable_op(circuit, names, values, ops, n_samples) # Just check that it computes without failing. self.assertAllClose(true_f, res, atol=1e-1, rtol=1e-1) self.assertAllClose(true_g, g.gradient(res, values), atol=1e-1, rtol=1e-1)
def test_stochastic_differentiator_call_sampled(self, coordinate, generator, cost, uniform): """Test if SGDifferentiator.differentiate_sampled doesn't crash before running.""" programs, names, values, ops, n_samples, true_f, true_g = \ _simple_op_inputs() diff = stochastic_differentiator.SGDifferentiator( coordinate, generator, cost, uniform) op = diff.generate_differentiable_op( sampled_op=circuit_execution_ops.get_sampled_expectation_op()) with tf.GradientTape() as g: g.watch(values) expectations = op(programs, names, values, ops, n_samples) grads = g.gradient(expectations, values) self.assertAllClose(expectations, true_f, atol=1e-1, rtol=1e-1) self.assertAllClose(grads, true_g, atol=1e-1, rtol=1e-1)
] SAMPLING_OPS = [ circuit_execution_ops.get_sampling_op(backend=None), circuit_execution_ops.get_sampling_op(backend=WF_SIM), circuit_execution_ops.get_sampling_op(backend=DM_SIM) ] STATE_OPS = [ circuit_execution_ops.get_state_op(backend=None), circuit_execution_ops.get_state_op(backend=WF_SIM), circuit_execution_ops.get_state_op(backend=DM_SIM) ] SAMPLED_EXPECTATION_OPS = [ circuit_execution_ops.get_sampled_expectation_op(backend=None), circuit_execution_ops.get_sampled_expectation_op(backend=WF_SIM), circuit_execution_ops.get_sampled_expectation_op(backend=DM_SIM) ] SIMS = [WF_SIM, WF_SIM, DM_SIM] class OpGetterInputChecks(tf.test.TestCase): """Check that the op getters handle inputs correctly.""" def test_get_expectation_inputs(self): """Test that get expectation only accepts inputs it should.""" circuit_execution_ops.get_expectation_op() circuit_execution_ops.get_expectation_op(backend=cirq.Simulator()) circuit_execution_ops.get_expectation_op( backend=cirq.DensityMatrixSimulator())
quantum_concurrent=True), # For timing interests C++ backend is tested in quantum_concurrent mode. circuit_execution_ops.get_sampling_op(backend=None, quantum_concurrent=False) ] STATE_OPS = [ circuit_execution_ops.get_state_op(backend=None, quantum_concurrent=True), circuit_execution_ops.get_state_op(backend=WF_SIM, quantum_concurrent=True), circuit_execution_ops.get_state_op(backend=DM_SIM, quantum_concurrent=True), # For timing interests C++ backend is tested in quantum_concurrent mode. circuit_execution_ops.get_state_op(backend=None, quantum_concurrent=False) ] SAMPLED_EXPECTATION_OPS = [ circuit_execution_ops.get_sampled_expectation_op(backend=None, quantum_concurrent=True), circuit_execution_ops.get_sampled_expectation_op(backend=WF_SIM, quantum_concurrent=True), circuit_execution_ops.get_sampled_expectation_op(backend=DM_SIM, quantum_concurrent=True), # For timing interests C++ backend is tested in quantum_concurrent mode. circuit_execution_ops.get_sampled_expectation_op(backend=None, quantum_concurrent=False), ] SIMS = [WF_SIM, WF_SIM, DM_SIM, WF_SIM] class OpGetterInputChecks(tf.test.TestCase): """Check that the op getters handle inputs correctly."""
SAMPLED_DIFFS = [ linear_combination.ForwardDifference(grid_spacing=0.05), linear_combination.CentralDifference(grid_spacing=0.05), parameter_shift.ParameterShift(), ] SAMPLED_DIFFS_TOLS = [0.5, 0.5, 0.2] ANALYTIC_OPS = [ circuit_execution_ops.get_expectation_op(cirq.sim.Simulator()), # WF circuit_execution_ops.get_expectation_op() # C++ ] SAMPLED_OPS = [ circuit_execution_ops.get_sampled_expectation_op( cirq.sim.Simulator()), # WF circuit_execution_ops.get_sampled_expectation_op() # C++ ] def _cirq_simple_finite_difference(circuit_batch, resolvers, symbol_names, op_batch, grid_spacing=0.0001): """A simple finite difference code that calculates the gradient of a batch of circuits using cirq.""" simulator = cirq.sim.Simulator() init_vals = batch_util.batch_calculate_expectation(circuit_batch, resolvers, op_batch,
linear_combination.ForwardDifference(grid_spacing=0.1), linear_combination.CentralDifference(grid_spacing=0.1), parameter_shift.ParameterShift(), ] SAMPLED_DIFFS_TOLS = [0.5, 0.5, 0.2] ANALYTIC_OPS = [ circuit_execution_ops.get_expectation_op(cirq.sim.Simulator()), # WF circuit_execution_ops.get_expectation_op( cirq.DensityMatrixSimulator()), # DM circuit_execution_ops.get_expectation_op() # C++ ] SAMPLED_OPS = [ circuit_execution_ops.get_sampled_expectation_op( cirq.sim.Simulator()), # WF circuit_execution_ops.get_sampled_expectation_op( cirq.DensityMatrixSimulator()), # DM circuit_execution_ops.get_sampled_expectation_op() # C++ ] def _cirq_simple_finite_difference(circuit_batch, resolvers, symbol_names, op_batch, grid_spacing=0.0001): """A simple finite difference code that calculates the gradient of a batch of circuits using cirq.""" simulator = cirq.sim.Simulator()