From a167b64826ade3fdfd16bc9343e9a1cbdb273a4b Mon Sep 17 00:00:00 2001 From: Doug Strain Date: Wed, 13 Nov 2019 12:53:18 -0800 Subject: [PATCH] Client change google api (#2530) * Change client code to send cirq.google.api messages. * Change tests to use old proto and fix coverage --- cirq/api/google/v2/proto_test.py | 10 +++---- cirq/google/api/v2/results.py | 2 +- cirq/google/api/v2/results_test.py | 9 +++---- cirq/google/api/v2/sweeps.py | 2 +- cirq/google/api/v2/sweeps_test.py | 15 +++++------ cirq/google/engine/calibration_test.py | 2 +- cirq/google/engine/engine.py | 29 ++++++++++----------- cirq/google/engine/engine_test.py | 24 ++++++++--------- cirq/google/op_deserializer.py | 11 ++++---- cirq/google/op_serializer.py | 9 +++---- cirq/google/serializable_gate_set.py | 36 +++++++++++++------------- 11 files changed, 71 insertions(+), 78 deletions(-) diff --git a/cirq/api/google/v2/proto_test.py b/cirq/api/google/v2/proto_test.py index b6caabc6478..8d2506d0ba5 100644 --- a/cirq/api/google/v2/proto_test.py +++ b/cirq/api/google/v2/proto_test.py @@ -14,9 +14,9 @@ """Check protobuf modules initialize successfully.""" # pylint: disable=unused-import -from cirq.api.google.v2 import device_pb2 -from cirq.api.google.v2 import metrics_pb2 -from cirq.api.google.v2 import program_pb2 -from cirq.api.google.v2 import result_pb2 -from cirq.api.google.v2 import run_context_pb2 +from cirq.google.api.v2 import device_pb2 +from cirq.google.api.v2 import metrics_pb2 +from cirq.google.api.v2 import program_pb2 +from cirq.google.api.v2 import result_pb2 +from cirq.google.api.v2 import run_context_pb2 # pylint: enable=unused-import diff --git a/cirq/google/api/v2/results.py b/cirq/google/api/v2/results.py index 292cd60900e..a37b969fefc 100644 --- a/cirq/google/api/v2/results.py +++ b/cirq/google/api/v2/results.py @@ -18,8 +18,8 @@ from collections import OrderedDict import numpy as np -from cirq.api.google.v2 import result_pb2 from cirq.google.api import v2 +from cirq.google.api.v2 import result_pb2 from cirq import circuits from cirq import devices from cirq import ops diff --git a/cirq/google/api/v2/results_test.py b/cirq/google/api/v2/results_test.py index 5edcd37bdab..dbb523d6048 100644 --- a/cirq/google/api/v2/results_test.py +++ b/cirq/google/api/v2/results_test.py @@ -2,7 +2,6 @@ import pytest import cirq -from cirq.api.google.v2 import result_pb2 from cirq.google.api import v2 @@ -169,7 +168,7 @@ def test_results_to_proto(): ], ] proto = v2.results_to_proto(trial_results, measurements) - assert isinstance(proto, result_pb2.Result) + assert isinstance(proto, v2.result_pb2.Result) assert len(proto.sweep_results) == 2 deserialized = v2.results_from_proto(proto, measurements) assert len(deserialized) == 2 @@ -213,7 +212,7 @@ def test_results_from_proto_qubit_ordering(): slot=0, invert_mask=[False, False, False]) ] - proto = result_pb2.Result() + proto = v2.result_pb2.Result() sr = proto.sweep_results.add() sr.repetitions = 8 pr = sr.parameterized_results.add() @@ -254,7 +253,7 @@ def test_results_from_proto_duplicate_qubit(): slot=0, invert_mask=[False, False, False]) ] - proto = result_pb2.Result() + proto = v2.result_pb2.Result() sr = proto.sweep_results.add() sr.repetitions = 8 pr = sr.parameterized_results.add() @@ -274,7 +273,7 @@ def test_results_from_proto_duplicate_qubit(): def test_results_from_proto_default_ordering(): - proto = result_pb2.Result() + proto = v2.result_pb2.Result() sr = proto.sweep_results.add() sr.repetitions = 8 pr = sr.parameterized_results.add() diff --git a/cirq/google/api/v2/sweeps.py b/cirq/google/api/v2/sweeps.py index b9b448d46c5..586e3b0c944 100644 --- a/cirq/google/api/v2/sweeps.py +++ b/cirq/google/api/v2/sweeps.py @@ -15,7 +15,7 @@ from typing import Optional, Dict, List from cirq import value -from cirq.api.google.v2 import run_context_pb2 +from cirq.google.api.v2 import run_context_pb2 from cirq.study import sweeps def sweep_to_proto( diff --git a/cirq/google/api/v2/sweeps_test.py b/cirq/google/api/v2/sweeps_test.py index a0efd6d0b6d..19476d5b960 100644 --- a/cirq/google/api/v2/sweeps_test.py +++ b/cirq/google/api/v2/sweeps_test.py @@ -18,7 +18,6 @@ import sympy import cirq -from cirq.api.google.v2 import run_context_pb2 from cirq.google.api import v2 from cirq.study import sweeps @@ -58,7 +57,7 @@ def test_sweep_to_proto_roundtrip(sweep): def test_sweep_to_proto_linspace(): proto = v2.sweep_to_proto(cirq.Linspace('foo', 0, 1, 20)) - assert isinstance(proto, run_context_pb2.Sweep) + assert isinstance(proto, v2.run_context_pb2.Sweep) assert proto.HasField('single_sweep') assert proto.single_sweep.parameter_key == 'foo' assert proto.single_sweep.WhichOneof('sweep') == 'linspace' @@ -69,7 +68,7 @@ def test_sweep_to_proto_linspace(): def test_sweep_to_proto_points(): proto = v2.sweep_to_proto(cirq.Points('foo', [-1, 0, 1, 1.5])) - assert isinstance(proto, run_context_pb2.Sweep) + assert isinstance(proto, v2.run_context_pb2.Sweep) assert proto.HasField('single_sweep') assert proto.single_sweep.parameter_key == 'foo' assert proto.single_sweep.WhichOneof('sweep') == 'points' @@ -78,7 +77,7 @@ def test_sweep_to_proto_points(): def test_sweep_to_proto_unit(): proto = v2.sweep_to_proto(cirq.UnitSweep) - assert isinstance(proto, run_context_pb2.Sweep) + assert isinstance(proto, v2.run_context_pb2.Sweep) assert not proto.HasField('single_sweep') assert not proto.HasField('sweep_function') @@ -89,14 +88,14 @@ def test_sweep_from_proto_unknown_sweep_type(): def test_sweep_from_proto_sweep_function_not_set(): - proto = run_context_pb2.Sweep() + proto = v2.run_context_pb2.Sweep() proto.sweep_function.sweeps.add() with pytest.raises(ValueError, match='invalid sweep function type'): v2.sweep_from_proto(proto) def test_sweep_from_proto_single_sweep_type_not_set(): - proto = run_context_pb2.Sweep() + proto = v2.run_context_pb2.Sweep() proto.single_sweep.parameter_key = 'foo' with pytest.raises(ValueError, match='single sweep type not set'): v2.sweep_from_proto(proto) @@ -105,8 +104,8 @@ def test_sweep_from_proto_single_sweep_type_not_set(): def test_sweep_with_list_sweep(): ls = cirq.study.to_sweep([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]) proto = v2.sweep_to_proto(ls) - expected = run_context_pb2.Sweep() - expected.sweep_function.function_type = run_context_pb2.SweepFunction.ZIP + expected = v2.run_context_pb2.Sweep() + expected.sweep_function.function_type = v2.run_context_pb2.SweepFunction.ZIP p1 = expected.sweep_function.sweeps.add() p1.single_sweep.parameter_key = 'a' p1.single_sweep.points.points.extend([1, 3]) diff --git a/cirq/google/engine/calibration_test.py b/cirq/google/engine/calibration_test.py index 04d7954e891..101009f18f3 100644 --- a/cirq/google/engine/calibration_test.py +++ b/cirq/google/engine/calibration_test.py @@ -22,7 +22,7 @@ _CALIBRATION_DATA = { '@type': - 'type.googleapis.com/cirq.api.google.v2.MetricsSnapshot', + 'type.googleapis.com/cirq.google.api.v2.MetricsSnapshot', 'timestampMs': '1562544000021', 'metrics': [{ diff --git a/cirq/google/engine/engine.py b/cirq/google/engine/engine.py index 7689910e0b3..ae87266a524 100644 --- a/cirq/google/engine/engine.py +++ b/cirq/google/engine/engine.py @@ -42,10 +42,8 @@ from google.protobuf import any_pb2 from cirq import circuits, optimizers, schedules, study, value -from cirq.api.google import v1, v2 from cirq.google import gate_sets, serializable_gate_set -from cirq.google.api import v1 as api_v1 -from cirq.google.api import v2 as api_v2 +from cirq.google.api import v1, v2 from cirq.google.engine import (calibration, engine_job, engine_program, engine_sampler) @@ -450,8 +448,7 @@ def _serialize_run_context( context_dict = {} # type: Dict[str, Any] context_dict['@type'] = TYPE_PREFIX + context_descriptor.full_name context_dict['parameter_sweeps'] = [ - api_v1.sweep_to_proto_dict(sweep, repetitions) - for sweep in sweeps + v1.sweep_to_proto_dict(sweep, repetitions) for sweep in sweeps ] return context_dict elif proto_version == ProtoVersion.V2: @@ -459,7 +456,7 @@ def _serialize_run_context( for sweep in sweeps: sweep_proto = run_context.parameter_sweeps.add() sweep_proto.repetitions = repetitions - api_v2.sweep_to_proto(sweep, out=sweep_proto.sweep) + v2.sweep_to_proto(sweep, out=sweep_proto.sweep) return _any_dict_from_msg(run_context) else: @@ -516,7 +513,7 @@ def _serialize_program( program_dict = {} # type: Dict[str, Any] program_dict['@type'] = TYPE_PREFIX + program_descriptor.full_name program_dict['operations'] = [ - op for op in api_v1.schedule_to_proto_dicts(schedule) + op for op in v1.schedule_to_proto_dicts(schedule) ] return program_dict elif self.proto_version == ProtoVersion.V2: @@ -575,15 +572,15 @@ def get_job_results(self, parent=job_resource_name)) result = response['result'] result_type = result['@type'][len(TYPE_PREFIX):] - if result_type == 'cirq.api.google.v1.Result': - return self._get_job_results_v1(result) - if result_type == 'cirq.api.google.v2.Result': - return self._get_job_results_v2(result) if result_type == 'cirq.google.api.v1.Result': return self._get_job_results_v1(result) if result_type == 'cirq.google.api.v2.Result': - # Pretend the path is the other one until we switch over - result['@type'] = 'type.googleapis.com/cirq.api.google.v2.Result' + return self._get_job_results_v2(result) + if result_type == 'cirq.api.google.v1.Result': + return self._get_job_results_v1(result) + if result_type == 'cirq.api.google.v2.Result': + # Change path to the new path + result['@type'] = 'type.googleapis.com/cirq.google.api.v2.Result' return self._get_job_results_v2(result) raise ValueError('invalid result proto version: {}'.format( self.proto_version)) @@ -597,8 +594,8 @@ def _get_job_results_v1(self, for m in sweep_result['measurementKeys']] for result in sweep_result['parameterizedResults']: data = base64.standard_b64decode(result['measurementResults']) - measurements = api_v1.unpack_results(data, sweep_repetitions, - key_sizes) + measurements = v1.unpack_results(data, sweep_repetitions, + key_sizes) trial_results.append( study.TrialResult.from_single_parameter_set( @@ -613,7 +610,7 @@ def _get_job_results_v2(self, result_dict: Dict[str, Any] gp.json_format.ParseDict(result_dict, result_any) result = v2.result_pb2.Result() result_any.Unpack(result) - sweep_results = api_v2.results_from_proto(result) + sweep_results = v2.results_from_proto(result) # Flatten to single list to match to sampler api. return [ trial_result for sweep_result in sweep_results diff --git a/cirq/google/engine/engine_test.py b/cirq/google/engine/engine_test.py index e516e2d424d..a0146aed605 100644 --- a/cirq/google/engine/engine_test.py +++ b/cirq/google/engine/engine_test.py @@ -31,7 +31,7 @@ _A_RESULT = { '@type': - 'type.googleapis.com/cirq.api.google.v1.Result', + 'type.googleapis.com/cirq.google.api.v1.Result', 'sweepResults': [{ 'repetitions': 1, @@ -55,7 +55,7 @@ _RESULTS = { '@type': - 'type.googleapis.com/cirq.api.google.v1.Result', + 'type.googleapis.com/cirq.google.api.v1.Result', 'sweepResults': [{ 'repetitions': 1, @@ -86,7 +86,7 @@ _RESULTS_V2 = { '@type': - 'type.googleapis.com/cirq.api.google.v2.Result', + 'type.googleapis.com/cirq.google.api.v2.Result', 'sweepResults': [ { 'repetitions': @@ -242,7 +242,7 @@ def test_run_circuit(build): } }, 'run_context': { - '@type': 'type.googleapis.com/cirq.api.google.v1.RunContext', + '@type': 'type.googleapis.com/cirq.google.api.v1.RunContext', 'parameter_sweeps': [{ 'repetitions': 1 }] @@ -467,13 +467,13 @@ def test_run_sweep_params(build): @mock.patch.object(discovery, 'build') -def test_run_sweep_params_new_proto(build): +def test_run_sweep_params_old_proto(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() - results_new_proto = copy.deepcopy(_RESULTS) - results_new_proto['@type'] = 'type.googleapis.com/cirq.google.api.v1.Result' + results_old_proto = copy.deepcopy(_RESULTS) + results_old_proto['@type'] = 'type.googleapis.com/cirq.api.google.v1.Result' programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } @@ -489,7 +489,7 @@ def test_run_sweep_params_new_proto(build): 'state': 'SUCCESS' } } - jobs.getResult().execute.return_value = {'result': results_new_proto} + jobs.getResult().execute.return_value = {'result': results_old_proto} engine = cg.Engine(project_id='project-id') job = engine.run_sweep( @@ -681,7 +681,7 @@ def test_run_sweep_v2(build): @mock.patch.object(discovery, 'build') -def test_run_sweep_v2_new_proto(build): +def test_run_sweep_v2_old_proto(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() @@ -701,9 +701,9 @@ def test_run_sweep_v2_new_proto(build): 'state': 'SUCCESS' } } - results_new_proto = copy.deepcopy(_RESULTS_V2) - results_new_proto['@type'] = 'type.googleapis.com/cirq.google.api.v2.Result' - jobs.getResult().execute.return_value = {'result': results_new_proto} + results_old_proto = copy.deepcopy(_RESULTS_V2) + results_old_proto['@type'] = 'type.googleapis.com/cirq.api.google.v2.Result' + jobs.getResult().execute.return_value = {'result': results_old_proto} engine = cg.Engine( project_id='project-id', diff --git a/cirq/google/op_deserializer.py b/cirq/google/op_deserializer.py index f8edc5214cc..bdb7a57e51c 100644 --- a/cirq/google/op_deserializer.py +++ b/cirq/google/op_deserializer.py @@ -24,9 +24,7 @@ from google.protobuf import json_format -from cirq.api.google import v2 - -from cirq.google.api import v2 as api_v2 +from cirq.google.api import v2 from cirq.google import arg_func_langs if TYPE_CHECKING: @@ -89,7 +87,8 @@ def __init__(self, def from_proto_dict(self, proto: Dict, *, arg_function_language: str = '' ) -> 'cirq.GateOperation': - """Turns a cirq.api.google.v2.Operation proto into a GateOperation.""" + """Turns a cirq.google.api.v2.Operation proto into a GateOperation.""" + msg = v2.program_pb2.Operation() json_format.ParseDict(proto, msg) return self.from_proto(msg, arg_function_language=arg_function_language) @@ -98,8 +97,8 @@ def from_proto(self, proto: v2.program_pb2.Operation, *, arg_function_language: str = '') -> 'cirq.GateOperation': - """Turns a cirq.api.google.v2.Operation proto into a GateOperation.""" - qubits = [api_v2.grid_qubit_from_proto_id(q.id) for q in proto.qubits] + """Turns a cirq.google.api.v2.Operation proto into a GateOperation.""" + qubits = [v2.grid_qubit_from_proto_id(q.id) for q in proto.qubits] args = self._args_from_proto( proto, arg_function_language=arg_function_language) if self.num_qubits_param is not None: diff --git a/cirq/google/op_serializer.py b/cirq/google/op_serializer.py index 5e8c3322436..3e3b2d19468 100644 --- a/cirq/google/op_serializer.py +++ b/cirq/google/op_serializer.py @@ -20,9 +20,7 @@ from google.protobuf import json_format from cirq import devices, ops -from cirq.api.google import v2 - -from cirq.google.api import v2 as api_v2 +from cirq.google.api import v2 from cirq.google import arg_func_langs from cirq.google.arg_func_langs import _arg_to_proto @@ -117,7 +115,8 @@ def to_proto( *, arg_function_language: Optional[str] = '', ) -> Optional[v2.program_pb2.Operation]: - """Returns the cirq.api.google.v2.Operation message as a proto dict.""" + """Returns the cirq.google.api.v2.Operation message as a proto dict.""" + if not all(isinstance(qubit, devices.GridQubit) for qubit in op.qubits): raise ValueError('All qubits must be GridQubits') gate = op.gate @@ -134,7 +133,7 @@ def to_proto( msg.gate.id = self.serialized_gate_id for qubit in op.qubits: - msg.qubits.add().id = api_v2.qubit_to_proto_id( + msg.qubits.add().id = v2.qubit_to_proto_id( cast(devices.GridQubit, qubit)) for arg in self.args: value = self._value_from_gate(gate, arg) diff --git a/cirq/google/serializable_gate_set.py b/cirq/google/serializable_gate_set.py index 4a7f4cc334c..35438193e6d 100644 --- a/cirq/google/serializable_gate_set.py +++ b/cirq/google/serializable_gate_set.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Support for serializing and deserializing cirq.api.google.v2 protos.""" +"""Support for serializing and deserializing cirq.google.api.v2 protos.""" from typing import ( cast, @@ -28,8 +28,8 @@ from google.protobuf import json_format from cirq import circuits, ops, schedules, value -from cirq.api.google import v2 from cirq.google import op_deserializer, op_serializer, arg_func_langs +from cirq.google.api import v2 if TYPE_CHECKING: import cirq @@ -38,7 +38,7 @@ class SerializableGateSet: """A class for serializing and deserializing programs and operations. - This class is for cirq.api.google.v2. protos. + This class is for cirq.google.api.v2. protos. """ def __init__(self, gate_set_name: str, @@ -103,13 +103,13 @@ def serialize_dict(self, program: Union[circuits.Circuit, schedules.Schedule], *, arg_function_language: Optional[str] = None) -> Dict: - """Serialize a Circuit or Schedule to cirq.api.google.v2.Program proto. + """Serialize a Circuit or Schedule to cirq.google.api.v2.Program proto. Args: program: The Circuit or Schedule to serialize. Returns: - A dictionary corresponding to the cirq.api.google.v2.Program proto. + A dictionary corresponding to the cirq.google.api.v2.Program proto. """ return json_format.MessageToDict(self.serialize( program, arg_function_language=arg_function_language), @@ -123,7 +123,7 @@ def serialize(self, *, arg_function_language: Optional[str] = None ) -> v2.program_pb2.Program: - """Serialize a Circuit or Schedule to cirq.api.google.v2.Program proto. + """Serialize a Circuit or Schedule to cirq.google.api.v2.Program proto. Args: program: The Circuit or Schedule to serialize. @@ -158,13 +158,13 @@ def serialize_op_dict(self, op: 'cirq.Operation', *, arg_function_language: Optional[str] = '') -> Dict: - """Serialize an Operation to cirq.api.google.v2.Operation proto. + """Serialize an Operation to cirq.google.api.v2.Operation proto. Args: op: The operation to serialize. Returns: - A dictionary corresponds to the cirq.api.google.v2.Operation proto. + A dictionary corresponds to the cirq.google.api.v2.Operation proto. """ return json_format.MessageToDict(self.serialize_op( op, arg_function_language=arg_function_language), @@ -179,13 +179,13 @@ def serialize_op( *, arg_function_language: Optional[str] = '', ) -> v2.program_pb2.Operation: - """Serialize an Operation to cirq.api.google.v2.Operation proto. + """Serialize an Operation to cirq.google.api.v2.Operation proto. Args: op: The operation to serialize. Returns: - A dictionary corresponds to the cirq.api.google.v2.Operation proto. + A dictionary corresponds to the cirq.google.api.v2.Operation proto. """ gate_op = cast(ops.GateOperation, op) gate_type = type(gate_op.gate) @@ -208,10 +208,10 @@ def deserialize_dict(self, proto: Dict, device: Optional['cirq.Device'] = None ) -> Union[circuits.Circuit, schedules.Schedule]: - """Deserialize a Circuit or Schedule from a cirq.api.google.v2.Program. + """Deserialize a Circuit or Schedule from a cirq.google.api.v2.Program. Args: - proto: A dictionary representing a cirq.api.google.v2.Program proto. + proto: A dictionary representing a cirq.google.api.v2.Program proto. device: If the proto is for a schedule, a device is required Otherwise optional. @@ -227,10 +227,10 @@ def deserialize(self, proto: v2.program_pb2.Program, device: Optional['cirq.Device'] = None ) -> Union[circuits.Circuit, schedules.Schedule]: - """Deserialize a Circuit or Schedule from a cirq.api.google.v2.Program. + """Deserialize a Circuit or Schedule from a cirq.google.api.v2.Program. Args: - proto: A dictionary representing a cirq.api.google.v2.Program proto. + proto: A dictionary representing a cirq.google.api.v2.Program proto. device: If the proto is for a schedule, a device is required Otherwise optional. @@ -267,11 +267,11 @@ def deserialize_op_dict(self, *, arg_function_language: str = '' ) -> 'cirq.Operation': - """Deserialize an Operation from a cirq.api.google.v2.Operation. + """Deserialize an Operation from a cirq.google.api.v2.Operation. Args: operation_proto: A dictionary representing a - cirq.api.google.v2.Operation proto. + cirq.google.api.v2.Operation proto. Returns: The deserialized Operation. @@ -287,11 +287,11 @@ def deserialize_op( *, arg_function_language: str = '', ) -> 'cirq.Operation': - """Deserialize an Operation from a cirq.api.google.v2.Operation. + """Deserialize an Operation from a cirq.google.api.v2.Operation. Args: operation_proto: A dictionary representing a - cirq.api.google.v2.Operation proto. + cirq.google.api.v2.Operation proto. Returns: The deserialized Operation.