From eb1031895990796c8b50b58e2aa7da7edccdb1fb Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 27 Nov 2023 10:38:53 -0800 Subject: [PATCH 01/23] Created using Colaboratory --- docs/tutorials/google/start.ipynb | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/google/start.ipynb b/docs/tutorials/google/start.ipynb index 92ae54b7be4..0f910cd3bba 100644 --- a/docs/tutorials/google/start.ipynb +++ b/docs/tutorials/google/start.ipynb @@ -175,12 +175,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "cellView": "both", - "id": "EQoTYZIEPa9S" - }, - "outputs": [], + "id": "EQoTYZIEPa9S", + "outputId": "43c72568-3bc8-4b44-871b-b9db19c9e672", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Circuit:\n", + "(0, 0): ───X───M('result')───\n" + ] + } + ], "source": [ "# Define a qubit at an arbitrary grid location.\n", "qubit = cirq.GridQubit(0, 0)\n", From a68afb470ba3b301440987c8f96abd35d1ae2704 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 5 Feb 2024 20:16:48 +0000 Subject: [PATCH 02/23] throw notimplement error for run_calibration and run_batch_program --- .../cirq_google/api/v1/operations_pb2.py | 35 ++-- cirq-google/cirq_google/api/v1/params_pb2.py | 39 ++-- cirq-google/cirq_google/api/v1/program_pb2.py | 31 ++-- cirq-google/cirq_google/api/v2/batch.proto | 13 -- cirq-google/cirq_google/api/v2/batch_pb2.py | 19 +- cirq-google/cirq_google/api/v2/batch_pb2.pyi | 27 --- cirq-google/cirq_google/api/v2/calibration | 14 ++ .../cirq_google/api/v2/calibration.proto | 14 -- .../cirq_google/api/v2/calibration_pb2.py | 31 ++-- .../cirq_google/api/v2/calibration_pb2.pyi | 28 --- cirq-google/cirq_google/api/v2/device_pb2.py | 87 +++++---- cirq-google/cirq_google/api/v2/device_pb2.pyi | 4 +- cirq-google/cirq_google/api/v2/metrics_pb2.py | 19 +- cirq-google/cirq_google/api/v2/program_pb2.py | 175 +++++++++--------- .../cirq_google/api/v2/program_pb2.pyi | 2 +- cirq-google/cirq_google/api/v2/result_pb2.py | 35 ++-- .../cirq_google/api/v2/run_context_pb2.py | 43 +++-- .../cirq_google/api/v2/run_context_pb2.pyi | 2 +- cirq-google/cirq_google/engine/engine.py | 46 +---- cirq-google/cirq_google/engine/engine_test.py | 88 --------- https:/github.com/qh-lab/pyle/pull/42618 | 14 ++ 21 files changed, 285 insertions(+), 481 deletions(-) create mode 100644 cirq-google/cirq_google/api/v2/calibration create mode 100644 https:/github.com/qh-lab/pyle/pull/42618 diff --git a/cirq-google/cirq_google/api/v1/operations_pb2.py b/cirq-google/cirq_google/api/v1/operations_pb2.py index b50fdf8e963..a00a88c499e 100644 --- a/cirq-google/cirq_google/api/v1/operations_pb2.py +++ b/cirq-google/cirq_google/api/v1/operations_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/operations.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,25 +15,24 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#cirq_google/api/v1/operations.proto\x12\x12\x63irq.google.api.v1\"!\n\x05Qubit\x12\x0b\n\x03row\x18\x01 \x01(\x05\x12\x0b\n\x03\x63ol\x18\x02 \x01(\x05\"E\n\x12ParameterizedFloat\x12\r\n\x03raw\x18\x01 \x01(\x02H\x00\x12\x17\n\rparameter_key\x18\x02 \x01(\tH\x00\x42\x07\n\x05value\"\xae\x01\n\x04\x45xpW\x12)\n\x06target\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12?\n\x0f\x61xis_half_turns\x18\x02 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\x12:\n\nhalf_turns\x18\x03 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"m\n\x04\x45xpZ\x12)\n\x06target\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12:\n\nhalf_turns\x18\x02 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"\x9b\x01\n\x05\x45xp11\x12*\n\x07target1\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12*\n\x07target2\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12:\n\nhalf_turns\x18\x03 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"[\n\x0bMeasurement\x12*\n\x07targets\x18\x01 \x03(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x13\n\x0binvert_mask\x18\x03 \x03(\x08\"\xfa\x01\n\tOperation\x12%\n\x1dincremental_delay_picoseconds\x18\x01 \x01(\x04\x12)\n\x05\x65xp_w\x18\n \x01(\x0b\x32\x18.cirq.google.api.v1.ExpWH\x00\x12)\n\x05\x65xp_z\x18\x0b \x01(\x0b\x32\x18.cirq.google.api.v1.ExpZH\x00\x12+\n\x06\x65xp_11\x18\x0c \x01(\x0b\x32\x19.cirq.google.api.v1.Exp11H\x00\x12\x36\n\x0bmeasurement\x18\r \x01(\x0b\x32\x1f.cirq.google.api.v1.MeasurementH\x00\x42\x0b\n\toperationB2\n\x1d\x63om.google.cirq.google.api.v1B\x0fOperationsProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.operations_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.operations_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\017OperationsProtoP\001' - _globals['_QUBIT']._serialized_start=59 - _globals['_QUBIT']._serialized_end=92 - _globals['_PARAMETERIZEDFLOAT']._serialized_start=94 - _globals['_PARAMETERIZEDFLOAT']._serialized_end=163 - _globals['_EXPW']._serialized_start=166 - _globals['_EXPW']._serialized_end=340 - _globals['_EXPZ']._serialized_start=342 - _globals['_EXPZ']._serialized_end=451 - _globals['_EXP11']._serialized_start=454 - _globals['_EXP11']._serialized_end=609 - _globals['_MEASUREMENT']._serialized_start=611 - _globals['_MEASUREMENT']._serialized_end=702 - _globals['_OPERATION']._serialized_start=705 - _globals['_OPERATION']._serialized_end=955 + _QUBIT._serialized_start=59 + _QUBIT._serialized_end=92 + _PARAMETERIZEDFLOAT._serialized_start=94 + _PARAMETERIZEDFLOAT._serialized_end=163 + _EXPW._serialized_start=166 + _EXPW._serialized_end=340 + _EXPZ._serialized_start=342 + _EXPZ._serialized_end=451 + _EXP11._serialized_start=454 + _EXP11._serialized_end=609 + _MEASUREMENT._serialized_start=611 + _MEASUREMENT._serialized_end=702 + _OPERATION._serialized_start=705 + _OPERATION._serialized_end=955 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v1/params_pb2.py b/cirq-google/cirq_google/api/v1/params_pb2.py index fe788f8b1b9..f11b97760ff 100644 --- a/cirq-google/cirq_google/api/v1/params_pb2.py +++ b/cirq-google/cirq_google/api/v1/params_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/params.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,29 +15,28 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v1/params.proto\x12\x12\x63irq.google.api.v1\"V\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12/\n\x05sweep\x18\x02 \x01(\x0b\x32 .cirq.google.api.v1.ProductSweep\"=\n\x0cProductSweep\x12-\n\x07\x66\x61\x63tors\x18\x01 \x03(\x0b\x32\x1c.cirq.google.api.v1.ZipSweep\";\n\x08ZipSweep\x12/\n\x06sweeps\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v1.SingleSweep\"\x8d\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v1.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v1.LinspaceH\x00\x42\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\"\x8c\x01\n\rParameterDict\x12G\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32\x32.cirq.google.api.v1.ParameterDict.AssignmentsEntry\x1a\x32\n\x10\x41ssignmentsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x42.\n\x1d\x63om.google.cirq.google.api.v1B\x0bParamsProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.params_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.params_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\013ParamsProtoP\001' _PARAMETERDICT_ASSIGNMENTSENTRY._options = None _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_options = b'8\001' - _globals['_PARAMETERSWEEP']._serialized_start=55 - _globals['_PARAMETERSWEEP']._serialized_end=141 - _globals['_PRODUCTSWEEP']._serialized_start=143 - _globals['_PRODUCTSWEEP']._serialized_end=204 - _globals['_ZIPSWEEP']._serialized_start=206 - _globals['_ZIPSWEEP']._serialized_end=265 - _globals['_SINGLESWEEP']._serialized_start=268 - _globals['_SINGLESWEEP']._serialized_end=409 - _globals['_POINTS']._serialized_start=411 - _globals['_POINTS']._serialized_end=435 - _globals['_LINSPACE']._serialized_start=437 - _globals['_LINSPACE']._serialized_end=508 - _globals['_PARAMETERDICT']._serialized_start=511 - _globals['_PARAMETERDICT']._serialized_end=651 - _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_start=601 - _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_end=651 + _PARAMETERSWEEP._serialized_start=55 + _PARAMETERSWEEP._serialized_end=141 + _PRODUCTSWEEP._serialized_start=143 + _PRODUCTSWEEP._serialized_end=204 + _ZIPSWEEP._serialized_start=206 + _ZIPSWEEP._serialized_end=265 + _SINGLESWEEP._serialized_start=268 + _SINGLESWEEP._serialized_end=409 + _POINTS._serialized_start=411 + _POINTS._serialized_end=435 + _LINSPACE._serialized_start=437 + _LINSPACE._serialized_end=508 + _PARAMETERDICT._serialized_start=511 + _PARAMETERDICT._serialized_end=651 + _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_start=601 + _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_end=651 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v1/program_pb2.py b/cirq-google/cirq_google/api/v1/program_pb2.py index 4d06cec94e2..57c3370e4af 100644 --- a/cirq-google/cirq_google/api/v1/program_pb2.py +++ b/cirq-google/cirq_google/api/v1/program_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/program.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -17,25 +17,24 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v1/program.proto\x12\x12\x63irq.google.api.v1\x1a#cirq_google/api/v1/operations.proto\x1a\x1f\x63irq_google/api/v1/params.proto\"~\n\x07Program\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v1.Operation\x12@\n\x10parameter_sweeps\x18\x02 \x03(\x0b\x32\".cirq.google.api.v1.ParameterSweepB\x02\x18\x01\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v1.ParameterSweep\"e\n\x13ParameterizedResult\x12\x31\n\x06params\x18\x01 \x01(\x0b\x32!.cirq.google.api.v1.ParameterDict\x12\x1b\n\x13measurement_results\x18\x02 \x01(\x0c\"H\n\x0eMeasurementKey\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x06qubits\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v1.Qubit\"\xa8\x01\n\x0bSweepResult\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12<\n\x10measurement_keys\x18\x02 \x03(\x0b\x32\".cirq.google.api.v1.MeasurementKey\x12\x46\n\x15parameterized_results\x18\x03 \x03(\x0b\x32\'.cirq.google.api.v1.ParameterizedResult\"@\n\x06Result\x12\x36\n\rsweep_results\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v1.SweepResultB/\n\x1d\x63om.google.cirq.google.api.v1B\x0cProgramProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.program_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.program_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\014ProgramProtoP\001' _PROGRAM.fields_by_name['parameter_sweeps']._options = None _PROGRAM.fields_by_name['parameter_sweeps']._serialized_options = b'\030\001' - _globals['_PROGRAM']._serialized_start=126 - _globals['_PROGRAM']._serialized_end=252 - _globals['_RUNCONTEXT']._serialized_start=254 - _globals['_RUNCONTEXT']._serialized_end=328 - _globals['_PARAMETERIZEDRESULT']._serialized_start=330 - _globals['_PARAMETERIZEDRESULT']._serialized_end=431 - _globals['_MEASUREMENTKEY']._serialized_start=433 - _globals['_MEASUREMENTKEY']._serialized_end=505 - _globals['_SWEEPRESULT']._serialized_start=508 - _globals['_SWEEPRESULT']._serialized_end=676 - _globals['_RESULT']._serialized_start=678 - _globals['_RESULT']._serialized_end=742 + _PROGRAM._serialized_start=126 + _PROGRAM._serialized_end=252 + _RUNCONTEXT._serialized_start=254 + _RUNCONTEXT._serialized_end=328 + _PARAMETERIZEDRESULT._serialized_start=330 + _PARAMETERIZEDRESULT._serialized_end=431 + _MEASUREMENTKEY._serialized_start=433 + _MEASUREMENTKEY._serialized_end=505 + _SWEEPRESULT._serialized_start=508 + _SWEEPRESULT._serialized_end=676 + _RESULT._serialized_start=678 + _RESULT._serialized_end=742 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/batch.proto b/cirq-google/cirq_google/api/v2/batch.proto index 2645d91a6d8..daa86315ecb 100644 --- a/cirq-google/cirq_google/api/v2/batch.proto +++ b/cirq-google/cirq_google/api/v2/batch.proto @@ -10,19 +10,6 @@ option java_package = "com.google.cirq.google.api.v2"; option java_outer_classname = "BatchProto"; option java_multiple_files = true; -// A Batch of multiple circuits that should be run together -// as one QuantumProgram within Quantum Engine. -// -// Note: Batching is done on a best-effort basis. -// Circuits will be be bundled together, but the size -// of the total batch and different hardware constraints may -// cause the programs to be executed separately on the hardware. -message BatchProgram { - - // The circuits that should be bundled together as one program - repeated Program programs = 1; -} - // A batch of contexts for running a bundled batch of programs // To be used in conjunction with BatchProgram message BatchRunContext { diff --git a/cirq-google/cirq_google/api/v2/batch_pb2.py b/cirq-google/cirq_google/api/v2/batch_pb2.py index ddbb7464fea..446d019d3ec 100644 --- a/cirq-google/cirq_google/api/v2/batch_pb2.py +++ b/cirq-google/cirq_google/api/v2/batch_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/batch.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -16,19 +16,16 @@ from . import run_context_pb2 as cirq__google_dot_api_dot_v2_dot_run__context__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63irq_google/api/v2/batch.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/program.proto\x1a\x1f\x63irq_google/api/v2/result.proto\x1a$cirq_google/api/v2/run_context.proto\"=\n\x0c\x42\x61tchProgram\x12-\n\x08programs\x18\x01 \x03(\x0b\x32\x1b.cirq.google.api.v2.Program\"G\n\x0f\x42\x61tchRunContext\x12\x34\n\x0crun_contexts\x18\x01 \x03(\x0b\x32\x1e.cirq.google.api.v2.RunContext\":\n\x0b\x42\x61tchResult\x12+\n\x07results\x18\x01 \x03(\x0b\x32\x1a.cirq.google.api.v2.ResultB-\n\x1d\x63om.google.cirq.google.api.v2B\nBatchProtoP\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63irq_google/api/v2/batch.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/program.proto\x1a\x1f\x63irq_google/api/v2/result.proto\x1a$cirq_google/api/v2/run_context.proto\"G\n\x0f\x42\x61tchRunContext\x12\x34\n\x0crun_contexts\x18\x01 \x03(\x0b\x32\x1e.cirq.google.api.v2.RunContext\":\n\x0b\x42\x61tchResult\x12+\n\x07results\x18\x01 \x03(\x0b\x32\x1a.cirq.google.api.v2.ResultB-\n\x1d\x63om.google.cirq.google.api.v2B\nBatchProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.batch_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.batch_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\nBatchProtoP\001' - _globals['_BATCHPROGRAM']._serialized_start=159 - _globals['_BATCHPROGRAM']._serialized_end=220 - _globals['_BATCHRUNCONTEXT']._serialized_start=222 - _globals['_BATCHRUNCONTEXT']._serialized_end=293 - _globals['_BATCHRESULT']._serialized_start=295 - _globals['_BATCHRESULT']._serialized_end=353 + _BATCHRUNCONTEXT._serialized_start=159 + _BATCHRUNCONTEXT._serialized_end=230 + _BATCHRESULT._serialized_start=232 + _BATCHRESULT._serialized_end=290 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/batch_pb2.pyi b/cirq-google/cirq_google/api/v2/batch_pb2.pyi index cca65c630d9..ceaa2eb38f3 100644 --- a/cirq-google/cirq_google/api/v2/batch_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/batch_pb2.pyi @@ -3,7 +3,6 @@ isort:skip_file """ import builtins -import cirq_google.api.v2.program_pb2 import cirq_google.api.v2.result_pb2 import cirq_google.api.v2.run_context_pb2 import collections.abc @@ -19,32 +18,6 @@ else: DESCRIPTOR: google.protobuf.descriptor.FileDescriptor -@typing_extensions.final -class BatchProgram(google.protobuf.message.Message): - """A Batch of multiple circuits that should be run together - as one QuantumProgram within Quantum Engine. - - Note: Batching is done on a best-effort basis. - Circuits will be be bundled together, but the size - of the total batch and different hardware constraints may - cause the programs to be executed separately on the hardware. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PROGRAMS_FIELD_NUMBER: builtins.int - @property - def programs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[cirq_google.api.v2.program_pb2.Program]: - """The circuits that should be bundled together as one program""" - def __init__( - self, - *, - programs: collections.abc.Iterable[cirq_google.api.v2.program_pb2.Program] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["programs", b"programs"]) -> None: ... - -global___BatchProgram = BatchProgram - @typing_extensions.final class BatchRunContext(google.protobuf.message.Message): """A batch of contexts for running a bundled batch of programs diff --git a/cirq-google/cirq_google/api/v2/calibration b/cirq-google/cirq_google/api/v2/calibration new file mode 100644 index 00000000000..18b3ef417aa --- /dev/null +++ b/cirq-google/cirq_google/api/v2/calibration @@ -0,0 +1,14 @@ +// Copyright 2024 smeeks +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// 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. + diff --git a/cirq-google/cirq_google/api/v2/calibration.proto b/cirq-google/cirq_google/api/v2/calibration.proto index dff7806e282..5d057fef916 100644 --- a/cirq-google/cirq_google/api/v2/calibration.proto +++ b/cirq-google/cirq_google/api/v2/calibration.proto @@ -9,20 +9,6 @@ option java_package = "com.google.cirq.google.api.v2"; option java_outer_classname = "FocusedCalibrationProto"; option java_multiple_files = true; -// This message represents a request to execute a custom calibration routine. -// -message FocusedCalibration { - // The layers field represents each invocation of a calibration - // procedure. - // - // For instance, each (unique) moment of a circuit could be - // calibrated using parallel_xeb. In this case, - // each moment would have its own CalibrationLayer. - // - // Some calibrations, such as a readout calibration, - // will only have one layer. - repeated CalibrationLayer layers = 1; -} // Each CalibrationLayer represents one invocation // of a calibration procedure. diff --git a/cirq-google/cirq_google/api/v2/calibration_pb2.py b/cirq-google/cirq_google/api/v2/calibration_pb2.py index cde48fd4747..c840c65a854 100644 --- a/cirq-google/cirq_google/api/v2/calibration_pb2.py +++ b/cirq-google/cirq_google/api/v2/calibration_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/calibration.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,27 +15,24 @@ from . import program_pb2 as cirq__google_dot_api_dot_v2_dot_program__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/calibration.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/metrics.proto\x1a cirq_google/api/v2/program.proto\"J\n\x12\x46ocusedCalibration\x12\x34\n\x06layers\x18\x01 \x03(\x0b\x32$.cirq.google.api.v2.CalibrationLayer\"\xdc\x01\n\x10\x43\x61librationLayer\x12\x18\n\x10\x63\x61libration_type\x18\x01 \x01(\t\x12*\n\x05layer\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.Program\x12<\n\x04\x61rgs\x18\x03 \x03(\x0b\x32..cirq.google.api.v2.CalibrationLayer.ArgsEntry\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\"W\n\x18\x46ocusedCalibrationResult\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.cirq.google.api.v2.CalibrationLayerResult\"\xc4\x01\n\x16\x43\x61librationLayerResult\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0e\x32(.cirq.google.api.v2.CalibrationLayerCode\x12\x15\n\rerror_message\x18\x02 \x01(\t\x12\r\n\x05token\x18\x03 \x01(\t\x12\x34\n\x07metrics\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.MetricsSnapshot\x12\x16\n\x0evalid_until_ms\x18\x05 \x01(\x04*\xa7\x01\n\x14\x43\x61librationLayerCode\x12\"\n\x1e\x43\x41LIBRATION_RESULT_UNSPECIFIED\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x0f\n\x0b\x45RROR_OTHER\x10\x02\x12\x1c\n\x18\x45RROR_INVALID_PARAMETERS\x10\x03\x12\x11\n\rERROR_TIMEOUT\x10\x04\x12\x1c\n\x18\x45RROR_CALIBRATION_FAILED\x10\x05\x42:\n\x1d\x63om.google.cirq.google.api.v2B\x17\x46ocusedCalibrationProtoP\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/calibration.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/metrics.proto\x1a cirq_google/api/v2/program.proto\"\xdc\x01\n\x10\x43\x61librationLayer\x12\x18\n\x10\x63\x61libration_type\x18\x01 \x01(\t\x12*\n\x05layer\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.Program\x12<\n\x04\x61rgs\x18\x03 \x03(\x0b\x32..cirq.google.api.v2.CalibrationLayer.ArgsEntry\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\"W\n\x18\x46ocusedCalibrationResult\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.cirq.google.api.v2.CalibrationLayerResult\"\xc4\x01\n\x16\x43\x61librationLayerResult\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0e\x32(.cirq.google.api.v2.CalibrationLayerCode\x12\x15\n\rerror_message\x18\x02 \x01(\t\x12\r\n\x05token\x18\x03 \x01(\t\x12\x34\n\x07metrics\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.MetricsSnapshot\x12\x16\n\x0evalid_until_ms\x18\x05 \x01(\x04*\xa7\x01\n\x14\x43\x61librationLayerCode\x12\"\n\x1e\x43\x41LIBRATION_RESULT_UNSPECIFIED\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x0f\n\x0b\x45RROR_OTHER\x10\x02\x12\x1c\n\x18\x45RROR_INVALID_PARAMETERS\x10\x03\x12\x11\n\rERROR_TIMEOUT\x10\x04\x12\x1c\n\x18\x45RROR_CALIBRATION_FAILED\x10\x05\x42:\n\x1d\x63om.google.cirq.google.api.v2B\x17\x46ocusedCalibrationProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.calibration_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.calibration_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\027FocusedCalibrationProtoP\001' _CALIBRATIONLAYER_ARGSENTRY._options = None _CALIBRATIONLAYER_ARGSENTRY._serialized_options = b'8\001' - _globals['_CALIBRATIONLAYERCODE']._serialized_start=716 - _globals['_CALIBRATIONLAYERCODE']._serialized_end=883 - _globals['_FOCUSEDCALIBRATION']._serialized_start=128 - _globals['_FOCUSEDCALIBRATION']._serialized_end=202 - _globals['_CALIBRATIONLAYER']._serialized_start=205 - _globals['_CALIBRATIONLAYER']._serialized_end=425 - _globals['_CALIBRATIONLAYER_ARGSENTRY']._serialized_start=357 - _globals['_CALIBRATIONLAYER_ARGSENTRY']._serialized_end=425 - _globals['_FOCUSEDCALIBRATIONRESULT']._serialized_start=427 - _globals['_FOCUSEDCALIBRATIONRESULT']._serialized_end=514 - _globals['_CALIBRATIONLAYERRESULT']._serialized_start=517 - _globals['_CALIBRATIONLAYERRESULT']._serialized_end=713 + _CALIBRATIONLAYERCODE._serialized_start=640 + _CALIBRATIONLAYERCODE._serialized_end=807 + _CALIBRATIONLAYER._serialized_start=129 + _CALIBRATIONLAYER._serialized_end=349 + _CALIBRATIONLAYER_ARGSENTRY._serialized_start=281 + _CALIBRATIONLAYER_ARGSENTRY._serialized_end=349 + _FOCUSEDCALIBRATIONRESULT._serialized_start=351 + _FOCUSEDCALIBRATIONRESULT._serialized_end=438 + _CALIBRATIONLAYERRESULT._serialized_start=441 + _CALIBRATIONLAYERRESULT._serialized_end=637 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/calibration_pb2.pyi b/cirq-google/cirq_google/api/v2/calibration_pb2.pyi index 9a94d92b3ac..4a9d75edaee 100644 --- a/cirq-google/cirq_google/api/v2/calibration_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/calibration_pb2.pyi @@ -68,34 +68,6 @@ needed by the calibration did not exist. """ global___CalibrationLayerCode = CalibrationLayerCode -@typing_extensions.final -class FocusedCalibration(google.protobuf.message.Message): - """ This message represents a request to execute a custom calibration routine.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LAYERS_FIELD_NUMBER: builtins.int - @property - def layers(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CalibrationLayer]: - """The layers field represents each invocation of a calibration - procedure. - - For instance, each (unique) moment of a circuit could be - calibrated using parallel_xeb. In this case, - each moment would have its own CalibrationLayer. - - Some calibrations, such as a readout calibration, - will only have one layer. - """ - def __init__( - self, - *, - layers: collections.abc.Iterable[global___CalibrationLayer] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["layers", b"layers"]) -> None: ... - -global___FocusedCalibration = FocusedCalibration - @typing_extensions.final class CalibrationLayer(google.protobuf.message.Message): """Each CalibrationLayer represents one invocation diff --git a/cirq-google/cirq_google/api/v2/device_pb2.py b/cirq-google/cirq_google/api/v2/device_pb2.py index d86989e8db5..0d9bd036bca 100644 --- a/cirq-google/cirq_google/api/v2/device_pb2.py +++ b/cirq-google/cirq_google/api/v2/device_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/device.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,9 +15,8 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v2/device.proto\x12\x12\x63irq.google.api.v2\"\xfa\x01\n\x13\x44\x65viceSpecification\x12\x38\n\x0fvalid_gate_sets\x18\x01 \x03(\x0b\x32\x1b.cirq.google.api.v2.GateSetB\x02\x18\x01\x12:\n\x0bvalid_gates\x18\x05 \x03(\x0b\x32%.cirq.google.api.v2.GateSpecification\x12\x14\n\x0cvalid_qubits\x18\x02 \x03(\t\x12\x34\n\rvalid_targets\x18\x03 \x03(\x0b\x32\x1d.cirq.google.api.v2.TargetSet\x12!\n\x19\x64\x65veloper_recommendations\x18\x04 \x01(\t\"\xee\x06\n\x11GateSpecification\x12\x1b\n\x13gate_duration_picos\x18\x01 \x01(\x03\x12=\n\x03syc\x18\x02 \x01(\x0b\x32..cirq.google.api.v2.GateSpecification.SycamoreH\x00\x12\x45\n\nsqrt_iswap\x18\x03 \x01(\x0b\x32/.cirq.google.api.v2.GateSpecification.SqrtISwapH\x00\x12L\n\x0esqrt_iswap_inv\x18\x04 \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.SqrtISwapInvH\x00\x12\x36\n\x02\x63z\x18\x05 \x01(\x0b\x32(.cirq.google.api.v2.GateSpecification.CZH\x00\x12\x43\n\tphased_xz\x18\x06 \x01(\x0b\x32..cirq.google.api.v2.GateSpecification.PhasedXZH\x00\x12I\n\x0cvirtual_zpow\x18\x07 \x01(\x0b\x32\x31.cirq.google.api.v2.GateSpecification.VirtualZPowH\x00\x12K\n\rphysical_zpow\x18\x08 \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.PhysicalZPowH\x00\x12K\n\rcoupler_pulse\x18\t \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.CouplerPulseH\x00\x12\x41\n\x04meas\x18\n \x01(\x0b\x32\x31.cirq.google.api.v2.GateSpecification.MeasurementH\x00\x12:\n\x04wait\x18\x0b \x01(\x0b\x32*.cirq.google.api.v2.GateSpecification.WaitH\x00\x1a\n\n\x08Sycamore\x1a\x0b\n\tSqrtISwap\x1a\x0e\n\x0cSqrtISwapInv\x1a\x04\n\x02\x43Z\x1a\n\n\x08PhasedXZ\x1a\r\n\x0bVirtualZPow\x1a\x0e\n\x0cPhysicalZPow\x1a\x0e\n\x0c\x43ouplerPulse\x1a\r\n\x0bMeasurement\x1a\x06\n\x04WaitB\x06\n\x04gate\"P\n\x07GateSet\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x37\n\x0bvalid_gates\x18\x02 \x03(\x0b\x32\".cirq.google.api.v2.GateDefinition\"\xa1\x01\n\x0eGateDefinition\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10number_of_qubits\x18\x02 \x01(\x05\x12\x35\n\nvalid_args\x18\x03 \x03(\x0b\x32!.cirq.google.api.v2.ArgDefinition\x12\x1b\n\x13gate_duration_picos\x18\x04 \x01(\x03\x12\x15\n\rvalid_targets\x18\x05 \x03(\t\"\xda\x01\n\rArgDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x37\n\x04type\x18\x02 \x01(\x0e\x32).cirq.google.api.v2.ArgDefinition.ArgType\x12\x39\n\x0e\x61llowed_ranges\x18\x03 \x03(\x0b\x32!.cirq.google.api.v2.ArgumentRange\"G\n\x07\x41rgType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05\x46LOAT\x10\x01\x12\x14\n\x10REPEATED_BOOLEAN\x10\x02\x12\n\n\x06STRING\x10\x03\"=\n\rArgumentRange\x12\x15\n\rminimum_value\x18\x01 \x01(\x02\x12\x15\n\rmaximum_value\x18\x02 \x01(\x02\"\xef\x01\n\tTargetSet\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x45\n\x0ftarget_ordering\x18\x02 \x01(\x0e\x32,.cirq.google.api.v2.TargetSet.TargetOrdering\x12+\n\x07targets\x18\x03 \x03(\x0b\x32\x1a.cirq.google.api.v2.Target\"`\n\x0eTargetOrdering\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\r\n\tSYMMETRIC\x10\x01\x12\x12\n\nASYMMETRIC\x10\x02\x1a\x02\x08\x01\x12\x1a\n\x12SUBSET_PERMUTATION\x10\x03\x1a\x02\x08\x01\"\x15\n\x06Target\x12\x0b\n\x03ids\x18\x01 \x03(\tB.\n\x1d\x63om.google.cirq.google.api.v2B\x0b\x44\x65viceProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.device_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.device_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -28,44 +27,44 @@ _TARGETSET_TARGETORDERING.values_by_name["ASYMMETRIC"]._serialized_options = b'\010\001' _TARGETSET_TARGETORDERING.values_by_name["SUBSET_PERMUTATION"]._options = None _TARGETSET_TARGETORDERING.values_by_name["SUBSET_PERMUTATION"]._serialized_options = b'\010\001' - _globals['_DEVICESPECIFICATION']._serialized_start=56 - _globals['_DEVICESPECIFICATION']._serialized_end=306 - _globals['_GATESPECIFICATION']._serialized_start=309 - _globals['_GATESPECIFICATION']._serialized_end=1187 - _globals['_GATESPECIFICATION_SYCAMORE']._serialized_start=1052 - _globals['_GATESPECIFICATION_SYCAMORE']._serialized_end=1062 - _globals['_GATESPECIFICATION_SQRTISWAP']._serialized_start=1064 - _globals['_GATESPECIFICATION_SQRTISWAP']._serialized_end=1075 - _globals['_GATESPECIFICATION_SQRTISWAPINV']._serialized_start=1077 - _globals['_GATESPECIFICATION_SQRTISWAPINV']._serialized_end=1091 - _globals['_GATESPECIFICATION_CZ']._serialized_start=1093 - _globals['_GATESPECIFICATION_CZ']._serialized_end=1097 - _globals['_GATESPECIFICATION_PHASEDXZ']._serialized_start=1099 - _globals['_GATESPECIFICATION_PHASEDXZ']._serialized_end=1109 - _globals['_GATESPECIFICATION_VIRTUALZPOW']._serialized_start=1111 - _globals['_GATESPECIFICATION_VIRTUALZPOW']._serialized_end=1124 - _globals['_GATESPECIFICATION_PHYSICALZPOW']._serialized_start=1126 - _globals['_GATESPECIFICATION_PHYSICALZPOW']._serialized_end=1140 - _globals['_GATESPECIFICATION_COUPLERPULSE']._serialized_start=1142 - _globals['_GATESPECIFICATION_COUPLERPULSE']._serialized_end=1156 - _globals['_GATESPECIFICATION_MEASUREMENT']._serialized_start=1158 - _globals['_GATESPECIFICATION_MEASUREMENT']._serialized_end=1171 - _globals['_GATESPECIFICATION_WAIT']._serialized_start=1173 - _globals['_GATESPECIFICATION_WAIT']._serialized_end=1179 - _globals['_GATESET']._serialized_start=1189 - _globals['_GATESET']._serialized_end=1269 - _globals['_GATEDEFINITION']._serialized_start=1272 - _globals['_GATEDEFINITION']._serialized_end=1433 - _globals['_ARGDEFINITION']._serialized_start=1436 - _globals['_ARGDEFINITION']._serialized_end=1654 - _globals['_ARGDEFINITION_ARGTYPE']._serialized_start=1583 - _globals['_ARGDEFINITION_ARGTYPE']._serialized_end=1654 - _globals['_ARGUMENTRANGE']._serialized_start=1656 - _globals['_ARGUMENTRANGE']._serialized_end=1717 - _globals['_TARGETSET']._serialized_start=1720 - _globals['_TARGETSET']._serialized_end=1959 - _globals['_TARGETSET_TARGETORDERING']._serialized_start=1863 - _globals['_TARGETSET_TARGETORDERING']._serialized_end=1959 - _globals['_TARGET']._serialized_start=1961 - _globals['_TARGET']._serialized_end=1982 + _DEVICESPECIFICATION._serialized_start=56 + _DEVICESPECIFICATION._serialized_end=306 + _GATESPECIFICATION._serialized_start=309 + _GATESPECIFICATION._serialized_end=1187 + _GATESPECIFICATION_SYCAMORE._serialized_start=1052 + _GATESPECIFICATION_SYCAMORE._serialized_end=1062 + _GATESPECIFICATION_SQRTISWAP._serialized_start=1064 + _GATESPECIFICATION_SQRTISWAP._serialized_end=1075 + _GATESPECIFICATION_SQRTISWAPINV._serialized_start=1077 + _GATESPECIFICATION_SQRTISWAPINV._serialized_end=1091 + _GATESPECIFICATION_CZ._serialized_start=1093 + _GATESPECIFICATION_CZ._serialized_end=1097 + _GATESPECIFICATION_PHASEDXZ._serialized_start=1099 + _GATESPECIFICATION_PHASEDXZ._serialized_end=1109 + _GATESPECIFICATION_VIRTUALZPOW._serialized_start=1111 + _GATESPECIFICATION_VIRTUALZPOW._serialized_end=1124 + _GATESPECIFICATION_PHYSICALZPOW._serialized_start=1126 + _GATESPECIFICATION_PHYSICALZPOW._serialized_end=1140 + _GATESPECIFICATION_COUPLERPULSE._serialized_start=1142 + _GATESPECIFICATION_COUPLERPULSE._serialized_end=1156 + _GATESPECIFICATION_MEASUREMENT._serialized_start=1158 + _GATESPECIFICATION_MEASUREMENT._serialized_end=1171 + _GATESPECIFICATION_WAIT._serialized_start=1173 + _GATESPECIFICATION_WAIT._serialized_end=1179 + _GATESET._serialized_start=1189 + _GATESET._serialized_end=1269 + _GATEDEFINITION._serialized_start=1272 + _GATEDEFINITION._serialized_end=1433 + _ARGDEFINITION._serialized_start=1436 + _ARGDEFINITION._serialized_end=1654 + _ARGDEFINITION_ARGTYPE._serialized_start=1583 + _ARGDEFINITION_ARGTYPE._serialized_end=1654 + _ARGUMENTRANGE._serialized_start=1656 + _ARGUMENTRANGE._serialized_end=1717 + _TARGETSET._serialized_start=1720 + _TARGETSET._serialized_end=1959 + _TARGETSET_TARGETORDERING._serialized_start=1863 + _TARGETSET_TARGETORDERING._serialized_end=1959 + _TARGET._serialized_start=1961 + _TARGET._serialized_end=1982 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/device_pb2.pyi b/cirq-google/cirq_google/api/v2/device_pb2.pyi index f1b26dadc67..1e547a26f29 100644 --- a/cirq-google/cirq_google/api/v2/device_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/device_pb2.pyi @@ -295,7 +295,7 @@ class ArgDefinition(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ArgTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ArgDefinition._ArgType.ValueType], builtins.type): # noqa: F821 + class _ArgTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ArgDefinition._ArgType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNSPECIFIED: ArgDefinition._ArgType.ValueType # 0 FLOAT: ArgDefinition._ArgType.ValueType # 1 @@ -373,7 +373,7 @@ class TargetSet(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TargetOrderingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TargetSet._TargetOrdering.ValueType], builtins.type): # noqa: F821 + class _TargetOrderingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TargetSet._TargetOrdering.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNSPECIFIED: TargetSet._TargetOrdering.ValueType # 0 SYMMETRIC: TargetSet._TargetOrdering.ValueType # 1 diff --git a/cirq-google/cirq_google/api/v2/metrics_pb2.py b/cirq-google/cirq_google/api/v2/metrics_pb2.py index 864ea2103b4..f6ec216226d 100644 --- a/cirq-google/cirq_google/api/v2/metrics_pb2.py +++ b/cirq-google/cirq_google/api/v2/metrics_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/metrics.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,17 +15,16 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/metrics.proto\x12\x12\x63irq.google.api.v2\"T\n\x0fMetricsSnapshot\x12\x14\n\x0ctimestamp_ms\x18\x01 \x01(\x04\x12+\n\x07metrics\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Metric\"R\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07targets\x18\x02 \x03(\t\x12)\n\x06values\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Value\"a\n\x05Value\x12\x14\n\ndouble_val\x18\x01 \x01(\x01H\x00\x12\x13\n\tint32_val\x18\x02 \x01(\x05H\x00\x12\x13\n\tint64_val\x18\x03 \x01(\x03H\x00\x12\x11\n\x07str_val\x18\x04 \x01(\tH\x00\x42\x05\n\x03valB3\n\x1d\x63om.google.cirq.google.api.v2B\x10\x43\x61librationProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.metrics_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.metrics_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\020CalibrationProtoP\001' - _globals['_METRICSSNAPSHOT']._serialized_start=56 - _globals['_METRICSSNAPSHOT']._serialized_end=140 - _globals['_METRIC']._serialized_start=142 - _globals['_METRIC']._serialized_end=224 - _globals['_VALUE']._serialized_start=226 - _globals['_VALUE']._serialized_end=323 + _METRICSSNAPSHOT._serialized_start=56 + _METRICSSNAPSHOT._serialized_end=140 + _METRIC._serialized_start=142 + _METRIC._serialized_end=224 + _VALUE._serialized_start=226 + _VALUE._serialized_end=323 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/program_pb2.py b/cirq-google/cirq_google/api/v2/program_pb2.py index 2440805d87a..30384dfe286 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.py +++ b/cirq-google/cirq_google/api/v2/program_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/program.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,9 +15,8 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/program.proto\x12\x12\x63irq.google.api.v2\"\xd7\x01\n\x07Program\x12.\n\x08language\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.Language\x12.\n\x07\x63ircuit\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12\x30\n\x08schedule\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.ScheduleH\x00\x12/\n\tconstants\x18\x04 \x03(\x0b\x32\x1c.cirq.google.api.v2.ConstantB\t\n\x07program\"\x93\x01\n\x08\x43onstant\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x34\n\rcircuit_value\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12*\n\x05qubit\x18\x03 \x01(\x0b\x32\x19.cirq.google.api.v2.QubitH\x00\x42\r\n\x0b\x63onst_value\"\xd4\x01\n\x07\x43ircuit\x12K\n\x13scheduling_strategy\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.Circuit.SchedulingStrategy\x12+\n\x07moments\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Moment\"O\n\x12SchedulingStrategy\x12#\n\x1fSCHEDULING_STRATEGY_UNSPECIFIED\x10\x00\x12\x14\n\x10MOMENT_BY_MOMENT\x10\x01\"}\n\x06Moment\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12@\n\x12\x63ircuit_operations\x18\x02 \x03(\x0b\x32$.cirq.google.api.v2.CircuitOperation\"P\n\x08Schedule\x12\x44\n\x14scheduled_operations\x18\x03 \x03(\x0b\x32&.cirq.google.api.v2.ScheduledOperation\"`\n\x12ScheduledOperation\x12\x30\n\toperation\x18\x01 \x01(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12\x18\n\x10start_time_picos\x18\x02 \x01(\x03\"?\n\x08Language\x12\x14\n\x08gate_set\x18\x01 \x01(\tB\x02\x18\x01\x12\x1d\n\x15\x61rg_function_language\x18\x02 \x01(\t\"k\n\x08\x46loatArg\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x42\x05\n\x03\x61rg\":\n\x08XPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\":\n\x08YPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"Q\n\x08ZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x15\n\ris_physical_z\x18\x02 \x01(\x08\"v\n\x0ePhasedXPowGate\x12\x34\n\x0ephase_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12.\n\x08\x65xponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xad\x01\n\x0cPhasedXZGate\x12\x30\n\nx_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x30\n\nz_exponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x39\n\x13\x61xis_phase_exponent\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\";\n\tCZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"b\n\x08\x46SimGate\x12+\n\x05theta\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12)\n\x03phi\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\">\n\x0cISwapPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"e\n\x0fMeasurementGate\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12,\n\x0binvert_mask\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"@\n\x08WaitGate\x12\x34\n\x0e\x64uration_nanos\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xa9\x07\n\tOperation\x12*\n\x04gate\x18\x01 \x01(\x0b\x32\x18.cirq.google.api.v2.GateB\x02\x18\x01\x12\x30\n\x08xpowgate\x18\x07 \x01(\x0b\x32\x1c.cirq.google.api.v2.XPowGateH\x00\x12\x30\n\x08ypowgate\x18\x08 \x01(\x0b\x32\x1c.cirq.google.api.v2.YPowGateH\x00\x12\x30\n\x08zpowgate\x18\t \x01(\x0b\x32\x1c.cirq.google.api.v2.ZPowGateH\x00\x12<\n\x0ephasedxpowgate\x18\n \x01(\x0b\x32\".cirq.google.api.v2.PhasedXPowGateH\x00\x12\x38\n\x0cphasedxzgate\x18\x0b \x01(\x0b\x32 .cirq.google.api.v2.PhasedXZGateH\x00\x12\x32\n\tczpowgate\x18\x0c \x01(\x0b\x32\x1d.cirq.google.api.v2.CZPowGateH\x00\x12\x30\n\x08\x66simgate\x18\r \x01(\x0b\x32\x1c.cirq.google.api.v2.FSimGateH\x00\x12\x38\n\x0ciswappowgate\x18\x0e \x01(\x0b\x32 .cirq.google.api.v2.ISwapPowGateH\x00\x12>\n\x0fmeasurementgate\x18\x0f \x01(\x0b\x32#.cirq.google.api.v2.MeasurementGateH\x00\x12\x30\n\x08waitgate\x18\x10 \x01(\x0b\x32\x1c.cirq.google.api.v2.WaitGateH\x00\x12\x38\n\x0cinternalgate\x18\x11 \x01(\x0b\x32 .cirq.google.api.v2.InternalGateH\x00\x12\x39\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.Operation.ArgsEntryB\x02\x18\x01\x12)\n\x06qubits\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x1c\n\x14qubit_constant_index\x18\x06 \x03(\x05\x12\x15\n\x0btoken_value\x18\x04 \x01(\tH\x01\x12\x1e\n\x14token_constant_index\x18\x05 \x01(\x05H\x01\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42\x0c\n\ngate_valueB\x07\n\x05token\"\x12\n\x04Gate\x12\n\n\x02id\x18\x01 \x01(\t\"\x13\n\x05Qubit\x12\n\n\x02id\x18\x02 \x01(\t\"\x9c\x01\n\x03\x41rg\x12\x31\n\targ_value\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.ArgValueH\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x12\x18\n\x0e\x63onstant_index\x18\x04 \x01(\x05H\x00\x42\x05\n\x03\x61rg\"\xcf\x02\n\x08\x41rgValue\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12:\n\x0b\x62ool_values\x18\x02 \x01(\x0b\x32#.cirq.google.api.v2.RepeatedBooleanH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x39\n\x0cint64_values\x18\x05 \x01(\x0b\x32!.cirq.google.api.v2.RepeatedInt64H\x00\x12;\n\rdouble_values\x18\x06 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedDoubleH\x00\x12;\n\rstring_values\x18\x07 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedStringH\x00\x42\x0b\n\targ_value\"\x1f\n\rRepeatedInt64\x12\x0e\n\x06values\x18\x01 \x03(\x03\" \n\x0eRepeatedDouble\x12\x0e\n\x06values\x18\x01 \x03(\x01\" \n\x0eRepeatedString\x12\x0e\n\x06values\x18\x01 \x03(\t\"!\n\x0fRepeatedBoolean\x12\x0e\n\x06values\x18\x01 \x03(\x08\"B\n\x0b\x41rgFunction\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xaf\x02\n\x10\x43ircuitOperation\x12\x1e\n\x16\x63ircuit_constant_index\x18\x01 \x01(\x05\x12M\n\x18repetition_specification\x18\x02 \x01(\x0b\x32+.cirq.google.api.v2.RepetitionSpecification\x12\x33\n\tqubit_map\x18\x03 \x01(\x0b\x32 .cirq.google.api.v2.QubitMapping\x12\x46\n\x13measurement_key_map\x18\x04 \x01(\x0b\x32).cirq.google.api.v2.MeasurementKeyMapping\x12/\n\x07\x61rg_map\x18\x05 \x01(\x0b\x32\x1e.cirq.google.api.v2.ArgMapping\"\xbc\x01\n\x17RepetitionSpecification\x12S\n\x0erepetition_ids\x18\x01 \x01(\x0b\x32\x39.cirq.google.api.v2.RepetitionSpecification.RepetitionIdsH\x00\x12\x1a\n\x10repetition_count\x18\x02 \x01(\x05H\x00\x1a\x1c\n\rRepetitionIds\x12\x0b\n\x03ids\x18\x01 \x03(\tB\x12\n\x10repetition_value\"\xac\x01\n\x0cQubitMapping\x12<\n\x07\x65ntries\x18\x01 \x03(\x0b\x32+.cirq.google.api.v2.QubitMapping.QubitEntry\x1a^\n\nQubitEntry\x12&\n\x03key\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\"$\n\x0eMeasurementKey\x12\x12\n\nstring_key\x18\x01 \x01(\t\"\xe2\x01\n\x15MeasurementKeyMapping\x12N\n\x07\x65ntries\x18\x01 \x03(\x0b\x32=.cirq.google.api.v2.MeasurementKeyMapping.MeasurementKeyEntry\x1ay\n\x13MeasurementKeyEntry\x12/\n\x03key\x18\x01 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\"\xa0\x01\n\nArgMapping\x12\x38\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\'.cirq.google.api.v2.ArgMapping.ArgEntry\x1aX\n\x08\x41rgEntry\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xcd\x01\n\x0cInternalGate\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x12\n\nnum_qubits\x18\x03 \x01(\x05\x12\x41\n\tgate_args\x18\x04 \x03(\x0b\x32..cirq.google.api.v2.InternalGate.GateArgsEntry\x1aH\n\rGateArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42/\n\x1d\x63om.google.cirq.google.api.v2B\x0cProgramProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.program_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.program_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -32,88 +31,88 @@ _OPERATION.fields_by_name['args']._serialized_options = b'\030\001' _INTERNALGATE_GATEARGSENTRY._options = None _INTERNALGATE_GATEARGSENTRY._serialized_options = b'8\001' - _globals['_PROGRAM']._serialized_start=57 - _globals['_PROGRAM']._serialized_end=272 - _globals['_CONSTANT']._serialized_start=275 - _globals['_CONSTANT']._serialized_end=422 - _globals['_CIRCUIT']._serialized_start=425 - _globals['_CIRCUIT']._serialized_end=637 - _globals['_CIRCUIT_SCHEDULINGSTRATEGY']._serialized_start=558 - _globals['_CIRCUIT_SCHEDULINGSTRATEGY']._serialized_end=637 - _globals['_MOMENT']._serialized_start=639 - _globals['_MOMENT']._serialized_end=764 - _globals['_SCHEDULE']._serialized_start=766 - _globals['_SCHEDULE']._serialized_end=846 - _globals['_SCHEDULEDOPERATION']._serialized_start=848 - _globals['_SCHEDULEDOPERATION']._serialized_end=944 - _globals['_LANGUAGE']._serialized_start=946 - _globals['_LANGUAGE']._serialized_end=1009 - _globals['_FLOATARG']._serialized_start=1011 - _globals['_FLOATARG']._serialized_end=1118 - _globals['_XPOWGATE']._serialized_start=1120 - _globals['_XPOWGATE']._serialized_end=1178 - _globals['_YPOWGATE']._serialized_start=1180 - _globals['_YPOWGATE']._serialized_end=1238 - _globals['_ZPOWGATE']._serialized_start=1240 - _globals['_ZPOWGATE']._serialized_end=1321 - _globals['_PHASEDXPOWGATE']._serialized_start=1323 - _globals['_PHASEDXPOWGATE']._serialized_end=1441 - _globals['_PHASEDXZGATE']._serialized_start=1444 - _globals['_PHASEDXZGATE']._serialized_end=1617 - _globals['_CZPOWGATE']._serialized_start=1619 - _globals['_CZPOWGATE']._serialized_end=1678 - _globals['_FSIMGATE']._serialized_start=1680 - _globals['_FSIMGATE']._serialized_end=1778 - _globals['_ISWAPPOWGATE']._serialized_start=1780 - _globals['_ISWAPPOWGATE']._serialized_end=1842 - _globals['_MEASUREMENTGATE']._serialized_start=1844 - _globals['_MEASUREMENTGATE']._serialized_end=1945 - _globals['_WAITGATE']._serialized_start=1947 - _globals['_WAITGATE']._serialized_end=2011 - _globals['_OPERATION']._serialized_start=2014 - _globals['_OPERATION']._serialized_end=2951 - _globals['_OPERATION_ARGSENTRY']._serialized_start=2860 - _globals['_OPERATION_ARGSENTRY']._serialized_end=2928 - _globals['_GATE']._serialized_start=2953 - _globals['_GATE']._serialized_end=2971 - _globals['_QUBIT']._serialized_start=2973 - _globals['_QUBIT']._serialized_end=2992 - _globals['_ARG']._serialized_start=2995 - _globals['_ARG']._serialized_end=3151 - _globals['_ARGVALUE']._serialized_start=3154 - _globals['_ARGVALUE']._serialized_end=3489 - _globals['_REPEATEDINT64']._serialized_start=3491 - _globals['_REPEATEDINT64']._serialized_end=3522 - _globals['_REPEATEDDOUBLE']._serialized_start=3524 - _globals['_REPEATEDDOUBLE']._serialized_end=3556 - _globals['_REPEATEDSTRING']._serialized_start=3558 - _globals['_REPEATEDSTRING']._serialized_end=3590 - _globals['_REPEATEDBOOLEAN']._serialized_start=3592 - _globals['_REPEATEDBOOLEAN']._serialized_end=3625 - _globals['_ARGFUNCTION']._serialized_start=3627 - _globals['_ARGFUNCTION']._serialized_end=3693 - _globals['_CIRCUITOPERATION']._serialized_start=3696 - _globals['_CIRCUITOPERATION']._serialized_end=3999 - _globals['_REPETITIONSPECIFICATION']._serialized_start=4002 - _globals['_REPETITIONSPECIFICATION']._serialized_end=4190 - _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_start=4142 - _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_end=4170 - _globals['_QUBITMAPPING']._serialized_start=4193 - _globals['_QUBITMAPPING']._serialized_end=4365 - _globals['_QUBITMAPPING_QUBITENTRY']._serialized_start=4271 - _globals['_QUBITMAPPING_QUBITENTRY']._serialized_end=4365 - _globals['_MEASUREMENTKEY']._serialized_start=4367 - _globals['_MEASUREMENTKEY']._serialized_end=4403 - _globals['_MEASUREMENTKEYMAPPING']._serialized_start=4406 - _globals['_MEASUREMENTKEYMAPPING']._serialized_end=4632 - _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_start=4511 - _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_end=4632 - _globals['_ARGMAPPING']._serialized_start=4635 - _globals['_ARGMAPPING']._serialized_end=4795 - _globals['_ARGMAPPING_ARGENTRY']._serialized_start=4707 - _globals['_ARGMAPPING_ARGENTRY']._serialized_end=4795 - _globals['_INTERNALGATE']._serialized_start=4798 - _globals['_INTERNALGATE']._serialized_end=5003 - _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_start=4931 - _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_end=5003 + _PROGRAM._serialized_start=57 + _PROGRAM._serialized_end=272 + _CONSTANT._serialized_start=275 + _CONSTANT._serialized_end=422 + _CIRCUIT._serialized_start=425 + _CIRCUIT._serialized_end=637 + _CIRCUIT_SCHEDULINGSTRATEGY._serialized_start=558 + _CIRCUIT_SCHEDULINGSTRATEGY._serialized_end=637 + _MOMENT._serialized_start=639 + _MOMENT._serialized_end=764 + _SCHEDULE._serialized_start=766 + _SCHEDULE._serialized_end=846 + _SCHEDULEDOPERATION._serialized_start=848 + _SCHEDULEDOPERATION._serialized_end=944 + _LANGUAGE._serialized_start=946 + _LANGUAGE._serialized_end=1009 + _FLOATARG._serialized_start=1011 + _FLOATARG._serialized_end=1118 + _XPOWGATE._serialized_start=1120 + _XPOWGATE._serialized_end=1178 + _YPOWGATE._serialized_start=1180 + _YPOWGATE._serialized_end=1238 + _ZPOWGATE._serialized_start=1240 + _ZPOWGATE._serialized_end=1321 + _PHASEDXPOWGATE._serialized_start=1323 + _PHASEDXPOWGATE._serialized_end=1441 + _PHASEDXZGATE._serialized_start=1444 + _PHASEDXZGATE._serialized_end=1617 + _CZPOWGATE._serialized_start=1619 + _CZPOWGATE._serialized_end=1678 + _FSIMGATE._serialized_start=1680 + _FSIMGATE._serialized_end=1778 + _ISWAPPOWGATE._serialized_start=1780 + _ISWAPPOWGATE._serialized_end=1842 + _MEASUREMENTGATE._serialized_start=1844 + _MEASUREMENTGATE._serialized_end=1945 + _WAITGATE._serialized_start=1947 + _WAITGATE._serialized_end=2011 + _OPERATION._serialized_start=2014 + _OPERATION._serialized_end=2951 + _OPERATION_ARGSENTRY._serialized_start=2860 + _OPERATION_ARGSENTRY._serialized_end=2928 + _GATE._serialized_start=2953 + _GATE._serialized_end=2971 + _QUBIT._serialized_start=2973 + _QUBIT._serialized_end=2992 + _ARG._serialized_start=2995 + _ARG._serialized_end=3151 + _ARGVALUE._serialized_start=3154 + _ARGVALUE._serialized_end=3489 + _REPEATEDINT64._serialized_start=3491 + _REPEATEDINT64._serialized_end=3522 + _REPEATEDDOUBLE._serialized_start=3524 + _REPEATEDDOUBLE._serialized_end=3556 + _REPEATEDSTRING._serialized_start=3558 + _REPEATEDSTRING._serialized_end=3590 + _REPEATEDBOOLEAN._serialized_start=3592 + _REPEATEDBOOLEAN._serialized_end=3625 + _ARGFUNCTION._serialized_start=3627 + _ARGFUNCTION._serialized_end=3693 + _CIRCUITOPERATION._serialized_start=3696 + _CIRCUITOPERATION._serialized_end=3999 + _REPETITIONSPECIFICATION._serialized_start=4002 + _REPETITIONSPECIFICATION._serialized_end=4190 + _REPETITIONSPECIFICATION_REPETITIONIDS._serialized_start=4142 + _REPETITIONSPECIFICATION_REPETITIONIDS._serialized_end=4170 + _QUBITMAPPING._serialized_start=4193 + _QUBITMAPPING._serialized_end=4365 + _QUBITMAPPING_QUBITENTRY._serialized_start=4271 + _QUBITMAPPING_QUBITENTRY._serialized_end=4365 + _MEASUREMENTKEY._serialized_start=4367 + _MEASUREMENTKEY._serialized_end=4403 + _MEASUREMENTKEYMAPPING._serialized_start=4406 + _MEASUREMENTKEYMAPPING._serialized_end=4632 + _MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY._serialized_start=4511 + _MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY._serialized_end=4632 + _ARGMAPPING._serialized_start=4635 + _ARGMAPPING._serialized_end=4795 + _ARGMAPPING_ARGENTRY._serialized_start=4707 + _ARGMAPPING_ARGENTRY._serialized_end=4795 + _INTERNALGATE._serialized_start=4798 + _INTERNALGATE._serialized_end=5003 + _INTERNALGATE_GATEARGSENTRY._serialized_start=4931 + _INTERNALGATE_GATEARGSENTRY._serialized_end=5003 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/program_pb2.pyi b/cirq-google/cirq_google/api/v2/program_pb2.pyi index aa688fabb77..ac75a2dc0ac 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/program_pb2.pyi @@ -105,7 +105,7 @@ class Circuit(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _SchedulingStrategyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Circuit._SchedulingStrategy.ValueType], builtins.type): # noqa: F821 + class _SchedulingStrategyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Circuit._SchedulingStrategy.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SCHEDULING_STRATEGY_UNSPECIFIED: Circuit._SchedulingStrategy.ValueType # 0 """The scheduling strategy is unspecified.""" diff --git a/cirq-google/cirq_google/api/v2/result_pb2.py b/cirq-google/cirq_google/api/v2/result_pb2.py index bcc5007d653..6b202adc7bd 100644 --- a/cirq-google/cirq_google/api/v2/result_pb2.py +++ b/cirq-google/cirq_google/api/v2/result_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/result.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -16,27 +16,26 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v2/result.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/program.proto\"@\n\x06Result\x12\x36\n\rsweep_results\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v2.SweepResult\"j\n\x0bSweepResult\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12\x46\n\x15parameterized_results\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.ParameterizedResult\"\x8c\x01\n\x13ParameterizedResult\x12\x31\n\x06params\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.ParameterDict\x12\x42\n\x13measurement_results\x18\x02 \x03(\x0b\x32%.cirq.google.api.v2.MeasurementResult\"\x82\x01\n\x11MeasurementResult\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x11\n\tinstances\x18\x03 \x01(\x05\x12M\n\x19qubit_measurement_results\x18\x02 \x03(\x0b\x32*.cirq.google.api.v2.QubitMeasurementResult\"S\n\x16QubitMeasurementResult\x12(\n\x05qubit\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x0f\n\x07results\x18\x02 \x01(\x0c\"\x8c\x01\n\rParameterDict\x12G\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32\x32.cirq.google.api.v2.ParameterDict.AssignmentsEntry\x1a\x32\n\x10\x41ssignmentsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x42.\n\x1d\x63om.google.cirq.google.api.v2B\x0bResultProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.result_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.result_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\013ResultProtoP\001' _PARAMETERDICT_ASSIGNMENTSENTRY._options = None _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_options = b'8\001' - _globals['_RESULT']._serialized_start=89 - _globals['_RESULT']._serialized_end=153 - _globals['_SWEEPRESULT']._serialized_start=155 - _globals['_SWEEPRESULT']._serialized_end=261 - _globals['_PARAMETERIZEDRESULT']._serialized_start=264 - _globals['_PARAMETERIZEDRESULT']._serialized_end=404 - _globals['_MEASUREMENTRESULT']._serialized_start=407 - _globals['_MEASUREMENTRESULT']._serialized_end=537 - _globals['_QUBITMEASUREMENTRESULT']._serialized_start=539 - _globals['_QUBITMEASUREMENTRESULT']._serialized_end=622 - _globals['_PARAMETERDICT']._serialized_start=625 - _globals['_PARAMETERDICT']._serialized_end=765 - _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_start=715 - _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_end=765 + _RESULT._serialized_start=89 + _RESULT._serialized_end=153 + _SWEEPRESULT._serialized_start=155 + _SWEEPRESULT._serialized_end=261 + _PARAMETERIZEDRESULT._serialized_start=264 + _PARAMETERIZEDRESULT._serialized_end=404 + _MEASUREMENTRESULT._serialized_start=407 + _MEASUREMENTRESULT._serialized_end=537 + _QUBITMEASUREMENTRESULT._serialized_start=539 + _QUBITMEASUREMENTRESULT._serialized_end=622 + _PARAMETERDICT._serialized_start=625 + _PARAMETERDICT._serialized_end=765 + _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_start=715 + _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_end=765 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.py b/cirq-google/cirq_google/api/v2/run_context_pb2.py index ac1fbe25102..5b6b9afeed5 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.py +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/run_context.proto """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,29 +15,28 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/run_context.proto\x12\x12\x63irq.google.api.v2\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v2.ParameterSweep\"O\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12(\n\x05sweep\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Sweep\"\x86\x01\n\x05Sweep\x12;\n\x0esweep_function\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.SweepFunctionH\x00\x12\x37\n\x0csingle_sweep\x18\x02 \x01(\x0b\x32\x1f.cirq.google.api.v2.SingleSweepH\x00\x42\x07\n\x05sweep\"\xc6\x01\n\rSweepFunction\x12\x45\n\rfunction_type\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.SweepFunction.FunctionType\x12)\n\x06sweeps\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v2.Sweep\"C\n\x0c\x46unctionType\x12\x1d\n\x19\x46UNCTION_TYPE_UNSPECIFIED\x10\x00\x12\x0b\n\x07PRODUCT\x10\x01\x12\x07\n\x03ZIP\x10\x02\"W\n\x0f\x44\x65viceParameter\x12\x0c\n\x04path\x18\x01 \x03(\t\x12\x10\n\x03idx\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x12\n\x05units\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04_idxB\x08\n\x06_units\"\xc5\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v2.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.LinspaceH\x00\x12\x36\n\tparameter\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.DeviceParameterB\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\x42\x32\n\x1d\x63om.google.cirq.google.api.v2B\x0fRunContextProtoP\x01\x62\x06proto3') -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.run_context_pb2', _globals) +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.run_context_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\017RunContextProtoP\001' - _globals['_RUNCONTEXT']._serialized_start=60 - _globals['_RUNCONTEXT']._serialized_end=134 - _globals['_PARAMETERSWEEP']._serialized_start=136 - _globals['_PARAMETERSWEEP']._serialized_end=215 - _globals['_SWEEP']._serialized_start=218 - _globals['_SWEEP']._serialized_end=352 - _globals['_SWEEPFUNCTION']._serialized_start=355 - _globals['_SWEEPFUNCTION']._serialized_end=553 - _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_start=486 - _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_end=553 - _globals['_DEVICEPARAMETER']._serialized_start=555 - _globals['_DEVICEPARAMETER']._serialized_end=642 - _globals['_SINGLESWEEP']._serialized_start=645 - _globals['_SINGLESWEEP']._serialized_end=842 - _globals['_POINTS']._serialized_start=844 - _globals['_POINTS']._serialized_end=868 - _globals['_LINSPACE']._serialized_start=870 - _globals['_LINSPACE']._serialized_end=941 + _RUNCONTEXT._serialized_start=60 + _RUNCONTEXT._serialized_end=134 + _PARAMETERSWEEP._serialized_start=136 + _PARAMETERSWEEP._serialized_end=215 + _SWEEP._serialized_start=218 + _SWEEP._serialized_end=352 + _SWEEPFUNCTION._serialized_start=355 + _SWEEPFUNCTION._serialized_end=553 + _SWEEPFUNCTION_FUNCTIONTYPE._serialized_start=486 + _SWEEPFUNCTION_FUNCTIONTYPE._serialized_end=553 + _DEVICEPARAMETER._serialized_start=555 + _DEVICEPARAMETER._serialized_end=642 + _SINGLESWEEP._serialized_start=645 + _SINGLESWEEP._serialized_end=842 + _POINTS._serialized_start=844 + _POINTS._serialized_end=868 + _LINSPACE._serialized_start=870 + _LINSPACE._serialized_end=941 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi index 75afaa133e1..ea34266c37a 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi @@ -105,7 +105,7 @@ class SweepFunction(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _FunctionTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SweepFunction._FunctionType.ValueType], builtins.type): # noqa: F821 + class _FunctionTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SweepFunction._FunctionType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor FUNCTION_TYPE_UNSPECIFIED: SweepFunction._FunctionType.ValueType # 0 """The function type is not specified. Should never be used.""" diff --git a/cirq-google/cirq_google/engine/engine.py b/cirq-google/cirq_google/engine/engine.py index 71a1657eacd..6c1ab139828 100644 --- a/cirq-google/cirq_google/engine/engine.py +++ b/cirq-google/cirq_google/engine/engine.py @@ -664,24 +664,7 @@ async def create_batch_program_async( Raises: ValueError: If no gate set is provided. """ - if not program_id: - program_id = _make_random_id('prog-') - - batch = v2.batch_pb2.BatchProgram() - for program in programs: - self.context.serializer.serialize(program, msg=batch.programs.add()) - - new_program_id, new_program = await self.context.client.create_program_async( - self.project_id, - program_id, - code=util.pack_any(batch), - description=description, - labels=labels, - ) - - return engine_program.EngineProgram( - self.project_id, new_program_id, self.context, new_program, result_type=ResultType.Batch - ) + raise NotImplementedError('Batch programs are not yet supported by the Quantum Engine.') create_batch_program = duet.sync(create_batch_program_async) @@ -714,31 +697,8 @@ async def create_calibration_program_async( Raises: ValueError: If not gate set is given. """ - if not program_id: - program_id = _make_random_id('calibration-') - - calibration = v2.calibration_pb2.FocusedCalibration() - for layer in layers: - new_layer = calibration.layers.add() - new_layer.calibration_type = layer.calibration_type - for arg in layer.args: - arg_to_proto(layer.args[arg], out=new_layer.args[arg]) - self.context.serializer.serialize(layer.program, msg=new_layer.layer) - - new_program_id, new_program = await self.context.client.create_program_async( - self.project_id, - program_id, - code=util.pack_any(calibration), - description=description, - labels=labels, - ) - - return engine_program.EngineProgram( - self.project_id, - new_program_id, - self.context, - new_program, - result_type=ResultType.Calibration, + raise NotImplementedError( + 'Calibration programs are not yet supported on the Quantum Engine.' ) create_calibration_program = duet.sync(create_calibration_program_async) diff --git a/cirq-google/cirq_google/engine/engine_test.py b/cirq-google/cirq_google/engine/engine_test.py index f9fee387867..b5db2274337 100644 --- a/cirq-google/cirq_google/engine/engine_test.py +++ b/cirq-google/cirq_google/engine/engine_test.py @@ -737,59 +737,6 @@ def test_run_sweep_v2_with_stream_rpcs(client): assert sweeps[0].sweep.single_sweep.points.points == [1, 2] -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_batch(client): - setup_run_circuit_with_result_(client, _BATCH_RESULTS_V2) - - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - job = engine.run_batch( - programs=[_CIRCUIT, _CIRCUIT2], - job_id='job-id', - params_list=[cirq.Points('a', [1, 2]), cirq.Points('a', [3, 4])], - processor_ids=['mysim'], - ) - results = job.results() - assert len(results) == 4 - for i, v in enumerate([1, 2, 3, 4]): - assert results[i].repetitions == 1 - assert results[i].params.param_dict == {'a': v} - assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} - client().create_program_async.assert_called_once() - client().create_job_async.assert_called_once() - run_context = v2.batch_pb2.BatchRunContext() - client().create_job_async.call_args[1]['run_context'].Unpack(run_context) - assert len(run_context.run_contexts) == 2 - for idx, rc in enumerate(run_context.run_contexts): - sweeps = rc.parameter_sweeps - assert len(sweeps) == 1 - assert sweeps[0].repetitions == 1 - if idx == 0: - assert sweeps[0].sweep.single_sweep.points.points == [1.0, 2.0] - if idx == 1: - assert sweeps[0].sweep.single_sweep.points.points == [3.0, 4.0] - client().get_job_async.assert_called_once() - client().get_job_results_async.assert_called_once() - - -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_batch_no_params(client): - # OK to run with no params, it should use empty sweeps for each - # circuit. - setup_run_circuit_with_result_(client, _BATCH_RESULTS_V2) - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - engine.run_batch(programs=[_CIRCUIT, _CIRCUIT2], job_id='job-id', processor_ids=['mysim']) - # Validate correct number of params have been created and that they - # are empty sweeps. - run_context = v2.batch_pb2.BatchRunContext() - client().create_job_async.call_args[1]['run_context'].Unpack(run_context) - assert len(run_context.run_contexts) == 2 - for rc in run_context.run_contexts: - sweeps = rc.parameter_sweeps - assert len(sweeps) == 1 - assert sweeps[0].repetitions == 1 - assert sweeps[0].sweep == v2.run_context_pb2.Sweep() - - def test_batch_size_validation_fails(): engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) @@ -820,41 +767,6 @@ def test_bad_sweep_proto(): program.run_sweep() -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_calibration(client): - setup_run_circuit_with_result_(client, _CALIBRATION_RESULTS_V2) - - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - q1 = cirq.GridQubit(2, 3) - q2 = cirq.GridQubit(2, 4) - layer1 = cg.CalibrationLayer('xeb', cirq.Circuit(cirq.CZ(q1, q2)), {'num_layers': 42}) - layer2 = cg.CalibrationLayer( - 'readout', cirq.Circuit(cirq.measure(q1, q2)), {'num_samples': 4242} - ) - job = engine.run_calibration(layers=[layer1, layer2], job_id='job-id', processor_id='mysim') - results = job.calibration_results() - assert len(results) == 2 - assert results[0].code == v2.calibration_pb2.SUCCESS - assert results[0].error_message == 'First success' - assert results[0].token == 'abc123' - assert len(results[0].metrics) == 1 - assert len(results[0].metrics['fidelity']) == 1 - assert results[0].metrics['fidelity'][(q1, q2)] == [0.75] - assert results[1].code == v2.calibration_pb2.SUCCESS - assert results[1].error_message == 'Second success' - - # assert label is correct - client().create_job_async.assert_called_once_with( - project_id='proj', - program_id='prog', - job_id='job-id', - processor_ids=['mysim'], - run_context=util.pack_any(v2.run_context_pb2.RunContext()), - description=None, - labels={'calibration': ''}, - ) - - def test_run_calibration_validation_fails(): engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) q1 = cirq.GridQubit(2, 3) diff --git a/https:/github.com/qh-lab/pyle/pull/42618 b/https:/github.com/qh-lab/pyle/pull/42618 new file mode 100644 index 00000000000..18b3ef417aa --- /dev/null +++ b/https:/github.com/qh-lab/pyle/pull/42618 @@ -0,0 +1,14 @@ +// Copyright 2024 smeeks +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// 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. + From 8e4a3edfc8b728d04b2693d439f07d4e41d8b8e7 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 5 Feb 2024 20:17:45 +0000 Subject: [PATCH 03/23] lint --- https:/github.com/qh-lab/pyle/pull/42618 | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 https:/github.com/qh-lab/pyle/pull/42618 diff --git a/https:/github.com/qh-lab/pyle/pull/42618 b/https:/github.com/qh-lab/pyle/pull/42618 deleted file mode 100644 index 18b3ef417aa..00000000000 --- a/https:/github.com/qh-lab/pyle/pull/42618 +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2024 smeeks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. - From a991441e7f0e0492bd31534696146fd5bc2c12ae Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 5 Feb 2024 20:19:08 +0000 Subject: [PATCH 04/23] build protos --- cirq-google/cirq_google/api/v2/batch.proto | 1 - cirq-google/cirq_google/api/v2/batch_pb2.py | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cirq-google/cirq_google/api/v2/batch.proto b/cirq-google/cirq_google/api/v2/batch.proto index daa86315ecb..1959b34cd10 100644 --- a/cirq-google/cirq_google/api/v2/batch.proto +++ b/cirq-google/cirq_google/api/v2/batch.proto @@ -1,6 +1,5 @@ syntax = "proto3"; -import "cirq_google/api/v2/program.proto"; import "cirq_google/api/v2/result.proto"; import "cirq_google/api/v2/run_context.proto"; diff --git a/cirq-google/cirq_google/api/v2/batch_pb2.py b/cirq-google/cirq_google/api/v2/batch_pb2.py index 446d019d3ec..8da165e9073 100644 --- a/cirq-google/cirq_google/api/v2/batch_pb2.py +++ b/cirq-google/cirq_google/api/v2/batch_pb2.py @@ -11,12 +11,11 @@ _sym_db = _symbol_database.Default() -from . import program_pb2 as cirq__google_dot_api_dot_v2_dot_program__pb2 from . import result_pb2 as cirq__google_dot_api_dot_v2_dot_result__pb2 from . import run_context_pb2 as cirq__google_dot_api_dot_v2_dot_run__context__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63irq_google/api/v2/batch.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/program.proto\x1a\x1f\x63irq_google/api/v2/result.proto\x1a$cirq_google/api/v2/run_context.proto\"G\n\x0f\x42\x61tchRunContext\x12\x34\n\x0crun_contexts\x18\x01 \x03(\x0b\x32\x1e.cirq.google.api.v2.RunContext\":\n\x0b\x42\x61tchResult\x12+\n\x07results\x18\x01 \x03(\x0b\x32\x1a.cirq.google.api.v2.ResultB-\n\x1d\x63om.google.cirq.google.api.v2B\nBatchProtoP\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63irq_google/api/v2/batch.proto\x12\x12\x63irq.google.api.v2\x1a\x1f\x63irq_google/api/v2/result.proto\x1a$cirq_google/api/v2/run_context.proto\"G\n\x0f\x42\x61tchRunContext\x12\x34\n\x0crun_contexts\x18\x01 \x03(\x0b\x32\x1e.cirq.google.api.v2.RunContext\":\n\x0b\x42\x61tchResult\x12+\n\x07results\x18\x01 \x03(\x0b\x32\x1a.cirq.google.api.v2.ResultB-\n\x1d\x63om.google.cirq.google.api.v2B\nBatchProtoP\x01\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.batch_pb2', globals()) @@ -24,8 +23,8 @@ DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\nBatchProtoP\001' - _BATCHRUNCONTEXT._serialized_start=159 - _BATCHRUNCONTEXT._serialized_end=230 - _BATCHRESULT._serialized_start=232 - _BATCHRESULT._serialized_end=290 + _BATCHRUNCONTEXT._serialized_start=125 + _BATCHRUNCONTEXT._serialized_end=196 + _BATCHRESULT._serialized_start=198 + _BATCHRESULT._serialized_end=256 # @@protoc_insertion_point(module_scope) From f711c0b14e2ca78b79ee23ab7c33050629f60e51 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 5 Feb 2024 20:33:24 +0000 Subject: [PATCH 05/23] coverage --- cirq-google/cirq_google/engine/engine.py | 40 ++----------------- cirq-google/cirq_google/engine/engine_test.py | 19 +++++++++ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine.py b/cirq-google/cirq_google/engine/engine.py index 6c1ab139828..d63cfefddf3 100644 --- a/cirq-google/cirq_google/engine/engine.py +++ b/cirq-google/cirq_google/engine/engine.py @@ -46,9 +46,7 @@ util, ) from cirq_google.cloud import quantum -from cirq_google.engine.result_type import ResultType from cirq_google.serialization import CIRCUIT_SERIALIZER, Serializer -from cirq_google.serialization.arg_func_langs import arg_to_proto if TYPE_CHECKING: import cirq_google @@ -648,23 +646,10 @@ async def create_batch_program_async( ) -> engine_program.EngineProgram: """Wraps a list of Circuits into a BatchProgram for the Quantum Engine. - Args: - programs: The Circuits to execute within a batch. - program_id: A user-provided identifier for the program. This must be - unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'prog-################YYMMDD' will be generated, where # is - alphanumeric and YYMMDD is the current year, month, and day. - description: An optional description to set on the program. - labels: Optional set of labels to set on the program. - - Returns: - A EngineProgram for the newly created program. - Raises: - ValueError: If no gate set is provided. + NotImplementedError: Batch programs are no longer supported by the Quantum Engine. """ - raise NotImplementedError('Batch programs are not yet supported by the Quantum Engine.') + raise NotImplementedError('Batch programs are no longer supported by the Quantum Engine.') create_batch_program = duet.sync(create_batch_program_async) @@ -677,28 +662,11 @@ async def create_calibration_program_async( ) -> engine_program.EngineProgram: """Wraps a list of calibration layers into an Any for Quantum Engine. - Args: - layers: The calibration routines to execute. All layers will be - executed within the same API call in the order specified, - though some layers may be interleaved together using - hardware-specific batching. - program_id: A user-provided identifier for the program. This must be - unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'calibration-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - description: An optional description to set on the program. - labels: Optional set of labels to set on the program. - - Returns: - A EngineProgram for the newly created program. - Raises: - ValueError: If not gate set is given. + NotImplementedError: Calibration programs are no longer supported on the Quantum Engine. """ raise NotImplementedError( - 'Calibration programs are not yet supported on the Quantum Engine.' + 'Calibration programs are no longer supported on the Quantum Engine.' ) create_calibration_program = duet.sync(create_calibration_program_async) diff --git a/cirq-google/cirq_google/engine/engine_test.py b/cirq-google/cirq_google/engine/engine_test.py index b5db2274337..4aec66fe3f9 100644 --- a/cirq-google/cirq_google/engine/engine_test.py +++ b/cirq-google/cirq_google/engine/engine_test.py @@ -767,6 +767,25 @@ def test_bad_sweep_proto(): program.run_sweep() +@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) +def test_run_calibration(client): + setup_run_circuit_with_result_(client, _CALIBRATION_RESULTS_V2) + + engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) + q1 = cirq.GridQubit(2, 3) + q2 = cirq.GridQubit(2, 4) + layer1 = cg.CalibrationLayer('xeb', cirq.Circuit(cirq.CZ(q1, q2)), {'num_layers': 42}) + layer2 = cg.CalibrationLayer( + 'readout', cirq.Circuit(cirq.measure(q1, q2)), {'num_samples': 4242} + ) + + with pytest.raises( + NotImplementedError, + match='Calibration programs are no longer supported on the Quantum Engine.', + ): + engine.run_calibration(layers=[layer1, layer2], job_id='job-id', processor_id='mysim') + + def test_run_calibration_validation_fails(): engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) q1 = cirq.GridQubit(2, 3) From 00d7d7106caa441197c1dc7411ebfd3adcb54e1a Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 5 Feb 2024 23:13:26 +0000 Subject: [PATCH 06/23] rm unused proto files --- cirq-google/cirq_google/api/v2/batch.proto | 44 --------- .../cirq_google/api/v2/calibration.proto | 93 ------------------- 2 files changed, 137 deletions(-) delete mode 100644 cirq-google/cirq_google/api/v2/batch.proto delete mode 100644 cirq-google/cirq_google/api/v2/calibration.proto diff --git a/cirq-google/cirq_google/api/v2/batch.proto b/cirq-google/cirq_google/api/v2/batch.proto deleted file mode 100644 index 1959b34cd10..00000000000 --- a/cirq-google/cirq_google/api/v2/batch.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -import "cirq_google/api/v2/result.proto"; -import "cirq_google/api/v2/run_context.proto"; - -package cirq.google.api.v2; - -option java_package = "com.google.cirq.google.api.v2"; -option java_outer_classname = "BatchProto"; -option java_multiple_files = true; - -// A batch of contexts for running a bundled batch of programs -// To be used in conjunction with BatchProgram -message BatchRunContext { - - // Run contexts for each program in the BatchProgram - // Each RunContext should map directly to a Program in the corresponding - // BatchProgram. - // - // This message must have one RunContext for each Program in the - // BatchProgram, and the order of the RunContext messages should - // match the order of the Programs in the BatchProgram. - repeated RunContext run_contexts = 1; -} - - -// The result returned from running a BatchProgram/BatchRunContext -message BatchResult { - - // Results returned from executing a BatchProgram/BatchRunContext pair. - // - // After a BatchProgram and BatchRunContext is successfully run in - // Quantum Engine, the expected result if successful will be a BatchResult. - // - // Each Result in this message will directly correspond to a Program/ - // RunContext pair in the request. There will be one Result in this message - // for each corresponding pair in the request and the order of the Results - // will match the order of the Programs from the request. - // - // In case of partial results, an empty (default) Result object will be - // populated for programs that were not able to be run correctly. - repeated Result results = 1; -} - diff --git a/cirq-google/cirq_google/api/v2/calibration.proto b/cirq-google/cirq_google/api/v2/calibration.proto deleted file mode 100644 index 5d057fef916..00000000000 --- a/cirq-google/cirq_google/api/v2/calibration.proto +++ /dev/null @@ -1,93 +0,0 @@ -syntax = "proto3"; - -import "cirq_google/api/v2/metrics.proto"; -import "cirq_google/api/v2/program.proto"; - -package cirq.google.api.v2; - -option java_package = "com.google.cirq.google.api.v2"; -option java_outer_classname = "FocusedCalibrationProto"; -option java_multiple_files = true; - - -// Each CalibrationLayer represents one invocation -// of a calibration procedure. -message CalibrationLayer { - // The type of the calibration procedure to execute. - // The value of this field must be in one of the acceptable - // values found in the cirq enum TBD. - // TODO(dstrain): Point to the cirq enum once it exists. - string calibration_type = 1; - - // A circuit that identifies the layer or circuit to optimize - // if the calibration requires this. For many calibrations, - // this will be a single moment representing the layer to - // optimize for. - Program layer = 2; - - // Arguments that can be specified to the calibration procedure, - // such as the number of layers, which angles to optimize, etc - map args = 3; -} - -// The results returned by a FocusedCalibration request. -message FocusedCalibrationResult { - - // The results of each CalibrationLayer request. - // There will be one CalibrationLayerResults message for each - // CalibrationLayer in the request, and the results will - // correspond to the order of the requests. - repeated CalibrationLayerResult results = 1; -} - -// Response codes for Calibration requests -enum CalibrationLayerCode { - - // Zero is a default value and means the value was unknown or unset. - CALIBRATION_RESULT_UNSPECIFIED = 0; - - // Successful run of the calibration. - SUCCESS = 1; - - // Miscellaenous errors not covered by the below conditions. - ERROR_OTHER = 2; - - // The parameters given to the calibration were not valid. - // For instance, multiple moments were given to a type of calibration - // that expects a single moment. - ERROR_INVALID_PARAMETERS = 3; - - // The calibration took too long and was aborted. - ERROR_TIMEOUT = 4; - - // The calibration failed for internal reasons. For instance, - // suitable device parameters could not be acheived or dependencies - // needed by the calibration did not exist. - ERROR_CALIBRATION_FAILED = 5; -} - - -message CalibrationLayerResult { - // Whether the calibration procedure was a success or failure. - CalibrationLayerCode code = 1; - - // On non-successful results, contains additional information - // about the details of the error. - string error_message = 2; - - // A token identifying the calibration result. - // If a token exists in the response, it can be used to tag - // focused circuits that use parameters - // derived from this calibration. - // If no token exists, then the calibration was purely diagnostic. - string token = 3; - - // Results, such as gate fidelities, gate angles, etc - // would be returned in a similar format to calibration metrics. - // This allows the return result to be easily extensible. - MetricsSnapshot metrics = 4; - - // Timestamp of when the calibration is valid until, specified as - // milliseconds since the Unix epoch time. - uint64 valid_until_ms = 5; -} From 0c4a9f8bd2997dfacff3203aaa7db3ee7f32a238 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 8 Feb 2024 18:15:22 +0000 Subject: [PATCH 07/23] rm proto files --- cirq-google/cirq_google/api/v2/batch_pb2.py | 30 -- cirq-google/cirq_google/api/v2/batch_pb2.pyi | 78 ------ cirq-google/cirq_google/api/v2/calibration | 14 - .../cirq_google/api/v2/calibration_pb2.py | 38 --- .../cirq_google/api/v2/calibration_pb2.pyi | 197 ------------- cirq-google/cirq_google/engine/engine.py | 121 -------- cirq-google/cirq_google/engine/engine_job.py | 25 +- .../cirq_google/engine/engine_job_test.py | 260 ------------------ .../cirq_google/engine/engine_program.py | 150 +--------- .../cirq_google/engine/engine_program_test.py | 134 --------- .../cirq_google/engine/engine_validator.py | 8 +- .../cirq_google/engine/simulated_local_job.py | 14 - .../engine/simulated_local_processor.py | 5 +- 13 files changed, 9 insertions(+), 1065 deletions(-) delete mode 100644 cirq-google/cirq_google/api/v2/batch_pb2.py delete mode 100644 cirq-google/cirq_google/api/v2/batch_pb2.pyi delete mode 100644 cirq-google/cirq_google/api/v2/calibration delete mode 100644 cirq-google/cirq_google/api/v2/calibration_pb2.py delete mode 100644 cirq-google/cirq_google/api/v2/calibration_pb2.pyi diff --git a/cirq-google/cirq_google/api/v2/batch_pb2.py b/cirq-google/cirq_google/api/v2/batch_pb2.py deleted file mode 100644 index 8da165e9073..00000000000 --- a/cirq-google/cirq_google/api/v2/batch_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: cirq_google/api/v2/batch.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import result_pb2 as cirq__google_dot_api_dot_v2_dot_result__pb2 -from . import run_context_pb2 as cirq__google_dot_api_dot_v2_dot_run__context__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1e\x63irq_google/api/v2/batch.proto\x12\x12\x63irq.google.api.v2\x1a\x1f\x63irq_google/api/v2/result.proto\x1a$cirq_google/api/v2/run_context.proto\"G\n\x0f\x42\x61tchRunContext\x12\x34\n\x0crun_contexts\x18\x01 \x03(\x0b\x32\x1e.cirq.google.api.v2.RunContext\":\n\x0b\x42\x61tchResult\x12+\n\x07results\x18\x01 \x03(\x0b\x32\x1a.cirq.google.api.v2.ResultB-\n\x1d\x63om.google.cirq.google.api.v2B\nBatchProtoP\x01\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.batch_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\nBatchProtoP\001' - _BATCHRUNCONTEXT._serialized_start=125 - _BATCHRUNCONTEXT._serialized_end=196 - _BATCHRESULT._serialized_start=198 - _BATCHRESULT._serialized_end=256 -# @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/batch_pb2.pyi b/cirq-google/cirq_google/api/v2/batch_pb2.pyi deleted file mode 100644 index ceaa2eb38f3..00000000000 --- a/cirq-google/cirq_google/api/v2/batch_pb2.pyi +++ /dev/null @@ -1,78 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import cirq_google.api.v2.result_pb2 -import cirq_google.api.v2.run_context_pb2 -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class BatchRunContext(google.protobuf.message.Message): - """A batch of contexts for running a bundled batch of programs - To be used in conjunction with BatchProgram - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RUN_CONTEXTS_FIELD_NUMBER: builtins.int - @property - def run_contexts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[cirq_google.api.v2.run_context_pb2.RunContext]: - """Run contexts for each program in the BatchProgram - Each RunContext should map directly to a Program in the corresponding - BatchProgram. - - This message must have one RunContext for each Program in the - BatchProgram, and the order of the RunContext messages should - match the order of the Programs in the BatchProgram. - """ - def __init__( - self, - *, - run_contexts: collections.abc.Iterable[cirq_google.api.v2.run_context_pb2.RunContext] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["run_contexts", b"run_contexts"]) -> None: ... - -global___BatchRunContext = BatchRunContext - -@typing_extensions.final -class BatchResult(google.protobuf.message.Message): - """The result returned from running a BatchProgram/BatchRunContext""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESULTS_FIELD_NUMBER: builtins.int - @property - def results(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[cirq_google.api.v2.result_pb2.Result]: - """Results returned from executing a BatchProgram/BatchRunContext pair. - - After a BatchProgram and BatchRunContext is successfully run in - Quantum Engine, the expected result if successful will be a BatchResult. - - Each Result in this message will directly correspond to a Program/ - RunContext pair in the request. There will be one Result in this message - for each corresponding pair in the request and the order of the Results - will match the order of the Programs from the request. - - In case of partial results, an empty (default) Result object will be - populated for programs that were not able to be run correctly. - """ - def __init__( - self, - *, - results: collections.abc.Iterable[cirq_google.api.v2.result_pb2.Result] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["results", b"results"]) -> None: ... - -global___BatchResult = BatchResult diff --git a/cirq-google/cirq_google/api/v2/calibration b/cirq-google/cirq_google/api/v2/calibration deleted file mode 100644 index 18b3ef417aa..00000000000 --- a/cirq-google/cirq_google/api/v2/calibration +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2024 smeeks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. - diff --git a/cirq-google/cirq_google/api/v2/calibration_pb2.py b/cirq-google/cirq_google/api/v2/calibration_pb2.py deleted file mode 100644 index c840c65a854..00000000000 --- a/cirq-google/cirq_google/api/v2/calibration_pb2.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: cirq_google/api/v2/calibration.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import metrics_pb2 as cirq__google_dot_api_dot_v2_dot_metrics__pb2 -from . import program_pb2 as cirq__google_dot_api_dot_v2_dot_program__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/calibration.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/metrics.proto\x1a cirq_google/api/v2/program.proto\"\xdc\x01\n\x10\x43\x61librationLayer\x12\x18\n\x10\x63\x61libration_type\x18\x01 \x01(\t\x12*\n\x05layer\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.Program\x12<\n\x04\x61rgs\x18\x03 \x03(\x0b\x32..cirq.google.api.v2.CalibrationLayer.ArgsEntry\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\"W\n\x18\x46ocusedCalibrationResult\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.cirq.google.api.v2.CalibrationLayerResult\"\xc4\x01\n\x16\x43\x61librationLayerResult\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0e\x32(.cirq.google.api.v2.CalibrationLayerCode\x12\x15\n\rerror_message\x18\x02 \x01(\t\x12\r\n\x05token\x18\x03 \x01(\t\x12\x34\n\x07metrics\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.MetricsSnapshot\x12\x16\n\x0evalid_until_ms\x18\x05 \x01(\x04*\xa7\x01\n\x14\x43\x61librationLayerCode\x12\"\n\x1e\x43\x41LIBRATION_RESULT_UNSPECIFIED\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x0f\n\x0b\x45RROR_OTHER\x10\x02\x12\x1c\n\x18\x45RROR_INVALID_PARAMETERS\x10\x03\x12\x11\n\rERROR_TIMEOUT\x10\x04\x12\x1c\n\x18\x45RROR_CALIBRATION_FAILED\x10\x05\x42:\n\x1d\x63om.google.cirq.google.api.v2B\x17\x46ocusedCalibrationProtoP\x01\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.calibration_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\027FocusedCalibrationProtoP\001' - _CALIBRATIONLAYER_ARGSENTRY._options = None - _CALIBRATIONLAYER_ARGSENTRY._serialized_options = b'8\001' - _CALIBRATIONLAYERCODE._serialized_start=640 - _CALIBRATIONLAYERCODE._serialized_end=807 - _CALIBRATIONLAYER._serialized_start=129 - _CALIBRATIONLAYER._serialized_end=349 - _CALIBRATIONLAYER_ARGSENTRY._serialized_start=281 - _CALIBRATIONLAYER_ARGSENTRY._serialized_end=349 - _FOCUSEDCALIBRATIONRESULT._serialized_start=351 - _FOCUSEDCALIBRATIONRESULT._serialized_end=438 - _CALIBRATIONLAYERRESULT._serialized_start=441 - _CALIBRATIONLAYERRESULT._serialized_end=637 -# @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/calibration_pb2.pyi b/cirq-google/cirq_google/api/v2/calibration_pb2.pyi deleted file mode 100644 index 4a9d75edaee..00000000000 --- a/cirq-google/cirq_google/api/v2/calibration_pb2.pyi +++ /dev/null @@ -1,197 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -""" -import builtins -import cirq_google.api.v2.metrics_pb2 -import cirq_google.api.v2.program_pb2 -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -class _CalibrationLayerCode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _CalibrationLayerCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CalibrationLayerCode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - CALIBRATION_RESULT_UNSPECIFIED: _CalibrationLayerCode.ValueType # 0 - """Zero is a default value and means the value was unknown or unset.""" - SUCCESS: _CalibrationLayerCode.ValueType # 1 - """Successful run of the calibration.""" - ERROR_OTHER: _CalibrationLayerCode.ValueType # 2 - """Miscellaenous errors not covered by the below conditions.""" - ERROR_INVALID_PARAMETERS: _CalibrationLayerCode.ValueType # 3 - """The parameters given to the calibration were not valid. - For instance, multiple moments were given to a type of calibration - that expects a single moment. - """ - ERROR_TIMEOUT: _CalibrationLayerCode.ValueType # 4 - """The calibration took too long and was aborted.""" - ERROR_CALIBRATION_FAILED: _CalibrationLayerCode.ValueType # 5 - """The calibration failed for internal reasons. For instance, - suitable device parameters could not be acheived or dependencies - needed by the calibration did not exist. - """ - -class CalibrationLayerCode(_CalibrationLayerCode, metaclass=_CalibrationLayerCodeEnumTypeWrapper): - """Response codes for Calibration requests""" - -CALIBRATION_RESULT_UNSPECIFIED: CalibrationLayerCode.ValueType # 0 -"""Zero is a default value and means the value was unknown or unset.""" -SUCCESS: CalibrationLayerCode.ValueType # 1 -"""Successful run of the calibration.""" -ERROR_OTHER: CalibrationLayerCode.ValueType # 2 -"""Miscellaenous errors not covered by the below conditions.""" -ERROR_INVALID_PARAMETERS: CalibrationLayerCode.ValueType # 3 -"""The parameters given to the calibration were not valid. -For instance, multiple moments were given to a type of calibration -that expects a single moment. -""" -ERROR_TIMEOUT: CalibrationLayerCode.ValueType # 4 -"""The calibration took too long and was aborted.""" -ERROR_CALIBRATION_FAILED: CalibrationLayerCode.ValueType # 5 -"""The calibration failed for internal reasons. For instance, -suitable device parameters could not be acheived or dependencies -needed by the calibration did not exist. -""" -global___CalibrationLayerCode = CalibrationLayerCode - -@typing_extensions.final -class CalibrationLayer(google.protobuf.message.Message): - """Each CalibrationLayer represents one invocation - of a calibration procedure. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - @typing_extensions.final - class ArgsEntry(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - KEY_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - key: builtins.str - @property - def value(self) -> cirq_google.api.v2.program_pb2.Arg: ... - def __init__( - self, - *, - key: builtins.str = ..., - value: cirq_google.api.v2.program_pb2.Arg | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... - - CALIBRATION_TYPE_FIELD_NUMBER: builtins.int - LAYER_FIELD_NUMBER: builtins.int - ARGS_FIELD_NUMBER: builtins.int - calibration_type: builtins.str - """The type of the calibration procedure to execute. - The value of this field must be in one of the acceptable - values found in the cirq enum TBD. - TODO(dstrain): Point to the cirq enum once it exists. - """ - @property - def layer(self) -> cirq_google.api.v2.program_pb2.Program: - """A circuit that identifies the layer or circuit to optimize - if the calibration requires this. For many calibrations, - this will be a single moment representing the layer to - optimize for. - """ - @property - def args(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, cirq_google.api.v2.program_pb2.Arg]: - """Arguments that can be specified to the calibration procedure, - such as the number of layers, which angles to optimize, etc - """ - def __init__( - self, - *, - calibration_type: builtins.str = ..., - layer: cirq_google.api.v2.program_pb2.Program | None = ..., - args: collections.abc.Mapping[builtins.str, cirq_google.api.v2.program_pb2.Arg] | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["layer", b"layer"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["args", b"args", "calibration_type", b"calibration_type", "layer", b"layer"]) -> None: ... - -global___CalibrationLayer = CalibrationLayer - -@typing_extensions.final -class FocusedCalibrationResult(google.protobuf.message.Message): - """The results returned by a FocusedCalibration request.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESULTS_FIELD_NUMBER: builtins.int - @property - def results(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CalibrationLayerResult]: - """The results of each CalibrationLayer request. - There will be one CalibrationLayerResults message for each - CalibrationLayer in the request, and the results will - correspond to the order of the requests. - """ - def __init__( - self, - *, - results: collections.abc.Iterable[global___CalibrationLayerResult] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["results", b"results"]) -> None: ... - -global___FocusedCalibrationResult = FocusedCalibrationResult - -@typing_extensions.final -class CalibrationLayerResult(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - CODE_FIELD_NUMBER: builtins.int - ERROR_MESSAGE_FIELD_NUMBER: builtins.int - TOKEN_FIELD_NUMBER: builtins.int - METRICS_FIELD_NUMBER: builtins.int - VALID_UNTIL_MS_FIELD_NUMBER: builtins.int - code: global___CalibrationLayerCode.ValueType - """Whether the calibration procedure was a success or failure.""" - error_message: builtins.str - """On non-successful results, contains additional information - about the details of the error. - """ - token: builtins.str - """A token identifying the calibration result. - If a token exists in the response, it can be used to tag - focused circuits that use parameters - derived from this calibration. - If no token exists, then the calibration was purely diagnostic. - """ - @property - def metrics(self) -> cirq_google.api.v2.metrics_pb2.MetricsSnapshot: - """Results, such as gate fidelities, gate angles, etc - would be returned in a similar format to calibration metrics. - This allows the return result to be easily extensible. - """ - valid_until_ms: builtins.int - """Timestamp of when the calibration is valid until, specified as - milliseconds since the Unix epoch time. - """ - def __init__( - self, - *, - code: global___CalibrationLayerCode.ValueType = ..., - error_message: builtins.str = ..., - token: builtins.str = ..., - metrics: cirq_google.api.v2.metrics_pb2.MetricsSnapshot | None = ..., - valid_until_ms: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["metrics", b"metrics"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["code", b"code", "error_message", b"error_message", "metrics", b"metrics", "token", b"token", "valid_until_ms", b"valid_until_ms"]) -> None: ... - -global___CalibrationLayerResult = CalibrationLayerResult diff --git a/cirq-google/cirq_google/engine/engine.py b/cirq-google/cirq_google/engine/engine.py index d63cfefddf3..f49407f112c 100644 --- a/cirq-google/cirq_google/engine/engine.py +++ b/cirq-google/cirq_google/engine/engine.py @@ -153,7 +153,6 @@ class Engine(abstract_engine.AbstractEngine): * create_program * run * run_sweep - * run_batch Another set of methods return information about programs and jobs that have been previously created on the Quantum Engine, as well as metadata @@ -414,110 +413,6 @@ async def run_sweep_async( run_sweep = duet.sync(run_sweep_async) - # TODO(#5996) Migrate to stream client - # TODO(#6271): Deprecate and remove processor_ids before v1.4 - async def run_batch_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - params_list: Optional[List[cirq.Sweepable]] = None, - repetitions: int = 1, - processor_ids: Sequence[str] = (), - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - *, - processor_id: str = "", - run_name: str = "", - device_config_name: str = "", - ) -> engine_job.EngineJob: - """Runs the supplied Circuits via Quantum Engine.Creates - - This will combine each Circuit provided in `programs` into - a BatchProgram. Each circuit will pair with the associated - parameter sweep provided in the `params_list`. The number of - programs is required to match the number of sweeps. - - This method does not block until a result is returned. However, - no results will be available until the entire batch is complete. - - Args: - programs: The Circuits to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'prog-################YYMMDD' will be generated, where # is - alphanumeric and YYMMDD is the current year, month, and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'job-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - params_list: Parameter sweeps to use with the circuits. The number - of sweeps should match the number of circuits and will be - paired in order with the circuits. If this is None, it is - assumed that the circuits are not parameterized and do not - require sweeps. - repetitions: Number of circuit repetitions to run. Each sweep value - of each circuit in the batch will run with the same repetitions. - processor_ids: Deprecated list of candidate processor ids to run the program. - Only allowed to contain one processor_id. If the argument `processor_id` - is non-empty, `processor_ids` will be ignored. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. - processor_id: Processor id for running the program. If not set, - `processor_ids` will be used. - run_name: A unique identifier representing an automation run for the - specified processor. An Automation Run contains a collection of - device configurations for a processor. If specified, `processor_id` - is required to be set. - device_config_name: An identifier used to select the processor configuration - utilized to run the job. A configuration identifies the set of - available qubits, couplers, and supported gates in the processor. - If specified, `processor_id` is required to be set. - - Returns: - An EngineJob. If this is iterated over it returns a list of - TrialResults. All TrialResults for the first circuit are listed - first, then the TrialResults for the second, etc. The TrialResults - for a circuit are listed in the order imposed by the associated - parameter sweep. - - Raises: - ValueError: If the length of programs mismatches that of params_list, or - `processor_ids` is not supplied. - ValueError: If neither `processor_id` or `processor_ids` are set. - ValueError: If only one of `run_name` and `device_config_name` are specified. - ValueError: If `processor_ids` has more than one processor id. - ValueError: If either `run_name` and `device_config_name` are set but - `processor_id` is empty. - """ - if params_list is None: - params_list = [None] * len(programs) - elif len(programs) != len(params_list): - raise ValueError('Number of circuits and sweeps must match') - if not processor_ids and not processor_id: - raise ValueError('Processor id must be specified.') - engine_program = await self.create_batch_program_async( - programs, program_id, description=program_description, labels=program_labels - ) - return await engine_program.run_batch_async( - job_id=job_id, - params_list=params_list, - repetitions=repetitions, - processor_ids=processor_ids, - description=job_description, - labels=job_labels, - processor_id=processor_id, - run_name=run_name, - device_config_name=device_config_name, - ) - - run_batch = duet.sync(run_batch_async) - # TODO(#5996) Migrate to stream client async def run_calibration_async( self, @@ -637,22 +532,6 @@ async def create_program_async( create_program = duet.sync(create_program_async) - async def create_batch_program_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - description: Optional[str] = None, - labels: Optional[Dict[str, str]] = None, - ) -> engine_program.EngineProgram: - """Wraps a list of Circuits into a BatchProgram for the Quantum Engine. - - Raises: - NotImplementedError: Batch programs are no longer supported by the Quantum Engine. - """ - raise NotImplementedError('Batch programs are no longer supported by the Quantum Engine.') - - create_batch_program = duet.sync(create_batch_program_async) - async def create_calibration_program_async( self, layers: List['cirq_google.CalibrationLayer'], diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index 7d3db35dd88..ebba4f12fa0 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -28,7 +28,6 @@ from cirq_google.api import v1, v2 if TYPE_CHECKING: - import datetime import cirq_google.engine.engine as engine_base from cirq_google.engine.engine import engine_program from cirq_google.engine.engine import engine_processor @@ -81,8 +80,7 @@ def __init__( job_id: Unique ID of the job within the parent program. context: Engine configuration and context to use. _job: The optional current job state. - result_type: What type of results are expected, such as - batched results or the result of a focused calibration. + result_type: What type of results are expected. job_result_future: A future to be completed when the job result is available. If set, EngineJob will await this future when a caller asks for the job result. If the future is completed with a `QuantumJob`, it is assumed that the job has failed. @@ -269,18 +267,6 @@ def delete(self) -> None: """Deletes the job and result, if any.""" self.context.client.delete_job(self.project_id, self.program_id, self.job_id) - async def batched_results_async(self) -> Sequence[Sequence[EngineResult]]: - """Returns the job results, blocking until the job is complete. - - This method is intended for batched jobs. Instead of flattening - results into a single list, this will return a Sequence[Result] - for each circuit in the batch. - """ - await self.results_async() - if self._batched_results is None: - raise ValueError('batched_results called for a non-batch result.') - return self._batched_results - async def results_async(self) -> Sequence[EngineResult]: """Returns the job results, blocking until the job is complete.""" import cirq_google.engine.engine as engine_base @@ -301,10 +287,6 @@ async def results_async(self) -> Sequence[EngineResult]: ): v2_parsed_result = v2.result_pb2.Result.FromString(result.value) self._results = self._get_job_results_v2(v2_parsed_result) - elif result.Is(v2.batch_pb2.BatchResult.DESCRIPTOR): - v2_parsed_result = v2.batch_pb2.BatchResult.FromString(result.value) - self._batched_results = self._get_batch_results_v2(v2_parsed_result) - self._results = _flatten(self._batched_results) else: raise ValueError(f'invalid result proto version: {result_type}') return self._results @@ -395,11 +377,6 @@ def _get_job_results_v2(self, result: v2.result_pb2.Result) -> Sequence[EngineRe for result in sweep_result ] - def _get_batch_results_v2( - self, results: v2.batch_pb2.BatchResult - ) -> Sequence[Sequence[EngineResult]]: - return [self._get_job_results_v2(result) for result in results.results] - def __str__(self) -> str: return ( f'EngineJob(project_id=\'{self.project_id}\', ' diff --git a/cirq-google/cirq_google/engine/engine_job_test.py b/cirq-google/cirq_google/engine/engine_job_test.py index 1786d2651be..83b05f48f44 100644 --- a/cirq-google/cirq_google/engine/engine_job_test.py +++ b/cirq-google/cirq_google/engine/engine_job_test.py @@ -271,65 +271,6 @@ def test_get_processor_no_processor(): assert not job.get_processor() -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_calibration') -def test_get_calibration(get_calibration): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus( - calibration_name='projects/a/processors/p/calibrations/123' - ) - ) - calibration = quantum.QuantumCalibration( - data=util.pack_any( - Merge( - """ - timestamp_ms: 123000, - metrics: [{ - name: 'xeb', - targets: ['0_0', '0_1'], - values: [{ - double_val: .9999 - }] - }, { - name: 't1', - targets: ['0_0'], - values: [{ - double_val: 321 - }] - }, { - name: 'globalMetric', - values: [{ - int32_val: 12300 - }] - }] -""", - v2.metrics_pb2.MetricsSnapshot(), - ) - ) - ) - get_calibration.return_value = calibration - - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - assert list(job.get_calibration()) == ['xeb', 't1', 'globalMetric'] - get_calibration.assert_called_once_with('a', 'p', 123) - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_calibration_async') -def test_calibration__with_no_calibration(get_calibration): - job = cg.EngineJob( - 'a', - 'b', - 'steve', - EngineContext(), - _job=quantum.QuantumJob( - name='projects/project-id/programs/test/jobs/test', - execution_status={'state': 'SUCCESS'}, - ), - ) - calibration = job.get_calibration() - assert not calibration - assert not get_calibration.called - - @mock.patch('cirq_google.engine.engine_client.EngineClient.cancel_job_async') def test_cancel(cancel_job): job = cg.EngineJob('a', 'b', 'steve', EngineContext()) @@ -391,117 +332,6 @@ def test_delete(delete_job): ) -BATCH_RESULTS = quantum.QuantumResult( - result=util.pack_any( - Merge( - """ -results: [{ - sweep_results: [{ - repetitions: 3, - parameterized_results: [{ - params: { - assignments: { - key: 'a' - value: 1 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\006' - }] - } - },{ - params: { - assignments: { - key: 'a' - value: 2 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\007' - }] - } - }] - }], - },{ - sweep_results: [{ - repetitions: 4, - parameterized_results: [{ - params: { - assignments: { - key: 'a' - value: 3 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\013' - }] - } - },{ - params: { - assignments: { - key: 'a' - value: 4 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\011' - }] - } - }] - }] -}] -""", - v2.batch_pb2.BatchResult(), - ) - ) -) - -CALIBRATION_RESULT = quantum.QuantumResult( - result=util.pack_any( - Merge( - """ -results: [{ - code: ERROR_CALIBRATION_FAILED - error_message: 'uh oh' - token: 'abc' - valid_until_ms: 1234567891000 - metrics: { - timestamp_ms: 1234567890000, - metrics: [{ - name: 'theta', - targets: ['0_0', '0_1'], - values: [{ - double_val: .9999 - }] - }] - } -}] -""", - v2.calibration_pb2.FocusedCalibrationResult(), - ) - ) -) - UPDATE_TIME = datetime.datetime.now(tz=datetime.timezone.utc) @@ -596,96 +426,6 @@ def test_receives_job_via_stream_raises_and_updates_underlying_job(): assert actual_error_message == expected_error_message -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') -def test_batched_results(get_job_results): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus(state=quantum.ExecutionStatus.State.SUCCESS), - update_time=UPDATE_TIME, - ) - get_job_results.return_value = BATCH_RESULTS - - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - data = job.results() - assert len(data) == 4 - assert str(data[0]) == 'q=011' - assert str(data[1]) == 'q=111' - assert str(data[2]) == 'q=1101' - assert str(data[3]) == 'q=1001' - get_job_results.assert_called_once_with('a', 'b', 'steve') - - data = job.batched_results() - assert len(data) == 2 - assert len(data[0]) == 2 - assert len(data[1]) == 2 - assert str(data[0][0]) == 'q=011' - assert str(data[0][1]) == 'q=111' - assert str(data[1][0]) == 'q=1101' - assert str(data[1][1]) == 'q=1001' - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') -def test_batched_results_not_a_batch(get_job_results): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus(state=quantum.ExecutionStatus.State.SUCCESS), - update_time=UPDATE_TIME, - ) - get_job_results.return_value = RESULTS - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - with pytest.raises(ValueError, match='batched_results'): - job.batched_results() - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') -def test_calibration_results(get_job_results): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus(state=quantum.ExecutionStatus.State.SUCCESS), - update_time=UPDATE_TIME, - ) - get_job_results.return_value = CALIBRATION_RESULT - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - data = job.calibration_results() - get_job_results.assert_called_once_with('a', 'b', 'steve') - assert len(data) == 1 - assert data[0].code == v2.calibration_pb2.ERROR_CALIBRATION_FAILED - assert data[0].error_message == 'uh oh' - assert data[0].token == 'abc' - assert data[0].valid_until.timestamp() == 1234567891 - assert len(data[0].metrics) - assert data[0].metrics['theta'] == {(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)): [0.9999]} - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') -def test_calibration_defaults(get_job_results): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus(state=quantum.ExecutionStatus.State.SUCCESS), - update_time=UPDATE_TIME, - ) - result = v2.calibration_pb2.FocusedCalibrationResult() - result.results.add() - get_job_results.return_value = quantum.QuantumResult(result=util.pack_any(result)) - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - data = job.calibration_results() - get_job_results.assert_called_once_with('a', 'b', 'steve') - assert len(data) == 1 - assert data[0].code == v2.calibration_pb2.CALIBRATION_RESULT_UNSPECIFIED - assert data[0].error_message is None - assert data[0].token is None - assert data[0].valid_until is None - assert len(data[0].metrics) == 0 - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') -def test_calibration_results_not_a_calibration(get_job_results): - qjob = quantum.QuantumJob( - execution_status=quantum.ExecutionStatus(state=quantum.ExecutionStatus.State.SUCCESS), - update_time=UPDATE_TIME, - ) - get_job_results.return_value = RESULTS - job = cg.EngineJob('a', 'b', 'steve', EngineContext(), _job=qjob) - with pytest.raises(ValueError, match='calibration results'): - job.calibration_results() - - @mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') def test_results_len(get_job_results): qjob = quantum.QuantumJob( diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index 675ba32afc9..19003fee140 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -111,7 +111,6 @@ async def run_sweep_async( TrialResults, one for each parameter sweep. Raises: - ValueError: If called on a program that is a batch of programs. ValueError: If a processor id hasn't been specified to run the job ValueError: If only one of `run_name` and `device_config_name` are specified. ValueError: If `processor_ids` has more than one processor id. @@ -120,8 +119,6 @@ async def run_sweep_async( """ import cirq_google.engine.engine as engine_base - if self.result_type != ResultType.Program: - raise ValueError('Please use run_batch() for batch mode.') if not job_id: job_id = engine_base._make_random_id('job-') run_context = self.context._serialize_run_context(params, repetitions) @@ -144,112 +141,6 @@ async def run_sweep_async( run_sweep = duet.sync(run_sweep_async) - # TODO(#6271): Deprecate and remove processor_ids before v1.4 - async def run_batch_async( - self, - job_id: Optional[str] = None, - params_list: Optional[List[cirq.Sweepable]] = None, - repetitions: int = 1, - processor_ids: Sequence[str] = (), - description: Optional[str] = None, - labels: Optional[Dict[str, str]] = None, - *, - processor_id: str = "", - run_name: str = "", - device_config_name: str = "", - ) -> engine_job.EngineJob: - """Runs a batch of circuits on the QuantumEngine. - - This method should only be used if the Program object was created - with a BatchProgram. The number of parameter sweeps should match - the number of circuits within that BatchProgram. - - This method does not block until a result is returned. However, - no results will be available until the entire batch is complete. - - Args: - job_id: Optional job id to use. If this is not provided, a random id - of the format 'job-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - params_list: Parameter sweeps to run with the program. There must - be one Sweepable object for each circuit in the batch. If this - is None, it is assumed that the circuits are not parameterized - and do not require sweeps. - repetitions: The number of circuit repetitions to run. - processor_ids: Deprecated list of candidate processor ids to run the program. - Only allowed to contain one processor_id. If the argument `processor_id` - is non-empty, `processor_ids` will be ignored. - description: An optional description to set on the job. - labels: Optional set of labels to set on the job. - processor_id: Processor id for running the program. If not set, - `processor_ids` will be used. - run_name: A unique identifier representing an automation run for the - specified processor. An Automation Run contains a collection of - device configurations for a processor. If specified, `processor_id` - is required to be set. - device_config_name: An identifier used to select the processor configuration - utilized to run the job. A configuration identifies the set of - available qubits, couplers, and supported gates in the processor. - If specified, `processor_id` is required to be set. - - Returns: - An EngineJob. If this is iterated over it returns a list of - TrialResults. All TrialResults for the first circuit are listed - first, then the TrialResults for the second, etc. The TrialResults - for a circuit are listed in the order imposed by the associated - parameter sweep. - - Raises: - ValueError: if the program was not a batch program or no processors - were supplied. - Raises: - ValueError: If neither `processor_id` or `processor_ids` are set. - ValueError: If only one of `run_name` and `device_config_name` are specified. - ValueError: If `processor_ids` has more than one processor id. - ValueError: If either `run_name` and `device_config_name` are set but - `processor_id` is empty. - - """ - import cirq_google.engine.engine as engine_base - - if self.result_type != ResultType.Batch: - raise ValueError('Can only use run_batch() in batch mode.') - if params_list is None: - params_list = [None] * self.batch_size() - if not job_id: - job_id = engine_base._make_random_id('job-') - if not processor_ids and not processor_id: - raise ValueError('No processors specified') - - # Pack the run contexts into batches - batch_context = v2.batch_run_context_to_proto( - (params, repetitions) for params in params_list - ) - - created_job_id, job = await self.context.client.create_job_async( - project_id=self.project_id, - program_id=self.program_id, - job_id=job_id, - processor_ids=processor_ids, - run_context=util.pack_any(batch_context), - description=description, - labels=labels, - processor_id=processor_id, - run_name=run_name, - device_config_name=device_config_name, - ) - return engine_job.EngineJob( - self.project_id, - self.program_id, - created_job_id, - self.context, - job, - result_type=ResultType.Batch, - ) - - run_batch = duet.sync(run_batch_async) - async def run_calibration_async( self, job_id: Optional[str] = None, @@ -543,8 +434,8 @@ async def get_circuit_async(self, program_num: Optional[int] = None) -> cirq.Cir supported if the program was created with the V2 protos. Args: - program_num: if this is a batch program, the index of the circuit in - the batch. This argument is zero-indexed. Negative values + program_num: + The program number to retrieve. This argument is zero-indexed. Negative values indexing from the end of the list. Returns: @@ -558,31 +449,6 @@ async def get_circuit_async(self, program_num: Optional[int] = None) -> cirq.Cir get_circuit = duet.sync(get_circuit_async) - async def batch_size_async(self) -> int: - """Returns the number of programs in a batch program. - - Raises: - ValueError: if the program created was not a batch program. - """ - if self.result_type != ResultType.Batch: - raise ValueError( - f'Program was not a batch program but instead was of type {self.result_type}.' - ) - import cirq_google.engine.engine as engine_base - - if self._program is None or self._program.code is None: - self._program = await self.context.client.get_program_async( - self.project_id, self.program_id, True - ) - code = self._program.code - code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] - if code_type == 'cirq.google.api.v2.BatchProgram': - batch = v2.batch_pb2.BatchProgram.FromString(code.value) - return len(batch.programs) - raise ValueError(f'Program was not a batch program but instead was of type {code_type}.') - - batch_size = duet.sync(batch_size_async) - async def delete_async(self, delete_jobs: bool = False) -> None: """Deletes a previously created quantum program. @@ -615,18 +481,6 @@ def _deserialize_program(code: any_pb2.Any, program_num: Optional[int] = None) - raise ValueError('deserializing a v1 Program is not supported') elif code_type == 'cirq.google.api.v2.Program' or code_type == 'cirq.api.google.v2.Program': program = v2.program_pb2.Program.FromString(code.value) - elif code_type == 'cirq.google.api.v2.BatchProgram': - if program_num is None: - raise ValueError( - 'A program number must be specified when deserializing a Batch Program' - ) - batch = v2.batch_pb2.BatchProgram.FromString(code.value) - if abs(program_num) >= len(batch.programs): - raise ValueError( - f'Only {len(batch.programs)} in the batch but index {program_num} was specified' - ) - - program = batch.programs[program_num] if program is not None: return circuit_serializer.CIRCUIT_SERIALIZER.deserialize(program) diff --git a/cirq-google/cirq_google/engine/engine_program_test.py b/cirq-google/cirq_google/engine/engine_program_test.py index c661c9776f0..423ef7abfcc 100644 --- a/cirq-google/cirq_google/engine/engine_program_test.py +++ b/cirq-google/cirq_google/engine/engine_program_test.py @@ -28,56 +28,6 @@ from cirq_google.engine.engine import EngineContext from cirq_google.engine.result_type import ResultType -_BATCH_PROGRAM_V2 = util.pack_any( - Merge( - """programs { language { - gate_set: "v2_5" - arg_function_language: "exp" -} -circuit { - scheduling_strategy: MOMENT_BY_MOMENT - moments { - operations { - qubit_constant_index: 0 - phasedxpowgate { - phase_exponent { - float_value: 0.0 - } - exponent { - float_value: 0.5 - } - } - } - } - moments { - operations { - qubit_constant_index: 0 - measurementgate { - key { - arg_value { - string_value: "result" - } - } - invert_mask { - arg_value { - bool_values { - } - } - } - } - } - } -} -constants { - qubit { - id: "5_2" - } -} -} -""", - v2.batch_pb2.BatchProgram(), - ) -) _PROGRAM_V2 = util.pack_any( Merge( @@ -168,47 +118,6 @@ def test_run_calibration_no_processors(create_job_async): _ = program.run_calibration(job_id='spot') -@mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') -def test_run_batch_no_sweeps(create_job_async): - # Running with no sweeps is fine. Uses program's batch size to create - # proper empty sweeps. - create_job_async.return_value = ('kittens', quantum.QuantumJob()) - program = cg.EngineProgram( - 'my-meow', - 'my-meow', - _program=quantum.QuantumProgram(code=_BATCH_PROGRAM_V2), - context=EngineContext(), - result_type=ResultType.Batch, - ) - job = program.run_batch(job_id='steve', repetitions=10, processor_ids=['lazykitty']) - assert job._job == quantum.QuantumJob() - batch_run_context = v2.batch_pb2.BatchRunContext() - create_job_async.call_args[1]['run_context'].Unpack(batch_run_context) - assert len(batch_run_context.run_contexts) == 1 - - -def test_run_batch_no_processors(): - program = cg.EngineProgram('no-meow', 'no-meow', EngineContext(), result_type=ResultType.Batch) - resolver_list = [cirq.Points('cats', [1.0, 2.0]), cirq.Points('cats', [3.0, 4.0])] - with pytest.raises(ValueError, match='No processors specified'): - _ = program.run_batch(repetitions=1, params_list=resolver_list) - - -def test_run_batch_not_in_batch_mode(): - program = cg.EngineProgram('no-meow', 'no-meow', EngineContext()) - resolver_list = [cirq.Points('cats', [1.0, 2.0, 3.0]), cirq.Points('cats', [4.0, 5.0, 6.0])] - with pytest.raises(ValueError, match='Can only use run_batch'): - _ = program.run_batch(repetitions=1, processor_ids=['lazykitty'], params_list=resolver_list) - - -def test_run_in_batch_mode(): - program = cg.EngineProgram('no-meow', 'no-meow', EngineContext(), result_type=ResultType.Batch) - with pytest.raises(ValueError, match='Please use run_batch'): - _ = program.run_sweep( - repetitions=1, processor_ids=['lazykitty'], params=cirq.Points('cats', [1.0, 2.0, 3.0]) - ) - - @mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') @mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') def test_run_delegation(create_job_async, get_results_async): @@ -418,49 +327,6 @@ def test_get_circuit_v2(get_program_async): get_program_async.assert_called_once_with('a', 'b', True) -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_program_async') -def test_get_circuit_batch(get_program_async): - circuit = cirq.Circuit( - cirq.X(cirq.GridQubit(5, 2)) ** 0.5, cirq.measure(cirq.GridQubit(5, 2), key='result') - ) - - program = cg.EngineProgram('a', 'b', EngineContext()) - get_program_async.return_value = quantum.QuantumProgram(code=_BATCH_PROGRAM_V2) - with pytest.raises(ValueError, match='A program number must be specified'): - program.get_circuit() - with pytest.raises(ValueError, match='Only 1 in the batch but index 1 was specified'): - program.get_circuit(1) - assert program.get_circuit(0) == circuit - get_program_async.assert_called_once_with('a', 'b', True) - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_program_async') -def test_get_batch_size(get_program_async): - # Has to fetch from engine if not _program specified. - program = cg.EngineProgram('a', 'b', EngineContext(), result_type=ResultType.Batch) - get_program_async.return_value = quantum.QuantumProgram(code=_BATCH_PROGRAM_V2) - assert program.batch_size() == 1 - - # If _program specified, uses that value. - program = cg.EngineProgram( - 'a', - 'b', - EngineContext(), - _program=quantum.QuantumProgram(code=_BATCH_PROGRAM_V2), - result_type=ResultType.Batch, - ) - assert program.batch_size() == 1 - - with pytest.raises(ValueError, match='ResultType.Program'): - program = cg.EngineProgram('a', 'b', EngineContext(), result_type=ResultType.Program) - _ = program.batch_size() - - with pytest.raises(ValueError, match='cirq.google.api.v2.Program'): - get_program_async.return_value = quantum.QuantumProgram(code=_PROGRAM_V2) - program = cg.EngineProgram('a', 'b', EngineContext(), result_type=ResultType.Batch) - _ = program.batch_size() - - @pytest.fixture(scope='module', autouse=True) def mock_grpc_client(): with mock.patch( diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index 6d0ace5f2cf..9e6ebae1208 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -12,19 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Callable, Sequence, Union -from google.protobuf import any_pb2 import cirq from cirq_google.engine.validating_sampler import VALIDATOR_TYPE from cirq_google.serialization.serializer import Serializer -from cirq_google.api import v2 + MAX_MESSAGE_SIZE = 10_000_000 MAX_MOMENTS = 10000 MAX_TOTAL_REPETITIONS = 5_000_000 PROGRAM_VALIDATOR_TYPE = Callable[ - [Sequence[cirq.AbstractCircuit], Sequence[cirq.Sweepable], int, 'Serializer'], None, + [Sequence[cirq.AbstractCircuit], Sequence[cirq.Sweepable], int, 'Serializer'], None ] @@ -87,6 +86,8 @@ def validate_program( Raises: RuntimeError: if compiled proto is above the maximum size. """ + pass + """ batch = v2.batch_pb2.BatchProgram() packed = any_pb2.Any() for circuit in circuits: @@ -95,6 +96,7 @@ def validate_program( message_size = len(packed.SerializeToString()) if message_size > max_size: raise RuntimeError("INVALID_PROGRAM: Program too long.") + """ def create_program_validator(max_size: int = MAX_MESSAGE_SIZE) -> PROGRAM_VALIDATOR_TYPE: diff --git a/cirq-google/cirq_google/engine/simulated_local_job.py b/cirq-google/cirq_google/engine/simulated_local_job.py index e8d58838edd..de92a0bf25a 100644 --- a/cirq-google/cirq_google/engine/simulated_local_job.py +++ b/cirq-google/cirq_google/engine/simulated_local_job.py @@ -114,20 +114,6 @@ def delete(self) -> None: self.program().delete_job(self.id()) self._state = quantum.ExecutionStatus.State.STATE_UNSPECIFIED - async def batched_results_async(self) -> Sequence[Sequence[EngineResult]]: - """Returns the job results, blocking until the job is complete. - - This method is intended for batched jobs. Instead of flattening - results into a single list, this will return a Sequence[Result] - for each circuit in the batch. - """ - if self._type == LocalSimulationType.SYNCHRONOUS: - return self._execute_results() - elif self._type == LocalSimulationType.ASYNCHRONOUS: - return await self._future - else: - raise ValueError('Unsupported simulation type {self._type}') - def _execute_results(self) -> Sequence[Sequence[EngineResult]]: """Executes the circuit and sweeps on the sampler. diff --git a/cirq-google/cirq_google/engine/simulated_local_processor.py b/cirq-google/cirq_google/engine/simulated_local_processor.py index 98307140ffd..096da811225 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor.py @@ -29,10 +29,7 @@ from cirq_google.engine.processor_sampler import ProcessorSampler from cirq_google.engine import engine_validator -VALID_LANGUAGES = [ - 'type.googleapis.com/cirq.google.api.v2.Program', - 'type.googleapis.com/cirq.google.api.v2.BatchProgram', -] +VALID_LANGUAGES = ['type.googleapis.com/cirq.google.api.v2.Program'] def _date_to_timestamp( From b63a6c930e0ff215ead11ffd85bb371c8635ae38 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 8 Feb 2024 18:38:56 +0000 Subject: [PATCH 08/23] rm deps --- cirq-google/cirq_google/api/v2/__init__.py | 17 +- cirq-google/cirq_google/api/v2/sweeps.py | 40 +--- cirq-google/cirq_google/api/v2/sweeps_test.py | 31 --- cirq-google/cirq_google/engine/engine_test.py | 205 ------------------ .../engine/engine_validator_test.py | 29 --- .../engine/simulated_local_processor.py | 40 +--- .../engine/simulated_local_processor_test.py | 18 -- 7 files changed, 13 insertions(+), 367 deletions(-) diff --git a/cirq-google/cirq_google/api/v2/__init__.py b/cirq-google/cirq_google/api/v2/__init__.py index 2d4bdacacaf..cd601d52764 100644 --- a/cirq-google/cirq_google/api/v2/__init__.py +++ b/cirq-google/cirq_google/api/v2/__init__.py @@ -13,15 +13,7 @@ # limitations under the License. """Data format v2 for google api.""" -from cirq_google.api.v2 import ( - batch_pb2, - calibration_pb2, - device_pb2, - metrics_pb2, - program_pb2, - result_pb2, - run_context_pb2, -) +from cirq_google.api.v2 import device_pb2, metrics_pb2, program_pb2, result_pb2, run_context_pb2 from cirq_google.api.v2.program import ( grid_qubit_from_proto_id, @@ -40,9 +32,4 @@ results_to_proto, ) -from cirq_google.api.v2.sweeps import ( - batch_run_context_to_proto, - run_context_to_proto, - sweep_from_proto, - sweep_to_proto, -) +from cirq_google.api.v2.sweeps import run_context_to_proto, sweep_from_proto, sweep_to_proto diff --git a/cirq-google/cirq_google/api/v2/sweeps.py b/cirq-google/cirq_google/api/v2/sweeps.py index 6a6e1738424..cd25d234fef 100644 --- a/cirq-google/cirq_google/api/v2/sweeps.py +++ b/cirq-google/cirq_google/api/v2/sweeps.py @@ -17,7 +17,6 @@ import sympy import cirq -from cirq_google.api.v2 import batch_pb2 from cirq_google.api.v2 import run_context_pb2 from cirq_google.study.device_parameter import DeviceParameter @@ -106,12 +105,16 @@ def sweep_from_proto(msg: run_context_pb2.Sweep) -> cirq.Sweep: if msg.single_sweep.HasField("parameter"): metadata = DeviceParameter( path=msg.single_sweep.parameter.path, - idx=msg.single_sweep.parameter.idx - if msg.single_sweep.parameter.HasField("idx") - else None, - units=msg.single_sweep.parameter.units - if msg.single_sweep.parameter.HasField("units") - else None, + idx=( + msg.single_sweep.parameter.idx + if msg.single_sweep.parameter.HasField("idx") + else None + ), + units=( + msg.single_sweep.parameter.units + if msg.single_sweep.parameter.HasField("units") + else None + ), ) else: metadata = None @@ -152,26 +155,3 @@ def run_context_to_proto( sweep_proto.repetitions = repetitions sweep_to_proto(sweep, out=sweep_proto.sweep) return out - - -def batch_run_context_to_proto( - sweepables_and_reps: Iterable[Tuple[cirq.Sweepable, int]], - *, - out: Optional[batch_pb2.BatchRunContext] = None, -) -> batch_pb2.BatchRunContext: - """Populates a BatchRunContext protobuf message. - - Args: - sweepables_and_reps: Iterable over tuples of (sweepable, repetitions), one - for each run context in the batch. - out: Optional message to be populated. If not given, a new message will - be created. - - Returns: - Populated BatchRunContext protobuf message. - """ - if out is None: - out = batch_pb2.BatchRunContext() - for sweepable, reps in sweepables_and_reps: - run_context_to_proto(sweepable, reps, out=out.run_contexts.add()) - return out diff --git a/cirq-google/cirq_google/api/v2/sweeps_test.py b/cirq-google/cirq_google/api/v2/sweeps_test.py index 30a44573d39..53de71d8807 100644 --- a/cirq-google/cirq_google/api/v2/sweeps_test.py +++ b/cirq-google/cirq_google/api/v2/sweeps_test.py @@ -197,34 +197,3 @@ def test_run_context_to_proto(pass_out: bool) -> None: assert len(out.parameter_sweeps) == 1 assert v2.sweep_from_proto(out.parameter_sweeps[0].sweep) == sweep assert out.parameter_sweeps[0].repetitions == 100 - - -@pytest.mark.parametrize('pass_out', [False, True]) -def test_batch_run_context_to_proto(pass_out: bool) -> None: - msg = v2.batch_pb2.BatchRunContext() if pass_out else None - out = v2.batch_run_context_to_proto([], out=msg) - if pass_out: - assert out is msg - assert len(out.run_contexts) == 0 - - msg = v2.batch_pb2.BatchRunContext() if pass_out else None - out = v2.batch_run_context_to_proto([(None, 10)], out=msg) - if pass_out: - assert out is msg - assert len(out.run_contexts) == 1 - sweep_message = out.run_contexts[0].parameter_sweeps[0] - assert v2.sweep_from_proto(sweep_message.sweep) == cirq.UnitSweep - assert sweep_message.repetitions == 10 - - sweep = cirq.Linspace('a', 0, 1, 21) - msg = v2.batch_pb2.BatchRunContext() if pass_out else None - out = v2.batch_run_context_to_proto([(None, 10), (sweep, 100)], out=msg) - if pass_out: - assert out is msg - assert len(out.run_contexts) == 2 - sweep_message0 = out.run_contexts[0].parameter_sweeps[0] - assert v2.sweep_from_proto(sweep_message0.sweep) == cirq.UnitSweep - assert sweep_message0.repetitions == 10 - sweep_message1 = out.run_contexts[1].parameter_sweeps[0] - assert v2.sweep_from_proto(sweep_message1.sweep) == sweep - assert sweep_message1.repetitions == 100 diff --git a/cirq-google/cirq_google/engine/engine_test.py b/cirq-google/cirq_google/engine/engine_test.py index 4aec66fe3f9..9340677fb70 100644 --- a/cirq-google/cirq_google/engine/engine_test.py +++ b/cirq-google/cirq_google/engine/engine_test.py @@ -153,114 +153,6 @@ def _to_timestamp(json_string): ) ) -_BATCH_RESULTS_V2 = util.pack_any( - Merge( - """ -results: [{ - sweep_results: [{ - repetitions: 1, - parameterized_results: [{ - params: { - assignments: { - key: 'a' - value: 1 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\000\001' - }] - } - },{ - params: { - assignments: { - key: 'a' - value: 2 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\000\001' - }] - } - }] - }], - },{ - sweep_results: [{ - repetitions: 1, - parameterized_results: [{ - params: { - assignments: { - key: 'a' - value: 3 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\000\001' - }] - } - },{ - params: { - assignments: { - key: 'a' - value: 4 - } - }, - measurement_results: { - key: 'q' - qubit_measurement_results: [{ - qubit: { - id: '1_1' - } - results: '\000\001' - }] - } - }] - }] -}] -""", - v2.batch_pb2.BatchResult(), - ) -) - - -_CALIBRATION_RESULTS_V2 = util.pack_any( - Merge( - """ -results: [{ - code: 1 - error_message: 'First success' - token: 'abc123' - metrics: { - metrics: [{ - name: 'fidelity' - targets: ['q2_3','q2_4'] - values: [{ - double_val: 0.75 - }] - }]} - },{ - code: 1 - error_message: 'Second success' -}] -""", - v2.calibration_pb2.FocusedCalibrationResult(), - ) -) - def test_make_random_id(): with mock.patch('random.choice', return_value='A'): @@ -737,29 +629,6 @@ def test_run_sweep_v2_with_stream_rpcs(client): assert sweeps[0].sweep.single_sweep.points.points == [1, 2] -def test_batch_size_validation_fails(): - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - - with pytest.raises(ValueError, match='Number of circuits and sweeps'): - _ = engine.run_batch( - programs=[_CIRCUIT, _CIRCUIT2], - job_id='job-id', - params_list=[ - cirq.Points('a', [1, 2]), - cirq.Points('a', [3, 4]), - cirq.Points('a', [5, 6]), - ], - processor_ids=['mysim'], - ) - - with pytest.raises(ValueError, match='Processor id must be specified'): - _ = engine.run_batch( - programs=[_CIRCUIT, _CIRCUIT2], - job_id='job-id', - params_list=[cirq.Points('a', [1, 2]), cirq.Points('a', [3, 4])], - ) - - def test_bad_sweep_proto(): engine = cg.Engine(project_id='project-id', proto_version=cg.ProtoVersion.UNDEFINED) program = cg.EngineProgram('proj', 'prog', engine.context) @@ -767,43 +636,6 @@ def test_bad_sweep_proto(): program.run_sweep() -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_calibration(client): - setup_run_circuit_with_result_(client, _CALIBRATION_RESULTS_V2) - - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - q1 = cirq.GridQubit(2, 3) - q2 = cirq.GridQubit(2, 4) - layer1 = cg.CalibrationLayer('xeb', cirq.Circuit(cirq.CZ(q1, q2)), {'num_layers': 42}) - layer2 = cg.CalibrationLayer( - 'readout', cirq.Circuit(cirq.measure(q1, q2)), {'num_samples': 4242} - ) - - with pytest.raises( - NotImplementedError, - match='Calibration programs are no longer supported on the Quantum Engine.', - ): - engine.run_calibration(layers=[layer1, layer2], job_id='job-id', processor_id='mysim') - - -def test_run_calibration_validation_fails(): - engine = cg.Engine(project_id='proj', proto_version=cg.engine.engine.ProtoVersion.V2) - q1 = cirq.GridQubit(2, 3) - q2 = cirq.GridQubit(2, 4) - layer1 = cg.CalibrationLayer('xeb', cirq.Circuit(cirq.CZ(q1, q2)), {'num_layers': 42}) - layer2 = cg.CalibrationLayer( - 'readout', cirq.Circuit(cirq.measure(q1, q2)), {'num_samples': 4242} - ) - - with pytest.raises(ValueError, match='Processor id must be specified'): - _ = engine.run_calibration(layers=[layer1, layer2], job_id='job-id') - - with pytest.raises(ValueError, match='processor_id and processor_ids'): - _ = engine.run_calibration( - layers=[layer1, layer2], processor_ids=['mysim'], processor_id='mysim', job_id='job-id' - ) - - @mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) def test_bad_result_proto(client): result = any_pb2.Any() @@ -995,40 +827,3 @@ def test_get_engine_device(get_processor): device.validate_operation(cirq.H(cirq.GridQubit(0, 0))) with pytest.raises(ValueError): device.validate_operation(cirq.CZ(cirq.GridQubit(1, 1), cirq.GridQubit(2, 2))) - - -_CALIBRATION = quantum.QuantumCalibration( - name='projects/a/processors/p/calibrations/1562715599', - timestamp=_to_timestamp('2019-07-09T23:39:59Z'), - data=util.pack_any( - Merge( - """ - timestamp_ms: 1562544000021, - metrics: [ - { - name: 't1', - targets: ['0_0'], - values: [{ - double_val: 321 - }] - }, { - name: 'globalMetric', - values: [{ - int32_val: 12300 - }] - }] -""", - v2.metrics_pb2.MetricsSnapshot(), - ) - ), -) - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.get_current_calibration') -def test_get_engine_calibration(get_current_calibration): - get_current_calibration.return_value = _CALIBRATION - calibration = cirq_google.get_engine_calibration('rainbow', 'project') - assert calibration.timestamp == 1562544000021 - assert set(calibration.keys()) == {'t1', 'globalMetric'} - assert calibration['t1'][(cirq.GridQubit(0, 0),)] == [321.0] - get_current_calibration.assert_called_once_with('project', 'rainbow') diff --git a/cirq-google/cirq_google/engine/engine_validator_test.py b/cirq-google/cirq_google/engine/engine_validator_test.py index 27788bf0ae3..df574b2c758 100644 --- a/cirq-google/cirq_google/engine/engine_validator_test.py +++ b/cirq-google/cirq_google/engine/engine_validator_test.py @@ -37,35 +37,6 @@ def _big_circuit(num_cycles: int) -> cirq.Circuit: return c -def test_validate_gate_set(): - circuit = _big_circuit(4) - - engine_validator.validate_program( - [circuit] * 5, [{}] * 5, 1000, cg.CIRCUIT_SERIALIZER, max_size=30000 - ) - - with pytest.raises(RuntimeError, match='Program too long'): - engine_validator.validate_program( - [circuit] * 10, [{}] * 10, 1000, cg.CIRCUIT_SERIALIZER, max_size=30000 - ) - - with pytest.raises(RuntimeError, match='Program too long'): - engine_validator.validate_program( - [circuit] * 5, [{}] * 5, 1000, cg.CIRCUIT_SERIALIZER, max_size=10000 - ) - - -def test_create_gate_set_validator(): - circuit = _big_circuit(4) - - smaller_size_validator = engine_validator.create_program_validator(max_size=10000) - smaller_size_validator([circuit] * 2, [{}] * 2, 1000, cg.CIRCUIT_SERIALIZER) - with pytest.raises(RuntimeError, match='Program too long'): - smaller_size_validator([circuit] * 5, [{}] * 5, 1000, cg.CIRCUIT_SERIALIZER) - larger_size_validator = engine_validator.create_program_validator(max_size=500000) - larger_size_validator([circuit] * 10, [{}] * 10, 1000, cg.CIRCUIT_SERIALIZER) - - def test_validate_for_engine(): circuit = _big_circuit(4) long_circuit = cirq.Circuit([cirq.X(cirq.GridQubit(0, 0))] * 10001) diff --git a/cirq-google/cirq_google/engine/simulated_local_processor.py b/cirq-google/cirq_google/engine/simulated_local_processor.py index 096da811225..a395edf36b0 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor.py @@ -13,7 +13,7 @@ # limitations under the License. import datetime -from typing import Dict, List, Optional, Sequence, Union +from typing import Dict, List, Optional, Union import cirq @@ -196,44 +196,6 @@ def get_program(self, program_id: str) -> AbstractProgram: """ return self._programs[program_id] - async def run_batch_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - params_list: Optional[Sequence[cirq.Sweepable]] = None, - repetitions: int = 1, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - run_name: str = "", - device_config_name: str = "", - ) -> SimulatedLocalJob: - if program_id is None: - program_id = self._create_id(id_type='program') - if job_id is None: - job_id = self._create_id(id_type='job') - self._program_validator(programs, params_list or [{}], repetitions, CIRCUIT_SERIALIZER) - self._programs[program_id] = SimulatedLocalProgram( - program_id=program_id, - simulation_type=self._simulation_type, - circuits=programs, - engine=self.engine(), - processor=self, - ) - job = SimulatedLocalJob( - job_id=job_id, - processor_id=self.processor_id, - parent_program=self._programs[program_id], - repetitions=repetitions, - sweeps=list(params_list) if params_list is not None else None, - sampler=self._sampler, - simulation_type=self._simulation_type, - ) - self._programs[program_id].add_job(job_id, job) - return job - async def run_sweep_async( self, program: cirq.AbstractCircuit, diff --git a/cirq-google/cirq_google/engine/simulated_local_processor_test.py b/cirq-google/cirq_google/engine/simulated_local_processor_test.py index 74b40951c17..d0ec70d1cfd 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor_test.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor_test.py @@ -160,24 +160,6 @@ def test_run_sweep(): assert job.execution_status() == quantum.ExecutionStatus.State.SUCCESS -def test_run_batch(): - q = cirq.GridQubit(5, 4) - proc = SimulatedLocalProcessor(processor_id='test_proc') - circuits = [ - cirq.Circuit(cirq.X(q) ** sympy.Symbol('t'), cirq.measure(q, key='m')), - cirq.Circuit(cirq.X(q) ** sympy.Symbol('x'), cirq.measure(q, key='m2')), - ] - sweeps = [cirq.Points(key='t', points=[1, 0]), cirq.Points(key='x', points=[0, 1])] - job = proc.run_batch(circuits, params_list=sweeps, repetitions=100) - assert job.execution_status() == quantum.ExecutionStatus.State.READY - results = job.batched_results() - assert np.all(results[0][0].measurements['m'] == 1) - assert np.all(results[0][1].measurements['m'] == 0) - assert np.all(results[1][0].measurements['m2'] == 0) - assert np.all(results[1][1].measurements['m2'] == 1) - assert job.execution_status() == quantum.ExecutionStatus.State.SUCCESS - - def _no_y_gates(circuits: List[cirq.Circuit], sweeps: List[cirq.Sweepable], repetitions: int): for circuit in circuits: for moment in circuit: From 5f8a7a06416b3022456ebc5b09f9b6a535cac410 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 8 Feb 2024 19:25:44 +0000 Subject: [PATCH 09/23] all tests pass --- .../cirq_google/engine/abstract_job.py | 11 --- .../cirq_google/engine/abstract_job_test.py | 3 - .../engine/abstract_local_job_test.py | 3 - .../cirq_google/engine/engine_program.py | 22 ++++++ .../cirq_google/engine/engine_program_test.py | 11 --- .../engine/simulated_local_job_test.py | 74 ------------------- .../engine/simulated_local_processor.py | 40 +++++++++- 7 files changed, 61 insertions(+), 103 deletions(-) diff --git a/cirq-google/cirq_google/engine/abstract_job.py b/cirq-google/cirq_google/engine/abstract_job.py index f4dbab3dbb4..1fba672e705 100644 --- a/cirq-google/cirq_google/engine/abstract_job.py +++ b/cirq-google/cirq_google/engine/abstract_job.py @@ -163,17 +163,6 @@ def cancel(self) -> Optional[bool]: def delete(self) -> Optional[bool]: """Deletes the job and result, if any.""" - @abc.abstractmethod - async def batched_results_async(self) -> Sequence[Sequence[EngineResult]]: - """Returns the job results, blocking until the job is complete. - - This method is intended for batched jobs. Instead of flattening - results into a single list, this will return a List[Result] - for each circuit in the batch. - """ - - batched_results = duet.sync(batched_results_async) - @abc.abstractmethod async def results_async(self) -> Sequence[EngineResult]: """Returns the job results, blocking until the job is complete.""" diff --git a/cirq-google/cirq_google/engine/abstract_job_test.py b/cirq-google/cirq_google/engine/abstract_job_test.py index 23a80566b24..c639b237f0e 100644 --- a/cirq-google/cirq_google/engine/abstract_job_test.py +++ b/cirq-google/cirq_google/engine/abstract_job_test.py @@ -81,9 +81,6 @@ def cancel(self) -> None: def delete(self) -> None: pass - async def batched_results_async(self): - pass - async def results_async(self): return [cirq.ResultDict(params={}, measurements={'a': np.asarray([t])}) for t in range(5)] diff --git a/cirq-google/cirq_google/engine/abstract_local_job_test.py b/cirq-google/cirq_google/engine/abstract_local_job_test.py index df1f6e798d3..8cc4567753d 100644 --- a/cirq-google/cirq_google/engine/abstract_local_job_test.py +++ b/cirq-google/cirq_google/engine/abstract_local_job_test.py @@ -41,9 +41,6 @@ def cancel(self) -> None: def delete(self) -> None: pass - async def batched_results_async(self) -> Sequence[Sequence[EngineResult]]: - return [] # pragma: no cover - async def results_async(self) -> Sequence[EngineResult]: return [] # pragma: no cover diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index 19003fee140..a90793682dc 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -449,6 +449,28 @@ async def get_circuit_async(self, program_num: Optional[int] = None) -> cirq.Cir get_circuit = duet.sync(get_circuit_async) + async def batch_size_async(self) -> int: + """Returns the number of programs in a batch program. + + Raises: + ValueError: if the program created was not a batch program. + """ + if self.result_type != ResultType.Batch: + raise ValueError( + f'Program was not a batch program but instead was of type {self.result_type}.' + ) + import cirq_google.engine.engine as engine_base + + if self._program is None or self._program.code is None: + self._program = await self.context.client.get_program_async( + self.project_id, self.program_id, True + ) + code = self._program.code + code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] + raise ValueError(f'Program was not a batch program but instead was of type {code_type}.') + + batch_size = duet.sync(batch_size_async) + async def delete_async(self, delete_jobs: bool = False) -> None: """Deletes a previously created quantum program. diff --git a/cirq-google/cirq_google/engine/engine_program_test.py b/cirq-google/cirq_google/engine/engine_program_test.py index 423ef7abfcc..d0556e71c4f 100644 --- a/cirq-google/cirq_google/engine/engine_program_test.py +++ b/cirq-google/cirq_google/engine/engine_program_test.py @@ -91,17 +91,6 @@ def test_run_sweeps_delegation(create_job_async): assert job._job == quantum.QuantumJob() -@mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') -def test_run_batch_delegation(create_job_async): - create_job_async.return_value = ('kittens', quantum.QuantumJob()) - program = cg.EngineProgram('my-meow', 'my-meow', EngineContext(), result_type=ResultType.Batch) - resolver_list = [cirq.Points('cats', [1.0, 2.0, 3.0]), cirq.Points('cats', [4.0, 5.0, 6.0])] - job = program.run_batch( - job_id='steve', repetitions=10, params_list=resolver_list, processor_ids=['lazykitty'] - ) - assert job._job == quantum.QuantumJob() - - @mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') def test_run_calibration_delegation(create_job_async): create_job_async.return_value = ('dogs', quantum.QuantumJob()) diff --git a/cirq-google/cirq_google/engine/simulated_local_job_test.py b/cirq-google/cirq_google/engine/simulated_local_job_test.py index 89a6fd4b35c..ced15132452 100644 --- a/cirq-google/cirq_google/engine/simulated_local_job_test.py +++ b/cirq-google/cirq_google/engine/simulated_local_job_test.py @@ -67,52 +67,6 @@ def test_run_sweep(): assert job.execution_status() == quantum.ExecutionStatus.State.SUCCESS -@pytest.mark.parametrize( - 'simulation_type', [LocalSimulationType.SYNCHRONOUS, LocalSimulationType.ASYNCHRONOUS] -) -def test_run_batch(simulation_type): - program = ParentProgram( - [ - cirq.Circuit(cirq.X(Q) ** sympy.Symbol('t'), cirq.measure(Q, key='m')), - cirq.Circuit(cirq.X(Q) ** sympy.Symbol('x'), cirq.measure(Q, key='m2')), - ], - None, - ) - job = SimulatedLocalJob( - job_id='test_job', - processor_id='test1', - parent_program=program, - simulation_type=simulation_type, - repetitions=100, - sweeps=[cirq.Points(key='t', points=[1, 0]), cirq.Points(key='x', points=[0, 1])], - ) - if simulation_type == LocalSimulationType.ASYNCHRONOUS: - # Note: The simulation could have finished already - assert ( - job.execution_status() == quantum.ExecutionStatus.State.RUNNING - or job.execution_status() == quantum.ExecutionStatus.State.SUCCESS - ) - else: - assert job.execution_status() == quantum.ExecutionStatus.State.READY - results = job.batched_results() - assert np.all(results[0][0].measurements['m'] == 1) - assert np.all(results[0][1].measurements['m'] == 0) - assert np.all(results[1][0].measurements['m2'] == 0) - assert np.all(results[1][1].measurements['m2'] == 1) - assert job.execution_status() == quantum.ExecutionStatus.State.SUCCESS - # Using flattened results - results = job.results() - assert np.all(results[0].measurements['m'] == 1) - assert np.all(results[1].measurements['m'] == 0) - assert np.all(results[2].measurements['m2'] == 0) - assert np.all(results[3].measurements['m2'] == 1) - - for result in results: - assert result.job_id == 'test_job' - assert result.job_finished_time is not None - assert results == cirq.read_json(json_text=cirq.to_json(results)) - - def test_cancel(): program = ParentProgram([cirq.Circuit(cirq.X(Q), cirq.measure(Q, key='m'))], None) job = SimulatedLocalJob( @@ -134,34 +88,6 @@ def test_unsupported_types(): ) with pytest.raises(ValueError, match='Unsupported simulation type'): job.results() - with pytest.raises(ValueError, match='Unsupported simulation type'): - job.batched_results() - - -def test_failure(): - program = ParentProgram( - [cirq.Circuit(cirq.X(Q) ** sympy.Symbol('t'), cirq.measure(Q, key='m'))], None - ) - job = SimulatedLocalJob( - job_id='test_job', - processor_id='test1', - parent_program=program, - repetitions=100, - sweeps=[cirq.Points(key='x', points=[1, 0])], - ) - try: - _ = job.results() - except ValueError: - code, message = job.failure() - assert code == '500' - assert 'Circuit contains ops whose symbols were not specified' in message - - try: - _ = job.batched_results() - except ValueError: - code, message = job.failure() - assert code == '500' - assert 'Circuit contains ops whose symbols were not specified' in message def test_run_async(): diff --git a/cirq-google/cirq_google/engine/simulated_local_processor.py b/cirq-google/cirq_google/engine/simulated_local_processor.py index a395edf36b0..096da811225 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor.py @@ -13,7 +13,7 @@ # limitations under the License. import datetime -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Sequence, Union import cirq @@ -196,6 +196,44 @@ def get_program(self, program_id: str) -> AbstractProgram: """ return self._programs[program_id] + async def run_batch_async( + self, + programs: Sequence[cirq.AbstractCircuit], + program_id: Optional[str] = None, + job_id: Optional[str] = None, + params_list: Optional[Sequence[cirq.Sweepable]] = None, + repetitions: int = 1, + program_description: Optional[str] = None, + program_labels: Optional[Dict[str, str]] = None, + job_description: Optional[str] = None, + job_labels: Optional[Dict[str, str]] = None, + run_name: str = "", + device_config_name: str = "", + ) -> SimulatedLocalJob: + if program_id is None: + program_id = self._create_id(id_type='program') + if job_id is None: + job_id = self._create_id(id_type='job') + self._program_validator(programs, params_list or [{}], repetitions, CIRCUIT_SERIALIZER) + self._programs[program_id] = SimulatedLocalProgram( + program_id=program_id, + simulation_type=self._simulation_type, + circuits=programs, + engine=self.engine(), + processor=self, + ) + job = SimulatedLocalJob( + job_id=job_id, + processor_id=self.processor_id, + parent_program=self._programs[program_id], + repetitions=repetitions, + sweeps=list(params_list) if params_list is not None else None, + sampler=self._sampler, + simulation_type=self._simulation_type, + ) + self._programs[program_id].add_job(job_id, job) + return job + async def run_sweep_async( self, program: cirq.AbstractCircuit, From b592da1546871fd59e42d546f7388746544ab9f8 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 8 Feb 2024 22:31:16 +0000 Subject: [PATCH 10/23] lint --- cirq-google/cirq_google/api/v2/sweeps.py | 2 +- .../cirq_google/engine/calibration_result.py | 7 +- cirq-google/cirq_google/engine/engine.py | 18 --- .../cirq_google/engine/engine_processor.py | 130 ------------------ .../engine/engine_processor_test.py | 124 ----------------- .../engine/engine_processor_test.py:20 | 14 ++ .../cirq_google/engine/engine_validator.py | 64 +-------- .../engine/engine_validator_test.py | 1 - 8 files changed, 17 insertions(+), 343 deletions(-) create mode 100644 cirq-google/cirq_google/engine/engine_processor_test.py:20 diff --git a/cirq-google/cirq_google/api/v2/sweeps.py b/cirq-google/cirq_google/api/v2/sweeps.py index cd25d234fef..c325b5bb896 100644 --- a/cirq-google/cirq_google/api/v2/sweeps.py +++ b/cirq-google/cirq_google/api/v2/sweeps.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import cast, Dict, Iterable, List, Optional, Tuple +from typing import cast, Dict, List, Optional import sympy diff --git a/cirq-google/cirq_google/engine/calibration_result.py b/cirq-google/cirq_google/engine/calibration_result.py index bcf54358d32..fb1d0e0c17c 100644 --- a/cirq-google/cirq_google/engine/calibration_result.py +++ b/cirq-google/cirq_google/engine/calibration_result.py @@ -18,8 +18,6 @@ if TYPE_CHECKING: import cirq_google - import cirq - import cirq_google.api.v2.calibration_pb2 as calibration_pb2 @dataclasses.dataclass @@ -34,7 +32,6 @@ class CalibrationResult: These defaults will converted to `None` by the API client. """ - code: 'calibration_pb2.CalibrationLayerCode' error_message: Optional[str] token: Optional[str] valid_until: Optional[datetime.datetime] @@ -43,7 +40,6 @@ class CalibrationResult: @classmethod def _from_json_dict_( cls, - code: 'calibration_pb2.CalibrationLayerCode', error_message: Optional[str], token: Optional[str], utc_valid_until: float, @@ -56,7 +52,7 @@ def _from_json_dict_( if utc_valid_until is not None else None ) - return cls(code, error_message, token, valid_until, metrics) + return cls(error_message, token, valid_until, metrics) def _json_dict_(self) -> Dict[str, Any]: """Magic method for the JSON serialization protocol.""" @@ -66,7 +62,6 @@ def _json_dict_(self) -> Dict[str, Any]: else None ) return { - 'code': self.code, 'error_message': self.error_message, 'token': self.token, 'utc_valid_until': utc_valid_until, diff --git a/cirq-google/cirq_google/engine/engine.py b/cirq-google/cirq_google/engine/engine.py index f49407f112c..3ae9672e88e 100644 --- a/cirq-google/cirq_google/engine/engine.py +++ b/cirq-google/cirq_google/engine/engine.py @@ -532,24 +532,6 @@ async def create_program_async( create_program = duet.sync(create_program_async) - async def create_calibration_program_async( - self, - layers: List['cirq_google.CalibrationLayer'], - program_id: Optional[str] = None, - description: Optional[str] = None, - labels: Optional[Dict[str, str]] = None, - ) -> engine_program.EngineProgram: - """Wraps a list of calibration layers into an Any for Quantum Engine. - - Raises: - NotImplementedError: Calibration programs are no longer supported on the Quantum Engine. - """ - raise NotImplementedError( - 'Calibration programs are no longer supported on the Quantum Engine.' - ) - - create_calibration_program = duet.sync(create_calibration_program_async) - def get_program(self, program_id: str) -> engine_program.EngineProgram: """Returns an EngineProgram for an existing Quantum Engine program. diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 9df284d800f..87edabb4974 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -122,136 +122,6 @@ def get_sampler( processor=self, run_name=run_name, device_config_name=device_config_name ) - async def run_batch_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - params_list: Optional[Sequence[cirq.Sweepable]] = None, - repetitions: int = 1, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - run_name: str = "", - device_config_name: str = "", - ) -> 'abstract_job.AbstractJob': - """Runs the supplied Circuits on this processor. - - This will combine each Circuit provided in `programs` into - a BatchProgram. Each circuit will pair with the associated - parameter sweep provided in the `params_list`. The number of - programs is required to match the number of sweeps. - This method does not block until a result is returned. However, - no results will be available until the entire batch is complete. - Args: - programs: The Circuits to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'prog-################YYMMDD' will be generated, where # is - alphanumeric and YYMMDD is the current year, month, and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'job-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - params_list: Parameter sweeps to use with the circuits. The number - of sweeps should match the number of circuits and will be - paired in order with the circuits. If this is None, it is - assumed that the circuits are not parameterized and do not - require sweeps. - repetitions: Number of circuit repetitions to run. Each sweep value - of each circuit in the batch will run with the same repetitions. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. - run_name: A unique identifier representing an automation run for the - processor. An Automation Run contains a collection of device - configurations for the processor. - device_config_name: An identifier used to select the processor configuration - utilized to run the job. A configuration identifies the set of - available qubits, couplers, and supported gates in the processor. - Returns: - An `abstract_job.AbstractJob`. If this is iterated over it returns - a list of `cirq.Result`. All Results for the first circuit are listed - first, then the Results for the second, etc. The Results - for a circuit are listed in the order imposed by the associated - parameter sweep. - Raises: - ValueError: If neither `processor_id` or `processor_ids` are set. - ValueError: If only one of `run_name` and `device_config_name` are specified. - ValueError: If `processor_ids` has more than one processor id. - ValueError: If either `run_name` and `device_config_name` are set but - `processor_id` is empty. - """ - return await self.engine().run_batch_async( - programs=programs, - program_id=program_id, - params_list=list(params_list) if params_list is not None else None, - repetitions=repetitions, - program_description=program_description, - program_labels=program_labels, - job_description=job_description, - job_labels=job_labels, - processor_id=self.processor_id, - run_name=run_name, - device_config_name=device_config_name, - ) - - async def run_calibration_async( - self, - layers: List[calibration_layer.CalibrationLayer], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - ) -> 'abstract_job.AbstractJob': - """Runs the specified calibrations on the processor. - - Each calibration will be specified by a `CalibrationLayer` - that contains the type of the calibrations to run, a `Circuit` - to optimize, and any arguments needed by the calibration routine. - Arguments and circuits needed for each layer will vary based on the - calibration type. However, the typical calibration routine may - require a single moment defining the gates to optimize, for example. - Note: this is an experimental API and is not yet fully supported - for all users. - - Args: - layers: The layers of calibration to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'calibration-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'calibration-################YYMMDD' will be - generated, where # is alphanumeric and YYMMDD is the current - year, month, and day. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. By default, - this will add a 'calibration' label to the job. - Returns: - An AbstractJob whose results can be retrieved by calling - calibration_results(). - """ - return await self.engine().run_calibration_async( - layers=layers, - processor_id=self.processor_id, - program_id=program_id, - job_id=job_id, - program_description=program_description, - program_labels=program_labels, - job_description=job_description, - job_labels=job_labels, - ) - async def run_sweep_async( self, program: cirq.AbstractCircuit, diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py b/cirq-google/cirq_google/engine/engine_processor_test.py index 0273a70c0c7..2f79e42fed4 100644 --- a/cirq-google/cirq_google/engine/engine_processor_test.py +++ b/cirq-google/cirq_google/engine/engine_processor_test.py @@ -179,34 +179,6 @@ def _to_timestamp(json_string): ) -_BATCH_RESULTS_V2 = util.pack_any(v2.batch_pb2.BatchResult(results=[_RESULTS_V2, _RESULTS2_V2])) - - -_CALIBRATION_RESULTS_V2 = util.pack_any( - v2.calibration_pb2.FocusedCalibrationResult( - results=[ - v2.calibration_pb2.CalibrationLayerResult( - code=v2.calibration_pb2.SUCCESS, - error_message='First success', - token='abc123', - metrics=v2.metrics_pb2.MetricsSnapshot( - metrics=[ - v2.metrics_pb2.Metric( - name='fidelity', - targets=['q2_3', 'q2_4'], - values=[v2.metrics_pb2.Value(double_val=0.75)], - ) - ] - ), - ), - v2.calibration_pb2.CalibrationLayerResult( - code=v2.calibration_pb2.SUCCESS, error_message='Second success' - ), - ] - ) -) - - @pytest.fixture(scope='module', autouse=True) def mock_grpc_client(): with mock.patch( @@ -881,102 +853,6 @@ def test_run_sweep_params_with_stream_rpcs(client): assert sweeps[i].sweep.sweep_function.sweeps[0].single_sweep.points.points == [v] -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_batch(client): - client().create_program_async.return_value = ( - 'prog', - quantum.QuantumProgram(name='projects/proj/programs/prog'), - ) - client().create_job_async.return_value = ( - 'job-id', - quantum.QuantumJob( - name='projects/proj/programs/prog/jobs/job-id', execution_status={'state': 'READY'} - ), - ) - client().get_job_async.return_value = quantum.QuantumJob( - execution_status={'state': 'SUCCESS'}, update_time=_to_timestamp('2019-07-09T23:39:59Z') - ) - client().get_job_results_async.return_value = quantum.QuantumResult(result=_BATCH_RESULTS_V2) - - processor = cg.EngineProcessor('a', 'p', EngineContext()) - job = processor.run_batch( - programs=[_CIRCUIT, _CIRCUIT], - job_id='job-id', - params_list=[cirq.Points('a', [1, 2]), cirq.Points('a', [3, 4])], - ) - results = job.results() - assert len(results) == 4 - for i, v in enumerate([1, 2, 3, 4]): - assert results[i].repetitions == 1 - assert results[i].params.param_dict == {'a': v} - assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} - for result in results: - assert result.job_id == job.id() - client().create_program_async.assert_called_once() - client().create_job_async.assert_called_once() - run_context = v2.batch_pb2.BatchRunContext() - client().create_job_async.call_args[1]['run_context'].Unpack(run_context) - assert len(run_context.run_contexts) == 2 - for idx, rc in enumerate(run_context.run_contexts): - sweeps = rc.parameter_sweeps - assert len(sweeps) == 1 - assert sweeps[0].repetitions == 1 - if idx == 0: - assert sweeps[0].sweep.single_sweep.points.points == [1.0, 2.0] - if idx == 1: - assert sweeps[0].sweep.single_sweep.points.points == [3.0, 4.0] - client().get_job_async.assert_called_once() - client().get_job_results_async.assert_called_once() - - -@mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) -def test_run_calibration(client): - client().create_program_async.return_value = ( - 'prog', - quantum.QuantumProgram(name='projects/proj/programs/prog'), - ) - client().create_job_async.return_value = ( - 'job-id', - quantum.QuantumJob( - name='projects/proj/programs/prog/jobs/job-id', execution_status={'state': 'READY'} - ), - ) - client().get_job_async.return_value = quantum.QuantumJob(execution_status={'state': 'SUCCESS'}) - client().get_job_results_async.return_value = quantum.QuantumResult( - result=_CALIBRATION_RESULTS_V2 - ) - - q1 = cirq.GridQubit(2, 3) - q2 = cirq.GridQubit(2, 4) - layer1 = cg.CalibrationLayer('xeb', cirq.Circuit(cirq.CZ(q1, q2)), {'num_layers': 42}) - layer2 = cg.CalibrationLayer( - 'readout', cirq.Circuit(cirq.measure(q1, q2)), {'num_samples': 4242} - ) - processor = cg.EngineProcessor('proj', 'mysim', EngineContext()) - job = processor.run_calibration(layers=[layer1, layer2], job_id='job-id') - results = job.calibration_results() - assert len(results) == 2 - assert results[0].code == v2.calibration_pb2.SUCCESS - assert results[0].error_message == 'First success' - assert results[0].token == 'abc123' - assert len(results[0].metrics) == 1 - assert len(results[0].metrics['fidelity']) == 1 - assert results[0].metrics['fidelity'][(q1, q2)] == [0.75] - assert results[1].code == v2.calibration_pb2.SUCCESS - assert results[1].error_message == 'Second success' - - # assert label is correct - client().create_job_async.assert_called_once_with( - project_id='proj', - program_id='prog', - job_id='job-id', - processor_ids=['mysim'], - run_context=util.pack_any(v2.run_context_pb2.RunContext()), - description=None, - labels={'calibration': ''}, - ) - - @mock.patch('cirq_google.engine.engine_client.EngineClient', autospec=True) def test_sampler_with_unary_rpcs(client): client().create_program_async.return_value = ( diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py:20 b/cirq-google/cirq_google/engine/engine_processor_test.py:20 new file mode 100644 index 00000000000..18b3ef417aa --- /dev/null +++ b/cirq-google/cirq_google/engine/engine_processor_test.py:20 @@ -0,0 +1,14 @@ +// Copyright 2024 smeeks +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// 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. + diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index 9e6ebae1208..d048d4749f4 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -64,65 +64,6 @@ def _verify_measurements(circuits): raise RuntimeError('Code must measure at least one qubit.') -def validate_program( - circuits: Sequence[cirq.AbstractCircuit], - sweeps: Sequence[cirq.Sweepable], - repetitions: int, - serializer: Serializer, - max_size: int = MAX_MESSAGE_SIZE, -) -> None: - """Validate that the Program message size is below the maximum size limit. - - Args: - circuits: A sequence of `cirq.Circuit` objects to validate. For - sweeps and runs, this will be a single circuit. For batches, - this will be a list of circuits. - sweeps: Parameters to run with each circuit. The length of the - sweeps sequence should be the same as the circuits argument. - repetitions: Number of repetitions to run with each sweep. - serializer: Serializer to use to serialize the circuits and sweeps. - max_size: proto size limit to check against. - - Raises: - RuntimeError: if compiled proto is above the maximum size. - """ - pass - """ - batch = v2.batch_pb2.BatchProgram() - packed = any_pb2.Any() - for circuit in circuits: - serializer.serialize(circuit, msg=batch.programs.add()) - packed.Pack(batch) - message_size = len(packed.SerializeToString()) - if message_size > max_size: - raise RuntimeError("INVALID_PROGRAM: Program too long.") - """ - - -def create_program_validator(max_size: int = MAX_MESSAGE_SIZE) -> PROGRAM_VALIDATOR_TYPE: - """Creates a Callable program validator with a set message size. - - This validator can be used for a validator in `cg.ValidatingSampler` - and can also be useful in generating 'engine emulators' by using - `cg.SimulatedLocalProcessor` with this callable as a program_validator. - - Args: - max_size: proto size limit to check against. - - Returns: Callable to use in validation with the max_size already set. - """ - - def _validator( - circuits: Sequence[cirq.AbstractCircuit], - sweeps: Sequence[cirq.Sweepable], - repetitions: int, - serializer: Serializer, - ): - return validate_program(circuits, sweeps, repetitions, serializer, max_size) - - return _validator - - def validate_for_engine( circuits: Sequence[cirq.AbstractCircuit], sweeps: Sequence[cirq.Sweepable], @@ -150,9 +91,7 @@ def validate_for_engine( def create_engine_validator( - max_moments: int = MAX_MOMENTS, - max_repetitions: int = MAX_TOTAL_REPETITIONS, - max_duration_ns: int = 55000, + max_moments: int = MAX_MOMENTS, max_repetitions: int = MAX_TOTAL_REPETITIONS ) -> VALIDATOR_TYPE: """Creates a Callable gate set validator with a set message size. @@ -164,7 +103,6 @@ def create_engine_validator( max_moments: Maximum number of moments to allow. max_repetitions: Maximum number of parameter sweep values allowed when summed across all sweeps and all batches. - max_duration_ns: Maximum duration of the circuit, in nanoseconds. """ def _validator( diff --git a/cirq-google/cirq_google/engine/engine_validator_test.py b/cirq-google/cirq_google/engine/engine_validator_test.py index df574b2c758..11173224569 100644 --- a/cirq-google/cirq_google/engine/engine_validator_test.py +++ b/cirq-google/cirq_google/engine/engine_validator_test.py @@ -14,7 +14,6 @@ import pytest import cirq -import cirq_google as cg import cirq_google.engine.engine_validator as engine_validator SERIALIZABLE_GATE_DOMAIN = {cirq.X: 1, cirq.Y: 1, cirq.Z: 1, cirq.S: 1, cirq.T: 1, cirq.CZ: 2} From e4d461113ff37401a646130ba9e5d14dbd45b932 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 8 Feb 2024 23:44:40 +0000 Subject: [PATCH 11/23] generate protos --- .../cirq_google/api/v1/operations_pb2.py | 35 ++-- cirq-google/cirq_google/api/v1/params_pb2.py | 39 ++-- cirq-google/cirq_google/api/v1/program_pb2.py | 31 ++-- cirq-google/cirq_google/api/v2/device_pb2.py | 87 ++++----- cirq-google/cirq_google/api/v2/device_pb2.pyi | 4 +- cirq-google/cirq_google/api/v2/metrics_pb2.py | 19 +- cirq-google/cirq_google/api/v2/program_pb2.py | 175 +++++++++--------- .../cirq_google/api/v2/program_pb2.pyi | 2 +- cirq-google/cirq_google/api/v2/result_pb2.py | 35 ++-- .../cirq_google/api/v2/run_context_pb2.py | 43 ++--- .../cirq_google/api/v2/run_context_pb2.pyi | 2 +- 11 files changed, 240 insertions(+), 232 deletions(-) diff --git a/cirq-google/cirq_google/api/v1/operations_pb2.py b/cirq-google/cirq_google/api/v1/operations_pb2.py index a00a88c499e..b50fdf8e963 100644 --- a/cirq-google/cirq_google/api/v1/operations_pb2.py +++ b/cirq-google/cirq_google/api/v1/operations_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/operations.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,24 +15,25 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#cirq_google/api/v1/operations.proto\x12\x12\x63irq.google.api.v1\"!\n\x05Qubit\x12\x0b\n\x03row\x18\x01 \x01(\x05\x12\x0b\n\x03\x63ol\x18\x02 \x01(\x05\"E\n\x12ParameterizedFloat\x12\r\n\x03raw\x18\x01 \x01(\x02H\x00\x12\x17\n\rparameter_key\x18\x02 \x01(\tH\x00\x42\x07\n\x05value\"\xae\x01\n\x04\x45xpW\x12)\n\x06target\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12?\n\x0f\x61xis_half_turns\x18\x02 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\x12:\n\nhalf_turns\x18\x03 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"m\n\x04\x45xpZ\x12)\n\x06target\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12:\n\nhalf_turns\x18\x02 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"\x9b\x01\n\x05\x45xp11\x12*\n\x07target1\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12*\n\x07target2\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12:\n\nhalf_turns\x18\x03 \x01(\x0b\x32&.cirq.google.api.v1.ParameterizedFloat\"[\n\x0bMeasurement\x12*\n\x07targets\x18\x01 \x03(\x0b\x32\x19.cirq.google.api.v1.Qubit\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x13\n\x0binvert_mask\x18\x03 \x03(\x08\"\xfa\x01\n\tOperation\x12%\n\x1dincremental_delay_picoseconds\x18\x01 \x01(\x04\x12)\n\x05\x65xp_w\x18\n \x01(\x0b\x32\x18.cirq.google.api.v1.ExpWH\x00\x12)\n\x05\x65xp_z\x18\x0b \x01(\x0b\x32\x18.cirq.google.api.v1.ExpZH\x00\x12+\n\x06\x65xp_11\x18\x0c \x01(\x0b\x32\x19.cirq.google.api.v1.Exp11H\x00\x12\x36\n\x0bmeasurement\x18\r \x01(\x0b\x32\x1f.cirq.google.api.v1.MeasurementH\x00\x42\x0b\n\toperationB2\n\x1d\x63om.google.cirq.google.api.v1B\x0fOperationsProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.operations_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.operations_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\017OperationsProtoP\001' - _QUBIT._serialized_start=59 - _QUBIT._serialized_end=92 - _PARAMETERIZEDFLOAT._serialized_start=94 - _PARAMETERIZEDFLOAT._serialized_end=163 - _EXPW._serialized_start=166 - _EXPW._serialized_end=340 - _EXPZ._serialized_start=342 - _EXPZ._serialized_end=451 - _EXP11._serialized_start=454 - _EXP11._serialized_end=609 - _MEASUREMENT._serialized_start=611 - _MEASUREMENT._serialized_end=702 - _OPERATION._serialized_start=705 - _OPERATION._serialized_end=955 + _globals['_QUBIT']._serialized_start=59 + _globals['_QUBIT']._serialized_end=92 + _globals['_PARAMETERIZEDFLOAT']._serialized_start=94 + _globals['_PARAMETERIZEDFLOAT']._serialized_end=163 + _globals['_EXPW']._serialized_start=166 + _globals['_EXPW']._serialized_end=340 + _globals['_EXPZ']._serialized_start=342 + _globals['_EXPZ']._serialized_end=451 + _globals['_EXP11']._serialized_start=454 + _globals['_EXP11']._serialized_end=609 + _globals['_MEASUREMENT']._serialized_start=611 + _globals['_MEASUREMENT']._serialized_end=702 + _globals['_OPERATION']._serialized_start=705 + _globals['_OPERATION']._serialized_end=955 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v1/params_pb2.py b/cirq-google/cirq_google/api/v1/params_pb2.py index f11b97760ff..fe788f8b1b9 100644 --- a/cirq-google/cirq_google/api/v1/params_pb2.py +++ b/cirq-google/cirq_google/api/v1/params_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/params.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,28 +15,29 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v1/params.proto\x12\x12\x63irq.google.api.v1\"V\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12/\n\x05sweep\x18\x02 \x01(\x0b\x32 .cirq.google.api.v1.ProductSweep\"=\n\x0cProductSweep\x12-\n\x07\x66\x61\x63tors\x18\x01 \x03(\x0b\x32\x1c.cirq.google.api.v1.ZipSweep\";\n\x08ZipSweep\x12/\n\x06sweeps\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v1.SingleSweep\"\x8d\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v1.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v1.LinspaceH\x00\x42\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\"\x8c\x01\n\rParameterDict\x12G\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32\x32.cirq.google.api.v1.ParameterDict.AssignmentsEntry\x1a\x32\n\x10\x41ssignmentsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x42.\n\x1d\x63om.google.cirq.google.api.v1B\x0bParamsProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.params_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.params_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\013ParamsProtoP\001' _PARAMETERDICT_ASSIGNMENTSENTRY._options = None _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_options = b'8\001' - _PARAMETERSWEEP._serialized_start=55 - _PARAMETERSWEEP._serialized_end=141 - _PRODUCTSWEEP._serialized_start=143 - _PRODUCTSWEEP._serialized_end=204 - _ZIPSWEEP._serialized_start=206 - _ZIPSWEEP._serialized_end=265 - _SINGLESWEEP._serialized_start=268 - _SINGLESWEEP._serialized_end=409 - _POINTS._serialized_start=411 - _POINTS._serialized_end=435 - _LINSPACE._serialized_start=437 - _LINSPACE._serialized_end=508 - _PARAMETERDICT._serialized_start=511 - _PARAMETERDICT._serialized_end=651 - _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_start=601 - _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_end=651 + _globals['_PARAMETERSWEEP']._serialized_start=55 + _globals['_PARAMETERSWEEP']._serialized_end=141 + _globals['_PRODUCTSWEEP']._serialized_start=143 + _globals['_PRODUCTSWEEP']._serialized_end=204 + _globals['_ZIPSWEEP']._serialized_start=206 + _globals['_ZIPSWEEP']._serialized_end=265 + _globals['_SINGLESWEEP']._serialized_start=268 + _globals['_SINGLESWEEP']._serialized_end=409 + _globals['_POINTS']._serialized_start=411 + _globals['_POINTS']._serialized_end=435 + _globals['_LINSPACE']._serialized_start=437 + _globals['_LINSPACE']._serialized_end=508 + _globals['_PARAMETERDICT']._serialized_start=511 + _globals['_PARAMETERDICT']._serialized_end=651 + _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_start=601 + _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_end=651 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v1/program_pb2.py b/cirq-google/cirq_google/api/v1/program_pb2.py index 57c3370e4af..4d06cec94e2 100644 --- a/cirq-google/cirq_google/api/v1/program_pb2.py +++ b/cirq-google/cirq_google/api/v1/program_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v1/program.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -17,24 +17,25 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v1/program.proto\x12\x12\x63irq.google.api.v1\x1a#cirq_google/api/v1/operations.proto\x1a\x1f\x63irq_google/api/v1/params.proto\"~\n\x07Program\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v1.Operation\x12@\n\x10parameter_sweeps\x18\x02 \x03(\x0b\x32\".cirq.google.api.v1.ParameterSweepB\x02\x18\x01\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v1.ParameterSweep\"e\n\x13ParameterizedResult\x12\x31\n\x06params\x18\x01 \x01(\x0b\x32!.cirq.google.api.v1.ParameterDict\x12\x1b\n\x13measurement_results\x18\x02 \x01(\x0c\"H\n\x0eMeasurementKey\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x06qubits\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v1.Qubit\"\xa8\x01\n\x0bSweepResult\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12<\n\x10measurement_keys\x18\x02 \x03(\x0b\x32\".cirq.google.api.v1.MeasurementKey\x12\x46\n\x15parameterized_results\x18\x03 \x03(\x0b\x32\'.cirq.google.api.v1.ParameterizedResult\"@\n\x06Result\x12\x36\n\rsweep_results\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v1.SweepResultB/\n\x1d\x63om.google.cirq.google.api.v1B\x0cProgramProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.program_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v1.program_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v1B\014ProgramProtoP\001' _PROGRAM.fields_by_name['parameter_sweeps']._options = None _PROGRAM.fields_by_name['parameter_sweeps']._serialized_options = b'\030\001' - _PROGRAM._serialized_start=126 - _PROGRAM._serialized_end=252 - _RUNCONTEXT._serialized_start=254 - _RUNCONTEXT._serialized_end=328 - _PARAMETERIZEDRESULT._serialized_start=330 - _PARAMETERIZEDRESULT._serialized_end=431 - _MEASUREMENTKEY._serialized_start=433 - _MEASUREMENTKEY._serialized_end=505 - _SWEEPRESULT._serialized_start=508 - _SWEEPRESULT._serialized_end=676 - _RESULT._serialized_start=678 - _RESULT._serialized_end=742 + _globals['_PROGRAM']._serialized_start=126 + _globals['_PROGRAM']._serialized_end=252 + _globals['_RUNCONTEXT']._serialized_start=254 + _globals['_RUNCONTEXT']._serialized_end=328 + _globals['_PARAMETERIZEDRESULT']._serialized_start=330 + _globals['_PARAMETERIZEDRESULT']._serialized_end=431 + _globals['_MEASUREMENTKEY']._serialized_start=433 + _globals['_MEASUREMENTKEY']._serialized_end=505 + _globals['_SWEEPRESULT']._serialized_start=508 + _globals['_SWEEPRESULT']._serialized_end=676 + _globals['_RESULT']._serialized_start=678 + _globals['_RESULT']._serialized_end=742 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/device_pb2.py b/cirq-google/cirq_google/api/v2/device_pb2.py index 0d9bd036bca..d86989e8db5 100644 --- a/cirq-google/cirq_google/api/v2/device_pb2.py +++ b/cirq-google/cirq_google/api/v2/device_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/device.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,8 +15,9 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v2/device.proto\x12\x12\x63irq.google.api.v2\"\xfa\x01\n\x13\x44\x65viceSpecification\x12\x38\n\x0fvalid_gate_sets\x18\x01 \x03(\x0b\x32\x1b.cirq.google.api.v2.GateSetB\x02\x18\x01\x12:\n\x0bvalid_gates\x18\x05 \x03(\x0b\x32%.cirq.google.api.v2.GateSpecification\x12\x14\n\x0cvalid_qubits\x18\x02 \x03(\t\x12\x34\n\rvalid_targets\x18\x03 \x03(\x0b\x32\x1d.cirq.google.api.v2.TargetSet\x12!\n\x19\x64\x65veloper_recommendations\x18\x04 \x01(\t\"\xee\x06\n\x11GateSpecification\x12\x1b\n\x13gate_duration_picos\x18\x01 \x01(\x03\x12=\n\x03syc\x18\x02 \x01(\x0b\x32..cirq.google.api.v2.GateSpecification.SycamoreH\x00\x12\x45\n\nsqrt_iswap\x18\x03 \x01(\x0b\x32/.cirq.google.api.v2.GateSpecification.SqrtISwapH\x00\x12L\n\x0esqrt_iswap_inv\x18\x04 \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.SqrtISwapInvH\x00\x12\x36\n\x02\x63z\x18\x05 \x01(\x0b\x32(.cirq.google.api.v2.GateSpecification.CZH\x00\x12\x43\n\tphased_xz\x18\x06 \x01(\x0b\x32..cirq.google.api.v2.GateSpecification.PhasedXZH\x00\x12I\n\x0cvirtual_zpow\x18\x07 \x01(\x0b\x32\x31.cirq.google.api.v2.GateSpecification.VirtualZPowH\x00\x12K\n\rphysical_zpow\x18\x08 \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.PhysicalZPowH\x00\x12K\n\rcoupler_pulse\x18\t \x01(\x0b\x32\x32.cirq.google.api.v2.GateSpecification.CouplerPulseH\x00\x12\x41\n\x04meas\x18\n \x01(\x0b\x32\x31.cirq.google.api.v2.GateSpecification.MeasurementH\x00\x12:\n\x04wait\x18\x0b \x01(\x0b\x32*.cirq.google.api.v2.GateSpecification.WaitH\x00\x1a\n\n\x08Sycamore\x1a\x0b\n\tSqrtISwap\x1a\x0e\n\x0cSqrtISwapInv\x1a\x04\n\x02\x43Z\x1a\n\n\x08PhasedXZ\x1a\r\n\x0bVirtualZPow\x1a\x0e\n\x0cPhysicalZPow\x1a\x0e\n\x0c\x43ouplerPulse\x1a\r\n\x0bMeasurement\x1a\x06\n\x04WaitB\x06\n\x04gate\"P\n\x07GateSet\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x37\n\x0bvalid_gates\x18\x02 \x03(\x0b\x32\".cirq.google.api.v2.GateDefinition\"\xa1\x01\n\x0eGateDefinition\x12\n\n\x02id\x18\x01 \x01(\t\x12\x18\n\x10number_of_qubits\x18\x02 \x01(\x05\x12\x35\n\nvalid_args\x18\x03 \x03(\x0b\x32!.cirq.google.api.v2.ArgDefinition\x12\x1b\n\x13gate_duration_picos\x18\x04 \x01(\x03\x12\x15\n\rvalid_targets\x18\x05 \x03(\t\"\xda\x01\n\rArgDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x37\n\x04type\x18\x02 \x01(\x0e\x32).cirq.google.api.v2.ArgDefinition.ArgType\x12\x39\n\x0e\x61llowed_ranges\x18\x03 \x03(\x0b\x32!.cirq.google.api.v2.ArgumentRange\"G\n\x07\x41rgType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05\x46LOAT\x10\x01\x12\x14\n\x10REPEATED_BOOLEAN\x10\x02\x12\n\n\x06STRING\x10\x03\"=\n\rArgumentRange\x12\x15\n\rminimum_value\x18\x01 \x01(\x02\x12\x15\n\rmaximum_value\x18\x02 \x01(\x02\"\xef\x01\n\tTargetSet\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x45\n\x0ftarget_ordering\x18\x02 \x01(\x0e\x32,.cirq.google.api.v2.TargetSet.TargetOrdering\x12+\n\x07targets\x18\x03 \x03(\x0b\x32\x1a.cirq.google.api.v2.Target\"`\n\x0eTargetOrdering\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\r\n\tSYMMETRIC\x10\x01\x12\x12\n\nASYMMETRIC\x10\x02\x1a\x02\x08\x01\x12\x1a\n\x12SUBSET_PERMUTATION\x10\x03\x1a\x02\x08\x01\"\x15\n\x06Target\x12\x0b\n\x03ids\x18\x01 \x03(\tB.\n\x1d\x63om.google.cirq.google.api.v2B\x0b\x44\x65viceProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.device_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.device_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -27,44 +28,44 @@ _TARGETSET_TARGETORDERING.values_by_name["ASYMMETRIC"]._serialized_options = b'\010\001' _TARGETSET_TARGETORDERING.values_by_name["SUBSET_PERMUTATION"]._options = None _TARGETSET_TARGETORDERING.values_by_name["SUBSET_PERMUTATION"]._serialized_options = b'\010\001' - _DEVICESPECIFICATION._serialized_start=56 - _DEVICESPECIFICATION._serialized_end=306 - _GATESPECIFICATION._serialized_start=309 - _GATESPECIFICATION._serialized_end=1187 - _GATESPECIFICATION_SYCAMORE._serialized_start=1052 - _GATESPECIFICATION_SYCAMORE._serialized_end=1062 - _GATESPECIFICATION_SQRTISWAP._serialized_start=1064 - _GATESPECIFICATION_SQRTISWAP._serialized_end=1075 - _GATESPECIFICATION_SQRTISWAPINV._serialized_start=1077 - _GATESPECIFICATION_SQRTISWAPINV._serialized_end=1091 - _GATESPECIFICATION_CZ._serialized_start=1093 - _GATESPECIFICATION_CZ._serialized_end=1097 - _GATESPECIFICATION_PHASEDXZ._serialized_start=1099 - _GATESPECIFICATION_PHASEDXZ._serialized_end=1109 - _GATESPECIFICATION_VIRTUALZPOW._serialized_start=1111 - _GATESPECIFICATION_VIRTUALZPOW._serialized_end=1124 - _GATESPECIFICATION_PHYSICALZPOW._serialized_start=1126 - _GATESPECIFICATION_PHYSICALZPOW._serialized_end=1140 - _GATESPECIFICATION_COUPLERPULSE._serialized_start=1142 - _GATESPECIFICATION_COUPLERPULSE._serialized_end=1156 - _GATESPECIFICATION_MEASUREMENT._serialized_start=1158 - _GATESPECIFICATION_MEASUREMENT._serialized_end=1171 - _GATESPECIFICATION_WAIT._serialized_start=1173 - _GATESPECIFICATION_WAIT._serialized_end=1179 - _GATESET._serialized_start=1189 - _GATESET._serialized_end=1269 - _GATEDEFINITION._serialized_start=1272 - _GATEDEFINITION._serialized_end=1433 - _ARGDEFINITION._serialized_start=1436 - _ARGDEFINITION._serialized_end=1654 - _ARGDEFINITION_ARGTYPE._serialized_start=1583 - _ARGDEFINITION_ARGTYPE._serialized_end=1654 - _ARGUMENTRANGE._serialized_start=1656 - _ARGUMENTRANGE._serialized_end=1717 - _TARGETSET._serialized_start=1720 - _TARGETSET._serialized_end=1959 - _TARGETSET_TARGETORDERING._serialized_start=1863 - _TARGETSET_TARGETORDERING._serialized_end=1959 - _TARGET._serialized_start=1961 - _TARGET._serialized_end=1982 + _globals['_DEVICESPECIFICATION']._serialized_start=56 + _globals['_DEVICESPECIFICATION']._serialized_end=306 + _globals['_GATESPECIFICATION']._serialized_start=309 + _globals['_GATESPECIFICATION']._serialized_end=1187 + _globals['_GATESPECIFICATION_SYCAMORE']._serialized_start=1052 + _globals['_GATESPECIFICATION_SYCAMORE']._serialized_end=1062 + _globals['_GATESPECIFICATION_SQRTISWAP']._serialized_start=1064 + _globals['_GATESPECIFICATION_SQRTISWAP']._serialized_end=1075 + _globals['_GATESPECIFICATION_SQRTISWAPINV']._serialized_start=1077 + _globals['_GATESPECIFICATION_SQRTISWAPINV']._serialized_end=1091 + _globals['_GATESPECIFICATION_CZ']._serialized_start=1093 + _globals['_GATESPECIFICATION_CZ']._serialized_end=1097 + _globals['_GATESPECIFICATION_PHASEDXZ']._serialized_start=1099 + _globals['_GATESPECIFICATION_PHASEDXZ']._serialized_end=1109 + _globals['_GATESPECIFICATION_VIRTUALZPOW']._serialized_start=1111 + _globals['_GATESPECIFICATION_VIRTUALZPOW']._serialized_end=1124 + _globals['_GATESPECIFICATION_PHYSICALZPOW']._serialized_start=1126 + _globals['_GATESPECIFICATION_PHYSICALZPOW']._serialized_end=1140 + _globals['_GATESPECIFICATION_COUPLERPULSE']._serialized_start=1142 + _globals['_GATESPECIFICATION_COUPLERPULSE']._serialized_end=1156 + _globals['_GATESPECIFICATION_MEASUREMENT']._serialized_start=1158 + _globals['_GATESPECIFICATION_MEASUREMENT']._serialized_end=1171 + _globals['_GATESPECIFICATION_WAIT']._serialized_start=1173 + _globals['_GATESPECIFICATION_WAIT']._serialized_end=1179 + _globals['_GATESET']._serialized_start=1189 + _globals['_GATESET']._serialized_end=1269 + _globals['_GATEDEFINITION']._serialized_start=1272 + _globals['_GATEDEFINITION']._serialized_end=1433 + _globals['_ARGDEFINITION']._serialized_start=1436 + _globals['_ARGDEFINITION']._serialized_end=1654 + _globals['_ARGDEFINITION_ARGTYPE']._serialized_start=1583 + _globals['_ARGDEFINITION_ARGTYPE']._serialized_end=1654 + _globals['_ARGUMENTRANGE']._serialized_start=1656 + _globals['_ARGUMENTRANGE']._serialized_end=1717 + _globals['_TARGETSET']._serialized_start=1720 + _globals['_TARGETSET']._serialized_end=1959 + _globals['_TARGETSET_TARGETORDERING']._serialized_start=1863 + _globals['_TARGETSET_TARGETORDERING']._serialized_end=1959 + _globals['_TARGET']._serialized_start=1961 + _globals['_TARGET']._serialized_end=1982 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/device_pb2.pyi b/cirq-google/cirq_google/api/v2/device_pb2.pyi index 1e547a26f29..f1b26dadc67 100644 --- a/cirq-google/cirq_google/api/v2/device_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/device_pb2.pyi @@ -295,7 +295,7 @@ class ArgDefinition(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ArgTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ArgDefinition._ArgType.ValueType], builtins.type): + class _ArgTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ArgDefinition._ArgType.ValueType], builtins.type): # noqa: F821 DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNSPECIFIED: ArgDefinition._ArgType.ValueType # 0 FLOAT: ArgDefinition._ArgType.ValueType # 1 @@ -373,7 +373,7 @@ class TargetSet(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TargetOrderingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TargetSet._TargetOrdering.ValueType], builtins.type): + class _TargetOrderingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TargetSet._TargetOrdering.ValueType], builtins.type): # noqa: F821 DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNSPECIFIED: TargetSet._TargetOrdering.ValueType # 0 SYMMETRIC: TargetSet._TargetOrdering.ValueType # 1 diff --git a/cirq-google/cirq_google/api/v2/metrics_pb2.py b/cirq-google/cirq_google/api/v2/metrics_pb2.py index f6ec216226d..864ea2103b4 100644 --- a/cirq-google/cirq_google/api/v2/metrics_pb2.py +++ b/cirq-google/cirq_google/api/v2/metrics_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/metrics.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,16 +15,17 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/metrics.proto\x12\x12\x63irq.google.api.v2\"T\n\x0fMetricsSnapshot\x12\x14\n\x0ctimestamp_ms\x18\x01 \x01(\x04\x12+\n\x07metrics\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Metric\"R\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07targets\x18\x02 \x03(\t\x12)\n\x06values\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Value\"a\n\x05Value\x12\x14\n\ndouble_val\x18\x01 \x01(\x01H\x00\x12\x13\n\tint32_val\x18\x02 \x01(\x05H\x00\x12\x13\n\tint64_val\x18\x03 \x01(\x03H\x00\x12\x11\n\x07str_val\x18\x04 \x01(\tH\x00\x42\x05\n\x03valB3\n\x1d\x63om.google.cirq.google.api.v2B\x10\x43\x61librationProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.metrics_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.metrics_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\020CalibrationProtoP\001' - _METRICSSNAPSHOT._serialized_start=56 - _METRICSSNAPSHOT._serialized_end=140 - _METRIC._serialized_start=142 - _METRIC._serialized_end=224 - _VALUE._serialized_start=226 - _VALUE._serialized_end=323 + _globals['_METRICSSNAPSHOT']._serialized_start=56 + _globals['_METRICSSNAPSHOT']._serialized_end=140 + _globals['_METRIC']._serialized_start=142 + _globals['_METRIC']._serialized_end=224 + _globals['_VALUE']._serialized_start=226 + _globals['_VALUE']._serialized_end=323 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/program_pb2.py b/cirq-google/cirq_google/api/v2/program_pb2.py index 30384dfe286..2440805d87a 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.py +++ b/cirq-google/cirq_google/api/v2/program_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/program.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,8 +15,9 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n cirq_google/api/v2/program.proto\x12\x12\x63irq.google.api.v2\"\xd7\x01\n\x07Program\x12.\n\x08language\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.Language\x12.\n\x07\x63ircuit\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12\x30\n\x08schedule\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.ScheduleH\x00\x12/\n\tconstants\x18\x04 \x03(\x0b\x32\x1c.cirq.google.api.v2.ConstantB\t\n\x07program\"\x93\x01\n\x08\x43onstant\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x34\n\rcircuit_value\x18\x02 \x01(\x0b\x32\x1b.cirq.google.api.v2.CircuitH\x00\x12*\n\x05qubit\x18\x03 \x01(\x0b\x32\x19.cirq.google.api.v2.QubitH\x00\x42\r\n\x0b\x63onst_value\"\xd4\x01\n\x07\x43ircuit\x12K\n\x13scheduling_strategy\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.Circuit.SchedulingStrategy\x12+\n\x07moments\x18\x02 \x03(\x0b\x32\x1a.cirq.google.api.v2.Moment\"O\n\x12SchedulingStrategy\x12#\n\x1fSCHEDULING_STRATEGY_UNSPECIFIED\x10\x00\x12\x14\n\x10MOMENT_BY_MOMENT\x10\x01\"}\n\x06Moment\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12@\n\x12\x63ircuit_operations\x18\x02 \x03(\x0b\x32$.cirq.google.api.v2.CircuitOperation\"P\n\x08Schedule\x12\x44\n\x14scheduled_operations\x18\x03 \x03(\x0b\x32&.cirq.google.api.v2.ScheduledOperation\"`\n\x12ScheduledOperation\x12\x30\n\toperation\x18\x01 \x01(\x0b\x32\x1d.cirq.google.api.v2.Operation\x12\x18\n\x10start_time_picos\x18\x02 \x01(\x03\"?\n\x08Language\x12\x14\n\x08gate_set\x18\x01 \x01(\tB\x02\x18\x01\x12\x1d\n\x15\x61rg_function_language\x18\x02 \x01(\t\"k\n\x08\x46loatArg\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x42\x05\n\x03\x61rg\":\n\x08XPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\":\n\x08YPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"Q\n\x08ZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x15\n\ris_physical_z\x18\x02 \x01(\x08\"v\n\x0ePhasedXPowGate\x12\x34\n\x0ephase_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12.\n\x08\x65xponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xad\x01\n\x0cPhasedXZGate\x12\x30\n\nx_exponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x30\n\nz_exponent\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12\x39\n\x13\x61xis_phase_exponent\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\";\n\tCZPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"b\n\x08\x46SimGate\x12+\n\x05theta\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\x12)\n\x03phi\x18\x02 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\">\n\x0cISwapPowGate\x12.\n\x08\x65xponent\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"e\n\x0fMeasurementGate\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12,\n\x0binvert_mask\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"@\n\x08WaitGate\x12\x34\n\x0e\x64uration_nanos\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.FloatArg\"\xa9\x07\n\tOperation\x12*\n\x04gate\x18\x01 \x01(\x0b\x32\x18.cirq.google.api.v2.GateB\x02\x18\x01\x12\x30\n\x08xpowgate\x18\x07 \x01(\x0b\x32\x1c.cirq.google.api.v2.XPowGateH\x00\x12\x30\n\x08ypowgate\x18\x08 \x01(\x0b\x32\x1c.cirq.google.api.v2.YPowGateH\x00\x12\x30\n\x08zpowgate\x18\t \x01(\x0b\x32\x1c.cirq.google.api.v2.ZPowGateH\x00\x12<\n\x0ephasedxpowgate\x18\n \x01(\x0b\x32\".cirq.google.api.v2.PhasedXPowGateH\x00\x12\x38\n\x0cphasedxzgate\x18\x0b \x01(\x0b\x32 .cirq.google.api.v2.PhasedXZGateH\x00\x12\x32\n\tczpowgate\x18\x0c \x01(\x0b\x32\x1d.cirq.google.api.v2.CZPowGateH\x00\x12\x30\n\x08\x66simgate\x18\r \x01(\x0b\x32\x1c.cirq.google.api.v2.FSimGateH\x00\x12\x38\n\x0ciswappowgate\x18\x0e \x01(\x0b\x32 .cirq.google.api.v2.ISwapPowGateH\x00\x12>\n\x0fmeasurementgate\x18\x0f \x01(\x0b\x32#.cirq.google.api.v2.MeasurementGateH\x00\x12\x30\n\x08waitgate\x18\x10 \x01(\x0b\x32\x1c.cirq.google.api.v2.WaitGateH\x00\x12\x38\n\x0cinternalgate\x18\x11 \x01(\x0b\x32 .cirq.google.api.v2.InternalGateH\x00\x12\x39\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.Operation.ArgsEntryB\x02\x18\x01\x12)\n\x06qubits\x18\x03 \x03(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x1c\n\x14qubit_constant_index\x18\x06 \x03(\x05\x12\x15\n\x0btoken_value\x18\x04 \x01(\tH\x01\x12\x1e\n\x14token_constant_index\x18\x05 \x01(\x05H\x01\x1a\x44\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42\x0c\n\ngate_valueB\x07\n\x05token\"\x12\n\x04Gate\x12\n\n\x02id\x18\x01 \x01(\t\"\x13\n\x05Qubit\x12\n\n\x02id\x18\x02 \x01(\t\"\x9c\x01\n\x03\x41rg\x12\x31\n\targ_value\x18\x01 \x01(\x0b\x32\x1c.cirq.google.api.v2.ArgValueH\x00\x12\x10\n\x06symbol\x18\x02 \x01(\tH\x00\x12/\n\x04\x66unc\x18\x03 \x01(\x0b\x32\x1f.cirq.google.api.v2.ArgFunctionH\x00\x12\x18\n\x0e\x63onstant_index\x18\x04 \x01(\x05H\x00\x42\x05\n\x03\x61rg\"\xcf\x02\n\x08\x41rgValue\x12\x15\n\x0b\x66loat_value\x18\x01 \x01(\x02H\x00\x12:\n\x0b\x62ool_values\x18\x02 \x01(\x0b\x32#.cirq.google.api.v2.RepeatedBooleanH\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x39\n\x0cint64_values\x18\x05 \x01(\x0b\x32!.cirq.google.api.v2.RepeatedInt64H\x00\x12;\n\rdouble_values\x18\x06 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedDoubleH\x00\x12;\n\rstring_values\x18\x07 \x01(\x0b\x32\".cirq.google.api.v2.RepeatedStringH\x00\x42\x0b\n\targ_value\"\x1f\n\rRepeatedInt64\x12\x0e\n\x06values\x18\x01 \x03(\x03\" \n\x0eRepeatedDouble\x12\x0e\n\x06values\x18\x01 \x03(\x01\" \n\x0eRepeatedString\x12\x0e\n\x06values\x18\x01 \x03(\t\"!\n\x0fRepeatedBoolean\x12\x0e\n\x06values\x18\x01 \x03(\x08\"B\n\x0b\x41rgFunction\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xaf\x02\n\x10\x43ircuitOperation\x12\x1e\n\x16\x63ircuit_constant_index\x18\x01 \x01(\x05\x12M\n\x18repetition_specification\x18\x02 \x01(\x0b\x32+.cirq.google.api.v2.RepetitionSpecification\x12\x33\n\tqubit_map\x18\x03 \x01(\x0b\x32 .cirq.google.api.v2.QubitMapping\x12\x46\n\x13measurement_key_map\x18\x04 \x01(\x0b\x32).cirq.google.api.v2.MeasurementKeyMapping\x12/\n\x07\x61rg_map\x18\x05 \x01(\x0b\x32\x1e.cirq.google.api.v2.ArgMapping\"\xbc\x01\n\x17RepetitionSpecification\x12S\n\x0erepetition_ids\x18\x01 \x01(\x0b\x32\x39.cirq.google.api.v2.RepetitionSpecification.RepetitionIdsH\x00\x12\x1a\n\x10repetition_count\x18\x02 \x01(\x05H\x00\x1a\x1c\n\rRepetitionIds\x12\x0b\n\x03ids\x18\x01 \x03(\tB\x12\n\x10repetition_value\"\xac\x01\n\x0cQubitMapping\x12<\n\x07\x65ntries\x18\x01 \x03(\x0b\x32+.cirq.google.api.v2.QubitMapping.QubitEntry\x1a^\n\nQubitEntry\x12&\n\x03key\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\"$\n\x0eMeasurementKey\x12\x12\n\nstring_key\x18\x01 \x01(\t\"\xe2\x01\n\x15MeasurementKeyMapping\x12N\n\x07\x65ntries\x18\x01 \x03(\x0b\x32=.cirq.google.api.v2.MeasurementKeyMapping.MeasurementKeyEntry\x1ay\n\x13MeasurementKeyEntry\x12/\n\x03key\x18\x01 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".cirq.google.api.v2.MeasurementKey\"\xa0\x01\n\nArgMapping\x12\x38\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\'.cirq.google.api.v2.ArgMapping.ArgEntry\x1aX\n\x08\x41rgEntry\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg\"\xcd\x01\n\x0cInternalGate\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x12\n\nnum_qubits\x18\x03 \x01(\x05\x12\x41\n\tgate_args\x18\x04 \x03(\x0b\x32..cirq.google.api.v2.InternalGate.GateArgsEntry\x1aH\n\rGateArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.cirq.google.api.v2.Arg:\x02\x38\x01\x42/\n\x1d\x63om.google.cirq.google.api.v2B\x0cProgramProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.program_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.program_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -31,88 +32,88 @@ _OPERATION.fields_by_name['args']._serialized_options = b'\030\001' _INTERNALGATE_GATEARGSENTRY._options = None _INTERNALGATE_GATEARGSENTRY._serialized_options = b'8\001' - _PROGRAM._serialized_start=57 - _PROGRAM._serialized_end=272 - _CONSTANT._serialized_start=275 - _CONSTANT._serialized_end=422 - _CIRCUIT._serialized_start=425 - _CIRCUIT._serialized_end=637 - _CIRCUIT_SCHEDULINGSTRATEGY._serialized_start=558 - _CIRCUIT_SCHEDULINGSTRATEGY._serialized_end=637 - _MOMENT._serialized_start=639 - _MOMENT._serialized_end=764 - _SCHEDULE._serialized_start=766 - _SCHEDULE._serialized_end=846 - _SCHEDULEDOPERATION._serialized_start=848 - _SCHEDULEDOPERATION._serialized_end=944 - _LANGUAGE._serialized_start=946 - _LANGUAGE._serialized_end=1009 - _FLOATARG._serialized_start=1011 - _FLOATARG._serialized_end=1118 - _XPOWGATE._serialized_start=1120 - _XPOWGATE._serialized_end=1178 - _YPOWGATE._serialized_start=1180 - _YPOWGATE._serialized_end=1238 - _ZPOWGATE._serialized_start=1240 - _ZPOWGATE._serialized_end=1321 - _PHASEDXPOWGATE._serialized_start=1323 - _PHASEDXPOWGATE._serialized_end=1441 - _PHASEDXZGATE._serialized_start=1444 - _PHASEDXZGATE._serialized_end=1617 - _CZPOWGATE._serialized_start=1619 - _CZPOWGATE._serialized_end=1678 - _FSIMGATE._serialized_start=1680 - _FSIMGATE._serialized_end=1778 - _ISWAPPOWGATE._serialized_start=1780 - _ISWAPPOWGATE._serialized_end=1842 - _MEASUREMENTGATE._serialized_start=1844 - _MEASUREMENTGATE._serialized_end=1945 - _WAITGATE._serialized_start=1947 - _WAITGATE._serialized_end=2011 - _OPERATION._serialized_start=2014 - _OPERATION._serialized_end=2951 - _OPERATION_ARGSENTRY._serialized_start=2860 - _OPERATION_ARGSENTRY._serialized_end=2928 - _GATE._serialized_start=2953 - _GATE._serialized_end=2971 - _QUBIT._serialized_start=2973 - _QUBIT._serialized_end=2992 - _ARG._serialized_start=2995 - _ARG._serialized_end=3151 - _ARGVALUE._serialized_start=3154 - _ARGVALUE._serialized_end=3489 - _REPEATEDINT64._serialized_start=3491 - _REPEATEDINT64._serialized_end=3522 - _REPEATEDDOUBLE._serialized_start=3524 - _REPEATEDDOUBLE._serialized_end=3556 - _REPEATEDSTRING._serialized_start=3558 - _REPEATEDSTRING._serialized_end=3590 - _REPEATEDBOOLEAN._serialized_start=3592 - _REPEATEDBOOLEAN._serialized_end=3625 - _ARGFUNCTION._serialized_start=3627 - _ARGFUNCTION._serialized_end=3693 - _CIRCUITOPERATION._serialized_start=3696 - _CIRCUITOPERATION._serialized_end=3999 - _REPETITIONSPECIFICATION._serialized_start=4002 - _REPETITIONSPECIFICATION._serialized_end=4190 - _REPETITIONSPECIFICATION_REPETITIONIDS._serialized_start=4142 - _REPETITIONSPECIFICATION_REPETITIONIDS._serialized_end=4170 - _QUBITMAPPING._serialized_start=4193 - _QUBITMAPPING._serialized_end=4365 - _QUBITMAPPING_QUBITENTRY._serialized_start=4271 - _QUBITMAPPING_QUBITENTRY._serialized_end=4365 - _MEASUREMENTKEY._serialized_start=4367 - _MEASUREMENTKEY._serialized_end=4403 - _MEASUREMENTKEYMAPPING._serialized_start=4406 - _MEASUREMENTKEYMAPPING._serialized_end=4632 - _MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY._serialized_start=4511 - _MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY._serialized_end=4632 - _ARGMAPPING._serialized_start=4635 - _ARGMAPPING._serialized_end=4795 - _ARGMAPPING_ARGENTRY._serialized_start=4707 - _ARGMAPPING_ARGENTRY._serialized_end=4795 - _INTERNALGATE._serialized_start=4798 - _INTERNALGATE._serialized_end=5003 - _INTERNALGATE_GATEARGSENTRY._serialized_start=4931 - _INTERNALGATE_GATEARGSENTRY._serialized_end=5003 + _globals['_PROGRAM']._serialized_start=57 + _globals['_PROGRAM']._serialized_end=272 + _globals['_CONSTANT']._serialized_start=275 + _globals['_CONSTANT']._serialized_end=422 + _globals['_CIRCUIT']._serialized_start=425 + _globals['_CIRCUIT']._serialized_end=637 + _globals['_CIRCUIT_SCHEDULINGSTRATEGY']._serialized_start=558 + _globals['_CIRCUIT_SCHEDULINGSTRATEGY']._serialized_end=637 + _globals['_MOMENT']._serialized_start=639 + _globals['_MOMENT']._serialized_end=764 + _globals['_SCHEDULE']._serialized_start=766 + _globals['_SCHEDULE']._serialized_end=846 + _globals['_SCHEDULEDOPERATION']._serialized_start=848 + _globals['_SCHEDULEDOPERATION']._serialized_end=944 + _globals['_LANGUAGE']._serialized_start=946 + _globals['_LANGUAGE']._serialized_end=1009 + _globals['_FLOATARG']._serialized_start=1011 + _globals['_FLOATARG']._serialized_end=1118 + _globals['_XPOWGATE']._serialized_start=1120 + _globals['_XPOWGATE']._serialized_end=1178 + _globals['_YPOWGATE']._serialized_start=1180 + _globals['_YPOWGATE']._serialized_end=1238 + _globals['_ZPOWGATE']._serialized_start=1240 + _globals['_ZPOWGATE']._serialized_end=1321 + _globals['_PHASEDXPOWGATE']._serialized_start=1323 + _globals['_PHASEDXPOWGATE']._serialized_end=1441 + _globals['_PHASEDXZGATE']._serialized_start=1444 + _globals['_PHASEDXZGATE']._serialized_end=1617 + _globals['_CZPOWGATE']._serialized_start=1619 + _globals['_CZPOWGATE']._serialized_end=1678 + _globals['_FSIMGATE']._serialized_start=1680 + _globals['_FSIMGATE']._serialized_end=1778 + _globals['_ISWAPPOWGATE']._serialized_start=1780 + _globals['_ISWAPPOWGATE']._serialized_end=1842 + _globals['_MEASUREMENTGATE']._serialized_start=1844 + _globals['_MEASUREMENTGATE']._serialized_end=1945 + _globals['_WAITGATE']._serialized_start=1947 + _globals['_WAITGATE']._serialized_end=2011 + _globals['_OPERATION']._serialized_start=2014 + _globals['_OPERATION']._serialized_end=2951 + _globals['_OPERATION_ARGSENTRY']._serialized_start=2860 + _globals['_OPERATION_ARGSENTRY']._serialized_end=2928 + _globals['_GATE']._serialized_start=2953 + _globals['_GATE']._serialized_end=2971 + _globals['_QUBIT']._serialized_start=2973 + _globals['_QUBIT']._serialized_end=2992 + _globals['_ARG']._serialized_start=2995 + _globals['_ARG']._serialized_end=3151 + _globals['_ARGVALUE']._serialized_start=3154 + _globals['_ARGVALUE']._serialized_end=3489 + _globals['_REPEATEDINT64']._serialized_start=3491 + _globals['_REPEATEDINT64']._serialized_end=3522 + _globals['_REPEATEDDOUBLE']._serialized_start=3524 + _globals['_REPEATEDDOUBLE']._serialized_end=3556 + _globals['_REPEATEDSTRING']._serialized_start=3558 + _globals['_REPEATEDSTRING']._serialized_end=3590 + _globals['_REPEATEDBOOLEAN']._serialized_start=3592 + _globals['_REPEATEDBOOLEAN']._serialized_end=3625 + _globals['_ARGFUNCTION']._serialized_start=3627 + _globals['_ARGFUNCTION']._serialized_end=3693 + _globals['_CIRCUITOPERATION']._serialized_start=3696 + _globals['_CIRCUITOPERATION']._serialized_end=3999 + _globals['_REPETITIONSPECIFICATION']._serialized_start=4002 + _globals['_REPETITIONSPECIFICATION']._serialized_end=4190 + _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_start=4142 + _globals['_REPETITIONSPECIFICATION_REPETITIONIDS']._serialized_end=4170 + _globals['_QUBITMAPPING']._serialized_start=4193 + _globals['_QUBITMAPPING']._serialized_end=4365 + _globals['_QUBITMAPPING_QUBITENTRY']._serialized_start=4271 + _globals['_QUBITMAPPING_QUBITENTRY']._serialized_end=4365 + _globals['_MEASUREMENTKEY']._serialized_start=4367 + _globals['_MEASUREMENTKEY']._serialized_end=4403 + _globals['_MEASUREMENTKEYMAPPING']._serialized_start=4406 + _globals['_MEASUREMENTKEYMAPPING']._serialized_end=4632 + _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_start=4511 + _globals['_MEASUREMENTKEYMAPPING_MEASUREMENTKEYENTRY']._serialized_end=4632 + _globals['_ARGMAPPING']._serialized_start=4635 + _globals['_ARGMAPPING']._serialized_end=4795 + _globals['_ARGMAPPING_ARGENTRY']._serialized_start=4707 + _globals['_ARGMAPPING_ARGENTRY']._serialized_end=4795 + _globals['_INTERNALGATE']._serialized_start=4798 + _globals['_INTERNALGATE']._serialized_end=5003 + _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_start=4931 + _globals['_INTERNALGATE_GATEARGSENTRY']._serialized_end=5003 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/program_pb2.pyi b/cirq-google/cirq_google/api/v2/program_pb2.pyi index ac75a2dc0ac..aa688fabb77 100644 --- a/cirq-google/cirq_google/api/v2/program_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/program_pb2.pyi @@ -105,7 +105,7 @@ class Circuit(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _SchedulingStrategyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Circuit._SchedulingStrategy.ValueType], builtins.type): + class _SchedulingStrategyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Circuit._SchedulingStrategy.ValueType], builtins.type): # noqa: F821 DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SCHEDULING_STRATEGY_UNSPECIFIED: Circuit._SchedulingStrategy.ValueType # 0 """The scheduling strategy is unspecified.""" diff --git a/cirq-google/cirq_google/api/v2/result_pb2.py b/cirq-google/cirq_google/api/v2/result_pb2.py index 6b202adc7bd..bcc5007d653 100644 --- a/cirq-google/cirq_google/api/v2/result_pb2.py +++ b/cirq-google/cirq_google/api/v2/result_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/result.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -16,26 +16,27 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63irq_google/api/v2/result.proto\x12\x12\x63irq.google.api.v2\x1a cirq_google/api/v2/program.proto\"@\n\x06Result\x12\x36\n\rsweep_results\x18\x01 \x03(\x0b\x32\x1f.cirq.google.api.v2.SweepResult\"j\n\x0bSweepResult\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12\x46\n\x15parameterized_results\x18\x02 \x03(\x0b\x32\'.cirq.google.api.v2.ParameterizedResult\"\x8c\x01\n\x13ParameterizedResult\x12\x31\n\x06params\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.ParameterDict\x12\x42\n\x13measurement_results\x18\x02 \x03(\x0b\x32%.cirq.google.api.v2.MeasurementResult\"\x82\x01\n\x11MeasurementResult\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x11\n\tinstances\x18\x03 \x01(\x05\x12M\n\x19qubit_measurement_results\x18\x02 \x03(\x0b\x32*.cirq.google.api.v2.QubitMeasurementResult\"S\n\x16QubitMeasurementResult\x12(\n\x05qubit\x18\x01 \x01(\x0b\x32\x19.cirq.google.api.v2.Qubit\x12\x0f\n\x07results\x18\x02 \x01(\x0c\"\x8c\x01\n\rParameterDict\x12G\n\x0b\x61ssignments\x18\x01 \x03(\x0b\x32\x32.cirq.google.api.v2.ParameterDict.AssignmentsEntry\x1a\x32\n\x10\x41ssignmentsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x42.\n\x1d\x63om.google.cirq.google.api.v2B\x0bResultProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.result_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.result_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\013ResultProtoP\001' _PARAMETERDICT_ASSIGNMENTSENTRY._options = None _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_options = b'8\001' - _RESULT._serialized_start=89 - _RESULT._serialized_end=153 - _SWEEPRESULT._serialized_start=155 - _SWEEPRESULT._serialized_end=261 - _PARAMETERIZEDRESULT._serialized_start=264 - _PARAMETERIZEDRESULT._serialized_end=404 - _MEASUREMENTRESULT._serialized_start=407 - _MEASUREMENTRESULT._serialized_end=537 - _QUBITMEASUREMENTRESULT._serialized_start=539 - _QUBITMEASUREMENTRESULT._serialized_end=622 - _PARAMETERDICT._serialized_start=625 - _PARAMETERDICT._serialized_end=765 - _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_start=715 - _PARAMETERDICT_ASSIGNMENTSENTRY._serialized_end=765 + _globals['_RESULT']._serialized_start=89 + _globals['_RESULT']._serialized_end=153 + _globals['_SWEEPRESULT']._serialized_start=155 + _globals['_SWEEPRESULT']._serialized_end=261 + _globals['_PARAMETERIZEDRESULT']._serialized_start=264 + _globals['_PARAMETERIZEDRESULT']._serialized_end=404 + _globals['_MEASUREMENTRESULT']._serialized_start=407 + _globals['_MEASUREMENTRESULT']._serialized_end=537 + _globals['_QUBITMEASUREMENTRESULT']._serialized_start=539 + _globals['_QUBITMEASUREMENTRESULT']._serialized_end=622 + _globals['_PARAMETERDICT']._serialized_start=625 + _globals['_PARAMETERDICT']._serialized_end=765 + _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_start=715 + _globals['_PARAMETERDICT_ASSIGNMENTSENTRY']._serialized_end=765 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.py b/cirq-google/cirq_google/api/v2/run_context_pb2.py index 5b6b9afeed5..ac1fbe25102 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.py +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: cirq_google/api/v2/run_context.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -15,28 +15,29 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$cirq_google/api/v2/run_context.proto\x12\x12\x63irq.google.api.v2\"J\n\nRunContext\x12<\n\x10parameter_sweeps\x18\x01 \x03(\x0b\x32\".cirq.google.api.v2.ParameterSweep\"O\n\x0eParameterSweep\x12\x13\n\x0brepetitions\x18\x01 \x01(\x05\x12(\n\x05sweep\x18\x02 \x01(\x0b\x32\x19.cirq.google.api.v2.Sweep\"\x86\x01\n\x05Sweep\x12;\n\x0esweep_function\x18\x01 \x01(\x0b\x32!.cirq.google.api.v2.SweepFunctionH\x00\x12\x37\n\x0csingle_sweep\x18\x02 \x01(\x0b\x32\x1f.cirq.google.api.v2.SingleSweepH\x00\x42\x07\n\x05sweep\"\xc6\x01\n\rSweepFunction\x12\x45\n\rfunction_type\x18\x01 \x01(\x0e\x32..cirq.google.api.v2.SweepFunction.FunctionType\x12)\n\x06sweeps\x18\x02 \x03(\x0b\x32\x19.cirq.google.api.v2.Sweep\"C\n\x0c\x46unctionType\x12\x1d\n\x19\x46UNCTION_TYPE_UNSPECIFIED\x10\x00\x12\x0b\n\x07PRODUCT\x10\x01\x12\x07\n\x03ZIP\x10\x02\"W\n\x0f\x44\x65viceParameter\x12\x0c\n\x04path\x18\x01 \x03(\t\x12\x10\n\x03idx\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x12\n\x05units\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x06\n\x04_idxB\x08\n\x06_units\"\xc5\x01\n\x0bSingleSweep\x12\x15\n\rparameter_key\x18\x01 \x01(\t\x12,\n\x06points\x18\x02 \x01(\x0b\x32\x1a.cirq.google.api.v2.PointsH\x00\x12\x30\n\x08linspace\x18\x03 \x01(\x0b\x32\x1c.cirq.google.api.v2.LinspaceH\x00\x12\x36\n\tparameter\x18\x04 \x01(\x0b\x32#.cirq.google.api.v2.DeviceParameterB\x07\n\x05sweep\"\x18\n\x06Points\x12\x0e\n\x06points\x18\x01 \x03(\x02\"G\n\x08Linspace\x12\x13\n\x0b\x66irst_point\x18\x01 \x01(\x02\x12\x12\n\nlast_point\x18\x02 \x01(\x02\x12\x12\n\nnum_points\x18\x03 \x01(\x03\x42\x32\n\x1d\x63om.google.cirq.google.api.v2B\x0fRunContextProtoP\x01\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.run_context_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cirq_google.api.v2.run_context_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\035com.google.cirq.google.api.v2B\017RunContextProtoP\001' - _RUNCONTEXT._serialized_start=60 - _RUNCONTEXT._serialized_end=134 - _PARAMETERSWEEP._serialized_start=136 - _PARAMETERSWEEP._serialized_end=215 - _SWEEP._serialized_start=218 - _SWEEP._serialized_end=352 - _SWEEPFUNCTION._serialized_start=355 - _SWEEPFUNCTION._serialized_end=553 - _SWEEPFUNCTION_FUNCTIONTYPE._serialized_start=486 - _SWEEPFUNCTION_FUNCTIONTYPE._serialized_end=553 - _DEVICEPARAMETER._serialized_start=555 - _DEVICEPARAMETER._serialized_end=642 - _SINGLESWEEP._serialized_start=645 - _SINGLESWEEP._serialized_end=842 - _POINTS._serialized_start=844 - _POINTS._serialized_end=868 - _LINSPACE._serialized_start=870 - _LINSPACE._serialized_end=941 + _globals['_RUNCONTEXT']._serialized_start=60 + _globals['_RUNCONTEXT']._serialized_end=134 + _globals['_PARAMETERSWEEP']._serialized_start=136 + _globals['_PARAMETERSWEEP']._serialized_end=215 + _globals['_SWEEP']._serialized_start=218 + _globals['_SWEEP']._serialized_end=352 + _globals['_SWEEPFUNCTION']._serialized_start=355 + _globals['_SWEEPFUNCTION']._serialized_end=553 + _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_start=486 + _globals['_SWEEPFUNCTION_FUNCTIONTYPE']._serialized_end=553 + _globals['_DEVICEPARAMETER']._serialized_start=555 + _globals['_DEVICEPARAMETER']._serialized_end=642 + _globals['_SINGLESWEEP']._serialized_start=645 + _globals['_SINGLESWEEP']._serialized_end=842 + _globals['_POINTS']._serialized_start=844 + _globals['_POINTS']._serialized_end=868 + _globals['_LINSPACE']._serialized_start=870 + _globals['_LINSPACE']._serialized_end=941 # @@protoc_insertion_point(module_scope) diff --git a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi index ea34266c37a..75afaa133e1 100644 --- a/cirq-google/cirq_google/api/v2/run_context_pb2.pyi +++ b/cirq-google/cirq_google/api/v2/run_context_pb2.pyi @@ -105,7 +105,7 @@ class SweepFunction(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _FunctionTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SweepFunction._FunctionType.ValueType], builtins.type): + class _FunctionTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SweepFunction._FunctionType.ValueType], builtins.type): # noqa: F821 DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor FUNCTION_TYPE_UNSPECIFIED: SweepFunction._FunctionType.ValueType # 0 """The function type is not specified. Should never be used.""" From 8aee9009dd267a91ffe70385eb858cf1aa42489c Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 9 Feb 2024 02:39:31 +0000 Subject: [PATCH 12/23] lint --- .../cirq_google/calibration/phased_fsim.py | 6 - .../calibration/phased_fsim_test.py | 5 - .../cirq_google/calibration/workflow.py | 92 +-------------- .../cirq_google/calibration/workflow_test.py | 3 - .../cirq_google/engine/abstract_job.py | 10 -- .../cirq_google/engine/abstract_job_test.py | 3 - .../engine/abstract_local_engine_test.py | 6 - .../engine/abstract_local_job_test.py | 4 - .../engine/abstract_local_processor_test.py | 6 - .../cirq_google/engine/abstract_processor.py | 108 +----------------- cirq-google/cirq_google/engine/engine.py | 77 ------------- cirq-google/cirq_google/engine/engine_job.py | 27 ----- .../cirq_google/engine/engine_processor.py | 10 +- .../cirq_google/engine/engine_program.py | 66 +---------- .../cirq_google/engine/engine_validator.py | 43 +++++++ .../engine/simulated_local_engine_test.py | 6 - .../cirq_google/engine/simulated_local_job.py | 8 -- .../engine/simulated_local_processor.py | 43 +------ .../engine/virtual_engine_factory.py | 2 +- 19 files changed, 55 insertions(+), 470 deletions(-) diff --git a/cirq-google/cirq_google/calibration/phased_fsim.py b/cirq-google/cirq_google/calibration/phased_fsim.py index fbef6271e0f..1f06912a50e 100644 --- a/cirq-google/cirq_google/calibration/phased_fsim.py +++ b/cirq-google/cirq_google/calibration/phased_fsim.py @@ -729,9 +729,6 @@ def to_calibration_layer(self) -> CalibrationLayer: def parse_result( self, result: CalibrationResult, job: Optional[EngineJob] = None ) -> PhasedFSimCalibrationResult: - if result.code != v2.calibration_pb2.SUCCESS: - raise PhasedFSimCalibrationError(result.error_message) - decoded: Dict[int, Dict[str, Any]] = collections.defaultdict(lambda: {}) for keys, values in result.metrics['angles'].items(): for key, value in zip(keys, values): @@ -915,9 +912,6 @@ def to_calibration_layer(self) -> CalibrationLayer: def parse_result( self, result: CalibrationResult, job: Optional[EngineJob] = None ) -> PhasedFSimCalibrationResult: - if result.code != v2.calibration_pb2.SUCCESS: - raise PhasedFSimCalibrationError(result.error_message) - # pylint: disable=unused-variable initial_fids = _parse_xeb_fidelities_df(result.metrics, 'initial_fidelities') final_fids = _parse_xeb_fidelities_df(result.metrics, 'final_fidelities') diff --git a/cirq-google/cirq_google/calibration/phased_fsim_test.py b/cirq-google/cirq_google/calibration/phased_fsim_test.py index 4b60b051cac..00d4cb38815 100644 --- a/cirq-google/cirq_google/calibration/phased_fsim_test.py +++ b/cirq-google/cirq_google/calibration/phased_fsim_test.py @@ -323,7 +323,6 @@ def test_floquet_parse_result(): ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, error_message=None, token=None, valid_until=None, @@ -397,7 +396,6 @@ def test_floquet_parse_result_failure(): ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.ERROR_CALIBRATION_FAILED, error_message="Test message", token=None, valid_until=None, @@ -414,7 +412,6 @@ def _load_xeb_results_textproto() -> cirq_google.CalibrationResult: f.read(), cirq_google.api.v2.metrics_pb2.MetricsSnapshot() ) return cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, # type: ignore error_message=None, token=None, valid_until=None, @@ -516,7 +513,6 @@ def test_xeb_parse_result_failure(): ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.ERROR_CALIBRATION_FAILED, error_message="Test message", token=None, valid_until=None, @@ -570,7 +566,6 @@ def test_floquet_parse_result_bad_metric(): ), ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, error_message=None, token=None, valid_until=None, diff --git a/cirq-google/cirq_google/calibration/workflow.py b/cirq-google/cirq_google/calibration/workflow.py index 37bf3456c09..289dcbca37b 100644 --- a/cirq-google/cirq_google/calibration/workflow.py +++ b/cirq-google/cirq_google/calibration/workflow.py @@ -17,7 +17,6 @@ import cirq from cirq.experiments import HALF_GRID_STAGGERED_PATTERN -from cirq_google.calibration.engine_simulator import PhasedFSimEngineSimulator from cirq_google.calibration.phased_fsim import ( FloquetPhasedFSimCalibrationOptions, FloquetPhasedFSimCalibrationRequest, @@ -36,7 +35,7 @@ LocalXEBPhasedFSimCalibrationRequest, ) from cirq_google.calibration.xeb_wrapper import run_local_xeb_calibration -from cirq_google.engine import AbstractProcessor, AbstractEngine, ProcessorSampler +from cirq_google.engine import AbstractEngine _CALIBRATION_IRRELEVANT_GATES = cirq.MeasurementGate, cirq.WaitGate @@ -727,38 +726,6 @@ def _merge_into_calibrations( return index -def _run_calibrations_via_engine( - calibration_requests: Sequence[PhasedFSimCalibrationRequest], - processor: AbstractProcessor, - max_layers_per_request: int = 1, - progress_func: Optional[Callable[[int, int], None]] = None, -): - """Helper function for run_calibrations. - - This batches and runs calibration requests the normal way: by using engine.run_calibration. - This function assumes that all inputs have been validated (by `run_calibrations`). - """ - results = [] - nested_calibration_layers = [ - [ - calibration.to_calibration_layer() - for calibration in calibration_requests[offset : offset + max_layers_per_request] - ] - for offset in range(0, len(calibration_requests), max_layers_per_request) - ] - - for cal_layers in nested_calibration_layers: - job = processor.run_calibration(cal_layers) - request_results = job.calibration_results() - results += [ - calibration.parse_result(result, job) # type: ignore[arg-type] - for calibration, result in zip(calibration_requests, request_results) - ] - if progress_func: - progress_func(len(results), len(calibration_requests)) - return results - - def _run_local_calibrations_via_sampler( calibration_requests: Sequence[PhasedFSimCalibrationRequest], sampler: cirq.Sampler ): @@ -802,52 +769,7 @@ def run_calibrations( different types was supplied, if no `processor_id` or `gate_set` is provided, or if the calibration / sampler combo is not supported. """ - if max_layers_per_request < 1: - raise ValueError( - f'Maximum number of layers per request must be at least 1, {max_layers_per_request} ' - f'given' - ) - - if not calibrations: - return [] - - calibration_request_types = set(type(cr) for cr in calibrations) - if len(calibration_request_types) > 1: - raise ValueError( - f"All calibrations must be of the same type. You gave: {calibration_request_types}" - ) - (calibration_request_type,) = calibration_request_types - - if isinstance(sampler, AbstractEngine): - if processor_id is None: - raise ValueError('processor_id must be provided.') # pragma: no cover - processor: Optional[AbstractProcessor] = sampler.get_processor(processor_id=processor_id) - elif isinstance(sampler, ProcessorSampler): - processor = sampler.processor - else: - processor = None - - if processor is not None: - if calibration_request_type == LocalXEBPhasedFSimCalibrationRequest: - engine_sampler = processor.get_sampler() - return _run_local_calibrations_via_sampler(calibrations, engine_sampler) - - return _run_calibrations_via_engine( - calibrations, processor, max_layers_per_request, progress_func - ) - - if calibration_request_type == LocalXEBPhasedFSimCalibrationRequest: - return _run_local_calibrations_via_sampler( - calibrations, sampler=cast(cirq.Sampler, sampler) - ) - - if isinstance(sampler, PhasedFSimEngineSimulator): - return sampler.get_calibrations(calibrations) - - raise ValueError( - f'Unsupported sampler/request combination: Sampler {sampler} cannot run ' - f'calibration request of type {calibration_request_type}' - ) + raise NotImplementedError def make_zeta_chi_gamma_compensation_for_moments( @@ -982,12 +904,10 @@ def _make_zeta_chi_gamma_compensation( if characterization_index is not None: parameters = characterizations[characterization_index] - ( - decompositions, - decompositions_moment_to_calibration, - other, - ) = _find_moment_zeta_chi_gamma_corrections( - moment, characterization_index, parameters, gates_translator + (decompositions, decompositions_moment_to_calibration, other) = ( + _find_moment_zeta_chi_gamma_corrections( + moment, characterization_index, parameters, gates_translator + ) ) if decompositions: diff --git a/cirq-google/cirq_google/calibration/workflow_test.py b/cirq-google/cirq_google/calibration/workflow_test.py index 7d6d1f4c90f..f94b749d1ed 100644 --- a/cirq-google/cirq_google/calibration/workflow_test.py +++ b/cirq-google/cirq_google/calibration/workflow_test.py @@ -964,7 +964,6 @@ def test_run_calibrations(): ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, error_message=None, token=None, valid_until=None, @@ -1067,7 +1066,6 @@ def test_run_characterization_with_engine(): ) result = cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, error_message=None, token=None, valid_until=None, @@ -1228,7 +1226,6 @@ def test_run_floquet_characterization_for_moments(): job = cirq_google.engine.EngineJob('project_id', 'program_id', 'job_id', None) job._calibration_results = [ cirq_google.CalibrationResult( - code=cirq_google.api.v2.calibration_pb2.SUCCESS, error_message=None, token=None, valid_until=None, diff --git a/cirq-google/cirq_google/engine/abstract_job.py b/cirq-google/cirq_google/engine/abstract_job.py index 1fba672e705..78106d6f784 100644 --- a/cirq-google/cirq_google/engine/abstract_job.py +++ b/cirq-google/cirq_google/engine/abstract_job.py @@ -25,7 +25,6 @@ if TYPE_CHECKING: import datetime import cirq_google.engine.calibration as calibration - import cirq_google.engine.calibration_result as calibration_result import cirq_google.engine.abstract_engine as abstract_engine import cirq_google.engine.abstract_processor as abstract_processor import cirq_google.engine.abstract_program as abstract_program @@ -169,15 +168,6 @@ async def results_async(self) -> Sequence[EngineResult]: results = duet.sync(results_async) - @abc.abstractmethod - async def calibration_results_async(self) -> Sequence['calibration_result.CalibrationResult']: - """Returns the results of a run_calibration() call. - - This function will fail if any other type of results were returned. - """ - - calibration_results = duet.sync(calibration_results_async) - def __iter__(self) -> Iterator[cirq.Result]: yield from self.results() diff --git a/cirq-google/cirq_google/engine/abstract_job_test.py b/cirq-google/cirq_google/engine/abstract_job_test.py index c639b237f0e..8994c6905ac 100644 --- a/cirq-google/cirq_google/engine/abstract_job_test.py +++ b/cirq-google/cirq_google/engine/abstract_job_test.py @@ -84,9 +84,6 @@ def delete(self) -> None: async def results_async(self): return [cirq.ResultDict(params={}, measurements={'a': np.asarray([t])}) for t in range(5)] - async def calibration_results_async(self): - pass - def test_instantiation_and_iteration(): job = MockJob() diff --git a/cirq-google/cirq_google/engine/abstract_local_engine_test.py b/cirq-google/cirq_google/engine/abstract_local_engine_test.py index e7f8498ca71..50a43704619 100644 --- a/cirq-google/cirq_google/engine/abstract_local_engine_test.py +++ b/cirq-google/cirq_google/engine/abstract_local_engine_test.py @@ -53,12 +53,6 @@ def health(self, *args, **kwargs): def list_calibrations(self, *args, **kwargs): pass - async def run_batch_async(self, *args, **kwargs): - pass - - async def run_calibration_async(self, *args, **kwargs): - pass - async def run_sweep_async(self, *args, **kwargs): pass diff --git a/cirq-google/cirq_google/engine/abstract_local_job_test.py b/cirq-google/cirq_google/engine/abstract_local_job_test.py index 8cc4567753d..2104775faef 100644 --- a/cirq-google/cirq_google/engine/abstract_local_job_test.py +++ b/cirq-google/cirq_google/engine/abstract_local_job_test.py @@ -17,7 +17,6 @@ import cirq from cirq_google.cloud import quantum -from cirq_google.engine.calibration_result import CalibrationResult from cirq_google.engine.abstract_local_job import AbstractLocalJob from cirq_google.engine.engine_result import EngineResult @@ -44,9 +43,6 @@ def delete(self) -> None: async def results_async(self) -> Sequence[EngineResult]: return [] # pragma: no cover - async def calibration_results_async(self) -> Sequence[CalibrationResult]: - return [] # pragma: no cover - def test_description_and_labels(): job = NothingJob( diff --git a/cirq-google/cirq_google/engine/abstract_local_processor_test.py b/cirq-google/cirq_google/engine/abstract_local_processor_test.py index 7e621bcd8c3..f9dcac00731 100644 --- a/cirq-google/cirq_google/engine/abstract_local_processor_test.py +++ b/cirq-google/cirq_google/engine/abstract_local_processor_test.py @@ -52,12 +52,6 @@ def health(self, *args, **kwargs): def list_calibrations(self, *args, **kwargs): pass - async def run_batch_async(self, *args, **kwargs): - pass - - async def run_calibration_async(self, *args, **kwargs): - pass - async def run_sweep_async(self, *args, **kwargs): pass diff --git a/cirq-google/cirq_google/engine/abstract_processor.py b/cirq-google/cirq_google/engine/abstract_processor.py index 0ac47f8672c..0ec26f2c7e7 100644 --- a/cirq-google/cirq_google/engine/abstract_processor.py +++ b/cirq-google/cirq_google/engine/abstract_processor.py @@ -20,7 +20,7 @@ import abc import datetime -from typing import Dict, List, Optional, Sequence, TYPE_CHECKING, Union +from typing import Dict, List, Optional, TYPE_CHECKING, Union import duet @@ -163,112 +163,6 @@ async def run_sweep_async( run_sweep = duet.sync(run_sweep_async) - @abc.abstractmethod - async def run_batch_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - params_list: Optional[Sequence[cirq.Sweepable]] = None, - repetitions: int = 1, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - run_name: str = "", - device_config_name: str = "", - ) -> 'abstract_job.AbstractJob': - """Runs the supplied Circuits on this processor. - - This will combine each Circuit provided in `programs` into - a BatchProgram. Each circuit will pair with the associated - parameter sweep provided in the `params_list`. The number of - programs is required to match the number of sweeps. - This method does not block until a result is returned. However, - no results will be available until the entire batch is complete. - Args: - programs: The Circuits to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'prog-################YYMMDD' will be generated, where # is - alphanumeric and YYMMDD is the current year, month, and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'job-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - params_list: Parameter sweeps to use with the circuits. The number - of sweeps should match the number of circuits and will be - paired in order with the circuits. If this is None, it is - assumed that the circuits are not parameterized and do not - require sweeps. - repetitions: Number of circuit repetitions to run. Each sweep value - of each circuit in the batch will run with the same repetitions. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. - run_name: A unique identifier representing an automation run for the - processor. An Automation Run contains a collection of device - configurations for the processor. - device_config_name: An identifier used to select the processor configuration - utilized to run the job. A configuration identifies the set of - available qubits, couplers, and supported gates in the processor. - Returns: - An AbstractJob. If this is iterated over it returns a list of - `cirq.Result`. All Results for the first circuit are listed - first, then the Results for the second, etc. The Results - for a circuit are listed in the order imposed by the associated - parameter sweep. - """ - - run_batch = duet.sync(run_batch_async) - - @abc.abstractmethod - async def run_calibration_async( - self, - layers: List['cg.CalibrationLayer'], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - ) -> 'abstract_job.AbstractJob': - """Runs the specified calibrations on the processor. - - Each calibration will be specified by a `CalibrationLayer` - that contains the type of the calibrations to run, a `Circuit` - to optimize, and any arguments needed by the calibration routine. - Arguments and circuits needed for each layer will vary based on the - calibration type. However, the typical calibration routine may - require a single moment defining the gates to optimize, for example. - Note: this is an experimental API and is not yet fully supported - for all users. - Args: - layers: The layers of calibration to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'calibration-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'calibration-################YYMMDD' will be - generated, where # is alphanumeric and YYMMDD is the current - year, month, and day. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. By default, - this will add a 'calibration' label to the job. - Returns: - An AbstractJob whose results can be retrieved by calling - calibration_results(). - """ - - run_calibration = duet.sync(run_calibration_async) - @abc.abstractmethod def get_sampler( self, run_name: str = "", device_config_name: str = "" diff --git a/cirq-google/cirq_google/engine/engine.py b/cirq-google/cirq_google/engine/engine.py index 3ae9672e88e..3db1d91b5e2 100644 --- a/cirq-google/cirq_google/engine/engine.py +++ b/cirq-google/cirq_google/engine/engine.py @@ -413,83 +413,6 @@ async def run_sweep_async( run_sweep = duet.sync(run_sweep_async) - # TODO(#5996) Migrate to stream client - async def run_calibration_async( - self, - layers: List['cirq_google.CalibrationLayer'], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - processor_id: Optional[str] = None, - processor_ids: Sequence[str] = (), - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - ) -> engine_job.EngineJob: - """Runs the specified calibrations via the Calibration API. - - Each calibration will be specified by a `CalibrationLayer` - that contains the type of the calibrations to run, a `Circuit` - to optimize, and any arguments needed by the calibration routine. - - Arguments and circuits needed for each layer will vary based on the - calibration type. However, the typical calibration routine may - require a single moment defining the gates to optimize, for example. - - Note: this is an experimental API and is not yet fully supported - for all users. - - Args: - layers: The layers of calibration to execute as a batch. - program_id: A user-provided identifier for the program. This must - be unique within the Google Cloud project being used. If this - parameter is not provided, a random id of the format - 'calibration-################YYMMDD' will be generated, - where # is alphanumeric and YYMMDD is the current year, month, - and day. - job_id: Job identifier to use. If this is not provided, a random id - of the format 'calibration-################YYMMDD' will be - generated, where # is alphanumeric and YYMMDD is the current - year, month, and day. - processor_id: The engine processor that should run the calibration. - If this is specified, processor_ids should not be specified. - processor_ids: The engine processors that should be candidates - to run the program. Only one of these will be scheduled for - execution. - program_description: An optional description to set on the program. - program_labels: Optional set of labels to set on the program. - job_description: An optional description to set on the job. - job_labels: Optional set of labels to set on the job. By default, - this will add a 'calibration' label to the job. - - Returns: - An EngineJob whose results can be retrieved by calling - calibration_results(). - - Raises: - ValueError: If `processor_id` and `processor_ids` are both specified, or neither is - supplied. - """ - if processor_id and processor_ids: - raise ValueError('Only one of processor_id and processor_ids can be specified.') - if not processor_ids and not processor_id: - raise ValueError('Processor id must be specified.') - if processor_id: - processor_ids = [processor_id] - if job_labels is None: - job_labels = {'calibration': ''} - engine_program = await self.create_calibration_program_async( - layers, program_id, description=program_description, labels=program_labels - ) - return await engine_program.run_calibration_async( - job_id=job_id, - processor_ids=processor_ids, - description=job_description, - labels=job_labels, - ) - - run_calibration = duet.sync(run_calibration_async) - async def create_program_async( self, program: cirq.AbstractCircuit, diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index ebba4f12fa0..44e2254fce2 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -316,33 +316,6 @@ async def _await_result_async(self) -> quantum.QuantumResult: ) return response - async def calibration_results_async(self) -> Sequence[CalibrationResult]: - """Returns the results of a run_calibration() call. - - This function will fail if any other type of results were returned - by the Engine. - """ - import cirq_google.engine.engine as engine_base - - if self._calibration_results is None: - result_response = await self._await_result_async() - result = result_response.result - result_type = result.type_url[len(engine_base.TYPE_PREFIX) :] - if result_type != 'cirq.google.api.v2.FocusedCalibrationResult': - raise ValueError(f'Did not find calibration results, instead found: {result_type}') - parsed_val = v2.calibration_pb2.FocusedCalibrationResult.FromString(result.value) - cal_results = [] - for layer in parsed_val.results: - metrics = calibration.Calibration(layer.metrics) - message = layer.error_message or None - token = layer.token or None - ts: Optional[datetime.datetime] = None - if layer.valid_until_ms > 0: - ts = datetime.datetime.fromtimestamp(layer.valid_until_ms / 1000) - cal_results.append(CalibrationResult(layer.code, message, token, ts, metrics)) - self._calibration_results = cal_results - return self._calibration_results - def _get_job_results_v1(self, result: v1.program_pb2.Result) -> Sequence[EngineResult]: job_id = self.id() job_finished = self.update_time() diff --git a/cirq-google/cirq_google/engine/engine_processor.py b/cirq-google/cirq_google/engine/engine_processor.py index 87edabb4974..19b21d78901 100644 --- a/cirq-google/cirq_google/engine/engine_processor.py +++ b/cirq-google/cirq_google/engine/engine_processor.py @@ -14,7 +14,7 @@ import datetime -from typing import Dict, List, Optional, Sequence, TYPE_CHECKING, Union +from typing import Dict, List, Optional, TYPE_CHECKING, Union from google.protobuf import any_pb2 @@ -22,13 +22,7 @@ from cirq_google.cloud import quantum from cirq_google.api import v2 from cirq_google.devices import grid_device -from cirq_google.engine import ( - abstract_processor, - calibration, - calibration_layer, - processor_sampler, - util, -) +from cirq_google.engine import abstract_processor, calibration, processor_sampler, util if TYPE_CHECKING: import cirq_google as cg diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index a90793682dc..d5a592b51de 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -19,7 +19,7 @@ from google.protobuf import any_pb2 import cirq -from cirq_google.engine import abstract_program, engine_client, util +from cirq_google.engine import abstract_program, engine_client from cirq_google.cloud import quantum from cirq_google.engine.result_type import ResultType from cirq_google.api import v2 @@ -141,70 +141,6 @@ async def run_sweep_async( run_sweep = duet.sync(run_sweep_async) - async def run_calibration_async( - self, - job_id: Optional[str] = None, - processor_ids: Sequence[str] = (), - description: Optional[str] = None, - labels: Optional[Dict[str, str]] = None, - ) -> engine_job.EngineJob: - """Runs layers of calibration routines on the Quantum Engine. - - This method should only be used if the Program object was created - with a `FocusedCalibration`. - - This method does not block until a result is returned. However, - no results will be available until all calibration routines complete. - - Args: - job_id: Optional job id to use. If this is not provided, a random id - of the format 'calibration-################YYMMDD' will be - generated, where # is alphanumeric and YYMMDD is the current - year, month, and day. - processor_ids: The engine processors that should be candidates - to run the program. Only one of these will be scheduled for - execution. - description: An optional description to set on the job. - labels: Optional set of labels to set on the job. - - Returns: - An EngineJob. Results can be accessed with calibration_results(). - - Raises: - ValueError: If no processors are specified. - """ - import cirq_google.engine.engine as engine_base - - if not job_id: - job_id = engine_base._make_random_id('calibration-') - if not processor_ids: - raise ValueError('No processors specified') - - # Default run context - # Note that Quantum Engine currently requires a valid type url - # on a run context in order to succeed validation. - run_context = v2.run_context_pb2.RunContext() - - created_job_id, job = await self.context.client.create_job_async( - project_id=self.project_id, - program_id=self.program_id, - job_id=job_id, - processor_ids=processor_ids, - run_context=util.pack_any(run_context), - description=description, - labels=labels, - ) - return engine_job.EngineJob( - self.project_id, - self.program_id, - created_job_id, - self.context, - job, - result_type=ResultType.Batch, - ) - - run_calibration = duet.sync(run_calibration_async) - # TODO(#6271): Deprecate and remove processor_ids before v1.4 async def run_async( self, diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index d048d4749f4..2d507edff12 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -64,6 +64,49 @@ def _verify_measurements(circuits): raise RuntimeError('Code must measure at least one qubit.') +def validate_program( + circuits: Sequence[cirq.AbstractCircuit], + sweeps: Sequence[cirq.Sweepable], + repetitions: int, + serializer: Serializer, + max_size: int = MAX_MESSAGE_SIZE, +) -> None: + """Validate that the Program message size is below the maximum size limit. + Args: + circuits: A sequence of `cirq.Circuit` objects to validate. For + sweeps and runs, this will be a single circuit. For batches, + this will be a list of circuits. + sweeps: Parameters to run with each circuit. The length of the + sweeps sequence should be the same as the circuits argument. + repetitions: Number of repetitions to run with each sweep. + serializer: Serializer to use to serialize the circuits and sweeps. + max_size: proto size limit to check against. + Raises: + RuntimeError: if compiled proto is above the maximum size. + """ + + +def create_program_validator(max_size: int = MAX_MESSAGE_SIZE) -> PROGRAM_VALIDATOR_TYPE: + """Creates a Callable program validator with a set message size. + This validator can be used for a validator in `cg.ValidatingSampler` + and can also be useful in generating 'engine emulators' by using + `cg.SimulatedLocalProcessor` with this callable as a program_validator. + Args: + max_size: proto size limit to check against. + Returns: Callable to use in validation with the max_size already set. + """ + + def _validator( + circuits: Sequence[cirq.AbstractCircuit], + sweeps: Sequence[cirq.Sweepable], + repetitions: int, + serializer: Serializer, + ): + return validate_program(circuits, sweeps, repetitions, serializer, max_size) + + return _validator + + def validate_for_engine( circuits: Sequence[cirq.AbstractCircuit], sweeps: Sequence[cirq.Sweepable], diff --git a/cirq-google/cirq_google/engine/simulated_local_engine_test.py b/cirq-google/cirq_google/engine/simulated_local_engine_test.py index 2e798f5e647..1a8f3fcea31 100644 --- a/cirq-google/cirq_google/engine/simulated_local_engine_test.py +++ b/cirq-google/cirq_google/engine/simulated_local_engine_test.py @@ -57,12 +57,6 @@ def health(self, *args, **kwargs): def list_calibrations(self, *args, **kwargs): pass - async def run_batch_async(self, *args, **kwargs): - pass - - async def run_calibration_async(self, *args, **kwargs): - pass - async def run_sweep_async(self, *args, **kwargs): pass diff --git a/cirq-google/cirq_google/engine/simulated_local_job.py b/cirq-google/cirq_google/engine/simulated_local_job.py index de92a0bf25a..eac5fd21a97 100644 --- a/cirq-google/cirq_google/engine/simulated_local_job.py +++ b/cirq-google/cirq_google/engine/simulated_local_job.py @@ -21,7 +21,6 @@ import cirq from cirq_google.cloud import quantum -from cirq_google.engine.calibration_result import CalibrationResult from cirq_google.engine.abstract_local_job import AbstractLocalJob from cirq_google.engine.local_simulation_type import LocalSimulationType from cirq_google.engine.engine_result import EngineResult @@ -150,10 +149,3 @@ async def results_async(self) -> Sequence[EngineResult]: return _flatten_results(await self._future) else: raise ValueError('Unsupported simulation type {self._type}') - - async def calibration_results_async(self) -> Sequence[CalibrationResult]: - """Returns the results of a run_calibration() call. - - This function will fail if any other type of results were returned. - """ - raise NotImplementedError diff --git a/cirq-google/cirq_google/engine/simulated_local_processor.py b/cirq-google/cirq_google/engine/simulated_local_processor.py index 096da811225..c8d4cbaec8e 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor.py @@ -13,7 +13,7 @@ # limitations under the License. import datetime -from typing import Dict, List, Optional, Sequence, Union +from typing import Dict, List, Optional, Union import cirq @@ -196,44 +196,6 @@ def get_program(self, program_id: str) -> AbstractProgram: """ return self._programs[program_id] - async def run_batch_async( - self, - programs: Sequence[cirq.AbstractCircuit], - program_id: Optional[str] = None, - job_id: Optional[str] = None, - params_list: Optional[Sequence[cirq.Sweepable]] = None, - repetitions: int = 1, - program_description: Optional[str] = None, - program_labels: Optional[Dict[str, str]] = None, - job_description: Optional[str] = None, - job_labels: Optional[Dict[str, str]] = None, - run_name: str = "", - device_config_name: str = "", - ) -> SimulatedLocalJob: - if program_id is None: - program_id = self._create_id(id_type='program') - if job_id is None: - job_id = self._create_id(id_type='job') - self._program_validator(programs, params_list or [{}], repetitions, CIRCUIT_SERIALIZER) - self._programs[program_id] = SimulatedLocalProgram( - program_id=program_id, - simulation_type=self._simulation_type, - circuits=programs, - engine=self.engine(), - processor=self, - ) - job = SimulatedLocalJob( - job_id=job_id, - processor_id=self.processor_id, - parent_program=self._programs[program_id], - repetitions=repetitions, - sweeps=list(params_list) if params_list is not None else None, - sampler=self._sampler, - simulation_type=self._simulation_type, - ) - self._programs[program_id].add_job(job_id, job) - return job - async def run_sweep_async( self, program: cirq.AbstractCircuit, @@ -271,6 +233,3 @@ async def run_sweep_async( ) self._programs[program_id].add_job(job_id, job) return job - - async def run_calibration_async(self, *args, **kwargs): - raise NotImplementedError diff --git a/cirq-google/cirq_google/engine/virtual_engine_factory.py b/cirq-google/cirq_google/engine/virtual_engine_factory.py index 451db1e00fe..79c02535565 100644 --- a/cirq-google/cirq_google/engine/virtual_engine_factory.py +++ b/cirq-google/cirq_google/engine/virtual_engine_factory.py @@ -402,7 +402,7 @@ def create_default_noisy_quantum_virtual_machine( if simulator_class is None: try: # pragma: no cover - import qsimcirq # type: ignore + import qsimcirq simulator_class = qsimcirq.QSimSimulator # pragma: no cover except ImportError: From 7a12d20f130a0e6993b21d8048226b309e2ea538 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 12 Feb 2024 20:13:07 +0000 Subject: [PATCH 13/23] rm even more files --- cirq-google/cirq_google/__init__.py | 35 - .../cirq_google/calibration/__init__.py | 56 - .../calibration/engine_simulator.py | 516 ----- .../calibration/engine_simulator_test.py | 539 ----- .../cirq_google/calibration/phased_fsim.py | 1138 ----------- .../calibration/phased_fsim_test.py | 1069 ---------- .../test_data/xeb_calibration_layer.textproto | 136 -- .../test_data/xeb_results.textproto | 113 -- .../cirq_google/calibration/workflow.py | 1217 ------------ .../cirq_google/calibration/workflow_test.py | 1725 ----------------- .../cirq_google/calibration/xeb_wrapper.py | 114 -- .../calibration/xeb_wrapper_test.py | 151 -- cirq-google/cirq_google/engine/engine_job.py | 2 - .../cirq_google/engine/engine_program_test.py | 16 - .../engine/simulated_local_job_test.py | 13 - .../engine/simulated_local_processor_test.py | 6 - .../engine/virtual_engine_factory.py | 2 +- .../cirq_google/json_resolver_cache.py | 8 - .../json_test_data/CalibrationResult.json | 1 - .../CalibrationResult.json_inward | 1 - .../json_test_data/CalibrationResult.repr | 1 - .../CalibrationResult.repr_inward | 1 - .../FloquetPhasedFSimCalibrationOptions.json | 11 - ...etPhasedFSimCalibrationOptions.json_inward | 8 - .../FloquetPhasedFSimCalibrationOptions.repr | 1 - ...etPhasedFSimCalibrationOptions.repr_inward | 1 - .../FloquetPhasedFSimCalibrationRequest.json | 45 - ...etPhasedFSimCalibrationRequest.json_inward | 42 - .../FloquetPhasedFSimCalibrationRequest.repr | 13 - ...etPhasedFSimCalibrationRequest.repr_inward | 11 - .../LocalXEBPhasedFSimCalibrationOptions.json | 29 - .../LocalXEBPhasedFSimCalibrationOptions.repr | 1 - .../LocalXEBPhasedFSimCalibrationRequest.json | 63 - .../LocalXEBPhasedFSimCalibrationRequest.repr | 1 - .../PhasedFSimCalibrationResult.json | 64 - .../PhasedFSimCalibrationResult.json_inward | 58 - .../PhasedFSimCalibrationResult.repr | 23 - .../PhasedFSimCalibrationResult.repr_inward | 18 - .../PhasedFSimCharacterization.json | 8 - .../PhasedFSimCharacterization.json_inward | 8 - .../PhasedFSimCharacterization.repr | 1 - .../PhasedFSimCharacterization.repr_inward | 1 - .../XEBPhasedFSimCalibrationOptions.json | 28 - .../XEBPhasedFSimCalibrationOptions.repr | 1 - .../XEBPhasedFSimCalibrationRequest.json | 62 - .../XEBPhasedFSimCalibrationRequest.repr | 1 - .../cirq_google/json_test_data/spec.py | 13 +- 47 files changed, 2 insertions(+), 7370 deletions(-) delete mode 100644 cirq-google/cirq_google/calibration/__init__.py delete mode 100644 cirq-google/cirq_google/calibration/engine_simulator.py delete mode 100644 cirq-google/cirq_google/calibration/engine_simulator_test.py delete mode 100644 cirq-google/cirq_google/calibration/phased_fsim.py delete mode 100644 cirq-google/cirq_google/calibration/phased_fsim_test.py delete mode 100644 cirq-google/cirq_google/calibration/test_data/xeb_calibration_layer.textproto delete mode 100644 cirq-google/cirq_google/calibration/test_data/xeb_results.textproto delete mode 100644 cirq-google/cirq_google/calibration/workflow.py delete mode 100644 cirq-google/cirq_google/calibration/workflow_test.py delete mode 100644 cirq-google/cirq_google/calibration/xeb_wrapper.py delete mode 100644 cirq-google/cirq_google/calibration/xeb_wrapper_test.py delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json_inward delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr_inward delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json_inward delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr delete mode 100644 cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr_inward delete mode 100644 cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.json delete mode 100644 cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.repr delete mode 100644 cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.json delete mode 100644 cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.repr delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json_inward delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr_inward delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json_inward delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr delete mode 100644 cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr_inward delete mode 100644 cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.json delete mode 100644 cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.repr delete mode 100644 cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.json delete mode 100644 cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.repr diff --git a/cirq-google/cirq_google/__init__.py b/cirq-google/cirq_google/__init__.py index 8f868bfff56..0301afbfb20 100644 --- a/cirq-google/cirq_google/__init__.py +++ b/cirq-google/cirq_google/__init__.py @@ -20,41 +20,6 @@ from cirq_google._version import __version__ -from cirq_google.calibration import ( - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - CircuitWithCalibration, - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - FSimPhaseCorrections, - PhasedFSimCalibrationError, - PhasedFSimCalibrationOptions, - PhasedFSimCalibrationRequest, - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - PhasedFSimEngineSimulator, - XEBPhasedFSimCalibrationOptions, - XEBPhasedFSimCalibrationRequest, - LocalXEBPhasedFSimCalibrationOptions, - LocalXEBPhasedFSimCalibrationRequest, - SQRT_ISWAP_INV_PARAMETERS, - THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - make_zeta_chi_gamma_compensation_for_moments, - make_zeta_chi_gamma_compensation_for_operations, - merge_matching_results, - prepare_characterization_for_circuits_moments, - prepare_floquet_characterization_for_moments, - prepare_characterization_for_moments, - prepare_floquet_characterization_for_moment, - prepare_characterization_for_moment, - prepare_floquet_characterization_for_operations, - prepare_characterization_for_operations, - run_calibrations, - run_floquet_characterization_for_moments, - run_zeta_chi_gamma_compensation_for_moments, - try_convert_sqrt_iswap_to_fsim, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, -) - from cirq_google.devices import ( GoogleNoiseProperties, GridDevice, diff --git a/cirq-google/cirq_google/calibration/__init__.py b/cirq-google/cirq_google/calibration/__init__.py deleted file mode 100644 index 644885ecfc5..00000000000 --- a/cirq-google/cirq_google/calibration/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. - -"""Functions for calling the calibration API and characterizing qubits.""" - -from cirq_google.calibration.engine_simulator import PhasedFSimEngineSimulator - -from cirq_google.calibration.phased_fsim import ( - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - IncompatibleMomentError, - PhasedFSimCalibrationError, - PhasedFSimCalibrationOptions, - PhasedFSimCalibrationRequest, - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - XEBPhasedFSimCalibrationOptions, - XEBPhasedFSimCalibrationRequest, - LocalXEBPhasedFSimCalibrationOptions, - LocalXEBPhasedFSimCalibrationRequest, - SQRT_ISWAP_INV_PARAMETERS, - THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - merge_matching_results, - try_convert_sqrt_iswap_to_fsim, - try_convert_syc_or_sqrt_iswap_to_fsim, -) - -from cirq_google.calibration.workflow import ( - CircuitWithCalibration, - FSimPhaseCorrections, - make_zeta_chi_gamma_compensation_for_moments, - make_zeta_chi_gamma_compensation_for_operations, - prepare_floquet_characterization_for_moments, - prepare_characterization_for_circuits_moments, - prepare_characterization_for_moments, - prepare_floquet_characterization_for_moment, - prepare_characterization_for_moment, - prepare_floquet_characterization_for_operations, - prepare_characterization_for_operations, - run_calibrations, - run_floquet_characterization_for_moments, - run_zeta_chi_gamma_compensation_for_moments, -) diff --git a/cirq-google/cirq_google/calibration/engine_simulator.py b/cirq-google/cirq_google/calibration/engine_simulator.py deleted file mode 100644 index 43b469b22fe..00000000000 --- a/cirq-google/cirq_google/calibration/engine_simulator.py +++ /dev/null @@ -1,516 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -from typing import ( - Any, - Callable, - cast, - Dict, - Iterable, - Iterator, - List, - Optional, - Sequence, - Tuple, - Union, -) - -import numpy as np - -import cirq -from cirq import value -from cirq_google.calibration.phased_fsim import ( - FloquetPhasedFSimCalibrationRequest, - PhaseCalibratedFSimGate, - IncompatibleMomentError, - PhasedFSimCalibrationRequest, - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - SQRT_ISWAP_INV_PARAMETERS, - try_convert_gate_to_fsim, - try_convert_sqrt_iswap_to_fsim, -) - -ParametersDriftGenerator = Callable[[cirq.Qid, cirq.Qid, cirq.FSimGate], PhasedFSimCharacterization] -PhasedFsimDictParameters = Dict[ - Tuple[cirq.Qid, cirq.Qid], Union[Dict[str, float], PhasedFSimCharacterization] -] - - -class PhasedFSimEngineSimulator(cirq.SimulatesIntermediateStateVector[cirq.SparseSimulatorStep]): - """Wrapper on top of cirq.Simulator that allows to simulate calibration requests. - - This simulator introduces get_calibrations which allows to simulate - cirq_google.run_characterizations requests. The returned calibration results represent the - internal state of a simulator. Circuits which are run on this simulator are modified to account - for the changes in the unitary parameters as described by the calibration results. - - Attributes: - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. - """ - - def __init__( - self, - simulator: cirq.Simulator, - *, - drift_generator: ParametersDriftGenerator, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_sqrt_iswap_to_fsim, - ) -> None: - """Initializes the PhasedFSimEngineSimulator. - - Args: - simulator: cirq.Simulator that all the simulation requests are delegated to. - drift_generator: Callable that generates the imperfect parameters for each pair of - qubits and the gate. They are later used for simulation. - gates_translator: Function that translates a gate to a supported FSimGate which will - undergo characterization. - """ - super().__init__() - self._simulator = simulator - self._drift_generator = drift_generator - self._drifted_parameters: Dict[ - Tuple[cirq.Qid, cirq.Qid, cirq.FSimGate], PhasedFSimCharacterization - ] = {} - self.gates_translator = gates_translator - - @classmethod - def create_with_ideal_sqrt_iswap( - cls, *, simulator: Optional[cirq.Simulator] = None - ) -> 'PhasedFSimEngineSimulator': - """Creates a PhasedFSimEngineSimulator that simulates ideal FSimGate(theta=π/4, phi=0). - - Attributes: - simulator: Simulator object to use. When None, a new instance of cirq.Simulator() will - be created. - - Returns: - New PhasedFSimEngineSimulator instance. - """ - - def sample_gate( - _1: cirq.Qid, _2: cirq.Qid, gate: cirq.FSimGate - ) -> PhasedFSimCharacterization: - _assert_inv_sqrt_iswap_like(gate) - return PhasedFSimCharacterization( - theta=np.pi / 4, zeta=0.0, chi=0.0, gamma=0.0, phi=0.0 - ) - - if simulator is None: - simulator = cirq.Simulator() - - return cls( - simulator, drift_generator=sample_gate, gates_translator=try_convert_sqrt_iswap_to_fsim - ) - - @classmethod - def create_with_random_gaussian_sqrt_iswap( - cls, - mean: PhasedFSimCharacterization = SQRT_ISWAP_INV_PARAMETERS, - *, - simulator: Optional[cirq.Simulator] = None, - sigma: PhasedFSimCharacterization = PhasedFSimCharacterization( - theta=0.02, zeta=0.05, chi=0.05, gamma=0.05, phi=0.02 - ), - random_or_seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None, - ) -> 'PhasedFSimEngineSimulator': - """Creates a PhasedFSimEngineSimulator that introduces a random deviation from the mean. - - The random deviations are described by a Gaussian distribution of a given mean and sigma, - for each angle respectively. - - Each gate for each pair of qubits retains the sampled values for the entire simulation, even - when used multiple times within a circuit. - - Attributes: - mean: The mean value for each unitary angle. All parameters must be provided. - simulator: Simulator object to use. When None, a new instance of cirq.Simulator() will - be created. - sigma: The standard deviation for each unitary angle. For sigma parameters that are - None, the mean value will be used without any sampling. - - Returns: - New PhasedFSimEngineSimulator instance. - - Raises: - ValueError: If not all mean values were supplied. - """ - - if mean.any_none(): - raise ValueError(f'All mean values must be provided, got mean of {mean}') - - rand = value.parse_random_state(random_or_seed) - - def sample_value(gaussian_mean: Optional[float], gaussian_sigma: Optional[float]) -> float: - assert gaussian_mean is not None - if gaussian_sigma is None: - return gaussian_mean - return rand.normal(gaussian_mean, gaussian_sigma) - - def sample_gate( - _1: cirq.Qid, _2: cirq.Qid, gate: cirq.FSimGate - ) -> PhasedFSimCharacterization: - _assert_inv_sqrt_iswap_like(gate) - - return PhasedFSimCharacterization( - theta=sample_value(mean.theta, sigma.theta), - zeta=sample_value(mean.zeta, sigma.zeta), - chi=sample_value(mean.chi, sigma.chi), - gamma=sample_value(mean.gamma, sigma.gamma), - phi=sample_value(mean.phi, sigma.phi), - ) - - if simulator is None: - simulator = cirq.Simulator() - - return cls( - simulator, drift_generator=sample_gate, gates_translator=try_convert_sqrt_iswap_to_fsim - ) - - @classmethod - def create_from_dictionary_sqrt_iswap( - cls, - parameters: PhasedFsimDictParameters, - *, - simulator: Optional[cirq.Simulator] = None, - ideal_when_missing_gate: bool = False, - ideal_when_missing_parameter: bool = False, - ) -> 'PhasedFSimEngineSimulator': - """Creates PhasedFSimEngineSimulator with fixed drifts. - - Args: - parameters: Parameters to use for each gate. All keys must be stored in canonical order, - when the first qubit is not greater than the second one. - simulator: Simulator object to use. When None, a new instance of cirq.Simulator() will - be created. - ideal_when_missing_gate: When set and parameters for some gate for a given pair of - qubits are not specified in the parameters dictionary then the - FSimGate(theta=π/4, phi=0) gate parameters will be used. When not set and this - situation occurs, ValueError is thrown during simulation. - ideal_when_missing_parameter: When set and some parameter for some gate for a given pair - of qubits is specified then the matching parameter of FSimGate(theta=π/4, phi=0) - gate will be used. When not set and this situation occurs, ValueError is thrown - during simulation. - - Returns: - New PhasedFSimEngineSimulator instance. - - Raises: - ValueError: If missing parameters for the given pair of qubits. - """ - - def sample_gate( - a: cirq.Qid, b: cirq.Qid, gate: cirq.FSimGate - ) -> PhasedFSimCharacterization: - _assert_inv_sqrt_iswap_like(gate) - - if (a, b) in parameters: - pair_parameters = parameters[(a, b)] - if not isinstance(pair_parameters, PhasedFSimCharacterization): - pair_parameters = PhasedFSimCharacterization(**pair_parameters) - elif (b, a) in parameters: - pair_parameters = parameters[(b, a)] - if not isinstance(pair_parameters, PhasedFSimCharacterization): - pair_parameters = PhasedFSimCharacterization(**pair_parameters) - pair_parameters = pair_parameters.parameters_for_qubits_swapped() - elif ideal_when_missing_gate: - pair_parameters = SQRT_ISWAP_INV_PARAMETERS - else: - raise ValueError(f'Missing parameters for pair {(a, b)}') - - if pair_parameters.any_none(): - if not ideal_when_missing_parameter: - raise ValueError( - f'Missing parameter value for pair {(a, b)}, ' - f'parameters={pair_parameters}' - ) - pair_parameters = pair_parameters.merge_with(SQRT_ISWAP_INV_PARAMETERS) - - return pair_parameters - - for a, b in parameters: - if a > b: - raise ValueError( - f'All qubit pairs must be given in canonical order where the first qubit is ' - f'less than the second, got {a} > {b}' - ) - - if simulator is None: - simulator = cirq.Simulator() - - return cls( - simulator, drift_generator=sample_gate, gates_translator=try_convert_sqrt_iswap_to_fsim - ) - - @classmethod - def create_from_dictionary( - cls, - parameters: Dict[ - Tuple[cirq.Qid, cirq.Qid], Dict[cirq.FSimGate, Union[PhasedFSimCharacterization, Dict]] - ], - *, - simulator: Optional[cirq.Simulator] = None, - ) -> 'PhasedFSimEngineSimulator': - """Creates PhasedFSimEngineSimulator with fixed drifts. - - Args: - parameters: maps every pair of qubits and engine gate on that pair to a - characterization for that gate. - simulator: Simulator object to use. When None, a new instance of cirq.Simulator() will - be created. - - Returns: - New PhasedFSimEngineSimulator instance. - - Raises: - ValueError: If missing parameters for the given pair of qubits. - """ - - for a, b in parameters.keys(): - if a > b: - raise ValueError( - f'All qubit pairs must be given in canonical order where the first qubit is ' - f'less than the second, got {a} > {b}' - ) - - def sample_gate( - a: cirq.Qid, b: cirq.Qid, gate: cirq.FSimGate - ) -> PhasedFSimCharacterization: - pair_parameters = None - swapped = False - if (a, b) in parameters: - pair_parameters = parameters[(a, b)].get(gate) - elif (b, a) in parameters: - pair_parameters = parameters[(b, a)].get(gate) - swapped = True - - if pair_parameters is None: - raise ValueError(f'Missing parameters for value for pair {(a, b)} and gate {gate}.') - if not isinstance(pair_parameters, PhasedFSimCharacterization): - pair_parameters = PhasedFSimCharacterization(**pair_parameters) - if swapped: - pair_parameters = pair_parameters.parameters_for_qubits_swapped() - - return pair_parameters - - if simulator is None: - simulator = cirq.Simulator() - return cls( - simulator, drift_generator=sample_gate, gates_translator=try_convert_gate_to_fsim - ) - - @classmethod - def create_from_characterizations_sqrt_iswap( - cls, - characterizations: Iterable[PhasedFSimCalibrationResult], - *, - simulator: Optional[cirq.Simulator] = None, - ideal_when_missing_gate: bool = False, - ideal_when_missing_parameter: bool = False, - ) -> 'PhasedFSimEngineSimulator': - """Creates PhasedFSimEngineSimulator with fixed drifts from the characterizations results. - - Args: - characterizations: Characterization results which are source of the parameters for - each gate. - simulator: Simulator object to use. When None, a new instance of cirq.Simulator() will - be created. - ideal_when_missing_gate: When set and parameters for some gate for a given pair of - qubits are not specified in the parameters dictionary then the - FSimGate(theta=π/4, phi=0) gate parameters will be used. When not set and this - situation occurs, ValueError is thrown during simulation. - ideal_when_missing_parameter: When set and some parameter for some gate for a given pair - of qubits is specified then the matching parameter of FSimGate(theta=π/4, phi=0) - gate will be used. When not set and this situation occurs, ValueError is thrown - during simulation. - - Returns: - New PhasedFSimEngineSimulator instance. - - Raises: - ValueError: If the gate was not a gate like `ISWAP ** -0.5` or the pair of qubits it - acts on appears in multiple different moments. - """ - - parameters: PhasedFsimDictParameters = {} - for characterization in characterizations: - gate = characterization.gate - _assert_inv_sqrt_iswap_like(gate) - - for (a, b), pair_parameters in characterization.parameters.items(): - if a > b: - a, b = b, a - pair_parameters = pair_parameters.parameters_for_qubits_swapped() - if (a, b) in parameters: - raise ValueError( - f'Pair ({(a, b)}) appears in multiple moments, multi-moment ' - f'simulation is not supported.' - ) - parameters[(a, b)] = pair_parameters - - if simulator is None: - simulator = cirq.Simulator() - - return cls.create_from_dictionary_sqrt_iswap( - parameters, - simulator=simulator, - ideal_when_missing_gate=ideal_when_missing_gate, - ideal_when_missing_parameter=ideal_when_missing_parameter, - ) - - def final_state_vector(self, program: cirq.Circuit) -> np.ndarray: - result = self.simulate(program) - return result.state_vector() - - def get_calibrations( - self, requests: Sequence[PhasedFSimCalibrationRequest] - ) -> List[PhasedFSimCalibrationResult]: - """Retrieves the calibration that matches the requests - - Args: - requests: Calibration requests to obtain. - - Returns: - Calibration results that reflect the internal state of simulator. - - Raises: - ValueError: If supplied type of request is not supported or if the request contains - and unsupported gate. - """ - results = [] - for request in requests: - if isinstance(request, FloquetPhasedFSimCalibrationRequest): - options = request.options - characterize_theta = options.characterize_theta - characterize_zeta = options.characterize_zeta - characterize_chi = options.characterize_chi - characterize_gamma = options.characterize_gamma - characterize_phi = options.characterize_phi - else: - raise ValueError(f'Unsupported calibration request {request}') - - translated = self.gates_translator(request.gate) - if translated is None: - raise ValueError(f'Calibration request contains unsupported gate {request.gate}') - - parameters = {} - for a, b in request.pairs: - drifted = self.create_gate_with_drift(a, b, translated) - parameters[a, b] = PhasedFSimCharacterization( - theta=cast(float, drifted.theta) if characterize_theta else None, - zeta=cast(float, drifted.zeta) if characterize_zeta else None, - chi=cast(float, drifted.chi) if characterize_chi else None, - gamma=cast(float, drifted.gamma) if characterize_gamma else None, - phi=cast(float, drifted.phi) if characterize_phi else None, - ) - - results.append( - PhasedFSimCalibrationResult( - parameters=parameters, gate=request.gate, options=options - ) - ) - - return results - - def create_gate_with_drift( - self, a: cirq.Qid, b: cirq.Qid, gate_calibration: PhaseCalibratedFSimGate - ) -> cirq.PhasedFSimGate: - """Generates a gate with drift for a given gate. - - Args: - a: The first qubit. - b: The second qubit. - gate_calibration: Reference gate together with a phase information. - - Returns: - A modified gate that includes the drifts induced by internal state of the simulator. - """ - gate = gate_calibration.engine_gate - if (a, b, gate) in self._drifted_parameters: - parameters = self._drifted_parameters[(a, b, gate)] - elif (b, a, gate) in self._drifted_parameters: - parameters = self._drifted_parameters[(b, a, gate)].parameters_for_qubits_swapped() - else: - parameters = self._drift_generator(a, b, gate) - self._drifted_parameters[(a, b, gate)] = parameters - - return gate_calibration.as_characterized_phased_fsim_gate(parameters) - - def run_sweep_iter( - self, program: cirq.AbstractCircuit, params: cirq.Sweepable, repetitions: int = 1 - ) -> Iterator[cirq.Result]: - converted = _convert_to_circuit_with_drift(self, program) - yield from self._simulator.run_sweep_iter(converted, params, repetitions) - - def simulate( - self, - program: cirq.AbstractCircuit, - param_resolver: cirq.ParamResolverOrSimilarType = None, - qubit_order: cirq.QubitOrderOrList = cirq.QubitOrder.DEFAULT, - initial_state: Any = None, - ) -> cirq.StateVectorTrialResult: - converted = _convert_to_circuit_with_drift(self, program) - return self._simulator.simulate(converted, param_resolver, qubit_order, initial_state) - - def _create_partial_simulation_state( - self, - initial_state: Union[int, cirq.StateVectorSimulationState], - qubits: Sequence[cirq.Qid], - classical_data: cirq.ClassicalDataStore, - ) -> cirq.StateVectorSimulationState: - # Needs an implementation since it's abstract but will never actually be called. - raise NotImplementedError() - - def _create_step_result(self, sim_state: cirq.SimulationStateBase) -> cirq.SparseSimulatorStep: - # Needs an implementation since it's abstract but will never actually be called. - raise NotImplementedError() - - -def _convert_to_circuit_with_drift( - simulator: PhasedFSimEngineSimulator, circuit: cirq.AbstractCircuit -) -> cirq.Circuit: - def map_func(op: cirq.Operation, _) -> cirq.Operation: - if op.gate is None: - raise IncompatibleMomentError(f'Operation {op} has a missing gate') - - if ( - isinstance(op.gate, (cirq.MeasurementGate, cirq.WaitGate)) - or cirq.num_qubits(op.gate) == 1 - ): - return op - - translated = simulator.gates_translator(op.gate) - if translated is None: - raise IncompatibleMomentError( - f'Moment contains non-single qubit operation {op} with unsupported gate' - ) - - a, b = op.qubits - return simulator.create_gate_with_drift(a, b, translated).on(a, b) - - return cirq.map_operations(circuit, map_func).unfreeze(copy=False) - - -def _assert_inv_sqrt_iswap_like(gate: cirq.Gate): - assert isinstance(gate, cirq.FSimGate), f'Expected FSimGate, got {gate}' - - if cirq.is_parameterized(gate): - raise ValueError("Only unparameterized gates are supported. Gate: {gate}.") - theta = gate.theta - phi = gate.phi - assert isinstance(theta, float) and isinstance(phi, float) - assert np.isclose(theta, np.pi / 4) and np.isclose( - phi, 0.0 - ), f'Expected ISWAP ** -0.5 like gate, got {gate}' diff --git a/cirq-google/cirq_google/calibration/engine_simulator_test.py b/cirq-google/cirq_google/calibration/engine_simulator_test.py deleted file mode 100644 index c51c4ccf252..00000000000 --- a/cirq-google/cirq_google/calibration/engine_simulator_test.py +++ /dev/null @@ -1,539 +0,0 @@ -# pylint: disable=wrong-or-nonexistent-copyright-notice -from typing import Iterable, Optional, Tuple - -import collections -from unittest import mock - -import numpy as np -import pytest -import sympy - -import cirq_google -from cirq_google.calibration.engine_simulator import ( - PhasedFSimEngineSimulator, - SQRT_ISWAP_INV_PARAMETERS, -) -from cirq_google.calibration import ( - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - IncompatibleMomentError, - PhasedFSimCalibrationRequest, - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, -) -import cirq - -SQRT_ISWAP_INV_GATE = cirq.FSimGate(np.pi / 4, 0.0) - - -class ExamplePhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest): - def to_calibration_layer(self) -> cirq_google.CalibrationLayer: - return NotImplemented - - def parse_result( - self, result: cirq_google.CalibrationResult, job: Optional[cirq_google.EngineJob] = None - ) -> PhasedFSimCalibrationResult: - return NotImplemented - - -def test_test_calibration_request(): - a, b = cirq.LineQubit.range(2) - request = ExamplePhasedFSimCalibrationRequest( - gate=cirq.FSimGate(np.pi / 4, 0.5), - pairs=((a, b),), - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - - assert request.to_calibration_layer() is NotImplemented - - result = mock.MagicMock(spec=cirq_google.CalibrationResult) - assert request.parse_result(result) is NotImplemented - - -def test_floquet_get_calibrations(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - parameters_bc = cirq_google.PhasedFSimCharacterization( - theta=0.8, zeta=-0.5, chi=-0.4, gamma=-0.3, phi=-0.2 - ) - parameters_cd_dict = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - parameters_cd = cirq_google.PhasedFSimCharacterization(**parameters_cd_dict) - - a, b, c, d = cirq.LineQubit.range(4) - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd_dict} - ) - - requests = [_create_sqrt_iswap_request([(a, b), (c, d)]), _create_sqrt_iswap_request([(b, c)])] - - results = engine_simulator.get_calibrations(requests) - - assert results == [ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(a, b): parameters_ab, (c, d): parameters_cd}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(b, c): parameters_bc}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - ] - - -def test_floquet_get_calibrations_when_invalid_request_fails(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - - a, b = cirq.LineQubit.range(2) - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab} - ) - - with pytest.raises(ValueError): - engine_simulator.get_calibrations( - [ - FloquetPhasedFSimCalibrationRequest( - gate=cirq.FSimGate(np.pi / 4, 0.5), - pairs=((a, b),), - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - ) - - with pytest.raises(ValueError): - engine_simulator.get_calibrations( - [ - ExamplePhasedFSimCalibrationRequest( - gate=cirq.FSimGate(np.pi / 4, 0.5), - pairs=((a, b),), - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - ) - - -def test_ideal_sqrt_iswap_simulates_correctly(): - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, c)], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_with_ideal_sqrt_iswap() - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_ideal_sqrt_iswap_inverse_simulates_correctly(): - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(-np.pi / 4, 0.0).on(a, b), cirq.FSimGate(-np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(-np.pi / 4, 0.0).on(b, c)], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_with_ideal_sqrt_iswap() - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_ideal_sqrt_iswap_simulates_correctly_invalid_circuit_fails(): - engine_simulator = PhasedFSimEngineSimulator.create_with_ideal_sqrt_iswap() - a, b = cirq.LineQubit.range(2) - - with pytest.raises(IncompatibleMomentError): - circuit = cirq.Circuit([cirq.CZ.on(a, b)]) - engine_simulator.simulate(circuit) - - with pytest.raises(IncompatibleMomentError): - circuit = cirq.Circuit(cirq.global_phase_operation(coefficient=1.0)) - engine_simulator.simulate(circuit) - - with pytest.raises(IncompatibleMomentError): - circuit = cirq.Circuit(cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(a)))) - engine_simulator.simulate(circuit) - - -def test_with_random_gaussian_sqrt_iswap_simulates_correctly(): - engine_simulator = PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap( - mean=SQRT_ISWAP_INV_PARAMETERS, - sigma=PhasedFSimCharacterization(theta=0.02, zeta=0.05, chi=0.05, gamma=None, phi=0.02), - ) - - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, a), cirq.FSimGate(np.pi / 4, 0.0).on(d, c)], - ] - ) - - calibrations = engine_simulator.get_calibrations( - [_create_sqrt_iswap_request([(a, b), (c, d)]), _create_sqrt_iswap_request([(b, c)])] - ) - parameters = collections.ChainMap(*(calibration.parameters for calibration in calibrations)) - - expected_circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.X(c)], - [ - cirq.PhasedFSimGate(**parameters[(a, b)].asdict()).on(a, b), - cirq.PhasedFSimGate(**parameters[(c, d)].asdict()).on(c, d), - ], - [cirq.PhasedFSimGate(**parameters[(b, c)].asdict()).on(b, c)], - [ - cirq.PhasedFSimGate(**parameters[(a, b)].asdict()).on(a, b), - cirq.PhasedFSimGate(**parameters[(c, d)].asdict()).on(c, d), - ], - ] - ) - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(expected_circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected, atol=1e-6) - - -def test_with_random_gaussian_runs_correctly(): - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, c)], - cirq.measure(a, b, c, d, key='z'), - ] - ) - - simulator = cirq.Simulator() - engine_simulator = PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap( - SQRT_ISWAP_INV_PARAMETERS, simulator=simulator - ) - - actual = engine_simulator.run(circuit, repetitions=20000).measurements['z'] - expected = simulator.run(circuit, repetitions=20000).measurements['z'] - - assert np.allclose(np.average(actual, axis=0), np.average(expected, axis=0), atol=0.1) - - -def test_with_random_gaussian_sqrt_iswap_fails_with_invalid_mean(): - with pytest.raises(ValueError): - PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap( - mean=PhasedFSimCharacterization(theta=np.pi / 4) - ) - - -def test_from_dictionary_sqrt_iswap_simulates_correctly(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - parameters_bc = cirq_google.PhasedFSimCharacterization( - theta=0.8, zeta=-0.5, chi=-0.4, gamma=-0.3, phi=-0.2 - ) - parameters_cd_dict = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(d, c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - ] - ) - expected_circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.X(c)], - [ - cirq.PhasedFSimGate(**parameters_ab.asdict()).on(a, b), - cirq.PhasedFSimGate(**parameters_cd_dict).on(c, d), - ], - [cirq.PhasedFSimGate(**parameters_bc.asdict()).on(b, c)], - [ - cirq.PhasedFSimGate(**parameters_ab.asdict()).on(a, b), - cirq.PhasedFSimGate(**parameters_cd_dict).on(c, d), - ], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd_dict} - ) - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(expected_circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_create_from_dictionary_simulates_correctly(): - parameters_ab_1 = {'theta': 0.6, 'zeta': 0.5, 'chi': 0.4, 'gamma': 0.3, 'phi': 0.2} - parameters_ab_2 = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - parameters_bc = {'theta': 0.8, 'zeta': -0.5, 'chi': -0.4, 'gamma': -0.3, 'phi': -0.2} - parameters_cd = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(b), cirq.Z(c), cirq.H(d)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(d, c)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [cirq_google.SYC.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - ] - ) - expected_circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(b), cirq.Z(c), cirq.H(d)], - [ - cirq.PhasedFSimGate(**parameters_ab_1).on(a, b), - cirq.PhasedFSimGate(**parameters_cd).on(c, d), - ], - [cirq.PhasedFSimGate(**parameters_bc).on(b, c)], - [ - cirq.PhasedFSimGate(**parameters_ab_2).on(a, b), - cirq.PhasedFSimGate(**parameters_cd).on(c, d), - ], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary( - parameters={ - (a, b): {SQRT_ISWAP_INV_GATE: parameters_ab_1, cirq_google.SYC: parameters_ab_2}, - (b, c): {SQRT_ISWAP_INV_GATE: parameters_bc}, - (c, d): {SQRT_ISWAP_INV_GATE: parameters_cd}, - } - ) - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(expected_circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_from_dictionary_sqrt_iswap_ideal_when_missing_gate_fails(): - a, b = cirq.LineQubit.range(2) - circuit = cirq.Circuit(cirq.FSimGate(np.pi / 4, 0.0).on(a, b)) - - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap(parameters={}) - - with pytest.raises(ValueError): - engine_simulator.final_state_vector(circuit) - - -def test_from_dictionary_sqrt_iswap_ideal_when_missing_parameter_fails(): - parameters_ab = cirq_google.PhasedFSimCharacterization(theta=0.8, zeta=-0.5, chi=-0.4) - - a, b = cirq.LineQubit.range(2) - circuit = cirq.Circuit(cirq.FSimGate(np.pi / 4, 0.0).on(a, b)) - - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab} - ) - - with pytest.raises(ValueError): - engine_simulator.final_state_vector(circuit) - - -def test_from_dictionary_sqrt_iswap_ideal_when_missing_simulates_correctly(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - parameters_bc = cirq_google.PhasedFSimCharacterization(theta=0.8, zeta=-0.5, chi=-0.4) - - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(np.pi / 4, 0.0).on(b, c)], - ] - ) - expected_circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.X(c)], - [ - cirq.PhasedFSimGate(**parameters_ab.asdict()).on(a, b), - cirq.PhasedFSimGate(**SQRT_ISWAP_INV_PARAMETERS.asdict()).on(c, d), - ], - [ - cirq.PhasedFSimGate( - **parameters_bc.merge_with(SQRT_ISWAP_INV_PARAMETERS).asdict() - ).on(b, c) - ], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab, (b, c): parameters_bc}, - ideal_when_missing_parameter=True, - ideal_when_missing_gate=True, - ) - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(expected_circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_from_dictionary_sqrt_iswap_fails_when_invalid_parameters(): - a, b = cirq.LineQubit.range(2) - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - - with pytest.raises(ValueError): - PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(b, a): parameters_ab} - ) - - -def test_from_characterizations_sqrt_iswap_simulates_correctly(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - parameters_bc = cirq_google.PhasedFSimCharacterization( - theta=0.8, zeta=-0.5, chi=-0.4, gamma=-0.3, phi=-0.2 - ) - parameters_cd = cirq_google.PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5 - ) - - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [cirq.FSimGate(np.pi / 4, 0.0).on(a, b), cirq.FSimGate(np.pi / 4, 0.0).on(c, d)], - [cirq.FSimGate(np.pi / 4, 0.0).on(c, b)], - ] - ) - expected_circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.X(c)], - [ - cirq.PhasedFSimGate(**parameters_ab.asdict()).on(a, b), - cirq.PhasedFSimGate(**parameters_cd.asdict()).on(c, d), - ], - [cirq.PhasedFSimGate(**parameters_bc.asdict()).on(b, c)], - ] - ) - - engine_simulator = PhasedFSimEngineSimulator.create_from_characterizations_sqrt_iswap( - characterizations=[ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(a, b): parameters_ab, (c, d): parameters_cd}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(c, b): parameters_bc.parameters_for_qubits_swapped()}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - ] - ) - - actual = engine_simulator.final_state_vector(circuit) - expected = cirq.final_state_vector(expected_circuit) - - assert cirq.allclose_up_to_global_phase(actual, expected) - - -def test_from_characterizations_sqrt_iswap_when_invalid_arguments_fails(): - parameters_ab = cirq_google.PhasedFSimCharacterization( - theta=0.6, zeta=0.5, chi=0.4, gamma=0.3, phi=0.2 - ) - parameters_bc = cirq_google.PhasedFSimCharacterization( - theta=0.8, zeta=-0.5, chi=-0.4, gamma=-0.3, phi=-0.2 - ) - - a, b = cirq.LineQubit.range(2) - - with pytest.raises(ValueError, match="multiple moments"): - PhasedFSimEngineSimulator.create_from_characterizations_sqrt_iswap( - characterizations=[ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(a, b): parameters_ab}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.0), - parameters={(a, b): parameters_bc}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - ] - ) - - with pytest.raises(AssertionError, match="Expected ISWA"): - PhasedFSimEngineSimulator.create_from_characterizations_sqrt_iswap( - characterizations=[ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, 0.2), - parameters={(a, b): parameters_ab}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - ) - - with pytest.raises(ValueError, match="unparameterized"): - PhasedFSimEngineSimulator.create_from_characterizations_sqrt_iswap( - characterizations=[ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(np.pi / 4, sympy.Symbol("a")), - parameters={(a, b): parameters_ab}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - ) - - with pytest.raises(AssertionError, match="Expected FSimGate"): - PhasedFSimEngineSimulator.create_from_characterizations_sqrt_iswap( - characterizations=[ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.CNOT, - parameters={(a, b): parameters_ab}, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - ) - - -def test_create_from_dictionary_imvalid_parameters_fails(): - a, b = cirq.LineQubit.range(2) - circuit = cirq.Circuit(cirq.CZ(a, b)) - - simulator = PhasedFSimEngineSimulator.create_from_dictionary({}) - with pytest.raises(ValueError, match='Missing parameters'): - simulator.final_state_vector(circuit) - - with pytest.raises(ValueError, match='canonical order'): - PhasedFSimEngineSimulator.create_from_dictionary( - parameters={(b, a): {'theta': 0.6, 'phi': 0.2}} - ) - - -def _create_sqrt_iswap_request( - pairs: Iterable[Tuple[cirq.Qid, cirq.Qid]], - options: FloquetPhasedFSimCalibrationOptions = ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, -) -> FloquetPhasedFSimCalibrationRequest: - return FloquetPhasedFSimCalibrationRequest( - gate=cirq.FSimGate(np.pi / 4, 0.0), pairs=tuple(pairs), options=options - ) diff --git a/cirq-google/cirq_google/calibration/phased_fsim.py b/cirq-google/cirq_google/calibration/phased_fsim.py deleted file mode 100644 index 1f06912a50e..00000000000 --- a/cirq-google/cirq_google/calibration/phased_fsim.py +++ /dev/null @@ -1,1138 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import abc -import collections -import dataclasses -import functools -import math -import re -from typing import ( - Any, - Callable, - Dict, - Iterable, - List, - MutableMapping, - Optional, - Tuple, - Type, - TypeVar, - TYPE_CHECKING, - Generic, - Union, - cast, -) - -import numpy as np -import pandas as pd - - -import cirq -from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions -from cirq_google.api import v2 -from cirq_google.engine import ( - Calibration, - CalibrationLayer, - CalibrationResult, - Engine, - EngineJob, - util, -) -from cirq_google.ops import FSimGateFamily, SycamoreGate - -if TYPE_CHECKING: - import cirq_google - - -_FLOQUET_PHASED_FSIM_HANDLER_NAME = 'floquet_phased_fsim_characterization' -_XEB_PHASED_FSIM_HANDLER_NAME = 'xeb_phased_fsim_characterization' -_DEFAULT_XEB_CYCLE_DEPTHS = (5, 25, 50, 100, 200, 300) -# Copied from cirq-google/cirq_google/engine/calibration_to_noise_properties.py -GATE_ZPHASE_CODE_PAIRS: Dict[Type['cirq.Gate'], str] = { - SycamoreGate: 'syc', - cirq.ISwapPowGate: 'sqrt_iswap', -} - -T = TypeVar('T') - -RequestT = TypeVar('RequestT', bound='PhasedFSimCalibrationRequest') - - -# Workaround for: https://github.com/python/mypy/issues/5858 -def lru_cache_typesafe(func: Callable[..., T]) -> T: - return functools.lru_cache(maxsize=None)(func) # type: ignore - - -def _create_pairs_from_moment( - moment: cirq.Moment, -) -> Tuple[Tuple[Tuple[cirq.Qid, cirq.Qid], ...], cirq.Gate]: - """Creates instantiation parameters from a Moment. - - Given a moment, creates a tuple of pairs of qubits and the - gate for instantiation of a sub-class of PhasedFSimCalibrationRequest, - Sub-classes of PhasedFSimCalibrationRequest can call this function - to implement a from_moment function. - """ - gate = None - pairs: List[Tuple[cirq.Qid, cirq.Qid]] = [] - for op in moment: - if op.gate is None: - raise ValueError('All gates in request object must be two qubit gates: {op}') - if gate is None: - gate = op.gate - elif gate != op.gate: - raise ValueError('All gates in request object must be identical {gate}!={op.gate}') - if len(op.qubits) != 2: - raise ValueError('All gates in request object must be two qubit gates: {op}') - pairs.append((op.qubits[0], op.qubits[1])) - if gate is None: - raise ValueError('No gates found to create request {moment}') - return tuple(pairs), gate - - -@dataclasses.dataclass(frozen=True) -class PhasedFSimCharacterization: - """Holder for the unitary angles of the cirq.PhasedFSimGate. - - This class stores five unitary parameters (θ, ζ, χ, γ and φ) that describe the - cirq.PhasedFSimGate which is the most general particle conserving two-qubit gate. The unitary - of the underlying gate is: - - [[1, 0, 0, 0], - [0, exp(-i(γ + ζ)) cos(θ), -i exp(-i(γ - χ)) sin(θ), 0], - [0, -i exp(-i(γ + χ)) sin(θ), exp(-i(γ - ζ)) cos(θ), 0], - [0, 0, 0, exp(-i(2γ + φ))]] - - The parameters θ, γ and φ are symmetric and parameters ζ and χ asymmetric under the qubits - exchange. - - All the angles described by this class are optional and can be left unknown. This is relevant - for characterization routines that characterize only subset of the gate parameters. All the - angles are assumed to take a fixed numerical values which reflect the current state of the - characterized gate. - - This class supports JSON serialization and deserialization. - - Attributes: - theta: θ angle in radians or None when unknown. - zeta: ζ angle in radians or None when unknown. - chi: χ angle in radians or None when unknown. - gamma: γ angle in radians or None when unknown. - phi: φ angle in radians or None when unknown. - """ - - theta: Optional[float] = None - zeta: Optional[float] = None - chi: Optional[float] = None - gamma: Optional[float] = None - phi: Optional[float] = None - - def asdict(self) -> Dict[str, float]: - """Converts parameters to a dictionary that maps angle names to values.""" - return dataclasses.asdict(self) - - def all_none(self) -> bool: - """Returns True if all the angles are None""" - return ( - self.theta is None - and self.zeta is None - and self.chi is None - and self.gamma is None - and self.phi is None - ) - - def any_none(self) -> bool: - """Returns True if any the angle is None""" - return ( - self.theta is None - or self.zeta is None - or self.chi is None - or self.gamma is None - or self.phi is None - ) - - def parameters_for_qubits_swapped(self) -> 'PhasedFSimCharacterization': - """Parameters for the gate with qubits swapped between each other. - - The angles theta, gamma and phi are kept unchanged. The angles zeta and chi are negated for - the gate with swapped qubits. - - Returns: - New instance with angles adjusted for swapped qubits. - """ - return PhasedFSimCharacterization( - theta=self.theta, - zeta=-self.zeta if self.zeta is not None else None, - chi=-self.chi if self.chi is not None else None, - gamma=self.gamma, - phi=self.phi, - ) - - def merge_with(self, other: 'PhasedFSimCharacterization') -> 'PhasedFSimCharacterization': - """Substitutes missing parameter with values from other. - - Args: - other: Parameters to use for None values. - - Returns: - New instance of PhasedFSimCharacterization with values from this instance if they are - set or values from other when some parameter is None. - """ - return PhasedFSimCharacterization( - theta=other.theta if self.theta is None else self.theta, - zeta=other.zeta if self.zeta is None else self.zeta, - chi=other.chi if self.chi is None else self.chi, - gamma=other.gamma if self.gamma is None else self.gamma, - phi=other.phi if self.phi is None else self.phi, - ) - - def override_by(self, other: 'PhasedFSimCharacterization') -> 'PhasedFSimCharacterization': - """Overrides other parameters that are not None. - - Args: - other: Parameters to use for override. - - Returns: - New instance of PhasedFSimCharacterization with values from other if set (values from - other that are not None). Otherwise the current values are used. - """ - return other.merge_with(self) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -SQRT_ISWAP_INV_PARAMETERS = PhasedFSimCharacterization( - theta=np.pi / 4, zeta=0.0, chi=0.0, gamma=0.0, phi=0.0 -) - - -class PhasedFSimCalibrationOptions(abc.ABC, Generic[RequestT]): - """Base class for calibration-specific options passed together with the requests.""" - - @abc.abstractmethod - def create_phased_fsim_request( - self, pairs: Tuple[Tuple[cirq.Qid, cirq.Qid], ...], gate: cirq.Gate - ) -> RequestT: - """Create a PhasedFSimCalibrationRequest of the correct type for these options. - - Args: - pairs: Set of qubit pairs to characterize. A single qubit can appear on at most one - pair in the set. - gate: Gate to characterize for each qubit pair from pairs. This must be a supported gate - which can be described cirq.PhasedFSim gate. This gate must be serialized by the - cirq_google.SerializableGateSet used - """ - - -@dataclasses.dataclass -class PhasedFSimCalibrationResult: - """The PhasedFSimGate characterization result. - - Attributes: - parameters: Map from qubit pair to characterization result. For each pair of characterized - quibts a and b either only (a, b) or only (b, a) is present. - gate: Characterized gate for each qubit pair. This is copied from the matching - PhasedFSimCalibrationRequest and is included to preserve execution context. - options: The options used to gather this result. - project_id: Google's job project id. - program_id: Google's job program id. - job_id: Google's job job id. - """ - - parameters: Dict[Tuple[cirq.Qid, cirq.Qid], PhasedFSimCharacterization] - gate: cirq.Gate - options: PhasedFSimCalibrationOptions - project_id: Optional[str] = None - program_id: Optional[str] = None - job_id: Optional[str] = None - _engine_job: Optional[EngineJob] = None - _calibration: Optional[Calibration] = None - - def override(self, parameters: PhasedFSimCharacterization) -> 'PhasedFSimCalibrationResult': - """Creates the new results with certain parameters overridden for all characterizations. - - This functionality can be used to zero-out the corrected angles and do the analysis on - remaining errors. - - Args: - parameters: Parameters that will be used when overriding. The angles of that object - which are not None will be used to replace current parameters for every pair stored. - - Returns: - New instance of PhasedFSimCalibrationResult with certain parameters overridden. - """ - return PhasedFSimCalibrationResult( - parameters={ - pair: pair_parameters.override_by(parameters) - for pair, pair_parameters in self.parameters.items() - }, - gate=self.gate, - options=self.options, - ) - - def get_parameters(self, a: cirq.Qid, b: cirq.Qid) -> Optional['PhasedFSimCharacterization']: - """Returns parameters for a qubit pair (a, b) or None when unknown.""" - if (a, b) in self.parameters: - return self.parameters[(a, b)] - elif (b, a) in self.parameters: - return self.parameters[(b, a)].parameters_for_qubits_swapped() - else: - return None - - @property - def engine_job(self) -> Optional[EngineJob]: - """The cirq_google.EngineJob associated with this calibration request. - - Available only when project_id, program_id and job_id attributes are present. - """ - if self._engine_job is None and self.project_id and self.program_id and self.job_id: - engine = Engine(project_id=self.project_id) - self._engine_job = engine.get_program(self.program_id).get_job(self.job_id) - return self._engine_job - - @property - def engine_calibration(self) -> Optional[Calibration]: - """The underlying device calibration that was used for this user-specific calibration. - - This is a cached property that triggers a network call at the first use. - """ - if self._calibration is None and self.engine_job is not None: - self._calibration = self.engine_job.get_calibration() - return self._calibration - - @classmethod - def _create_parameters_dict( - cls, parameters: List[Tuple[cirq.Qid, cirq.Qid, PhasedFSimCharacterization]] - ) -> Dict[Tuple[cirq.Qid, cirq.Qid], PhasedFSimCharacterization]: - """Utility function to create parameters from JSON. - - Can be used from child classes to instantiate classes in a _from_json_dict_ - method.""" - return {(q_a, q_b): params for q_a, q_b, params in parameters} - - @classmethod - def _from_json_dict_(cls, **kwargs) -> 'PhasedFSimCalibrationResult': - """Magic method for the JSON serialization protocol. - - Converts serialized dictionary into a dict suitable for - class instantiation.""" - del kwargs['cirq_type'] - kwargs['parameters'] = cls._create_parameters_dict(kwargs['parameters']) - return cls(**kwargs) - - def _json_dict_(self) -> Dict[str, Any]: - """Magic method for the JSON serialization protocol.""" - return { - 'gate': self.gate, - 'parameters': [(q_a, q_b, params) for (q_a, q_b), params in self.parameters.items()], - 'options': self.options, - 'project_id': self.project_id, - 'program_id': self.program_id, - 'job_id': self.job_id, - } - - -def to_zphase_data(results: Iterable[PhasedFSimCalibrationResult]) -> util.ZPhaseDataType: - """Packages a collection of results into ZPhaseDataType. - - Args: - results: List of results to pack into ZPhaseDataType. If multiple results provide a value - for a given (gate, angle, qubits) tuple, only the last one will be kept. - - Returns: - A ZPhaseDataType-formatted result representation. This can be used with the - calibration-to-noise pipeline for generating noise models. - - Raises: - ValueError: if results for a gate other than Sycamore or ISwapPowGate are given. - """ - zphase_data: util.ZPhaseDataType = {} - for result in results: - gate_type = GATE_ZPHASE_CODE_PAIRS.get(type(result.gate)) - if gate_type is None: - raise ValueError( - f"Only 'SycamoreGate' and 'ISwapPowGate' are supported, got {result.gate}" - ) - gate_dict = zphase_data.setdefault(gate_type, {}) - for qubits, data in result.parameters.items(): - for angle, value in data.asdict().items(): - if value is None: - continue - angle_dict = gate_dict.setdefault(angle, {}) - angle_dict[qubits] = value - - return zphase_data - - -def merge_matching_results( - results: Iterable[PhasedFSimCalibrationResult], -) -> Optional[PhasedFSimCalibrationResult]: - """Merges a collection of results into a single result. - - Args: - results: List of results to merge. They must be compatible with each other: all gate and - options fields must be equal and every characterized pair must be present only in one of - the characterizations. - - Returns: - New PhasedFSimCalibrationResult that contains all the parameters from every result in - results or None when the results list is empty. - - Raises: - ValueError: If the gate and options fields are not all equal, or if the - results have shared keys. - """ - all_parameters: Dict[Tuple[cirq.Qid, cirq.Qid], PhasedFSimCharacterization] = {} - common_gate = None - common_options = None - for result in results: - if common_gate is None: - common_gate = result.gate - elif common_gate != result.gate: - raise ValueError( - f'Only matching results can be merged, got gates {common_gate} and {result.gate}' - ) - - if common_options is None: - common_options = result.options - elif common_options != result.options: - raise ValueError( - f'Only matching results can be merged, got options {common_options} and ' - f'{result.options}' - ) - - if not all_parameters.keys().isdisjoint(result.parameters): - raise ValueError('Only results with disjoint parameters sets can be merged') - - all_parameters.update(result.parameters) - - if common_gate is None or common_options is None: - return None - - return PhasedFSimCalibrationResult(all_parameters, common_gate, common_options) - - -class PhasedFSimCalibrationError(Exception): - """Error that indicates the calibration failure.""" - - -@dataclasses.dataclass(frozen=True) -class PhasedFSimCalibrationRequest(abc.ABC): - """Description of the request to characterize PhasedFSimGate. - - Attributes: - pairs: Set of qubit pairs to characterize. A single qubit can appear on at most one pair in - the set. - gate: Gate to characterize for each qubit pair from pairs. This must be a supported gate - which can be described cirq.PhasedFSim gate. This gate must be serialized by the - cirq_google.SerializableGateSet used - """ - - pairs: Tuple[Tuple[cirq.Qid, cirq.Qid], ...] - gate: cirq.Gate # Any gate which can be described by cirq.PhasedFSim - options: PhasedFSimCalibrationOptions - - @property - @lru_cache_typesafe - def qubit_to_pair(self) -> MutableMapping[cirq.Qid, Tuple[cirq.Qid, cirq.Qid]]: - """Returns mapping from qubit to a qubit pair that it belongs to.""" - # Returning mutable mapping as a cached result because it's hard to get a frozen dictionary - # in Python... - return collections.ChainMap(*({q: pair for q in pair} for pair in self.pairs)) - - @abc.abstractmethod - def to_calibration_layer(self) -> CalibrationLayer: - """Encodes this characterization request in a CalibrationLayer object.""" - - @abc.abstractmethod - def parse_result( - self, result: CalibrationResult, job: Optional[EngineJob] = None - ) -> PhasedFSimCalibrationResult: - """Decodes the characterization result issued for this request.""" - - -@dataclasses.dataclass(frozen=True) -class XEBPhasedFSimCalibrationOptions(PhasedFSimCalibrationOptions): - """Options for configuring a PhasedFSim calibration using XEB. - - XEB uses the fidelity of random circuits to characterize PhasedFSim gates. The parameters - of the gate are varied by a classical optimizer to maximize the observed fidelities. - - Args: - n_library_circuits: The number of distinct, two-qubit random circuits to use in our - library of random circuits. This should be the same order of magnitude as - `n_combinations`. - n_combinations: We take each library circuit and randomly assign it to qubit pairs. - This parameter controls the number of random combinations of the two-qubit random - circuits we execute. Higher values increase the precision of estimates but linearly - increase experimental runtime. - cycle_depths: We run the random circuits at these cycle depths to fit an exponential - decay in the fidelity. - fatol: The absolute convergence tolerance for the objective function evaluation in - the Nelder-Mead optimization. This controls the runtime of the classical - characterization optimization loop. - xatol: The absolute convergence tolerance for the parameter estimates in - the Nelder-Mead optimization. This controls the runtime of the classical - characterization optimization loop. - fsim_options: An instance of `XEBPhasedFSimCharacterizationOptions` that controls aspects - of the PhasedFSim characterization like initial guesses and which angles to - characterize. - """ - - n_library_circuits: int = 20 - n_combinations: int = 10 - cycle_depths: Tuple[int, ...] = _DEFAULT_XEB_CYCLE_DEPTHS - fatol: Optional[float] = 5e-3 - xatol: Optional[float] = 5e-3 - - fsim_options: XEBPhasedFSimCharacterizationOptions = XEBPhasedFSimCharacterizationOptions() - - def to_args(self) -> Dict[str, Any]: - """Convert this dataclass to an `args` dictionary suitable for sending to the Quantum - Engine calibration API.""" - args: Dict[str, Any] = { - 'n_library_circuits': self.n_library_circuits, - 'n_combinations': self.n_combinations, - 'cycle_depths': '_'.join(f'{cd:d}' for cd in self.cycle_depths), - } - if self.fatol is not None: - args['fatol'] = self.fatol - if self.xatol is not None: - args['xatol'] = self.xatol - - fsim_options = dataclasses.asdict(self.fsim_options) - fsim_options = {k: v for k, v in fsim_options.items() if v is not None} - args.update(fsim_options) - return args - - def create_phased_fsim_request( - self, pairs: Tuple[Tuple[cirq.Qid, cirq.Qid], ...], gate: cirq.Gate - ) -> 'XEBPhasedFSimCalibrationRequest': - return XEBPhasedFSimCalibrationRequest(pairs=pairs, gate=gate, options=self) - - @classmethod - def _from_json_dict_(cls, **kwargs): - del kwargs['cirq_type'] - kwargs['cycle_depths'] = tuple(kwargs['cycle_depths']) - return cls(**kwargs) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -@dataclasses.dataclass(frozen=True) -class LocalXEBPhasedFSimCalibrationOptions(XEBPhasedFSimCalibrationOptions): - """Options for configuring a PhasedFSim calibration using a local version of XEB. - - XEB uses the fidelity of random circuits to characterize PhasedFSim gates. The parameters - of the gate are varied by a classical optimizer to maximize the observed fidelities. - - These "Local" options (corresponding to `LocalXEBPhasedFSimCalibrationRequest`) instruct - `cirq_google.run_calibrations` to execute XEB analysis locally (not via the quantum - engine). As such, `run_calibrations` can work with any `cirq.Sampler`, not just - `ProcessorSampler`. - - Args: - n_library_circuits: The number of distinct, two-qubit random circuits to use in our - library of random circuits. This should be the same order of magnitude as - `n_combinations`. - n_combinations: We take each library circuit and randomly assign it to qubit pairs. - This parameter controls the number of random combinations of the two-qubit random - circuits we execute. Higher values increase the precision of estimates but linearly - increase experimental runtime. - cycle_depths: We run the random circuits at these cycle depths to fit an exponential - decay in the fidelity. - fatol: The absolute convergence tolerance for the objective function evaluation in - the Nelder-Mead optimization. This controls the runtime of the classical - characterization optimization loop. - xatol: The absolute convergence tolerance for the parameter estimates in - the Nelder-Mead optimization. This controls the runtime of the classical - characterization optimization loop. - fsim_options: An instance of `XEBPhasedFSimCharacterizationOptions` that controls aspects - of the PhasedFSim characterization like initial guesses and which angles to - characterize. - n_processes: The number of multiprocessing processes to analyze the XEB characterization - data. By default, we use a value equal to the number of CPU cores. If `1` is specified, - multiprocessing is not used. - """ - - n_processes: Optional[int] = None - - def create_phased_fsim_request( - self, pairs: Tuple[Tuple[cirq.Qid, cirq.Qid], ...], gate: cirq.Gate - ): - return LocalXEBPhasedFSimCalibrationRequest(pairs=pairs, gate=gate, options=self) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -@dataclasses.dataclass(frozen=True) -class FloquetPhasedFSimCalibrationOptions(PhasedFSimCalibrationOptions): - """Options specific to Floquet PhasedFSimCalibration. - - Some angles require another angle to be characterized first so result might have more angles - characterized than requested here. - - Attributes: - characterize_theta: Whether to characterize θ angle. - characterize_zeta: Whether to characterize ζ angle. - characterize_chi: Whether to characterize χ angle. - characterize_gamma: Whether to characterize γ angle. - characterize_phi: Whether to characterize φ angle. - readout_error_tolerance: Threshold for pairwise-correlated readout errors above which the - calibration will report to fail. Just before each calibration all pairwise two-qubit - readout errors are checked and when any of the pairs reports an error above the - threshold, the calibration will fail. This value is a sanity check to determine if - calibration is reasonable and allows for quick termination if it is not. Set to 1.0 to - disable readout error checks and None to use default, device-specific thresholds. - """ - - characterize_theta: bool - characterize_zeta: bool - characterize_chi: bool - characterize_gamma: bool - characterize_phi: bool - readout_error_tolerance: Optional[float] = None - version: int = 2 - measure_qubits: Optional[Tuple[cirq.Qid, ...]] = None - - def zeta_chi_gamma_correction_override(self) -> PhasedFSimCharacterization: - """Gives a PhasedFSimCharacterization that can be used to override characterization after - correcting for zeta, chi and gamma angles. - """ - return PhasedFSimCharacterization( - zeta=0.0 if self.characterize_zeta else None, - chi=0.0 if self.characterize_chi else None, - gamma=0.0 if self.characterize_gamma else None, - ) - - def create_phased_fsim_request( - self, pairs: Tuple[Tuple[cirq.Qid, cirq.Qid], ...], gate: cirq.Gate - ) -> 'FloquetPhasedFSimCalibrationRequest': - return FloquetPhasedFSimCalibrationRequest(pairs=pairs, gate=gate, options=self) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -"""Floquet PhasedFSimCalibrationOptions options with all angles characterization requests set to -True.""" -ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION = FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=True, -) - -"""XEB PhasedFSimCalibrationOptions options with all angles characterization requests set to -True.""" -ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION = XEBPhasedFSimCalibrationOptions( - fsim_options=XEBPhasedFSimCharacterizationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=True, - ) -) - - -"""PhasedFSimCalibrationOptions with all but chi angle characterization requests set to True.""" -WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION = FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=True, - characterize_phi=True, -) - - -"""PhasedFSimCalibrationOptions with theta, zeta and gamma angles characterization requests set to -True. - -Those are the most efficient options that can be used to cancel out the errors by adding the -appropriate single-qubit Z rotations to the circuit. The angles zeta, chi and gamma can be removed -by those additions. The angle chi is disabled because it's not supported by Floquet characterization -currently. The angle theta is set enabled because it is characterized together with zeta and adding -it doesn't cost anything. -""" -THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION = FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=True, - characterize_phi=False, -) - - -@dataclasses.dataclass(frozen=True) -class FloquetPhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest): - """PhasedFSim characterization request specific to Floquet calibration. - - Attributes: - options: Floquet-specific characterization options. - """ - - options: FloquetPhasedFSimCalibrationOptions - - @classmethod - def from_moment(cls, moment: cirq.Moment, options: FloquetPhasedFSimCalibrationOptions): - """Creates a FloquetPhasedFSimCalibrationRequest from a Moment. - - Given a `Moment` object, this function extracts out the pairs of - qubits and the `Gate` used to create a `FloquetPhasedFSimCalibrationRequest` - object. The moment must contain only identical two-qubit FSimGates. - If dissimilar gates are passed in, a ValueError is raised. - """ - pairs, gate = _create_pairs_from_moment(moment) - return cls(pairs, gate, options) - - def to_calibration_layer(self) -> CalibrationLayer: - circuit = cirq.Circuit(self.gate.on(*pair) for pair in self.pairs) - if self.options.measure_qubits is not None: - circuit += cirq.Moment(cirq.measure(*self.options.measure_qubits)) - args: Dict[str, Any] = { - 'est_theta': self.options.characterize_theta, - 'est_zeta': self.options.characterize_zeta, - 'est_chi': self.options.characterize_chi, - 'est_gamma': self.options.characterize_gamma, - 'est_phi': self.options.characterize_phi, - # Experimental option that should always be set to True. - 'readout_corrections': True, - 'version': self.options.version, - } - if self.options.readout_error_tolerance is not None: - # Maximum error of the diagonal elements of the two-qubit readout confusion matrix. - args['readout_error_tolerance'] = self.options.readout_error_tolerance - # Maximum error of the off-diagonal elements of the two-qubit readout confusion matrix. - args['correlated_readout_error_tolerance'] = _correlated_from_readout_tolerance( - self.options.readout_error_tolerance - ) - return CalibrationLayer( - calibration_type=_FLOQUET_PHASED_FSIM_HANDLER_NAME, program=circuit, args=args - ) - - def parse_result( - self, result: CalibrationResult, job: Optional[EngineJob] = None - ) -> PhasedFSimCalibrationResult: - decoded: Dict[int, Dict[str, Any]] = collections.defaultdict(lambda: {}) - for keys, values in result.metrics['angles'].items(): - for key, value in zip(keys, values): - match = re.match(r'(\d+)_(.+)', str(key)) - if not match: - raise ValueError(f'Unknown metric name {key}') - index = int(match[1]) - name = match[2] - decoded[index][name] = value - - parsed = {} - for data in decoded.values(): - a = v2.qubit_from_proto_id(data['qubit_a']) - b = v2.qubit_from_proto_id(data['qubit_b']) - parsed[(a, b)] = PhasedFSimCharacterization( - theta=data.get('theta_est', None), - zeta=data.get('zeta_est', None), - chi=data.get('chi_est', None), - gamma=data.get('gamma_est', None), - phi=data.get('phi_est', None), - ) - - return PhasedFSimCalibrationResult( - parameters=parsed, - gate=self.gate, - options=self.options, - project_id=None if job is None else job.project_id, - program_id=None if job is None else job.program_id, - job_id=None if job is None else job.job_id, - ) - - @classmethod - def _from_json_dict_( - cls, - gate: cirq.Gate, - pairs: List[Tuple[cirq.Qid, cirq.Qid]], - options: FloquetPhasedFSimCalibrationOptions, - **kwargs, - ) -> 'FloquetPhasedFSimCalibrationRequest': - """Magic method for the JSON serialization protocol. - - Converts serialized dictionary into a dict suitable for - class instantiation.""" - instantiation_pairs = tuple((q_a, q_b) for q_a, q_b in pairs) - return cls(instantiation_pairs, gate, options) - - def _json_dict_(self) -> Dict[str, Any]: - """Magic method for the JSON serialization protocol.""" - return { - 'pairs': [(pair[0], pair[1]) for pair in self.pairs], - 'gate': self.gate, - 'options': self.options, - } - - -def _correlated_from_readout_tolerance(readout_tolerance: float) -> float: - """Heuristic formula for the off-diagonal confusion matrix error thresholds. - - This is chosen to return 0.3 for readout_tolerance = 0.4 and 1.0 for readout_tolerance = 1.0. - """ - return max(0.0, min(1.0, 7 / 6 * readout_tolerance - 1 / 6)) - - -def _get_labeled_int(key: str, s: str): - ma = re.match(rf'{key}_(\d+)$', s) - if ma is None: - raise ValueError(f"Could not parse {key} value for {s}") - return int(ma.group(1)) - - -def _parse_xeb_fidelities_df(metrics: 'cirq_google.Calibration', super_name: str) -> pd.DataFrame: - """Parse a fidelities DataFrame from Metric protos. - - Args: - metrics: The metrics from a CalibrationResult - super_name: The metric name prefix. We will extract information for metrics named like - "{super_name}_depth_{depth}", so you can have multiple independent DataFrames in - one CalibrationResult. - """ - records: List[Dict[str, Union[int, float, Tuple[cirq.Qid, cirq.Qid]]]] = [] - for metric_name in metrics.keys(): - ma = re.match(fr'{super_name}_depth_(\d+)$', metric_name) - if ma is None: - continue - - for (layer_str, pair_str, qa, qb), (value,) in metrics[metric_name].items(): - records.append( - { - 'cycle_depth': int(ma.group(1)), - 'layer_i': _get_labeled_int('layer', cast(str, layer_str)), - 'pair_i': _get_labeled_int('pair', cast(str, pair_str)), - 'fidelity': float(value), - 'pair': (cast(cirq.GridQubit, qa), cast(cirq.GridQubit, qb)), - } - ) - return pd.DataFrame(records) - - -def _parse_characterized_angles( - metrics: 'cirq_google.Calibration', super_name: str -) -> Dict[Tuple[cirq.Qid, cirq.Qid], Dict[str, float]]: - """Parses characterized angles from Metric protos. - - Args: - metrics: The metrics from a CalibrationResult - super_name: The metric name prefix. We extract angle names as "{super_name}_{angle_name}". - """ - - records: Dict[Tuple[cirq.Qid, cirq.Qid], Dict[str, float]] = collections.defaultdict(dict) - for metric_name in metrics.keys(): - ma = re.match(fr'{super_name}_(\w+)$', metric_name) - if ma is None: - continue - - angle_name = ma.group(1) - for (qa, qb), (value,) in metrics[metric_name].items(): - qa = cast(cirq.GridQubit, qa) - qb = cast(cirq.GridQubit, qb) - value = float(value) - records[qa, qb][angle_name] = value - return dict(records) - - -@dataclasses.dataclass(frozen=True) -class LocalXEBPhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest): - """PhasedFSim characterization request for local cross entropy benchmarking (XEB) calibration. - - A "Local" request (corresponding to `LocalXEBPhasedFSimCalibrationOptions`) instructs - `cirq_google.run_calibrations` to execute XEB analysis locally (not via the quantum - engine). As such, `run_calibrations` can work with any `cirq.Sampler`, not just - `ProcessorSampler`. - - Attributes: - options: local-XEB-specific characterization options. - """ - - options: LocalXEBPhasedFSimCalibrationOptions - - def parse_result( - self, result: CalibrationResult, job: Optional[EngineJob] = None - ) -> PhasedFSimCalibrationResult: - raise NotImplementedError('Not applicable for local calibrations') - - def to_calibration_layer(self) -> CalibrationLayer: - raise NotImplementedError('Not applicable for local calibrations') - - @classmethod - def _from_json_dict_( - cls, - gate: cirq.Gate, - pairs: List[Tuple[cirq.Qid, cirq.Qid]], - options: LocalXEBPhasedFSimCalibrationOptions, - **kwargs, - ) -> 'LocalXEBPhasedFSimCalibrationRequest': - # List -> Tuple - instantiation_pairs = tuple((q_a, q_b) for q_a, q_b in pairs) - return cls(instantiation_pairs, gate, options) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -@dataclasses.dataclass(frozen=True) -class XEBPhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest): - """PhasedFSim characterization request for cross entropy benchmarking (XEB) calibration. - - Attributes: - options: XEB-specific characterization options. - """ - - options: XEBPhasedFSimCalibrationOptions - - def to_calibration_layer(self) -> CalibrationLayer: - circuit = cirq.Circuit(self.gate.on(*pair) for pair in self.pairs) - return CalibrationLayer( - calibration_type=_XEB_PHASED_FSIM_HANDLER_NAME, - program=circuit, - args=self.options.to_args(), - ) - - def parse_result( - self, result: CalibrationResult, job: Optional[EngineJob] = None - ) -> PhasedFSimCalibrationResult: - # pylint: disable=unused-variable - initial_fids = _parse_xeb_fidelities_df(result.metrics, 'initial_fidelities') - final_fids = _parse_xeb_fidelities_df(result.metrics, 'final_fidelities') - # pylint: enable=unused-variable - - final_params = { - pair: PhasedFSimCharacterization(**angles) - for pair, angles in _parse_characterized_angles( - result.metrics, 'characterized_angles' - ).items() - } - - # TODO: Return initial_fids, final_fids somehow. - return PhasedFSimCalibrationResult( - parameters=final_params, - gate=self.gate, - options=self.options, - project_id=None if job is None else job.project_id, - program_id=None if job is None else job.program_id, - job_id=None if job is None else job.job_id, - ) - - @classmethod - def _from_json_dict_( - cls, - gate: cirq.Gate, - pairs: List[Tuple[cirq.Qid, cirq.Qid]], - options: XEBPhasedFSimCalibrationOptions, - **kwargs, - ) -> 'XEBPhasedFSimCalibrationRequest': - # List -> Tuple - instantiation_pairs = tuple((q_a, q_b) for q_a, q_b in pairs) - return cls(instantiation_pairs, gate, options) - - def _json_dict_(self): - return cirq.dataclass_json_dict(self) - - -class IncompatibleMomentError(Exception): - """Error that occurs when a moment is not supported by a calibration routine.""" - - -@dataclasses.dataclass(frozen=True) -class PhaseCalibratedFSimGate: - """Association of a user gate with gate to calibrate. - - This association stores information regarding rotation of the calibrated FSim gate by - phase_exponent p: - - (Z^-p ⊗ Z^p) FSim (Z^p ⊗ Z^-p). - - The unitary matrix of the gate is: - - [[1, 0, 0, 0], - [0, cos(θ), (1/g^2) sin(θ), 0], - [0, (g^2) sin(θ), cos(θ), 0], - [0, 0, 0, exp(-iφ)]] - - where g = exp(i·π·p) - - The rotation should be reflected back during the compilation after the gate is calibrated and - is equivalent to the shift of -2πp in the χ angle of PhasedFSimGate. - - Attributes: - engine_gate: Gate that should be used for calibration purposes. - phase_exponent: Phase rotation exponent p. - """ - - engine_gate: cirq.FSimGate - phase_exponent: float - - def as_characterized_phased_fsim_gate( - self, parameters: PhasedFSimCharacterization - ) -> cirq.PhasedFSimGate: - """Creates a PhasedFSimGate which represents the characterized engine_gate but includes - deviations in unitary parameters. - - Args: - parameters: The results of characterization of the engine gate. - - Returns: - Instance of PhasedFSimGate that executes a gate according to the characterized - parameters of the engine_gate. - """ - assert parameters.chi is not None - return cirq.PhasedFSimGate( - theta=parameters.theta or 0.0, - zeta=parameters.zeta or 0.0, - chi=parameters.chi - 2 * np.pi * self.phase_exponent, - gamma=parameters.gamma or 0.0, - phi=parameters.phi or 0.0, - ) - - def with_zeta_chi_gamma_compensated( - self, - qubits: Tuple[cirq.Qid, cirq.Qid], - parameters: PhasedFSimCharacterization, - *, - engine_gate: Optional[cirq.Gate] = None, - ) -> Tuple[Tuple[cirq.Operation, ...], ...]: - """Creates a composite operation that compensates for zeta, chi and gamma angles of the - characterization. - - Args: - qubits: Qubits that the gate should act on. - parameters: The results of characterization of the engine gate. - engine_gate: 2-qubit gate that represents the engine gate. When None, the internal - engine_gate of this instance is used. This argument is useful for testing - purposes. - - Returns: - Tuple of tuple of operations that describe the compensated gate. The first index - iterates over moments of the composed operation. - - Raises: - ValueError: If the engine gate is not a 2-qubit gate. - """ - assert parameters.zeta is not None, "Zeta value must not be None" - zeta = parameters.zeta - - assert parameters.gamma is not None, "Gamma value must not be None" - gamma = parameters.gamma - - assert parameters.chi is not None, "Chi value must not be None" - chi = parameters.chi + 2 * np.pi * self.phase_exponent - - if engine_gate is None: - engine_gate = self.engine_gate - else: - if cirq.num_qubits(engine_gate) != 2: - raise ValueError('Engine gate must be a two-qubit gate') # pragma: no cover - - a, b = qubits - - alpha = 0.5 * (zeta + chi) - beta = 0.5 * (zeta - chi) - - return ( - (cirq.rz(0.5 * gamma - alpha).on(a), cirq.rz(0.5 * gamma + alpha).on(b)), - (engine_gate.on(a, b),), - (cirq.rz(0.5 * gamma - beta).on(a), cirq.rz(0.5 * gamma + beta).on(b)), - ) - - def _unitary_(self) -> np.ndarray: - """Implements Cirq's `unitary` protocol for this object.""" - p = np.exp(-np.pi * 1j * self.phase_exponent) - return ( - np.diag([1, p, 1 / p, 1]) @ cirq.unitary(self.engine_gate) @ np.diag([1, 1 / p, p, 1]) - ) - - -def try_convert_sqrt_iswap_to_fsim(gate: cirq.Gate) -> Optional[PhaseCalibratedFSimGate]: - """Converts an equivalent gate to FSimGate(theta=π/4, phi=0) if possible. - - Args: - gate: Gate to verify. - - Returns: - FSimGateCalibration with engine_gate FSimGate(theta=π/4, phi=0) if the provided gate is - either FSimGate, ISWapPowGate, PhasedFSimGate or PhasedISwapPowGate that is equivalent to - FSimGate(theta=±π/4, phi=0). None otherwise. - """ - result = try_convert_gate_to_fsim(gate) - if result is None: - return None - engine_gate = result.engine_gate - if math.isclose(cast(float, engine_gate.theta), np.pi / 4) and math.isclose( - cast(float, engine_gate.phi), 0.0 - ): - return result - return None - - -def try_convert_gate_to_fsim(gate: cirq.Gate) -> Optional[PhaseCalibratedFSimGate]: - """Converts a gate to equivalent PhaseCalibratedFSimGate if possible. - - Args: - gate: Gate to convert. - - Returns: - If provided gate is equivalent to some PhaseCalibratedFSimGate, returns that gate. - Otherwise returns None. - """ - cgate = FSimGateFamily().convert(gate, cirq.PhasedFSimGate) - if cgate is None or cirq.is_parameterized(cgate): - return None - assert isinstance(cgate.zeta, float) and isinstance(cgate.gamma, float) - if not (np.isclose(cgate.zeta, 0.0) and np.isclose(cgate.gamma, 0.0)): - return None - # On comparing the unitary matrices of `PhasedFSimGate` and `PhaseCalibratedFSimGate`, we get: - theta = cgate.theta - phi = cgate.phi - phase_exponent = -cgate.chi / (2 * np.pi) - - phi = phi % (2 * np.pi) - theta = theta % (2 * np.pi) - if theta >= np.pi: - theta = 2 * np.pi - theta - phase_exponent = phase_exponent + 0.5 - phase_exponent %= 1 - return PhaseCalibratedFSimGate(cirq.FSimGate(theta=theta, phi=phi), phase_exponent) - - -def try_convert_syc_or_sqrt_iswap_to_fsim(gate: cirq.Gate) -> Optional[PhaseCalibratedFSimGate]: - """Converts a gate to equivalent PhaseCalibratedFSimGate if possible. - - Args: - gate: Gate to convert. - - Returns: - Equivalent PhaseCalibratedFSimGate if its `engine_gate` is Sycamore or inverse sqrt(iSWAP) - gate. Otherwise returns None. - """ - result = try_convert_gate_to_fsim(gate) - if result is None: - return None - engine_gate = result.engine_gate - if math.isclose(engine_gate.theta, np.pi / 2) and math.isclose(engine_gate.phi, np.pi / 6): - # Sycamore gate. - return result - if math.isclose(engine_gate.theta, np.pi / 4) and math.isclose(engine_gate.phi, 0.0): - # Inverse sqrt(iSWAP) gate. - return result - return None diff --git a/cirq-google/cirq_google/calibration/phased_fsim_test.py b/cirq-google/cirq_google/calibration/phased_fsim_test.py deleted file mode 100644 index 00d4cb38815..00000000000 --- a/cirq-google/cirq_google/calibration/phased_fsim_test.py +++ /dev/null @@ -1,1069 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import os - -from typing import cast -from unittest import mock -import numpy as np -import pandas as pd -import pytest -import sympy -from google.protobuf import text_format - -import cirq -import cirq_google -from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions -from cirq_google.api import v2 -from cirq_google.calibration.phased_fsim import ( - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - PhaseCalibratedFSimGate, - PhasedFSimCalibrationError, - PhasedFSimCharacterization, - PhasedFSimCalibrationResult, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - merge_matching_results, - to_zphase_data, - try_convert_gate_to_fsim, - try_convert_syc_or_sqrt_iswap_to_fsim, - try_convert_sqrt_iswap_to_fsim, - XEBPhasedFSimCalibrationRequest, - XEBPhasedFSimCalibrationOptions, - _parse_xeb_fidelities_df, - _parse_characterized_angles, -) -from cirq_google.serialization.arg_func_langs import arg_to_proto - - -def test_asdict(): - characterization_angles = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - characterization = PhasedFSimCharacterization(**characterization_angles) - assert characterization.asdict() == characterization_angles - - -def test_all_none(): - assert PhasedFSimCharacterization().all_none() - - characterization_angles = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - for angle, value in characterization_angles.items(): - assert not PhasedFSimCharacterization(**{angle: value}).all_none() - - -def test_any_none(): - characterization_angles = {'theta': 0.1, 'zeta': 0.2, 'chi': 0.3, 'gamma': 0.4, 'phi': 0.5} - assert not PhasedFSimCharacterization(**characterization_angles).any_none() - - for angle in characterization_angles: - none_angles = dict(characterization_angles) - del none_angles[angle] - assert PhasedFSimCharacterization(**none_angles).any_none() - - -def test_parameters_for_qubits_swapped(): - characterization = PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5) - assert characterization.parameters_for_qubits_swapped() == PhasedFSimCharacterization( - theta=0.1, zeta=-0.2, chi=-0.3, gamma=0.4, phi=0.5 - ) - - -def test_merge_with(): - characterization = PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=0.3) - other = PhasedFSimCharacterization(gamma=0.4, phi=0.5, theta=0.6) - assert characterization.merge_with(other) == PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5 - ) - - -def test_override_by(): - characterization = PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=0.3) - other = PhasedFSimCharacterization(gamma=0.4, phi=0.5, theta=0.6) - assert characterization.override_by(other) == PhasedFSimCharacterization( - theta=0.6, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5 - ) - - -def test_floquet_to_calibration_layer(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - assert request.to_calibration_layer() == cirq_google.CalibrationLayer( - calibration_type='floquet_phased_fsim_characterization', - program=cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03)]), - args={ - 'est_theta': True, - 'est_zeta': True, - 'est_chi': False, - 'est_gamma': False, - 'est_phi': True, - 'readout_corrections': True, - 'version': 2, - }, - ) - - -def test_floquet_to_calibration_layer_with_version_override(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - version=3, - ), - ) - - assert request.to_calibration_layer() == cirq_google.CalibrationLayer( - calibration_type='floquet_phased_fsim_characterization', - program=cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03)]), - args={ - 'est_theta': True, - 'est_zeta': True, - 'est_chi': False, - 'est_gamma': False, - 'est_phi': True, - 'readout_corrections': True, - 'version': 3, - }, - ) - - -def test_floquet_to_calibration_layer_readout_thresholds(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - readout_error_tolerance=0.4, - ), - ) - - assert request.to_calibration_layer() == cirq_google.CalibrationLayer( - calibration_type='floquet_phased_fsim_characterization', - program=cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03)]), - args={ - 'est_theta': True, - 'est_zeta': True, - 'est_chi': False, - 'est_gamma': False, - 'est_phi': True, - 'readout_corrections': True, - 'readout_error_tolerance': 0.4, - 'correlated_readout_error_tolerance': 7 / 6 * 0.4 - 1 / 6, - 'version': 2, - }, - ) - - -def test_floquet_to_calibration_layer_with_measure_qubits(): - qubits = tuple(cirq.GridQubit(0, index) for index in range(5)) - q_00, q_01, q_02, q_03, _ = qubits - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - measure_qubits=qubits, - ), - ) - - assert request.to_calibration_layer() == cirq_google.CalibrationLayer( - calibration_type='floquet_phased_fsim_characterization', - program=cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03), cirq.measure(*qubits)]), - args={ - 'est_theta': True, - 'est_zeta': True, - 'est_chi': False, - 'est_gamma': False, - 'est_phi': True, - 'readout_corrections': True, - 'version': 2, - }, - ) - - -def test_xeb_to_calibration_layer(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=0.75, phi=0.0) - request = XEBPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=XEBPhasedFSimCalibrationOptions( - n_library_circuits=22, - fatol=0.0078125, - xatol=0.0078125, - fsim_options=XEBPhasedFSimCharacterizationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ), - ) - layer = request.to_calibration_layer() - assert layer == cirq_google.CalibrationLayer( - calibration_type='xeb_phased_fsim_characterization', - program=cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03)]), - args={ - 'n_library_circuits': 22, - 'n_combinations': 10, - 'cycle_depths': '5_25_50_100_200_300', - 'fatol': 0.0078125, - 'xatol': 0.0078125, - 'characterize_theta': True, - 'characterize_zeta': True, - 'characterize_chi': False, - 'characterize_gamma': False, - 'characterize_phi': True, - }, - ) - - # Serialize to proto - calibration = v2.calibration_pb2.FocusedCalibration() - new_layer = calibration.layers.add() - new_layer.calibration_type = layer.calibration_type - for arg in layer.args: - arg_to_proto(layer.args[arg], out=new_layer.args[arg]) - cirq_google.CIRCUIT_SERIALIZER.serialize(layer.program, msg=new_layer.layer) - with open(os.path.dirname(__file__) + '/test_data/xeb_calibration_layer.textproto') as f: - desired_textproto = f.read() - - layer_str = str(new_layer) - assert layer_str == desired_textproto - - -def test_from_moment(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - m = cirq.Moment(cirq.ISWAP(q_00, q_01) ** 0.5, cirq.ISWAP(q_02, q_03) ** 0.5) - options = FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ) - request = FloquetPhasedFSimCalibrationRequest.from_moment(m, options) - assert request == FloquetPhasedFSimCalibrationRequest( - gate=cirq.ISWAP**0.5, pairs=((q_00, q_01), (q_02, q_03)), options=options - ) - - non_identical = cirq.Moment(cirq.ISWAP(q_00, q_01) ** 0.5, cirq.ISWAP(q_02, q_03)) - with pytest.raises(ValueError, match='must be identical'): - _ = FloquetPhasedFSimCalibrationRequest.from_moment(non_identical, options) - - sq = cirq.Moment(cirq.X(q_00)) - with pytest.raises(ValueError, match='must be two qubit gates'): - _ = FloquetPhasedFSimCalibrationRequest.from_moment(sq, options) - - threeq = cirq.Moment(cirq.TOFFOLI(q_00, q_01, q_02)) - with pytest.raises(ValueError, match='must be two qubit gates'): - _ = FloquetPhasedFSimCalibrationRequest.from_moment(threeq, options) - - not_gate = cirq.Moment(cirq.CircuitOperation(cirq.FrozenCircuit())) - with pytest.raises(ValueError, match='must be two qubit gates'): - _ = FloquetPhasedFSimCalibrationRequest.from_moment(not_gate, options) - - empty = cirq.Moment() - with pytest.raises(ValueError, match='No gates found'): - _ = FloquetPhasedFSimCalibrationRequest.from_moment(empty, options) - - -def test_floquet_parse_result(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - result = cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration( - cirq_google.api.v2.metrics_pb2.MetricsSnapshot( - metrics=[ - cirq_google.api.v2.metrics_pb2.Metric( - name='angles', - targets=[ - '0_qubit_a', - '0_qubit_b', - '0_theta_est', - '0_zeta_est', - '0_phi_est', - '1_qubit_a', - '1_qubit_b', - '1_theta_est', - '1_zeta_est', - '1_phi_est', - ], - values=[ - cirq_google.api.v2.metrics_pb2.Value(str_val='0_0'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_1'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.1), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.2), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.3), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_2'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_3'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.4), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.5), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.6), - ], - ) - ] - ) - ), - ) - - assert request.parse_result(result) == PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=gate, - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - -def test_floquet_parse_result_failure(): - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=(), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - result = cirq_google.CalibrationResult( - error_message="Test message", - token=None, - valid_until=None, - metrics=cirq_google.Calibration(), - ) - - with pytest.raises(PhasedFSimCalibrationError, match='Test message'): - request.parse_result(result) - - -def _load_xeb_results_textproto() -> cirq_google.CalibrationResult: - with open(os.path.dirname(__file__) + '/test_data/xeb_results.textproto') as f: - metrics_snapshot = text_format.Parse( - f.read(), cirq_google.api.v2.metrics_pb2.MetricsSnapshot() - ) - return cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration(metrics_snapshot), - ) - - -def test_xeb_parse_fidelities(): - q0, q1, q2, q3 = [cirq.GridQubit(0, index) for index in range(4)] - pair0 = (q0, q1) - pair1 = (q2, q3) - result = _load_xeb_results_textproto() - metrics = result.metrics - df = _parse_xeb_fidelities_df(metrics, 'initial_fidelities') - should_be = pd.DataFrame( - { - 'cycle_depth': [5, 5, 25, 25], - 'layer_i': [0, 0, 0, 0], - 'pair_i': [0, 1, 0, 1], - 'fidelity': [0.99, 0.99, 0.88, 0.88], - 'pair': [pair0, pair1, pair0, pair1], - } - ) - pd.testing.assert_frame_equal(df, should_be) - - df = _parse_xeb_fidelities_df(metrics, 'final_fidelities') - should_be = pd.DataFrame( - { - 'cycle_depth': [5, 5, 25, 25], - 'layer_i': [0, 0, 0, 0], - 'pair_i': [0, 1, 0, 1], - 'fidelity': [0.99, 0.99, 0.98, 0.98], - 'pair': [pair0, pair1, pair0, pair1], - } - ) - pd.testing.assert_frame_equal(df, should_be) - - -def test_xeb_parse_bad_fidelities(): - metrics = cirq_google.Calibration( - metrics={ - 'initial_fidelities_depth_5': { - ('layer_0', 'pair_0', cirq.GridQubit(0, 0), cirq.GridQubit(1, 1)): [1.0] - } - } - ) - df = _parse_xeb_fidelities_df(metrics, 'initial_fidelities') - pd.testing.assert_frame_equal( - df, - pd.DataFrame( - { - 'cycle_depth': [5], - 'layer_i': [0], - 'pair_i': [0], - 'fidelity': [1.0], - 'pair': [(cirq.GridQubit(0, 0), cirq.GridQubit(1, 1))], - } - ), - ) - - metrics = cirq_google.Calibration( - metrics={'initial_fidelities_depth_5x': {('layer_0', 'pair_0', '0_0', '1_1'): [1.0]}} - ) - df = _parse_xeb_fidelities_df(metrics, 'initial_fidelities') - assert len(df) == 0, 'bad metric name ignored' - - metrics = cirq_google.Calibration( - metrics={'initial_fidelities_depth_5': {('bad_name_0', 'pair_0', '0_0', '1_1'): [1.0]}} - ) - with pytest.raises(ValueError, match=r'Could not parse layer value for bad_name_0'): - _parse_xeb_fidelities_df(metrics, 'initial_fidelities') - - -def test_xeb_parse_angles(): - q0, q1, q2, q3 = [cirq.GridQubit(0, index) for index in range(4)] - result = _load_xeb_results_textproto() - metrics = result.metrics - angles = _parse_characterized_angles(metrics, 'characterized_angles') - assert angles == { - (q0, q1): {'theta': -0.7853981, 'phi': 0.0}, - (q2, q3): {'theta': -0.7853981, 'phi': 0.0}, - } - - -def test_xeb_parse_result_failure(): - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = XEBPhasedFSimCalibrationRequest( - gate=gate, - pairs=(), - options=XEBPhasedFSimCalibrationOptions( - fsim_options=XEBPhasedFSimCharacterizationOptions( - characterize_theta=False, - characterize_zeta=False, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ) - ), - ) - - result = cirq_google.CalibrationResult( - error_message="Test message", - token=None, - valid_until=None, - metrics=cirq_google.Calibration(), - ) - - with pytest.raises(PhasedFSimCalibrationError, match='Test message'): - request.parse_result(result) - - -def test_xeb_parse_result(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = XEBPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=XEBPhasedFSimCalibrationOptions( - fsim_options=XEBPhasedFSimCharacterizationOptions( - characterize_theta=False, - characterize_zeta=False, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ) - ), - ) - - result = _load_xeb_results_textproto() - assert request.parse_result(result) == PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization(phi=0.0, theta=-0.7853981), - (q_02, q_03): PhasedFSimCharacterization(phi=0.0, theta=-0.7853981), - }, - gate=gate, - options=request.options, - ) - - -def test_floquet_parse_result_bad_metric(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - result = cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration( - cirq_google.api.v2.metrics_pb2.MetricsSnapshot( - metrics=[ - cirq_google.api.v2.metrics_pb2.Metric( - name='angles', - targets=['1000gerbils'], - values=[cirq_google.api.v2.metrics_pb2.Value(str_val='100_10')], - ) - ] - ) - ), - ) - with pytest.raises(ValueError, match='Unknown metric name 1000gerbils'): - _ = request.parse_result(result) - - -def test_get_parameters(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - result = PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=gate, - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - assert result.get_parameters(q_00, q_01) == PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ) - assert result.get_parameters(q_01, q_00) == PhasedFSimCharacterization( - theta=0.1, zeta=-0.2, chi=None, gamma=None, phi=0.3 - ) - assert result.get_parameters(q_02, q_03) == PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ) - assert result.get_parameters(q_00, q_03) is None - - -def test_to_zphase_data(): - q0, q1, q2 = cirq.GridQubit.rect(1, 3) - result_1 = PhasedFSimCalibrationResult( - { - (q0, q1): PhasedFSimCharacterization(zeta=0.1, gamma=0.2), - (q1, q2): PhasedFSimCharacterization(zeta=0.3, gamma=0.4), - }, - gate=cirq_google.SycamoreGate(), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - result_2 = PhasedFSimCalibrationResult( - { - (q0, q1): PhasedFSimCharacterization(zeta=0.5, gamma=0.6), - (q1, q2): PhasedFSimCharacterization(zeta=0.7, gamma=0.8), - }, - gate=cirq.ISwapPowGate(), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - assert to_zphase_data([result_1, result_2]) == { - 'syc': {'zeta': {(q0, q1): 0.1, (q1, q2): 0.3}, 'gamma': {(q0, q1): 0.2, (q1, q2): 0.4}}, - 'sqrt_iswap': { - 'zeta': {(q0, q1): 0.5, (q1, q2): 0.7}, - 'gamma': {(q0, q1): 0.6, (q1, q2): 0.8}, - }, - } - # Test update and override - result_3 = PhasedFSimCalibrationResult( - { - (q0, q1): PhasedFSimCharacterization(theta=0.01), - (q1, q2): PhasedFSimCharacterization(zeta=0.02), - (q2, q0): PhasedFSimCharacterization(zeta=0.03, gamma=0.04, theta=0.05), - }, - gate=cirq_google.SycamoreGate(), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - assert to_zphase_data([result_1, result_3]) == { - 'syc': { - 'zeta': {(q0, q1): 0.1, (q1, q2): 0.02, (q2, q0): 0.03}, - 'gamma': {(q0, q1): 0.2, (q1, q2): 0.4, (q2, q0): 0.04}, - 'theta': {(q0, q1): 0.01, (q2, q0): 0.05}, - } - } - - -def test_to_zphase_unknown_gate_raises_error(): - q0, q1, q2 = cirq.GridQubit.rect(1, 3) - result_1 = PhasedFSimCalibrationResult( - { - (q0, q1): PhasedFSimCharacterization(zeta=0.1, gamma=0.2), - (q1, q2): PhasedFSimCharacterization(zeta=0.3, gamma=0.4), - }, - gate=cirq.CZPowGate(), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - with pytest.raises(ValueError, match="Only 'SycamoreGate' and 'ISwapPowGate' are supported"): - _ = to_zphase_data([result_1]) - - -def test_merge_matching_results(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - parameters_1 = { - (q_00, q_01): PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3) - } - parameters_2 = { - (q_02, q_03): PhasedFSimCharacterization(theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6) - } - - results = [ - PhasedFSimCalibrationResult(parameters=parameters_1, gate=gate, options=options), - PhasedFSimCalibrationResult(parameters=parameters_2, gate=gate, options=options), - ] - - assert merge_matching_results(results) == PhasedFSimCalibrationResult( - parameters={**parameters_1, **parameters_2}, gate=gate, options=options - ) - - -def test_merge_matching_results_when_empty_none(): - assert merge_matching_results([]) is None - - -def test_merge_matching_results_when_incompatible_fails(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - parameters_1 = { - (q_00, q_01): PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3) - } - parameters_2 = { - (q_02, q_03): PhasedFSimCharacterization(theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6) - } - - with pytest.raises(ValueError): - results = [ - PhasedFSimCalibrationResult(parameters=parameters_1, gate=gate, options=options), - PhasedFSimCalibrationResult(parameters=parameters_1, gate=gate, options=options), - ] - assert merge_matching_results(results) - - with pytest.raises(ValueError): - results = [ - PhasedFSimCalibrationResult(parameters=parameters_1, gate=gate, options=options), - PhasedFSimCalibrationResult(parameters=parameters_2, gate=cirq.CZ, options=options), - ] - assert merge_matching_results(results) - - with pytest.raises(ValueError): - results = [ - PhasedFSimCalibrationResult(parameters=parameters_1, gate=gate, options=options), - PhasedFSimCalibrationResult( - parameters=parameters_2, - gate=gate, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ), - ] - assert merge_matching_results(results) - - -@pytest.mark.parametrize('phase_exponent', np.linspace(0, 1, 5)) -def test_phase_calibrated_fsim_gate_as_characterized_phased_fsim_gate(phase_exponent: float): - a, b = cirq.LineQubit.range(2) - ideal_gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - characterized_gate = cirq.PhasedFSimGate( - theta=ideal_gate.theta, zeta=0.1, chi=0.2, gamma=0.3, phi=ideal_gate.phi - ) - parameters = PhasedFSimCharacterization( - theta=cast(float, ideal_gate.theta), - zeta=cast(float, characterized_gate.zeta), - chi=cast(float, characterized_gate.chi), - gamma=cast(float, characterized_gate.gamma), - phi=cast(float, ideal_gate.phi), - ) - - calibrated = PhaseCalibratedFSimGate(ideal_gate, phase_exponent=phase_exponent) - phased_gate = calibrated.as_characterized_phased_fsim_gate(parameters).on(a, b) - - assert np.allclose( - cirq.unitary(phased_gate), - cirq.unitary( - cirq.Circuit( - [ - [cirq.Z(a) ** -phase_exponent, cirq.Z(b) ** phase_exponent], - characterized_gate.on(a, b), - [cirq.Z(a) ** phase_exponent, cirq.Z(b) ** -phase_exponent], - ] - ) - ), - ) - - -@pytest.mark.parametrize('phase_exponent', np.linspace(0, 1, 5)) -def test_phase_calibrated_fsim_gate_compensated(phase_exponent: float): - a, b = cirq.LineQubit.range(2) - ideal_gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - characterized_gate = cirq.PhasedFSimGate( - theta=ideal_gate.theta, zeta=0.1, chi=0.2, gamma=0.3, phi=ideal_gate.phi - ) - parameters = PhasedFSimCharacterization( - theta=cast(float, ideal_gate.theta), - zeta=cast(float, characterized_gate.zeta), - chi=cast(float, characterized_gate.chi), - gamma=cast(float, characterized_gate.gamma), - phi=cast(float, ideal_gate.phi), - ) - - calibrated = PhaseCalibratedFSimGate(ideal_gate, phase_exponent=phase_exponent) - - # Passing characterized_gate as engine_gate simulates the hardware execution. - operations = calibrated.with_zeta_chi_gamma_compensated( - (a, b), parameters, engine_gate=characterized_gate - ) - - cirq.testing.assert_allclose_up_to_global_phase( - cirq.unitary(cirq.Circuit(operations)), - cirq.unitary( - cirq.Circuit( - [ - [cirq.Z(a) ** -phase_exponent, cirq.Z(b) ** phase_exponent], - ideal_gate.on(a, b), - [cirq.Z(a) ** phase_exponent, cirq.Z(b) ** -phase_exponent], - ] - ) - ), - atol=1e-8, - ) - - -def test_try_convert_sqrt_iswap_to_fsim_converts_correctly(): - expected = cirq.FSimGate(theta=np.pi / 4, phi=0) - expected_unitary = cirq.unitary(expected) - - fsim = cirq.FSimGate(theta=np.pi / 4, phi=0) - assert np.allclose(cirq.unitary(fsim), expected_unitary) - assert try_convert_sqrt_iswap_to_fsim(fsim) == PhaseCalibratedFSimGate(expected, 0.0) - assert try_convert_sqrt_iswap_to_fsim(cirq.FSimGate(theta=np.pi / 4, phi=0.1)) is None - assert try_convert_sqrt_iswap_to_fsim(cirq.FSimGate(theta=np.pi / 3, phi=0)) is None - - phased_fsim = cirq.PhasedFSimGate(theta=np.pi / 4, phi=0) - assert np.allclose(cirq.unitary(phased_fsim), expected_unitary) - assert try_convert_sqrt_iswap_to_fsim(phased_fsim) == PhaseCalibratedFSimGate(expected, 0.0) - assert ( - try_convert_sqrt_iswap_to_fsim(cirq.PhasedFSimGate(theta=np.pi / 4, zeta=0.1, phi=0)) - is None - ) - - iswap_pow = cirq.ISwapPowGate(exponent=-0.5) - assert np.allclose(cirq.unitary(iswap_pow), expected_unitary) - assert try_convert_sqrt_iswap_to_fsim(iswap_pow) == PhaseCalibratedFSimGate(expected, 0.0) - assert try_convert_sqrt_iswap_to_fsim(cirq.ISwapPowGate(exponent=-0.4)) is None - - phased_iswap_pow = cirq.PhasedISwapPowGate(exponent=0.5, phase_exponent=-0.5) - assert np.allclose(cirq.unitary(phased_iswap_pow), expected_unitary) - assert try_convert_sqrt_iswap_to_fsim(phased_iswap_pow) == PhaseCalibratedFSimGate( - expected, 0.0 - ) - assert ( - try_convert_sqrt_iswap_to_fsim(cirq.PhasedISwapPowGate(exponent=-0.6, phase_exponent=0.1)) - is None - ) - - assert try_convert_sqrt_iswap_to_fsim(cirq.CZ) is None - - assert ( - try_convert_sqrt_iswap_to_fsim( - cirq.FSimGate(theta=sympy.Symbol('t'), phi=sympy.Symbol('p')) - ) - is None - ) - - -def test_result_override(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - result = PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=0.4, phi=0.5 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.6, zeta=0.7, chi=None, gamma=0.9, phi=1.0 - ), - }, - gate=gate, - options=options, - ) - - overridden = result.override(options.zeta_chi_gamma_correction_override()) - - assert overridden == PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.0, chi=None, gamma=0.0, phi=0.5 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.6, zeta=0.0, chi=None, gamma=0.0, phi=1.0 - ), - }, - gate=gate, - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - - -@mock.patch('cirq_google.engine.engine_client.EngineClient') -def test_result_engine_job(_client): - result = PhasedFSimCalibrationResult( - parameters={}, - gate=cirq.FSimGate(theta=np.pi / 4, phi=0.0), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) - - assert result.engine_job.project_id == 'project_id' - assert result.engine_job.program_id == 'program_id' - assert result.engine_job.job_id == 'job_id' - - -def test_result_engine_job_none(): - result = PhasedFSimCalibrationResult( - parameters={}, - gate=cirq.FSimGate(theta=np.pi / 4, phi=0.0), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - - assert result.engine_job is None - - -@mock.patch('cirq_google.engine.engine_client.EngineClient') -def test_result_engine_calibration(_client): - result = PhasedFSimCalibrationResult( - parameters={}, - gate=cirq.FSimGate(theta=np.pi / 4, phi=0.0), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) - - test_calibration = cirq_google.Calibration() - result.engine_job.get_calibration = lambda: test_calibration - - assert result.engine_calibration == test_calibration - - -def test_result_engine_calibration_none(): - result = PhasedFSimCalibrationResult( - parameters={}, - gate=cirq.FSimGate(theta=np.pi / 4, phi=0.0), - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - - assert result.engine_calibration is None - - -def test_options_phase_corrected_override(): - assert ( - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION.zeta_chi_gamma_correction_override() - == PhasedFSimCharacterization(zeta=0.0, chi=0.0, gamma=0.0) - ) - - assert ( - FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=False, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=False, - ).zeta_chi_gamma_correction_override() - == PhasedFSimCharacterization() - ) - - -def test_try_convert_gate_to_fsim(): - def check(gate: cirq.Gate, expected: PhaseCalibratedFSimGate): - assert np.allclose(cirq.unitary(gate), cirq.unitary(expected)) - assert try_convert_gate_to_fsim(gate) == expected - - check( - cirq.FSimGate(theta=0.3, phi=0.5), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.3, phi=0.5), 0.0), - ) - - check( - cirq.FSimGate(7 * np.pi / 4, 0.0), - PhaseCalibratedFSimGate(cirq.FSimGate(np.pi / 4, 0.0), 0.5), - ) - - check( - cirq.ISwapPowGate(exponent=-0.5), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.25 * np.pi, phi=0.0), 0.0), - ) - - check( - cirq.ops.ISwapPowGate(exponent=0.8, global_shift=2.5), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.4 * np.pi, phi=0.0), 0.5), - ) - - gate = cirq.ops.ISwapPowGate(exponent=0.3, global_shift=0.4) - assert try_convert_gate_to_fsim(gate) is None - - check( - cirq.PhasedFSimGate(theta=0.2, phi=0.5, chi=1.5 * np.pi), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.2, phi=0.5), 0.25), - ) - - gate = cirq.PhasedFSimGate(theta=0.2, phi=0.5, zeta=1.5 * np.pi) - assert try_convert_gate_to_fsim(gate) is None - - check( - cirq.PhasedISwapPowGate(exponent=-0.5, phase_exponent=0.75), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.25 * np.pi, phi=0.0), 0.25), - ) - - check(cirq.CZ, PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.0, phi=np.pi), 0.0)) - - check( - cirq.ops.CZPowGate(exponent=0.3), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.0, phi=-0.3 * np.pi), 0.0), - ) - - check( - cirq.ops.CZPowGate(exponent=0.8, global_shift=2.5), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=0.0, phi=-0.8 * np.pi), 0.0), - ) - - gate = cirq.ops.CZPowGate(exponent=0.3, global_shift=0.4) - assert try_convert_gate_to_fsim(gate) is None - - check( - cirq_google.ops.SYC, - PhaseCalibratedFSimGate(cirq.FSimGate(phi=np.pi / 6, theta=np.pi / 2), 0.0), - ) - - assert try_convert_gate_to_fsim(cirq.CX) is None - - # Parameterized gates are not supported. - x = sympy.Symbol('x') - assert try_convert_gate_to_fsim(cirq.ops.ISwapPowGate(exponent=x)) is None - assert try_convert_gate_to_fsim(cirq.PhasedFSimGate(theta=x)) is None - assert try_convert_gate_to_fsim(cirq.FSimGate(theta=x, phi=x)) is None - assert try_convert_gate_to_fsim(cirq.PhasedISwapPowGate(exponent=x)) is None - assert try_convert_gate_to_fsim(cirq.CZPowGate(exponent=x)) is None - - -def test_try_convert_syc_or_sqrt_iswap_to_fsim(): - def check_converts(gate: cirq.Gate): - result = try_convert_syc_or_sqrt_iswap_to_fsim(gate) - assert np.allclose(cirq.unitary(gate), cirq.unitary(result)) - - def check_none(gate: cirq.Gate): - assert try_convert_syc_or_sqrt_iswap_to_fsim(gate) is None - - check_converts(cirq_google.ops.SYC) - check_converts(cirq.FSimGate(np.pi / 2, np.pi / 6)) - check_none(cirq.FSimGate(0, np.pi)) - check_converts(cirq.FSimGate(np.pi / 4, 0.0)) - check_none(cirq.FSimGate(0.2, 0.3)) - check_converts(cirq.ISwapPowGate(exponent=0.5)) - check_converts(cirq.ISwapPowGate(exponent=-0.5)) - check_none(cirq.ISwapPowGate(exponent=0.3)) - check_converts(cirq.PhasedFSimGate(theta=np.pi / 4, phi=0.0, chi=0.7)) - check_none(cirq.PhasedFSimGate(theta=0.3, phi=0.4)) - check_converts(cirq.PhasedISwapPowGate(exponent=0.5, phase_exponent=0.75)) - check_none(cirq.PhasedISwapPowGate(exponent=0.4, phase_exponent=0.75)) - check_none(cirq.ops.CZPowGate(exponent=1.0)) - check_none(cirq.CX) - - -# Test that try_convert_gate_to_fsim is extension of try_convert_sqrt_iswap_to_fsim. -# In other words, that both function return the same result for all gates on which -# try_convert_sqrt_iswap_to_fsim is defined. -def test_gate_translators_are_consistent(): - def check(gate): - result1 = try_convert_gate_to_fsim(gate) - result2 = try_convert_sqrt_iswap_to_fsim(gate) - assert result1 == result2 - assert result1 is not None - - check(cirq.FSimGate(theta=np.pi / 4, phi=0)) - check(cirq.FSimGate(theta=-np.pi / 4, phi=0)) - check(cirq.FSimGate(theta=7 * np.pi / 4, phi=0)) - check(cirq.PhasedFSimGate(theta=np.pi / 4, phi=0)) - check(cirq.ISwapPowGate(exponent=0.5)) - check(cirq.ISwapPowGate(exponent=-0.5)) - check(cirq.PhasedISwapPowGate(exponent=0.5, phase_exponent=-0.5)) diff --git a/cirq-google/cirq_google/calibration/test_data/xeb_calibration_layer.textproto b/cirq-google/cirq_google/calibration/test_data/xeb_calibration_layer.textproto deleted file mode 100644 index fa766ef05fd..00000000000 --- a/cirq-google/cirq_google/calibration/test_data/xeb_calibration_layer.textproto +++ /dev/null @@ -1,136 +0,0 @@ -calibration_type: "xeb_phased_fsim_characterization" -layer { - language { - gate_set: "v2_5" - arg_function_language: "exp" - } - circuit { - scheduling_strategy: MOMENT_BY_MOMENT - moments { - operations { - fsimgate { - theta { - float_value: 0.75 - } - phi { - float_value: 0 - } - } - qubit_constant_index: 0 - qubit_constant_index: 1 - } - operations { - fsimgate { - theta { - float_value: 0.75 - } - phi { - float_value: 0 - } - } - qubit_constant_index: 2 - qubit_constant_index: 3 - } - } - } - constants { - qubit { - id: "0_0" - } - } - constants { - qubit { - id: "0_1" - } - } - constants { - qubit { - id: "0_2" - } - } - constants { - qubit { - id: "0_3" - } - } -} -args { - key: "xatol" - value { - arg_value { - float_value: 0.0078125 - } - } -} -args { - key: "n_library_circuits" - value { - arg_value { - float_value: 22 - } - } -} -args { - key: "n_combinations" - value { - arg_value { - float_value: 10 - } - } -} -args { - key: "fatol" - value { - arg_value { - float_value: 0.0078125 - } - } -} -args { - key: "cycle_depths" - value { - arg_value { - string_value: "5_25_50_100_200_300" - } - } -} -args { - key: "characterize_zeta" - value { - arg_value { - float_value: 1 - } - } -} -args { - key: "characterize_theta" - value { - arg_value { - float_value: 1 - } - } -} -args { - key: "characterize_phi" - value { - arg_value { - float_value: 1 - } - } -} -args { - key: "characterize_gamma" - value { - arg_value { - float_value: 0 - } - } -} -args { - key: "characterize_chi" - value { - arg_value { - float_value: 0 - } - } -} diff --git a/cirq-google/cirq_google/calibration/test_data/xeb_results.textproto b/cirq-google/cirq_google/calibration/test_data/xeb_results.textproto deleted file mode 100644 index bb6364f1937..00000000000 --- a/cirq-google/cirq_google/calibration/test_data/xeb_results.textproto +++ /dev/null @@ -1,113 +0,0 @@ -timestamp_ms: 1616621454164 -metrics { - name: "initial_fidelities_depth_5" - targets: "layer_0" - targets: "pair_0" - targets: "0_0" - targets: "0_1" - values { - double_val: 0.99 - } -} -metrics { - name: "initial_fidelities_depth_25" - targets: "layer_0" - targets: "pair_0" - targets: "0_0" - targets: "0_1" - values { - double_val: 0.88 - } -} -metrics { - name: "initial_fidelities_depth_5" - targets: "layer_0" - targets: "pair_1" - targets: "0_2" - targets: "0_3" - values { - double_val: 0.99 - } -} -metrics { - name: "initial_fidelities_depth_25" - targets: "layer_0" - targets: "pair_1" - targets: "0_2" - targets: "0_3" - values { - double_val: 0.88 - } -} -metrics { - name: "final_fidelities_depth_5" - targets: "layer_0" - targets: "pair_0" - targets: "0_0" - targets: "0_1" - values { - double_val: 0.99 - } -} -metrics { - name: "final_fidelities_depth_25" - targets: "layer_0" - targets: "pair_0" - targets: "0_0" - targets: "0_1" - values { - double_val: 0.98 - } -} -metrics { - name: "final_fidelities_depth_5" - targets: "layer_0" - targets: "pair_1" - targets: "0_2" - targets: "0_3" - values { - double_val: 0.99 - } -} -metrics { - name: "final_fidelities_depth_25" - targets: "layer_0" - targets: "pair_1" - targets: "0_2" - targets: "0_3" - values { - double_val: 0.98 - } -} -metrics { - name: "characterized_angles_theta" - targets: "0_0" - targets: "0_1" - values { - double_val: -0.7853981 - } -} -metrics { - name: "characterized_angles_phi" - targets: "0_0" - targets: "0_1" - values { - double_val: 0.0 - } -} -metrics { - name: "characterized_angles_theta" - targets: "0_2" - targets: "0_3" - values { - double_val: -0.7853981 - } -} -metrics { - name: "characterized_angles_phi" - targets: "0_2" - targets: "0_3" - values { - double_val: 0.0 - } -} \ No newline at end of file diff --git a/cirq-google/cirq_google/calibration/workflow.py b/cirq-google/cirq_google/calibration/workflow.py deleted file mode 100644 index 289dcbca37b..00000000000 --- a/cirq-google/cirq_google/calibration/workflow.py +++ /dev/null @@ -1,1217 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import dataclasses -import itertools -from typing import Callable, Dict, Iterable, List, Optional, Sequence, Set, Tuple, Union, cast - -import cirq -from cirq.experiments import HALF_GRID_STAGGERED_PATTERN -from cirq_google.calibration.phased_fsim import ( - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - PhaseCalibratedFSimGate, - IncompatibleMomentError, - PhasedFSimCalibrationRequest, - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - merge_matching_results, - try_convert_gate_to_fsim, - try_convert_syc_or_sqrt_iswap_to_fsim, - PhasedFSimCalibrationOptions, - RequestT, - LocalXEBPhasedFSimCalibrationRequest, -) -from cirq_google.calibration.xeb_wrapper import run_local_xeb_calibration -from cirq_google.engine import AbstractEngine - -_CALIBRATION_IRRELEVANT_GATES = cirq.MeasurementGate, cirq.WaitGate - - -@dataclasses.dataclass(frozen=True) -class CircuitWithCalibration: - """Circuit with characterization data annotations. - - Attributes: - circuit: Circuit instance. - moment_to_calibration: Maps each moment within a circuit to an index of a characterization - request or response. None means that there is no characterization data for that moment. - """ - - circuit: cirq.Circuit - moment_to_calibration: Sequence[Optional[int]] - - -def prepare_characterization_for_moment( - moment: cirq.Moment, - options: PhasedFSimCalibrationOptions[RequestT], - *, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - canonicalize_pairs: bool = False, - sort_pairs: bool = False, - permit_mixed_moments: bool = False, -) -> Optional[RequestT]: - """Describes a given moment in terms of a characterization request. - - Args: - moment: Moment to characterize. - options: Options that are applied to each characterized gate within a moment. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - canonicalize_pairs: Whether to sort each of the qubit pair so that the first qubit - is always lower than the second. - sort_pairs: Whether to sort all the qutibt pairs extracted from the moment which will - undergo characterization. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - Instance of a calibration request that characterizes a given moment, or None - when it is an empty, measurement or single-qubit gates only moment. - - Raises: - IncompatibleMomentError when a moment contains operations other than the operations matched - by gates_translator, or it mixes a single qubit and two qubit gates. - """ - pairs_and_gate = _list_moment_pairs_to_characterize( - moment, - gates_translator, - canonicalize_pairs=canonicalize_pairs, - permit_mixed_moments=permit_mixed_moments, - sort_pairs=sort_pairs, - ) - if pairs_and_gate is None: - return None - - pairs, gate = pairs_and_gate - return options.create_phased_fsim_request(pairs=pairs, gate=gate) - - -def prepare_floquet_characterization_for_moment( - moment: cirq.Moment, - options: FloquetPhasedFSimCalibrationOptions, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - canonicalize_pairs: bool = False, - sort_pairs: bool = False, - permit_mixed_moments: bool = False, -) -> Optional[FloquetPhasedFSimCalibrationRequest]: - """Describes a given moment in terms of a Floquet characterization request. - - Args: - moment: Moment to characterize. - options: Options that are applied to each characterized gate within a moment. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - canonicalize_pairs: Whether to sort each of the qubit pair so that the first qubit - is always lower than the second. - sort_pairs: Whether to sort all the qutibt pairs extracted from the moment which will - undergo characterization. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - Instance of FloquetPhasedFSimCalibrationRequest that characterizes a given moment, or None - when it is an empty, measurement or single-qubit gates only moment. - - Raises: - IncompatibleMomentError when a moment contains operations other than the operations matched - by gates_translator, or it mixes a single qubit and two qubit gates. - """ - return prepare_characterization_for_moment( - moment=moment, - options=options, - gates_translator=gates_translator, - canonicalize_pairs=canonicalize_pairs, - sort_pairs=sort_pairs, - permit_mixed_moments=permit_mixed_moments, - ) - - -def _list_moment_pairs_to_characterize( - moment: cirq.Moment, - gates_translator: Callable[[cirq.Gate], Optional[PhaseCalibratedFSimGate]], - canonicalize_pairs: bool, - permit_mixed_moments: bool, - sort_pairs: bool, -) -> Optional[Tuple[Tuple[Tuple[cirq.Qid, cirq.Qid], ...], cirq.Gate]]: - """Helper function to describe a given moment in terms of a characterization request. - - Args: - moment: Moment to characterize. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. - canonicalize_pairs: Whether to sort each of the qubit pair so that the first qubit - is always lower than the second. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - sort_pairs: Whether to sort all the qubit pairs extracted from the moment which will undergo - characterization. - - Returns: - Tuple with list of pairs to characterize and gate that should be used for characterization, - or None when no gate to characterize exists in a given moment. - - Raises: - IncompatibleMomentError: When a moment contains operations other than the operations matched - by gates_translator, or it mixes a single qubit and two qubit gates. - """ - other_operation = False - gate: Optional[cirq.FSimGate] = None - pairs = [] - - for op in moment: - if not isinstance(op, cirq.GateOperation): - raise IncompatibleMomentError('Moment contains operation different than GateOperation') - - if isinstance(op.gate, cirq.GlobalPhaseGate): - raise IncompatibleMomentError('Moment contains global phase gate') - - if isinstance(op.gate, _CALIBRATION_IRRELEVANT_GATES) or cirq.num_qubits(op.gate) == 1: - other_operation = True - else: - translated = gates_translator(op.gate) - if translated is None: - raise IncompatibleMomentError( - f'Moment {moment} contains unsupported non-single qubit operation {op}' - ) - - if gate is not None and gate != translated.engine_gate: - raise IncompatibleMomentError( - f'Moment {moment} contains operations resolved to two different gates {gate} ' - f'and {translated.engine_gate}' - ) - else: - gate = translated.engine_gate - - pair = cast( - Tuple[cirq.Qid, cirq.Qid], - tuple(sorted(op.qubits) if canonicalize_pairs else op.qubits), - ) - pairs.append(pair) - - if gate is None: - # Either empty, single-qubit or measurement moment. - return None - elif not permit_mixed_moments and other_operation: - raise IncompatibleMomentError( - 'Moment contains mixed two-qubit operations and either single-qubit measurement or ' - 'wait operations. See permit_mixed_moments option to relax this restriction.' - ) - - if sort_pairs: - pairs_tuple = tuple(sorted(pairs)) - else: - pairs_tuple = tuple(pairs) - - return pairs_tuple, gate - - -def _match_circuit_moments_with_characterizations( - circuit: cirq.Circuit, - characterizations: List[PhasedFSimCalibrationResult], - gates_translator: Callable[[cirq.Gate], Optional[PhaseCalibratedFSimGate]], - merge_subsets: bool, - permit_mixed_moments: bool, -): - characterized_gate_and_pairs = [ - (characterization.gate, set(characterization.parameters.keys())) - for characterization in characterizations - ] - - moment_to_calibration: List[Optional[int]] = [] - for moment in circuit: - pairs_and_gate = _list_moment_pairs_to_characterize( - moment, - gates_translator, - canonicalize_pairs=True, - permit_mixed_moments=permit_mixed_moments, - sort_pairs=True, - ) - if pairs_and_gate is None: - moment_to_calibration.append(None) - continue - - moment_pairs, moment_gate = pairs_and_gate - for index, (gate, pairs) in enumerate(characterized_gate_and_pairs): - if gate == moment_gate and ( - pairs.issuperset(moment_pairs) if merge_subsets else pairs == set(moment_pairs) - ): - moment_to_calibration.append(index) - break - else: - raise ValueError( - f'Moment {repr(moment)} of a given circuit is not compatible with any of the ' - f'characterizations' - ) - - return CircuitWithCalibration(circuit, moment_to_calibration) - - -def prepare_characterization_for_moments( - circuit: cirq.Circuit, - options: PhasedFSimCalibrationOptions[RequestT], - *, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - merge_subsets: bool = True, - initial: Optional[Sequence[RequestT]] = None, - permit_mixed_moments: bool = False, -) -> Tuple[CircuitWithCalibration, List[RequestT]]: - """Extracts a minimal set of characterization requests necessary to characterize given circuit. - - This prepare method works on moments of the circuit and assumes that all the - two-qubit gates to calibrate are not mixed with other gates in a moment. The method groups - together moments of similar structure to minimize the number of characterizations requested. - - The circuit can only be composed of single qubit operations, wait operations, measurement - operations and operations supported by gates_translator. - - See also prepare_characterization_for_circuits_moments that operates on a list of circuits. - - Args: - circuit: Circuit to characterize. - options: Options that are applied to each characterized gate within a moment. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: If `True` then this method tries to merge moments into the other moments - listed previously if they can be characterized together (they have no conflicting - operations). Otherwise, only moments of exactly the same structure are characterized - together. - initial: The characterization requests obtained by a previous scan of another circuit; i.e., - the requests field of the return value of prepare_characterization_for_moments invoked - on another circuit. This might be used to find a minimal set of moments to characterize - across many circuits. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - circuit_with_calibration: - The circuit and its mapping from moments to indices into the list of calibration - requests (the second returned value). - calibrations: - A list of calibration requests for each characterized moment. - - Raises: - IncompatibleMomentError when circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - """ - if initial is None: - initial = [] - - allocations: List[Optional[int]] = [] - calibrations = list(initial) - pairs_map = {calibration.pairs: index for index, calibration in enumerate(calibrations)} - - for moment in circuit: - calibration = prepare_characterization_for_moment( - moment, - options, - gates_translator=gates_translator, - canonicalize_pairs=True, - sort_pairs=True, - permit_mixed_moments=permit_mixed_moments, - ) - - if calibration is not None: - if merge_subsets: - index = _merge_into_calibrations(calibration, calibrations, pairs_map, options) - else: - index = _append_into_calibrations_if_missing(calibration, calibrations, pairs_map) - allocations.append(index) - else: - allocations.append(None) - - return CircuitWithCalibration(circuit, allocations), calibrations - - -def prepare_characterization_for_circuits_moments( - circuits: List[cirq.Circuit], - options: PhasedFSimCalibrationOptions[RequestT], - *, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - merge_subsets: bool = True, - initial: Optional[Sequence[RequestT]] = None, - permit_mixed_moments: bool = False, -) -> Tuple[List[CircuitWithCalibration], List[RequestT]]: - """Extracts a minimal set of characterization requests necessary to characterize given circuits. - - This prepare method works on moments of the circuit and assumes that all the - two-qubit gates to calibrate are not mixed with other gates in a moment. The method groups - together moments of similar structure to minimize the number of characterizations requested. - - The circuit can only be composed of single qubit operations, wait operations, measurement - operations and operations supported by gates_translator. - - See also prepare_characterization_for_moments that operates on a single circuit. - - Args: - circuits: Circuits list to characterize. - options: Options that are applied to each characterized gate within a moment. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: If `True` then this method tries to merge moments into the other moments - listed previously if they can be characterized together (they have no conflicting - operations). Otherwise, only moments of exactly the same structure are characterized - together. - initial: The characterization requests obtained by a previous scan of another circuit; i.e., - the requests field of the return value of prepare_characterization_for_moments invoked - on another circuit. This might be used to find a minimal set of moments to characterize - across many circuits. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - circuits_with_calibration: - The circuit and its mapping from moments to indices into the list of calibration - requests (the second returned value). When list of circuits was passed on input, this - will be a list of CircuitWithCalibration objects corresponding to each circuit on the - input list. - calibrations: - A list of calibration requests for each characterized moment. - - Raises: - IncompatibleMomentError when circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - """ - requests = list(initial) if initial is not None else [] - circuits_with_calibration = [] - for circuit in circuits: - circuit_with_calibration, requests = prepare_characterization_for_moments( - circuit, - options, - gates_translator=gates_translator, - merge_subsets=merge_subsets, - initial=requests, - permit_mixed_moments=permit_mixed_moments, - ) - circuits_with_calibration.append(circuit_with_calibration) - return circuits_with_calibration, requests - - -def prepare_floquet_characterization_for_moments( - circuit: cirq.Circuit, - options: FloquetPhasedFSimCalibrationOptions = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - merge_subsets: bool = True, - initial: Optional[Sequence[FloquetPhasedFSimCalibrationRequest]] = None, - permit_mixed_moments: bool = False, -) -> Tuple[CircuitWithCalibration, List[FloquetPhasedFSimCalibrationRequest]]: - """Extracts a minimal set of Floquet characterization requests necessary to characterize given - circuit. - - This variant of prepare method works on moments of the circuit and assumes that all the - two-qubit gates to calibrate are not mixed with other gates in a moment. The method groups - together moments of similar structure to minimize the number of characterizations requested. - - If merge_subsets parameter is True then the method tries to merge moments into the other moments - listed previously if they can be characterized together (they have no conflicting operations). - If merge_subsets is False then only moments of exactly the same structure are characterized - together. - - The circuit can only be composed of single qubit operations, wait operations, measurement - operations and operations supported by gates_translator. - - Args: - circuit: Circuit to characterize. - options: Options that are applied to each characterized gate within a moment. Defaults - to all_except_for_chi_options which is the broadest currently supported choice. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: Whether to merge moments that can be characterized at the same time - together. - initial: The characterization requests obtained by a previous scan of another circuit; i.e., - the requests field of the return value of make_floquet_request_for_circuit invoked on - another circuit. This might be used to find a minimal set of moments to characterize - across many circuits. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - Tuple of: - - Circuit and its mapping from moments to indices into the list of calibration requests - (the second returned value). - - List of PhasedFSimCalibrationRequest for each characterized moment. - - Raises: - IncompatibleMomentError when circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - """ - return cast( - Tuple[CircuitWithCalibration, List[FloquetPhasedFSimCalibrationRequest]], - prepare_characterization_for_moments( - circuit, - options, - gates_translator=gates_translator, - merge_subsets=merge_subsets, - initial=initial, - permit_mixed_moments=permit_mixed_moments, - ), - ) - - -def prepare_characterization_for_operations( - circuit: Union[cirq.Circuit, Iterable[cirq.Circuit]], - options: PhasedFSimCalibrationOptions[RequestT], - *, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - permit_mixed_moments: bool = False, -) -> List[RequestT]: - """Extracts a minimal set of characterization requests necessary to characterize all the - operations within a circuit(s). - - This prepare method works on two-qubit operations of the circuit. The method extracts - all the operations and groups them in a way to minimize the number of characterizations - requested, depending on the connectivity. - - Contrary to prepare_characterization_for_moments, this method ignores moments structure - and is less accurate because certain errors caused by cross-talk are ignored. - - The major advantage of this method is that the number of generated characterization requests is - bounded by four for grid-like devices, where for - prepare_characterization_for_moments the number of characterizations is bounded by - number of moments in a circuit. - - The circuit can only be composed of single qubit operations, wait operations, measurement - operations and operations supported by gates_translator. - - Args: - circuit: Circuit or circuits to characterize. Only circuits with qubits of type GridQubit - that can be covered by HALF_GRID_STAGGERED_PATTERN are supported - options: Options that are applied to each characterized gate within a moment. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - List of PhasedFSimCalibrationRequest for each group of operations to characterize. - - Raises: - IncompatibleMomentError: When circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - ValueError: If unable to cover all interactions with a half grid staggered pattern. - """ - - circuits = [circuit] if isinstance(circuit, cirq.Circuit) else circuit - pairs, gate = _extract_all_pairs_to_characterize( - circuits, gates_translator, permit_mixed_moments - ) - - if gate is None: - return [] - - characterizations = [] - for pattern in HALF_GRID_STAGGERED_PATTERN: - pattern_pairs = [pair for pair in pairs if pair in pattern] - if pattern_pairs: - characterizations.append( - options.create_phased_fsim_request(pairs=tuple(sorted(pattern_pairs)), gate=gate) - ) - - if sum((len(characterization.pairs) for characterization in characterizations)) != len(pairs): - raise ValueError('Unable to cover all interactions with HALF_GRID_STAGGERED_PATTERN') - - return characterizations - - -def prepare_floquet_characterization_for_operations( - circuit: Union[cirq.Circuit, Iterable[cirq.Circuit]], - options: FloquetPhasedFSimCalibrationOptions = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - permit_mixed_moments: bool = False, -) -> List[FloquetPhasedFSimCalibrationRequest]: - """Extracts a minimal set of Floquet characterization requests necessary to characterize all the - operations within a circuit(s). - - This variant of prepare method works on two-qubit operations of the circuit. The method extracts - all the operations and groups them in a way to minimize the number of characterizations - requested, depending on the connectivity. - - Contrary to prepare_floquet_characterization_for_moments, this method ignores moments structure - and is less accurate because certain errors caused by cross-talks are ignored. - - The major advantage of this method is that the number of generated characterization requests is - bounded by four for grid-like devices, where for the - prepare_floquet_characterization_for_moments the number of characterizations is bounded by - number of moments in a circuit. - - The circuit can only be composed of single qubit operations, wait operations, measurement - operations and operations supported by gates_translator. - - Args: - circuit: Circuit or circuits to characterize. Only circuits with qubits of type GridQubit - that can be covered by HALF_GRID_STAGGERED_PATTERN are supported - options: Options that are applied to each characterized gate within a moment. Defaults - to all_except_for_chi_options which is the broadest currently supported choice. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - List of FloquetPhasedFSimCalibrationRequest for each group of operations to characterize. - - Raises: - IncompatibleMomentError when circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - """ - return prepare_characterization_for_operations( - circuit=circuit, - options=options, - gates_translator=gates_translator, - permit_mixed_moments=permit_mixed_moments, - ) - - -def _extract_all_pairs_to_characterize( - circuits: Iterable[cirq.Circuit], - gates_translator: Callable[[cirq.Gate], Optional[PhaseCalibratedFSimGate]], - permit_mixed_moments: bool, -) -> Tuple[Set[Tuple[cirq.Qid, cirq.Qid]], Optional[cirq.Gate]]: - """Extracts the set of all two-qubit operations from the circuits. - - Args: - circuits: Circuits to extract the operations from. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - Tuple with set of all two-qubit interacting pairs and a common gate that represents those - interactions. The gate can be used for characterization purposes. If no interactions are - present the gate is None. - - Raises: - ValueError: If multiple types of two qubit gates appear in the (possibly translated) - circuits. - """ - - all_pairs: Set[Tuple[cirq.Qid, cirq.Qid]] = set() - common_gate = None - for circuit in circuits: - for moment in circuit: - pairs_and_gate = _list_moment_pairs_to_characterize( - moment, - gates_translator, - canonicalize_pairs=True, - permit_mixed_moments=permit_mixed_moments, - sort_pairs=False, - ) - - if pairs_and_gate is not None: - pairs, gate = pairs_and_gate - - if common_gate is None: - common_gate = gate - elif common_gate != gate: - raise ValueError( - f'Only a single type of gate is supported, got {gate} and {common_gate}' - ) - - all_pairs.update(pairs) - - return all_pairs, common_gate - - -def _append_into_calibrations_if_missing( - calibration: RequestT, - calibrations: List[RequestT], - pairs_map: Dict[Tuple[Tuple[cirq.Qid, cirq.Qid], ...], int], -) -> int: - """Adds calibration to the calibrations list if not already present. - - This function uses equivalence of calibration.pairs as a presence check. - - Args: - calibration: Calibration to be added. - calibrations: List of calibrations to be mutated. The list is expanded only if a calibration - is not on the list already. - pairs_map: Map from pairs parameter of each calibration on the calibrations list to the - index on that list. This map will be updated if the calibrations list us expanded. - - Returns: - Index of the calibration on the updated calibrations list. If the calibration was added, it - points to the last element of a list. If not, it points to already existing element. - """ - if calibration.pairs not in pairs_map: - index = len(calibrations) - calibrations.append(calibration) - pairs_map[calibration.pairs] = index - return index - else: - return pairs_map[calibration.pairs] - - -def _merge_into_calibrations( - calibration: RequestT, - calibrations: List[RequestT], - pairs_map: Dict[Tuple[Tuple[cirq.Qid, cirq.Qid], ...], int], - options: PhasedFSimCalibrationOptions[RequestT], -) -> int: - """Merges a calibration into list of calibrations. - - If calibrations contains an item of which pairs could be expanded to include a new calibration - pairs, without breaking a moment structure, then those two calibrations will be merged together - and used as a calibration for both old and newly added calibration. - If no calibration like that exists, the list will be expanded by the calibration item. - - Args: - calibration: Calibration to be added. - calibrations: List of calibrations to be mutated. - pairs_map: Map from pairs parameter of each calibration on the calibrations list to the - index on that list. This map will be updated if the calibrations list us updated. - options: Calibrations options to use when creating a new requests. - - Returns: - Index of the calibration on the updated calibrations list. If the calibration was added, it - points to the last element of a list. If not, it points to already existing element. - """ - new_pairs = set(calibration.pairs) - for index in pairs_map.values(): - can_merge = ( - calibration.gate == calibrations[index].gate - and calibration.options == calibrations[index].options - ) - if not can_merge: - continue - existing_pairs = calibrations[index].pairs - if new_pairs.issubset(existing_pairs): - return index - elif new_pairs.issuperset(existing_pairs): - calibrations[index] = calibration - return index - else: - new_qubit_pairs = calibration.qubit_to_pair - existing_qubit_pairs = calibrations[index].qubit_to_pair - if all( - ( - new_qubit_pairs[q] == existing_qubit_pairs[q] - for q in set(new_qubit_pairs.keys()).intersection(existing_qubit_pairs.keys()) - ) - ): - calibrations[index] = options.create_phased_fsim_request( - gate=calibration.gate, pairs=tuple(sorted(new_pairs.union(existing_pairs))) - ) - return index - - index = len(calibrations) - calibrations.append(calibration) - pairs_map[calibration.pairs] = index - return index - - -def _run_local_calibrations_via_sampler( - calibration_requests: Sequence[PhasedFSimCalibrationRequest], sampler: cirq.Sampler -): - """Helper function used by `run_calibrations` to run Local calibrations with a Sampler.""" - return [ - run_local_xeb_calibration( - cast(LocalXEBPhasedFSimCalibrationRequest, calibration_request), sampler - ) - for calibration_request in calibration_requests - ] - - -def run_calibrations( - calibrations: Sequence[PhasedFSimCalibrationRequest], - sampler: Union[AbstractEngine, cirq.Sampler], - processor_id: Optional[str] = None, - max_layers_per_request: int = 1, - progress_func: Optional[Callable[[int, int], None]] = None, -) -> List[PhasedFSimCalibrationResult]: - """Runs calibration requests on the Engine. - - Args: - calibrations: List of calibrations to perform described in a request object. - sampler: cirq_google.Engine or cirq.Sampler object used for running the calibrations. When - sampler is cirq_google.Engine or cirq_google.ProcessorSampler object then the - calibrations are issued against a Google's quantum device. The only other sampler - supported for simulation purposes is cirq_google.PhasedFSimEngineSimulator. - processor_id: Used when sampler is cirq_google.Engine object and passed to - cirq_google.Engine.run_calibrations method. - max_layers_per_request: Maximum number of calibration requests issued to cirq.Engine at a - single time. Defaults to 1. - progress_func: Optional callback function that might be used to report the calibration - progress. The callback is called with two integers, the first one being a number of - layers already calibrated and the second one the total number of layers to calibrate. - - Returns: - List of PhasedFSimCalibrationResult for each requested calibration. - - Raises: - ValueError: If less than one layers was requested to be calibrated, if calibrations of - different types was supplied, if no `processor_id` or `gate_set` is provided, or - if the calibration / sampler combo is not supported. - """ - raise NotImplementedError - - -def make_zeta_chi_gamma_compensation_for_moments( - circuit: Union[cirq.Circuit, CircuitWithCalibration], - characterizations: List[PhasedFSimCalibrationResult], - *, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_gate_to_fsim, - merge_subsets: bool = True, - permit_mixed_moments: bool = False, -) -> CircuitWithCalibration: - """Compensates circuit moments against errors in zeta, chi and gamma angles. - - This method creates a new circuit with a single-qubit Z gates added in a such way so that - zeta, chi and gamma angles discovered by characterizations are cancelled-out and set to 0. - - This function preserves a moment structure of the circuit. All single qubit gates appear on new - moments in the final circuit. - - Args: - circuit: Circuit to compensate or instance of CircuitWithCalibration (likely returned from - prepare_characterization_for_moments) whose mapping argument corresponds to the results - in the characterizations argument. If circuit is passed then the method will attempt to - match the circuit against a given characterizations. This step is can be skipped by - passing the pre-calculated instance of CircuitWithCalibration. - characterizations: List of characterization results (likely returned from run_calibrations). - This should correspond to the circuit and mapping in the circuit_with_calibration - argument. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: Whether to allow for matching moments which are subsets of the characterized - moments. This option is only used when instance of Circuit is passed as circuit. - permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant - single-qubit gates. - - Returns: - Calibrated circuit together with its calibration metadata in CircuitWithCalibration object. - The calibrated circuit has single-qubit Z gates added which compensates for the true gates - imperfections. - The moment to calibration mapping is updated for the new circuit so that successive - calibrations could be applied. - """ - - if isinstance(circuit, cirq.Circuit): - circuit_with_calibration = _match_circuit_moments_with_characterizations( - circuit, - characterizations, - gates_translator, - merge_subsets, - permit_mixed_moments=permit_mixed_moments, - ) - else: - circuit_with_calibration = circuit - - return _make_zeta_chi_gamma_compensation( - circuit_with_calibration, - characterizations, - gates_translator, - permit_mixed_moments=permit_mixed_moments, - ) - - -def make_zeta_chi_gamma_compensation_for_operations( - circuit: cirq.Circuit, - characterizations: List[PhasedFSimCalibrationResult], - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_gate_to_fsim, - permit_mixed_moments: bool = False, -) -> cirq.Circuit: - """Compensates circuit operations against errors in zeta, chi and gamma angles. - - This method creates a new circuit with a single-qubit Z gates added in a such way so that - zeta, chi and gamma angles discovered by characterizations are cancelled-out and set to 0. - - Contrary to make_zeta_chi_gamma_compensation_for_moments this method does not match - characterizations to the moment structure of the circuits and thus is less accurate because - some errors caused by cross-talks are not mitigated. - - The major advantage of this method over make_zeta_chi_gamma_compensation_for_moments is that it - can work with arbitrary set of characterizations that cover all the interactions of the circuit - (up to assumptions of merge_matching_results method). In particular, for grid-like devices the - number of characterizations is bounded by four, where in the case of - make_zeta_chi_gamma_compensation_for_moments the number of characterizations is bounded by - number of moments in a circuit. - - This function preserves a moment structure of the circuit. All single qubit gates appear on new - moments in the final circuit. - - Args: - circuit: Circuit to calibrate. - characterizations: List of characterization results (likely returned from run_calibrations). - All the characterizations must be compatible in sense of merge_matching_results, they - will be merged together. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - permit_mixed_moments: Whether to allow mixing single-qubit and two-qubit gates in a single - moment. - - Returns: - Calibrated circuit with a single-qubit Z gates added which compensates for the true gates - imperfections. - """ - - characterization = merge_matching_results(characterizations) - moment_to_calibration = [0] * len(circuit) - calibrated = _make_zeta_chi_gamma_compensation( - CircuitWithCalibration(circuit, moment_to_calibration), - [characterization] if characterization is not None else [], - gates_translator, - permit_mixed_moments=permit_mixed_moments, - ) - return calibrated.circuit - - -def _make_zeta_chi_gamma_compensation( - circuit_with_calibration: CircuitWithCalibration, - characterizations: List[PhasedFSimCalibrationResult], - gates_translator: Callable[[cirq.Gate], Optional[PhaseCalibratedFSimGate]], - permit_mixed_moments: bool, -) -> CircuitWithCalibration: - if len(circuit_with_calibration.circuit) != len(circuit_with_calibration.moment_to_calibration): - raise ValueError('Moment allocations does not match circuit length') - - compensated = cirq.Circuit() - compensated_moment_to_calibration: List[Optional[int]] = [] - for moment, characterization_index in zip( - circuit_with_calibration.circuit, circuit_with_calibration.moment_to_calibration - ): - parameters = None - if characterization_index is not None: - parameters = characterizations[characterization_index] - - (decompositions, decompositions_moment_to_calibration, other) = ( - _find_moment_zeta_chi_gamma_corrections( - moment, characterization_index, parameters, gates_translator - ) - ) - - if decompositions: - assert decompositions_moment_to_calibration is not None # Required for mypy - if not other: - moment_to_calibration_index: Optional[int] = None - else: - if not permit_mixed_moments: - raise IncompatibleMomentError( - f'Moment {moment} contains mixed operations. See permit_mixed_moments ' - f'option to relax this restriction.' - ) - (moment_to_calibration_index,) = [ - index - for index, moment_to_calibration in enumerate( - decompositions_moment_to_calibration - ) - if moment_to_calibration is not None - ] - - for index, operations in enumerate( - itertools.zip_longest(*decompositions, fillvalue=()) - ): - compensated += cirq.Moment( - operations, other if index == moment_to_calibration_index else () - ) - compensated_moment_to_calibration += decompositions_moment_to_calibration - elif other: - compensated += cirq.Moment(other) - compensated_moment_to_calibration.append(characterization_index) - - return CircuitWithCalibration(compensated, compensated_moment_to_calibration) - - -def _find_moment_zeta_chi_gamma_corrections( - moment: cirq.Moment, - characterization_index: Optional[int], - parameters: Optional[PhasedFSimCalibrationResult], - gates_translator: Callable[[cirq.Gate], Optional[PhaseCalibratedFSimGate]], -) -> Tuple[ - List[Tuple[Tuple[cirq.Operation, ...], ...]], - Optional[List[Optional[int]]], - List[cirq.Operation], -]: - """Finds corrections for each operation within a moment to compensate for zeta, chi and gamma. - - Args: - moment: Moment to compensate. - characterization_index: The original characterization index of a moment. - parameters: Characterizations results for a given moment. None, when not available. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - - Returns: - Tuple of: - - decompositions: the decomposed operations for each corrected operation, each element of - this list is a list of moments of the decomposed gate. - - decompositions_moment_to_calibration: for each moment in the decomposition, assigns a - characterization index that matches the original decomposed gate. None when no gate - was decomposed. - - other: the remaining gates that were not decomposed. - - Raises: - IncompatibleMomentError: If a moment has operations different than `cirq.GateOperation`, - if it contains an unsupported greater than one qubit operation, if parameters are - missing, if the engine gate does not match the `parameters` gate, or if there is - missing characterization data for a pair of qubits. - ValueError: If parameter is not supplied, if the translated engine gate does not match - the one in parameters, or if pair parameters cannot be obtained. - """ - default_phases = PhasedFSimCharacterization(zeta=0.0, chi=0.0, gamma=0.0) - - decompositions: List[Tuple[Tuple[cirq.Operation, ...], ...]] = [] - other: List[cirq.Operation] = [] - decompositions_moment_to_calibration: Optional[List[Optional[int]]] = None - - for op in moment: - if not isinstance(op, cirq.GateOperation): - raise IncompatibleMomentError('Moment contains operation different than GateOperation') - - if isinstance(op.gate, cirq.GlobalPhaseGate): - raise IncompatibleMomentError('Moment contains global phase gate') - - if isinstance(op.gate, _CALIBRATION_IRRELEVANT_GATES) or cirq.num_qubits(op.gate) == 1: - other.append(op) - continue - - a, b = op.qubits - translated = gates_translator(op.gate) - if translated is None: - raise IncompatibleMomentError( - f'Moment {moment} contains unsupported non-single qubit operation {op}' - ) - - if parameters is None: - raise ValueError(f'Missing characterization data for moment {moment}') - - if translated.engine_gate != parameters.gate: - raise ValueError( - f"Engine gate {translated.engine_gate} doesn't match characterized gate " - f'{parameters.gate}' - ) - - pair_parameters = parameters.get_parameters(a, b) - if pair_parameters is None: - raise ValueError(f'Missing characterization data for pair {(a, b)} in {parameters}') - pair_parameters = pair_parameters.merge_with(default_phases) - - corrections = FSimPhaseCorrections.from_characterization( - (a, b), translated, pair_parameters, characterization_index - ) - - if decompositions_moment_to_calibration is None: - decompositions_moment_to_calibration = corrections.moment_to_calibration - else: - assert ( - decompositions_moment_to_calibration == corrections.moment_to_calibration - ), f'Inconsistent decompositions with a moment {moment}' - - decompositions.append(corrections.operations) - - return decompositions, decompositions_moment_to_calibration, other - - -@dataclasses.dataclass(frozen=True) -class FSimPhaseCorrections: - """Operations that compensate for zeta, chi and gamma angles of an approximate FSimGate gate. - - Attributes: - operations: Tuple of tuple of operations that describe the gate. The first index iterates - over moments of the composed operation. - moment_to_calibration: List of indices pointing to the calibration for each moment in the - composed operation. - """ - - operations: Tuple[Tuple[cirq.Operation, ...], ...] - moment_to_calibration: List[Optional[int]] - - @classmethod - def from_characterization( - cls, - qubits: Tuple[cirq.Qid, cirq.Qid], - gate_calibration: PhaseCalibratedFSimGate, - parameters: PhasedFSimCharacterization, - characterization_index: Optional[int], - ) -> 'FSimPhaseCorrections': - """Creates an operation that compensates for zeta, chi and gamma angles of the supplied - gate and characterization. - - Args: - Args: - qubits: Qubits that the gate should act on. - gate_calibration: Original, imperfect gate that is supposed to run on the hardware - together with phase information. - parameters: The real parameters of the supplied gate. - characterization_index: characterization index to use at each moment with gate. - """ - operations = gate_calibration.with_zeta_chi_gamma_compensated(qubits, parameters) - moment_to_calibration = [None, characterization_index, None] - - return cls(operations, moment_to_calibration) - - def as_circuit(self) -> cirq.Circuit: - return cirq.Circuit(self.operations) - - -def run_floquet_characterization_for_moments( - circuit: cirq.Circuit, - sampler: Union[AbstractEngine, cirq.Sampler], - processor_id: Optional[str] = None, - options: FloquetPhasedFSimCalibrationOptions = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - merge_subsets: bool = True, - max_layers_per_request: int = 1, - progress_func: Optional[Callable[[int, int], None]] = None, - permit_mixed_moments: bool = False, -) -> Tuple[CircuitWithCalibration, List[PhasedFSimCalibrationResult]]: - """Extracts moments within a circuit to characterize and characterizes them against engine. - - The method calls prepare_floquet_characterization_for_moments to extract moments to characterize - and run_calibrations to characterize them. - - Args: - circuit: Circuit to characterize. - sampler: cirq_google.Engine or cirq.Sampler object used for running the calibrations. When - sampler is cirq_google.Engine or cirq_google.ProcessorSampler object then the - calibrations are issued against a Google's quantum device. The only other sampler - supported for simulation purposes is cirq_google.PhasedFSimEngineSimulator. - processor_id: Used when sampler is cirq_google.Engine object and passed to - cirq_google.Engine.run_calibrations method. - options: Options that are applied to each characterized gate within a moment. Defaults - to all_except_for_chi_options which is the broadest currently supported choice. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: Whether to merge moments that can be characterized at the same time - together. - max_layers_per_request: Maximum number of calibration requests issued to cirq.Engine at a - single time. Defaults to 1. - progress_func: Optional callback function that might be used to report the calibration - progress. The callback is called with two integers, the first one being a number of - layers already calibrated and the second one the total number of layers to calibrate. - permit_mixed_moments: Whether to allow mixing single-qubit and two-qubit gates in a single - moment. - - Returns: - Tuple of: - - Circuit and its mapping from moments to indices into the list of characterized requests - (the second returned value). - - List of PhasedFSimCalibrationRequest for each characterized moment. - - Raises: - IncompatibleMomentError when circuit contains a moment with operations other than the - operations matched by gates_translator, or it mixes a single qubit and two qubit gates. - """ - circuit_calibration, requests = prepare_floquet_characterization_for_moments( - circuit, - options, - gates_translator, - merge_subsets=merge_subsets, - permit_mixed_moments=permit_mixed_moments, - ) - results = run_calibrations( - requests, - sampler, - processor_id, - max_layers_per_request=max_layers_per_request, - progress_func=progress_func, - ) - return circuit_calibration, results - - -def run_zeta_chi_gamma_compensation_for_moments( - circuit: cirq.Circuit, - sampler: Union[AbstractEngine, cirq.Sampler], - processor_id: Optional[str] = None, - options: FloquetPhasedFSimCalibrationOptions = ( - THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ), - gates_translator: Callable[ - [cirq.Gate], Optional[PhaseCalibratedFSimGate] - ] = try_convert_syc_or_sqrt_iswap_to_fsim, - merge_subsets: bool = True, - max_layers_per_request: int = 1, - progress_func: Optional[Callable[[int, int], None]] = None, - permit_mixed_moments: bool = False, -) -> Tuple[CircuitWithCalibration, List[PhasedFSimCalibrationResult]]: - """Compensates circuit for errors in zeta, chi and gamma angles by running on the engine. - - The method calls prepare_floquet_characterization_for_moments to extract moments to - characterize, run_calibrations to characterize them and - make_zeta_chi_gamma_compensation_for_moments to compensate the circuit with characterization - data. - - Args: - circuit: Circuit to characterize and calibrate. - sampler: cirq_google.Engine or cirq.Sampler object used for running the calibrations. When - sampler is cirq_google.Engine or cirq_google.ProcessorSampler object then the - calibrations are issued against a Google's quantum device. The only other sampler - supported for simulation purposes is cirq_google.PhasedFSimEngineSimulator. - processor_id: Used when sampler is cirq_google.Engine object and passed to - cirq_google.Engine.run_calibrations method. - options: Options that are applied to each characterized gate within a moment. Defaults - to all_except_for_chi_options which is the broadest currently supported choice. - gates_translator: Function that translates a gate to a supported FSimGate which will undergo - characterization. Defaults to sqrt_iswap_gates_translator. - merge_subsets: Whether to merge moments that can be characterized at the same time - together. - max_layers_per_request: Maximum number of calibration requests issued to cirq.Engine at a - single time. Defaults to 1. - progress_func: Optional callback function that might be used to report the calibration - progress. The callback is called with two integers, the first one being a number of - layers already calibrated and the second one the total number of layers to calibrate. - permit_mixed_moments: Whether to allow mixing single-qubit and two-qubit gates in a single - moment. - - Returns: - Tuple of: - - Calibrated circuit together with its calibration metadata in CircuitWithCalibration - object. The calibrated circuit has single-qubit Z gates added which compensates for the - true gates imperfections. - The moment to calibration mapping is updated for the new circuit so that successive - calibrations could be applied. - - List of characterizations results that were obtained in order to calibrate the circuit. - """ - circuit_with_calibration, requests = prepare_floquet_characterization_for_moments( - circuit, - options, - gates_translator, - merge_subsets=merge_subsets, - permit_mixed_moments=permit_mixed_moments, - ) - characterizations = run_calibrations( - calibrations=requests, - sampler=sampler, - processor_id=processor_id, - max_layers_per_request=max_layers_per_request, - progress_func=progress_func, - ) - calibrated_circuit = make_zeta_chi_gamma_compensation_for_moments( - circuit_with_calibration, - characterizations, - gates_translator=gates_translator, - permit_mixed_moments=permit_mixed_moments, - ) - return calibrated_circuit, characterizations diff --git a/cirq-google/cirq_google/calibration/workflow_test.py b/cirq-google/cirq_google/calibration/workflow_test.py deleted file mode 100644 index f94b749d1ed..00000000000 --- a/cirq-google/cirq_google/calibration/workflow_test.py +++ /dev/null @@ -1,1725 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import itertools -from typing import Optional -from unittest import mock - -import numpy as np -import pytest - -import cirq -import cirq_google -import cirq_google.calibration.workflow as workflow -import cirq_google.calibration.xeb_wrapper -from cirq.experiments import ( - random_rotations_between_grid_interaction_layers_circuit, - XEBPhasedFSimCharacterizationOptions, -) -from cirq_google.calibration.engine_simulator import PhasedFSimEngineSimulator -from cirq_google.calibration.phased_fsim import ( - ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - FloquetPhasedFSimCalibrationOptions, - FloquetPhasedFSimCalibrationRequest, - PhaseCalibratedFSimGate, - PhasedFSimCharacterization, - PhasedFSimCalibrationResult, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, - LocalXEBPhasedFSimCalibrationRequest, - LocalXEBPhasedFSimCalibrationOptions, - XEBPhasedFSimCalibrationRequest, - XEBPhasedFSimCalibrationOptions, -) - -SQRT_ISWAP_INV_PARAMETERS = cirq_google.PhasedFSimCharacterization( - theta=np.pi / 4, zeta=0.0, chi=0.0, gamma=0.0, phi=0.0 -) -SYCAMORE_PARAMETERS = cirq_google.PhasedFSimCharacterization( - theta=np.pi / 2, zeta=0.0, chi=0.0, gamma=0.0, phi=np.pi / 6 -) -SQRT_ISWAP_GATE = cirq.FSimGate(7 * np.pi / 4, 0.0) -SQRT_ISWAP_INV_GATE = cirq.FSimGate(np.pi / 4, 0.0) - - -def _fsim_identity_converter(gate: cirq.Gate) -> Optional[PhaseCalibratedFSimGate]: - if isinstance(gate, cirq.FSimGate): - return PhaseCalibratedFSimGate(gate, 0.0) - return None - - -def test_prepare_floquet_characterization_for_moment_none_for_measurements(): - a, b, c, d = cirq.LineQubit.range(4) - moment = cirq.Moment(cirq.measure(a, b, c, d)) - assert ( - workflow.prepare_floquet_characterization_for_moment( - moment, WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - is None - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_none_for_measurements(options): - a, b, c, d = cirq.LineQubit.range(4) - moment = cirq.Moment(cirq.measure(a, b, c, d)) - assert workflow.prepare_characterization_for_moment(moment, options) is None - - -def test_prepare_floquet_characterization_for_moment_fails_for_non_gate_operation(): - moment = cirq.Moment(cirq.CircuitOperation(cirq.FrozenCircuit())) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_floquet_characterization_for_moment( - moment, WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - - -def test_prepare_floquet_characterization_for_moment_fails_for_global_phase(): - moment = cirq.Moment(cirq.global_phase_operation(coefficient=1.0)) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_floquet_characterization_for_moment( - moment, WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_fails_for_non_gate_operation(options): - moment = cirq.Moment(cirq.CircuitOperation(cirq.FrozenCircuit())) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_characterization_for_moment(moment, options) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_fails_for_global_phase(options): - moment = cirq.Moment(cirq.global_phase_operation(coefficient=1.0)) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_characterization_for_moment(moment, options) - - -def test_prepare_floquet_characterization_for_moment_fails_for_unsupported_gate(): - a, b = cirq.LineQubit.range(2) - moment = cirq.Moment(cirq.CZ(a, b)) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_floquet_characterization_for_moment( - moment, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator=_fsim_identity_converter, - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_fails_for_unsupported_gate(options): - a, b = cirq.LineQubit.range(2) - moment = cirq.Moment(cirq.CZ(a, b)) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_characterization_for_moment( - moment, options, gates_translator=_fsim_identity_converter - ) - - -def test_prepare_floquet_characterization_for_moment_fails_for_mixed_gates(): - a, b, c, d = cirq.LineQubit.range(4) - moment = cirq.Moment( - [ - cirq.FSimGate(theta=np.pi / 4, phi=0.0).on(a, b), - cirq.FSimGate(theta=np.pi / 8, phi=0.0).on(c, d), - ] - ) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_floquet_characterization_for_moment( - moment, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator=_fsim_identity_converter, - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_fails_for_mixed_gates(options): - a, b, c, d = cirq.LineQubit.range(4) - moment = cirq.Moment( - [ - cirq.FSimGate(theta=np.pi / 4, phi=0.0).on(a, b), - cirq.FSimGate(theta=np.pi / 8, phi=0.0).on(c, d), - ] - ) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_characterization_for_moment( - moment, - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - gates_translator=_fsim_identity_converter, - ) - - -def test_prepare_floquet_characterization_for_moment_fails_for_mixed_moment(): - a, b, c = cirq.LineQubit.range(3) - moment = cirq.Moment([cirq.FSimGate(theta=np.pi / 4, phi=0.0).on(a, b), cirq.Z.on(c)]) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_floquet_characterization_for_moment( - moment, WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_moment_fails_for_mixed_moment(options): - a, b, c = cirq.LineQubit.range(3) - moment = cirq.Moment([cirq.FSimGate(theta=np.pi / 4, phi=0.0).on(a, b), cirq.Z.on(c)]) - with pytest.raises(workflow.IncompatibleMomentError): - workflow.prepare_characterization_for_moment( - moment, WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - - -def test_prepare_floquet_characterization_for_moments(): - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(b)], - ] - ) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - circuit_with_calibration, requests = workflow.prepare_floquet_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, None] - - -def test_prepare_characterization_for_circuits_moments(): - a, b, c, d = cirq.LineQubit.range(4) - circuit_1 = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(b)], - ] - ) - circuit_2 = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(b)], - ] - ) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - circuits_with_calibration, requests = workflow.prepare_characterization_for_circuits_moments( - [circuit_1, circuit_2], options=options - ) - - assert requests == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - - assert len(circuits_with_calibration) == 2 - assert circuits_with_calibration[0].circuit == circuit_1 - assert circuits_with_calibration[0].moment_to_calibration == [None, 0, None] - assert circuits_with_calibration[1].circuit == circuit_2 - assert circuits_with_calibration[1].moment_to_calibration == [None, 1, None] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments(options_cls): - options, cls = options_cls - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(b)], - ] - ) - - circuit_with_calibration, requests = workflow.prepare_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, None] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments_with_permit_mixed_moments(options_cls): - options, cls = options_cls - a, b, c, d = cirq.LineQubit.range(4) - circuit = cirq.Circuit( - [ - cirq.Moment([cirq.X(a), cirq.Y(c)]), - cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)]), - cirq.Moment([cirq.X(a), SQRT_ISWAP_INV_GATE.on(b, c)], cirq.Y(d)), - cirq.Moment([cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(b)]), - ] - ) - - circuit_with_calibration, requests = workflow.prepare_characterization_for_moments( - circuit, options=options, permit_mixed_moments=True - ) - - assert requests == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, None] - - -def test_prepare_floquet_characterization_for_moments_merges_sub_sets(): - a, b, c, d, e = cirq.LineQubit.range(5) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - circuit_with_calibration, requests = workflow.prepare_floquet_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 0, 1] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments_merges_sub_sets(options_cls): - options, cls = options_cls - a, b, c, d, e = cirq.LineQubit.range(5) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - - circuit_with_calibration, requests = workflow.prepare_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 0, 1] - - -def test_prepare_floquet_characterization_for_moments_merges_many_circuits(): - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - a, b, c, d, e = cirq.LineQubit.range(5) - - circuit_1 = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - - circuit_with_calibration_1, requests_1 = workflow.prepare_floquet_characterization_for_moments( - circuit_1, options=options - ) - - assert requests_1 == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - assert circuit_with_calibration_1.circuit == circuit_1 - assert circuit_with_calibration_1.moment_to_calibration == [None, 0, 1, 0] - - circuit_2 = cirq.Circuit([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - - circuit_with_calibration_2, requests_2 = workflow.prepare_floquet_characterization_for_moments( - circuit_2, options=options, initial=requests_1 - ) - - assert requests_2 == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - assert circuit_with_calibration_2.circuit == circuit_2 - assert circuit_with_calibration_2.moment_to_calibration == [1] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments_merges_many_circuits(options_cls): - options, cls = options_cls - a, b, c, d, e = cirq.LineQubit.range(5) - - circuit_1 = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - - circuit_with_calibration_1, requests_1 = workflow.prepare_characterization_for_moments( - circuit_1, options=options - ) - - assert requests_1 == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - assert circuit_with_calibration_1.circuit == circuit_1 - assert circuit_with_calibration_1.moment_to_calibration == [None, 0, 1, 0] - - circuit_2 = cirq.Circuit([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - - circuit_with_calibration_2, requests_2 = workflow.prepare_characterization_for_moments( - circuit_2, options=options, initial=requests_1 - ) - - assert requests_2 == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - assert circuit_with_calibration_2.circuit == circuit_2 - assert circuit_with_calibration_2.moment_to_calibration == [1] - - -def test_prepare_floquet_characterization_for_moments_does_not_merge_sub_sets_when_disabled(): - a, b, c, d, e = cirq.LineQubit.range(5) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - circuit += cirq.Circuit( - [SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)], [SQRT_ISWAP_INV_GATE.on(b, c)] - ) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - circuit_with_calibration, requests = workflow.prepare_floquet_characterization_for_moments( - circuit, options=options, merge_subsets=False - ) - - assert requests == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 2, 3, 1] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments_does_not_merge_sub_sets_when_disabled(options_cls): - options, cls = options_cls - a, b, c, d, e = cirq.LineQubit.range(5) - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - [SQRT_ISWAP_INV_GATE.on(a, b)], - ] - ) - circuit += cirq.Circuit( - [SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)], [SQRT_ISWAP_INV_GATE.on(b, c)] - ) - - circuit_with_calibration, requests = workflow.prepare_characterization_for_moments( - circuit, options=options, merge_subsets=False - ) - - assert requests == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c),), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((a, b),), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 2, 3, 1] - - -def test_prepare_floquet_characterization_for_moments_merges_compatible_sets(): - a, b, c, d, e, f = cirq.LineQubit.range(6) - circuit = cirq.Circuit([cirq.X(a), cirq.Y(c)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, b)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(c, d)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, f), SQRT_ISWAP_INV_GATE.on(d, e)]) - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - circuit_with_calibration, requests = workflow.prepare_floquet_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((a, f), (b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 0, 1] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_moments_merges_compatible_sets(options_cls): - options, cls = options_cls - a, b, c, d, e, f = cirq.LineQubit.range(6) - circuit = cirq.Circuit([cirq.X(a), cirq.Y(c)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, b)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(b, c), SQRT_ISWAP_INV_GATE.on(d, e)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(c, d)]) - circuit += cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, f), SQRT_ISWAP_INV_GATE.on(d, e)]) - - circuit_with_calibration, requests = workflow.prepare_characterization_for_moments( - circuit, options=options - ) - - assert requests == [ - cls(pairs=((a, b), (c, d)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((a, f), (b, c), (d, e)), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [None, 0, 1, 0, 1] - - -def test_prepare_floquet_characterization_for_operations(): - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - q11 = cirq.GridQubit(1, 1) - q20 = cirq.GridQubit(2, 0) - q21 = cirq.GridQubit(2, 1) - - options = WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - - # Prepare characterizations for a single circuit. - circuit_1 = cirq.Circuit( - [ - [cirq.X(q00), cirq.Y(q11)], - [SQRT_ISWAP_INV_GATE.on(q00, q01), SQRT_ISWAP_INV_GATE.on(q10, q11)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(q01)], - ] - ) - - requests_1 = workflow.prepare_floquet_characterization_for_operations( - circuit_1, options=options - ) - - assert requests_1 == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q10, q11),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q00, q01),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - - # Prepare characterizations for a list of circuits. - circuit_2 = cirq.Circuit( - [ - [SQRT_ISWAP_INV_GATE.on(q00, q01), SQRT_ISWAP_INV_GATE.on(q10, q11)], - [SQRT_ISWAP_INV_GATE.on(q00, q10), SQRT_ISWAP_INV_GATE.on(q01, q11)], - [SQRT_ISWAP_INV_GATE.on(q10, q20), SQRT_ISWAP_INV_GATE.on(q11, q21)], - ] - ) - - requests_2 = workflow.prepare_floquet_characterization_for_operations( - [circuit_1, circuit_2], options=options - ) - - # The order of moments originates from HALF_GRID_STAGGERED_PATTERN. - assert requests_2 == [ - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q00, q10), (q11, q21)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q01, q11), (q10, q20)), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q10, q11),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - cirq_google.calibration.FloquetPhasedFSimCalibrationRequest( - pairs=((q00, q01),), gate=SQRT_ISWAP_INV_GATE, options=options - ), - ] - - -@pytest.mark.parametrize( - 'options_cls', - [ - ( - WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - cirq_google.FloquetPhasedFSimCalibrationRequest, - ), - (ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION, cirq_google.XEBPhasedFSimCalibrationRequest), - ], -) -def test_prepare_characterization_for_operations(options_cls): - options, cls = options_cls - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - q10 = cirq.GridQubit(1, 0) - q11 = cirq.GridQubit(1, 1) - q20 = cirq.GridQubit(2, 0) - q21 = cirq.GridQubit(2, 1) - - # Prepare characterizations for a single circuit. - circuit_1 = cirq.Circuit( - [ - [cirq.X(q00), cirq.Y(q11)], - [SQRT_ISWAP_INV_GATE.on(q00, q01), SQRT_ISWAP_INV_GATE.on(q10, q11)], - [cirq.WaitGate(duration=cirq.Duration(micros=5.0)).on(q01)], - ] - ) - - requests_1 = workflow.prepare_characterization_for_operations(circuit_1, options=options) - - assert requests_1 == [ - cls(pairs=((q10, q11),), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((q00, q01),), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - - # Prepare characterizations for a list of circuits. - circuit_2 = cirq.Circuit( - [ - [SQRT_ISWAP_INV_GATE.on(q00, q01), SQRT_ISWAP_INV_GATE.on(q10, q11)], - [SQRT_ISWAP_INV_GATE.on(q00, q10), SQRT_ISWAP_INV_GATE.on(q01, q11)], - [SQRT_ISWAP_INV_GATE.on(q10, q20), SQRT_ISWAP_INV_GATE.on(q11, q21)], - ] - ) - - requests_2 = workflow.prepare_characterization_for_operations( - [circuit_1, circuit_2], options=options - ) - - # The order of moments originates from HALF_GRID_STAGGERED_PATTERN. - assert requests_2 == [ - cls(pairs=((q00, q10), (q11, q21)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((q01, q11), (q10, q20)), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((q10, q11),), gate=SQRT_ISWAP_INV_GATE, options=options), - cls(pairs=((q00, q01),), gate=SQRT_ISWAP_INV_GATE, options=options), - ] - - -def test_prepare_floquet_characterization_for_operations_when_no_interactions(): - q00 = cirq.GridQubit(0, 0) - q11 = cirq.GridQubit(1, 1) - circuit = cirq.Circuit([cirq.X(q00), cirq.X(q11)]) - - assert workflow.prepare_floquet_characterization_for_operations(circuit) == [] - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_operations_when_no_interactions(options): - q00 = cirq.GridQubit(0, 0) - q11 = cirq.GridQubit(1, 1) - circuit = cirq.Circuit([cirq.X(q00), cirq.X(q11)]) - - assert workflow.prepare_characterization_for_operations(circuit, options) == [] - - -def test_prepare_floquet_characterization_for_operations_when_non_grid_fails(): - q00 = cirq.GridQubit(0, 0) - q11 = cirq.GridQubit(1, 1) - circuit = cirq.Circuit(SQRT_ISWAP_INV_GATE.on(q00, q11)) - - with pytest.raises(ValueError): - workflow.prepare_floquet_characterization_for_operations(circuit) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_operations_when_non_grid_fails(options): - q00 = cirq.GridQubit(0, 0) - q11 = cirq.GridQubit(1, 1) - circuit = cirq.Circuit(SQRT_ISWAP_INV_GATE.on(q00, q11)) - - with pytest.raises(ValueError): - workflow.prepare_characterization_for_operations(circuit, options) - - -def test_prepare_floquet_characterization_for_operations_when_multiple_gates_fails(): - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - circuit = cirq.Circuit( - [SQRT_ISWAP_INV_GATE.on(q00, q01), cirq.FSimGate(theta=0.0, phi=np.pi).on(q00, q01)] - ) - - with pytest.raises(ValueError): - workflow.prepare_floquet_characterization_for_operations( - circuit, gates_translator=_fsim_identity_converter - ) - - -@pytest.mark.parametrize( - 'options', - [WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, ALL_ANGLES_XEB_PHASED_FSIM_CHARACTERIZATION], -) -def test_prepare_characterization_for_operations_when_multiple_gates_fails(options): - q00 = cirq.GridQubit(0, 0) - q01 = cirq.GridQubit(0, 1) - circuit = cirq.Circuit( - [SQRT_ISWAP_INV_GATE.on(q00, q01), cirq.FSimGate(theta=0.0, phi=np.pi).on(q00, q01)] - ) - - with pytest.raises(ValueError): - workflow.prepare_characterization_for_operations( - circuit, gates_translator=_fsim_identity_converter, options=options - ) - - -def test_make_zeta_chi_gamma_compensation_for_operations(): - a, b, c, d = cirq.LineQubit.range(4) - parameters_ab = cirq_google.PhasedFSimCharacterization(zeta=0.5, chi=0.4, gamma=0.3) - parameters_bc = cirq_google.PhasedFSimCharacterization(zeta=-0.5, chi=-0.4, gamma=-0.3) - parameters_cd = cirq_google.PhasedFSimCharacterization(zeta=0.2, chi=0.3, gamma=0.4) - - parameters_dict = {(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd} - - engine_simulator = cirq_google.PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={ - pair: parameters.merge_with(SQRT_ISWAP_INV_PARAMETERS) - for pair, parameters in parameters_dict.items() - } - ) - - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - ] - ) - - options = cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=False, - ) - - characterizations = [ - PhasedFSimCalibrationResult( - parameters={pair: parameters}, gate=SQRT_ISWAP_INV_GATE, options=options - ) - for pair, parameters in parameters_dict.items() - ] - - calibrated_circuit = workflow.make_zeta_chi_gamma_compensation_for_operations( - circuit, characterizations - ) - - assert cirq.allclose_up_to_global_phase( - engine_simulator.final_state_vector(calibrated_circuit), cirq.final_state_vector(circuit) - ) - - -def test_make_zeta_chi_gamma_compensation_for_operations_with_permit_mixed_moments_disabled(): - a, b, c, d = cirq.LineQubit.range(4) - parameters_ab = cirq_google.PhasedFSimCharacterization(zeta=0.5, chi=0.4, gamma=0.3) - parameters_bc = cirq_google.PhasedFSimCharacterization(zeta=-0.5, chi=-0.4, gamma=-0.3) - parameters_cd = cirq_google.PhasedFSimCharacterization(zeta=0.2, chi=0.3, gamma=0.4) - - parameters_dict = {(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd} - - circuit = cirq.Circuit( - [ - cirq.Moment([cirq.X(a), cirq.Y(c)]), - cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)]), - cirq.Moment([cirq.X(a), SQRT_ISWAP_INV_GATE.on(b, c), cirq.Y(d)]), - ] - ) - - options = cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=False, - ) - - characterizations = [ - PhasedFSimCalibrationResult( - parameters={pair: parameters}, gate=SQRT_ISWAP_INV_GATE, options=options - ) - for pair, parameters in parameters_dict.items() - ] - - with pytest.raises(workflow.IncompatibleMomentError): - workflow.make_zeta_chi_gamma_compensation_for_operations(circuit, characterizations) - - -def test_make_zeta_chi_gamma_compensation_for_operations_with_permit_mixed_moments(): - a, b, c, d = cirq.LineQubit.range(4) - parameters_ab = cirq_google.PhasedFSimCharacterization(zeta=0.5, chi=0.4, gamma=0.3) - parameters_bc = cirq_google.PhasedFSimCharacterization(zeta=-0.5, chi=-0.4, gamma=-0.3) - parameters_cd = cirq_google.PhasedFSimCharacterization(zeta=0.2, chi=0.3, gamma=0.4) - - parameters_dict = {(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd} - - engine_simulator = cirq_google.PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={ - pair: parameters.merge_with(SQRT_ISWAP_INV_PARAMETERS) - for pair, parameters in parameters_dict.items() - } - ) - - circuit = cirq.Circuit( - [ - cirq.Moment([cirq.X(a), cirq.Y(c)]), - cirq.Moment([SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)]), - cirq.Moment([cirq.X(a), SQRT_ISWAP_INV_GATE.on(b, c), cirq.Y(d)]), - ] - ) - - options = cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=False, - ) - - characterizations = [ - PhasedFSimCalibrationResult( - parameters={pair: parameters}, gate=SQRT_ISWAP_INV_GATE, options=options - ) - for pair, parameters in parameters_dict.items() - ] - - calibrated_circuit = workflow.make_zeta_chi_gamma_compensation_for_operations( - circuit, characterizations, permit_mixed_moments=True - ) - - assert cirq.allclose_up_to_global_phase( - engine_simulator.final_state_vector(calibrated_circuit), cirq.final_state_vector(circuit) - ) - assert calibrated_circuit[5] == cirq.Moment( - [cirq.X(a), SQRT_ISWAP_INV_GATE.on(b, c), cirq.Y(d)] - ) - - -def test_run_calibrations(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - result = cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration( - cirq_google.api.v2.metrics_pb2.MetricsSnapshot( - metrics=[ - cirq_google.api.v2.metrics_pb2.Metric( - name='angles', - targets=[ - '0_qubit_a', - '0_qubit_b', - '0_theta_est', - '0_zeta_est', - '0_phi_est', - '1_qubit_a', - '1_qubit_b', - '1_theta_est', - '1_zeta_est', - '1_phi_est', - ], - values=[ - cirq_google.api.v2.metrics_pb2.Value(str_val='0_0'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_1'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.1), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.2), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.3), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_2'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_3'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.4), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.5), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.6), - ], - ) - ] - ) - ), - ) - - job = cirq_google.engine.EngineJob('project_id', 'program_id', 'job_id', None) - job._calibration_results = [result] - - processor = mock.MagicMock(spec=cirq_google.engine.SimulatedLocalProcessor) - processor.processor_id = 'qproc' - engine = cirq_google.engine.SimulatedLocalEngine([processor]) - processor.engine.return_value = engine - processor.run_calibration.return_value = job - progress_calls = [] - - sampler = cirq_google.ProcessorSampler(processor=processor) - - progress_calls = [] - - def progress(step: int, steps: int) -> None: - progress_calls.append((step, steps)) - - actual = workflow.run_calibrations([request], sampler, progress_func=progress) - - expected = [ - PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=gate, - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) - ] - - assert actual == expected - assert progress_calls == [(1, 1)] - - -def test_run_characterization_with_engine(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - result = cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration( - cirq_google.api.v2.metrics_pb2.MetricsSnapshot( - metrics=[ - cirq_google.api.v2.metrics_pb2.Metric( - name='angles', - targets=[ - '0_qubit_a', - '0_qubit_b', - '0_theta_est', - '0_zeta_est', - '0_phi_est', - '1_qubit_a', - '1_qubit_b', - '1_theta_est', - '1_zeta_est', - '1_phi_est', - ], - values=[ - cirq_google.api.v2.metrics_pb2.Value(str_val='0_0'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_1'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.1), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.2), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.3), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_2'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_3'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.4), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.5), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.6), - ], - ) - ] - ) - ), - ) - - job = cirq_google.engine.EngineJob('project_id', 'program_id', 'job_id', None) - job._calibration_results = [result] - - processor = mock.MagicMock(spec=cirq_google.engine.SimulatedLocalProcessor) - processor.processor_id = 'qproc' - engine = cirq_google.engine.SimulatedLocalEngine([processor]) - processor.engine.return_value = engine - processor.run_calibration.return_value = job - progress_calls = [] - - def progress(step: int, steps: int) -> None: - progress_calls.append((step, steps)) - - actual = workflow.run_calibrations([request], engine, 'qproc', progress_func=progress) - - expected = [ - PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=gate, - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) - ] - - assert actual == expected - assert progress_calls == [(1, 1)] - - -def test_run_calibrations_empty(): - assert workflow.run_calibrations([], None, 'qproc') == [] - - -def test_run_calibrations_fails_when_invalid_arguments(): - with pytest.raises(ValueError): - assert workflow.run_calibrations([], None, 'qproc', max_layers_per_request=0) - - request = FloquetPhasedFSimCalibrationRequest( - gate=SQRT_ISWAP_INV_GATE, pairs=(), options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION - ) - engine = mock.MagicMock(spec=cirq_google.Engine) - - with pytest.raises(ValueError): - assert workflow.run_calibrations([request], engine, None) - - with pytest.raises(ValueError): - assert workflow.run_calibrations([request], 0, 'qproc') - - -def test_run_calibrations_with_simulator(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = SQRT_ISWAP_INV_GATE - - request = FloquetPhasedFSimCalibrationRequest( - gate=gate, - pairs=((q_00, q_01), (q_02, q_03)), - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - - simulator = PhasedFSimEngineSimulator.create_with_ideal_sqrt_iswap() - - actual = workflow.run_calibrations([request], simulator) - - assert actual == [ - PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=np.pi / 4, zeta=0.0, chi=None, gamma=None, phi=0.0 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=np.pi / 4, zeta=0.0, chi=None, gamma=None, phi=0.0 - ), - }, - gate=SQRT_ISWAP_INV_GATE, - options=FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) - ] - - -def test_run_floquet_characterization_for_moments(): - q_00, q_01, q_02, q_03 = [cirq.GridQubit(0, index) for index in range(4)] - gate = cirq.FSimGate(theta=np.pi / 4, phi=0.0) - - circuit = cirq.Circuit([gate.on(q_00, q_01), gate.on(q_02, q_03)]) - - options = FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ) - - job = cirq_google.engine.EngineJob('project_id', 'program_id', 'job_id', None) - job._calibration_results = [ - cirq_google.CalibrationResult( - error_message=None, - token=None, - valid_until=None, - metrics=cirq_google.Calibration( - cirq_google.api.v2.metrics_pb2.MetricsSnapshot( - metrics=[ - cirq_google.api.v2.metrics_pb2.Metric( - name='angles', - targets=[ - '0_qubit_a', - '0_qubit_b', - '0_theta_est', - '0_zeta_est', - '0_phi_est', - '1_qubit_a', - '1_qubit_b', - '1_theta_est', - '1_zeta_est', - '1_phi_est', - ], - values=[ - cirq_google.api.v2.metrics_pb2.Value(str_val='0_0'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_1'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.1), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.2), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.3), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_2'), - cirq_google.api.v2.metrics_pb2.Value(str_val='0_3'), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.4), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.5), - cirq_google.api.v2.metrics_pb2.Value(double_val=0.6), - ], - ) - ] - ) - ), - ) - ] - - processor = mock.MagicMock(spec=cirq_google.engine.SimulatedLocalProcessor) - processor.processor_id = 'qproc' - engine = cirq_google.engine.SimulatedLocalEngine([processor]) - processor.engine.return_value = engine - processor.run_calibration.return_value = job - - circuit_with_calibration, requests = workflow.run_floquet_characterization_for_moments( - circuit, engine, 'qproc', options=options - ) - - assert requests == [ - PhasedFSimCalibrationResult( - parameters={ - (q_00, q_01): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (q_02, q_03): PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=gate, - options=options, - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) - ] - assert circuit_with_calibration.circuit == circuit - assert circuit_with_calibration.moment_to_calibration == [0] - - -@pytest.mark.parametrize( - 'theta,zeta,chi,gamma,phi', - itertools.product([0.1, 0.7], [-0.3, 0.1, 0.5], [-0.3, 0.2, 0.4], [-0.6, 0.1, 0.6], [0.2, 0.6]), -) -def test_fsim_phase_corrections( - theta: float, zeta: float, chi: float, gamma: float, phi: float -) -> None: - a, b = cirq.LineQubit.range(2) - - expected_gate = cirq.PhasedFSimGate(theta=theta, zeta=-zeta, chi=-chi, gamma=-gamma, phi=phi) - expected = cirq.unitary(expected_gate) - - corrected = workflow.FSimPhaseCorrections.from_characterization( - (a, b), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=theta, phi=phi), 0.0), - cirq_google.PhasedFSimCharacterization( - theta=theta, zeta=zeta, chi=chi, gamma=gamma, phi=phi - ), - characterization_index=5, - ) - actual = cirq.unitary(corrected.as_circuit()) - - assert cirq.equal_up_to_global_phase(actual, expected) - assert corrected.moment_to_calibration == [None, 5, None] - - -@pytest.mark.parametrize( - 'theta,zeta,chi,gamma,phi', - itertools.product( - [np.pi / 4, -0.2], [-0.3, 0.1, 0.5], [-0.3, 0.2, 0.4], [-0.6, 0.1, 0.6], [0.2, 0.6] - ), -) -def test_phase_corrected_fsim_operations_with_phase_exponent( - theta: float, zeta: float, chi: float, gamma: float, phi: float -) -> None: - a, b = cirq.LineQubit.range(2) - - phase_exponent = 0.5 - - # Theta is negated to match the phase exponent of 0.5. - expected_gate = cirq.PhasedFSimGate(theta=-theta, zeta=-zeta, chi=-chi, gamma=-gamma, phi=phi) - expected = cirq.unitary(expected_gate) - - corrected = workflow.FSimPhaseCorrections.from_characterization( - (a, b), - PhaseCalibratedFSimGate(cirq.FSimGate(theta=theta, phi=phi), phase_exponent), - cirq_google.PhasedFSimCharacterization( - theta=theta, zeta=zeta, chi=chi, gamma=gamma, phi=phi - ), - characterization_index=5, - ) - actual = cirq.unitary(corrected.as_circuit()) - - assert cirq.equal_up_to_global_phase(actual, expected) - assert corrected.moment_to_calibration == [None, 5, None] - - -def test_make_zeta_chi_gamma_compensation_for_moments(): - a, b = cirq.LineQubit.range(2) - - moment_allocations = [0] - - for gate_to_calibrate, engine_gate in [ - (cirq.FSimGate(theta=np.pi / 4, phi=0.0), SQRT_ISWAP_INV_GATE), - (cirq.FSimGate(theta=-np.pi / 4, phi=0.0), SQRT_ISWAP_INV_GATE), - (cirq.ISwapPowGate(exponent=0.2), cirq.FSimGate(theta=0.1 * np.pi, phi=0.0)), - (cirq.PhasedFSimGate(theta=0.1, phi=0.2), cirq.FSimGate(theta=0.1, phi=0.2)), - (cirq.PhasedFSimGate(theta=0.1, phi=0.2, chi=0.3), cirq.FSimGate(theta=0.1, phi=0.2)), - (cirq.PhasedISwapPowGate(exponent=0.2), cirq.FSimGate(theta=0.1 * np.pi, phi=0.0)), - ( - cirq.PhasedISwapPowGate(exponent=0.2, phase_exponent=0.4), - cirq.FSimGate(theta=0.1 * np.pi, phi=0.0), - ), - (cirq.CZ, cirq.FSimGate(theta=0.0, phi=np.pi)), - (cirq.ops.CZPowGate(exponent=0.5), cirq.FSimGate(theta=0.0, phi=1.5 * np.pi)), - (cirq_google.ops.SycamoreGate(), cirq.FSimGate(theta=np.pi / 2, phi=np.pi / 6)), - ]: - circuit = cirq.Circuit(gate_to_calibrate.on(a, b)) - characterizations = [ - PhasedFSimCalibrationResult( - # Assume that the engine gate is perfect. - parameters={ - (a, b): cirq_google.PhasedFSimCharacterization( - theta=engine_gate.theta, phi=engine_gate.phi, zeta=0.0, chi=0.0, gamma=0.0 - ) - }, - gate=engine_gate, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - calibrated_circuit = workflow.make_zeta_chi_gamma_compensation_for_moments( - workflow.CircuitWithCalibration(circuit, moment_allocations), characterizations - ) - assert np.allclose(cirq.unitary(circuit), cirq.unitary(calibrated_circuit.circuit)) - assert calibrated_circuit.moment_to_calibration == [None, 0, None] - - -def test_make_zeta_chi_gamma_compensation_for_moments_wrong_engine_gate_error(): - a, b = cirq.LineQubit.range(2) - circuit = cirq.Circuit(cirq.FSimGate(theta=np.pi / 4, phi=0.2).on(a, b)) - characterizations = [ - PhasedFSimCalibrationResult( - parameters={ - (a, b): cirq_google.PhasedFSimCharacterization( - theta=np.pi / 4, phi=0.2, zeta=0.0, chi=0.0, gamma=0.0 - ) - }, - gate=SQRT_ISWAP_INV_GATE, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - with pytest.raises(ValueError, match="Engine gate .+ doesn't match characterized gate .+"): - workflow.make_zeta_chi_gamma_compensation_for_moments( - workflow.CircuitWithCalibration(circuit, [0]), characterizations - ) - - -def test_make_zeta_chi_gamma_compensation_for_moments_circuit(): - a, b = cirq.LineQubit.range(2) - - characterizations = [ - PhasedFSimCalibrationResult( - parameters={(a, b): SQRT_ISWAP_INV_PARAMETERS}, - gate=SQRT_ISWAP_INV_GATE, - options=ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - - for circuit, expected_moment_to_calibration in [ - (cirq.Circuit(cirq.FSimGate(theta=np.pi / 4, phi=0.0).on(a, b)), [None, 0, None]), - ( - cirq.Circuit([cirq.Z.on(a), cirq.FSimGate(theta=-np.pi / 4, phi=0.0).on(a, b)]), - [None, None, 0, None], - ), - ]: - calibrated_circuit = workflow.make_zeta_chi_gamma_compensation_for_moments( - circuit, characterizations - ) - assert np.allclose(cirq.unitary(circuit), cirq.unitary(calibrated_circuit.circuit)) - assert calibrated_circuit.moment_to_calibration == expected_moment_to_calibration - - -def test_zmake_zeta_chi_gamma_compensation_for_moments_invalid_argument_fails() -> None: - a, b, c = cirq.LineQubit.range(3) - - with pytest.raises(ValueError): - circuit_with_calibration = workflow.CircuitWithCalibration(cirq.Circuit(), [1]) - workflow.make_zeta_chi_gamma_compensation_for_moments(circuit_with_calibration, []) - - with pytest.raises(ValueError): - circuit_with_calibration = workflow.CircuitWithCalibration( - cirq.Circuit(SQRT_ISWAP_INV_GATE.on(a, b)), [None] - ) - workflow.make_zeta_chi_gamma_compensation_for_moments(circuit_with_calibration, []) - - with pytest.raises(ValueError): - workflow.make_zeta_chi_gamma_compensation_for_moments( - cirq.Circuit(SQRT_ISWAP_INV_GATE.on(a, b)), [] - ) - - with pytest.raises(ValueError): - circuit_with_calibration = workflow.CircuitWithCalibration( - cirq.Circuit(SQRT_ISWAP_INV_GATE.on(a, b)), [0] - ) - characterizations = [ - PhasedFSimCalibrationResult( - parameters={}, - gate=SQRT_ISWAP_INV_GATE, - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - workflow.make_zeta_chi_gamma_compensation_for_moments( - circuit_with_calibration, characterizations - ) - - with pytest.raises(workflow.IncompatibleMomentError): - circuit_with_calibration = workflow.CircuitWithCalibration( - cirq.Circuit(cirq.global_phase_operation(coefficient=1.0)), [None] - ) - workflow.make_zeta_chi_gamma_compensation_for_moments(circuit_with_calibration, []) - - with pytest.raises(workflow.IncompatibleMomentError): - circuit_with_calibration = workflow.CircuitWithCalibration( - cirq.Circuit(cirq.CX.on(a, b)), [None] - ) - workflow.make_zeta_chi_gamma_compensation_for_moments(circuit_with_calibration, []) - - with pytest.raises(workflow.IncompatibleMomentError): - circuit_with_calibration = workflow.CircuitWithCalibration( - cirq.Circuit([SQRT_ISWAP_INV_GATE.on(a, b), cirq.Z.on(c)]), [0] - ) - characterizations = [ - PhasedFSimCalibrationResult( - parameters={ - (a, b): PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5 - ) - }, - gate=SQRT_ISWAP_INV_GATE, - options=WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION, - ) - ] - workflow.make_zeta_chi_gamma_compensation_for_moments( - circuit_with_calibration, characterizations - ) - - -def test_make_zeta_chi_gamma_compensation_for_moments_imperfect_gates(): - params_cz_ab = cirq_google.PhasedFSimCharacterization( - zeta=0.02, chi=0.05, gamma=0.04, theta=0.0, phi=np.pi - ) - params_cz_cd = cirq_google.PhasedFSimCharacterization( - zeta=0.03, chi=0.08, gamma=0.03, theta=0.0, phi=np.pi - ) - params_syc_ab = cirq_google.PhasedFSimCharacterization( - zeta=0.01, chi=0.09, gamma=0.02, theta=np.pi / 2, phi=np.pi / 6 - ) - params_sqrt_iswap_ac = cirq_google.PhasedFSimCharacterization( - zeta=0.05, chi=0.06, gamma=0.07, theta=np.pi / 4, phi=0.0 - ) - params_sqrt_iswap_bd = cirq_google.PhasedFSimCharacterization( - zeta=0.01, chi=0.02, gamma=0.03, theta=np.pi / 4, phi=0.0 - ) - - a, b, c, d = cirq.LineQubit.range(4) - engine_simulator = cirq_google.PhasedFSimEngineSimulator.create_from_dictionary( - parameters={ - (a, b): { - cirq.FSimGate(theta=0, phi=np.pi): params_cz_ab, - cirq_google.SYC: params_syc_ab, - }, - (c, d): {cirq.FSimGate(theta=0, phi=np.pi): params_cz_cd}, - (a, c): {SQRT_ISWAP_INV_GATE: params_sqrt_iswap_ac}, - (b, d): {SQRT_ISWAP_INV_GATE: params_sqrt_iswap_bd}, - } - ) - - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.H(c)], - [cirq.CZ.on(a, b), cirq.CZ.on(d, c)], - [cirq_google.SYC.on(a, b)], - [SQRT_ISWAP_GATE.on(a, c), SQRT_ISWAP_INV_GATE.on(b, d)], - ] - ) - - options = cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=False, - ) - - characterizations = [ - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(theta=0, phi=np.pi), - parameters={(a, b): params_cz_ab, (c, d): params_cz_cd}, - options=options, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(theta=np.pi / 2, phi=np.pi / 6), - parameters={(a, b): params_syc_ab}, - options=options, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq.FSimGate(theta=np.pi / 4, phi=0), - parameters={(a, c): params_sqrt_iswap_ac, (b, d): params_sqrt_iswap_bd}, - options=options, - ), - ] - - circuit_with_calibration = workflow.make_zeta_chi_gamma_compensation_for_moments( - circuit, characterizations - ) - - assert cirq.allclose_up_to_global_phase( - engine_simulator.final_state_vector(circuit_with_calibration.circuit), - cirq.final_state_vector(circuit), - ) - - -def test_run_zeta_chi_gamma_calibration_for_moments() -> None: - parameters_ab = cirq_google.PhasedFSimCharacterization(zeta=0.5, chi=0.4, gamma=0.3) - parameters_bc = cirq_google.PhasedFSimCharacterization(zeta=-0.5, chi=-0.4, gamma=-0.3) - parameters_cd = cirq_google.PhasedFSimCharacterization(zeta=0.2, chi=0.3, gamma=0.4) - - a, b, c, d = cirq.LineQubit.range(4) - engine_simulator = cirq_google.PhasedFSimEngineSimulator.create_from_dictionary( - parameters={ - (a, b): {SQRT_ISWAP_INV_GATE: parameters_ab.merge_with(SQRT_ISWAP_INV_PARAMETERS)}, - (b, c): {cirq_google.ops.SYC: parameters_bc.merge_with(SYCAMORE_PARAMETERS)}, - (c, d): {SQRT_ISWAP_INV_GATE: parameters_cd.merge_with(SQRT_ISWAP_INV_PARAMETERS)}, - } - ) - - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [cirq_google.ops.SYC.on(b, c)], - ] - ) - - options = cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=False, - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_phi=False, - ) - - calibrated_circuit, calibrations = workflow.run_zeta_chi_gamma_compensation_for_moments( - circuit, engine_simulator, processor_id=None, options=options - ) - - assert cirq.allclose_up_to_global_phase( - engine_simulator.final_state_vector(calibrated_circuit.circuit), - cirq.final_state_vector(circuit), - ) - assert calibrations == [ - cirq_google.PhasedFSimCalibrationResult( - gate=SQRT_ISWAP_INV_GATE, - parameters={(a, b): parameters_ab, (c, d): parameters_cd}, - options=options, - ), - cirq_google.PhasedFSimCalibrationResult( - gate=cirq_google.ops.SYC, parameters={(b, c): parameters_bc}, options=options - ), - ] - assert calibrated_circuit.moment_to_calibration == [None, None, 0, None, None, 1, None] - - -def test_run_zeta_chi_gamma_calibration_for_moments_no_chi() -> None: - parameters_ab = cirq_google.PhasedFSimCharacterization(theta=np.pi / 4, zeta=0.5, gamma=0.3) - parameters_bc = cirq_google.PhasedFSimCharacterization(theta=np.pi / 4, zeta=-0.5, gamma=-0.3) - parameters_cd = cirq_google.PhasedFSimCharacterization(theta=np.pi / 4, zeta=0.2, gamma=0.4) - - a, b, c, d = cirq.LineQubit.range(4) - engine_simulator = cirq_google.PhasedFSimEngineSimulator.create_from_dictionary_sqrt_iswap( - parameters={(a, b): parameters_ab, (b, c): parameters_bc, (c, d): parameters_cd}, - ideal_when_missing_parameter=True, - ) - - circuit = cirq.Circuit( - [ - [cirq.X(a), cirq.Y(c)], - [SQRT_ISWAP_INV_GATE.on(a, b), SQRT_ISWAP_INV_GATE.on(c, d)], - [SQRT_ISWAP_INV_GATE.on(b, c)], - ] - ) - - calibrated_circuit, *_ = workflow.run_zeta_chi_gamma_compensation_for_moments( - circuit, engine_simulator, processor_id=None - ) - - assert cirq.allclose_up_to_global_phase( - engine_simulator.final_state_vector(calibrated_circuit.circuit), - cirq.final_state_vector(circuit), - ) - - -_MOCK_ENGINE_SAMPLER = mock.MagicMock(spec=cirq_google.ProcessorSampler) - - -@pytest.mark.parametrize('sampler_engine', [cirq.Simulator, _MOCK_ENGINE_SAMPLER]) -def test_run_local(sampler_engine, monkeypatch): - called_times = 0 - - def myfunc(calibration: LocalXEBPhasedFSimCalibrationRequest, sampler: cirq.Sampler): - nonlocal called_times - assert isinstance(calibration, LocalXEBPhasedFSimCalibrationRequest) - assert sampler is not None - called_times += 1 - return [] - - # Note: you must patch specifically the function imported into `workflow`. - monkeypatch.setattr('cirq_google.calibration.workflow.run_local_xeb_calibration', myfunc) - - qubit_indices = [(0, 5), (0, 6), (1, 6), (2, 6)] - qubits = [cirq.GridQubit(*idx) for idx in qubit_indices] - - circuits = [ - random_rotations_between_grid_interaction_layers_circuit( - qubits, - depth=depth, - two_qubit_op_factory=lambda a, b, _: SQRT_ISWAP_INV_GATE.on(a, b), - pattern=cirq.experiments.GRID_ALIGNED_PATTERN, - seed=10, - ) - for depth in [5, 10] - ] - - options = LocalXEBPhasedFSimCalibrationOptions( - fsim_options=XEBPhasedFSimCharacterizationOptions( - characterize_zeta=True, - characterize_gamma=True, - characterize_chi=True, - characterize_theta=False, - characterize_phi=False, - theta_default=np.pi / 4, - ), - n_processes=1, - ) - - characterization_requests = [] - for circuit in circuits: - _, characterization_requests = workflow.prepare_characterization_for_moments( - circuit, options=options, initial=characterization_requests - ) - assert len(characterization_requests) == 2 - for cr in characterization_requests: - assert isinstance(cr, LocalXEBPhasedFSimCalibrationRequest) - - workflow.run_calibrations(characterization_requests, sampler_engine) - assert called_times == 2 - - -def test_multiple_calibration_types_error(): - r1 = LocalXEBPhasedFSimCalibrationRequest( - pairs=[], gate=None, options=LocalXEBPhasedFSimCalibrationOptions() - ) - r2 = XEBPhasedFSimCalibrationRequest( - pairs=[], gate=None, options=XEBPhasedFSimCalibrationOptions() - ) - with pytest.raises(ValueError, match=r'must be of the same type\.'): - workflow.run_calibrations([r1, r2], cirq.Simulator()) diff --git a/cirq-google/cirq_google/calibration/xeb_wrapper.py b/cirq-google/cirq_google/calibration/xeb_wrapper.py deleted file mode 100644 index 9aa90b118a2..00000000000 --- a/cirq-google/cirq_google/calibration/xeb_wrapper.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import contextlib -import multiprocessing -import multiprocessing.pool -from typing import Optional, Union, Iterator - -import cirq -import cirq.experiments.random_quantum_circuit_generation as rqcg -import cirq.experiments.xeb_fitting as xebf -import cirq.experiments.xeb_sampling as xebsamp -from cirq_google.calibration.phased_fsim import ( - PhasedFSimCalibrationResult, - PhasedFSimCharacterization, - LocalXEBPhasedFSimCalibrationRequest, - LocalXEBPhasedFSimCalibrationOptions, -) - - -@contextlib.contextmanager -def _maybe_multiprocessing_pool( - n_processes: Optional[int] = None, -) -> Iterator[Union['multiprocessing.pool.Pool', None]]: - """Yield a multiprocessing.Pool as a context manager, unless n_processes=1; then yield None, - which should disable multiprocessing in XEB apis.""" - if n_processes == 1: - yield None - return - - with multiprocessing.get_context('spawn').Pool(processes=n_processes) as pool: - yield pool - - -def run_local_xeb_calibration( - calibration: LocalXEBPhasedFSimCalibrationRequest, sampler: cirq.Sampler -) -> PhasedFSimCalibrationResult: - """Run a calibration request using `cirq.experiments` XEB utilities and a sampler rather - than `Engine.run_calibrations`. - - Args: - calibration: A LocalXEBPhasedFSimCalibration request describing the XEB characterization - to carry out. - sampler: A sampler to execute circuits. - """ - options: LocalXEBPhasedFSimCalibrationOptions = calibration.options - circuit = cirq.Circuit([calibration.gate.on(*pair) for pair in calibration.pairs]) - - # 2. Set up XEB experiment - cycle_depths = options.cycle_depths - circuits = rqcg.generate_library_of_2q_circuits( - n_library_circuits=options.n_library_circuits, - two_qubit_gate=calibration.gate, - max_cycle_depth=max(cycle_depths), - ) - combs_by_layer = rqcg.get_random_combinations_for_layer_circuit( - n_library_circuits=len(circuits), - n_combinations=options.n_combinations, - layer_circuit=circuit, - ) - - # 3. Sample data - sampled_df = xebsamp.sample_2q_xeb_circuits( - sampler=sampler, - circuits=circuits, - cycle_depths=cycle_depths, - combinations_by_layer=combs_by_layer, - ) - - # 4. Initial fidelities - # initial_fids = xebf.benchmark_2q_xeb_fidelities( - # sampled_df=sampled_df, - # circuits=circuits, - # cycle_depths=cycle_depths, - # ) - - # 5. Characterize by fitting angles. - if options.fsim_options.defaults_set(): - fsim_options = options.fsim_options - else: - fsim_options = options.fsim_options.with_defaults_from_gate(calibration.gate) - - pcircuits = [xebf.parameterize_circuit(circuit, fsim_options) for circuit in circuits] - fatol = options.fatol if options.fatol is not None else 5e-3 - xatol = options.xatol if options.xatol is not None else 5e-3 - with _maybe_multiprocessing_pool(n_processes=options.n_processes) as pool: - char_results = xebf.characterize_phased_fsim_parameters_with_xeb_by_pair( - sampled_df=sampled_df, - parameterized_circuits=pcircuits, - cycle_depths=cycle_depths, - options=fsim_options, - pool=pool, - fatol=fatol, - xatol=xatol, - ) - - return PhasedFSimCalibrationResult( - parameters={ - pair: PhasedFSimCharacterization(**param_dict) - for pair, param_dict in char_results.final_params.items() - }, - gate=calibration.gate, - options=options, - ) diff --git a/cirq-google/cirq_google/calibration/xeb_wrapper_test.py b/cirq-google/cirq_google/calibration/xeb_wrapper_test.py deleted file mode 100644 index 4a6fe6669ec..00000000000 --- a/cirq-google/cirq_google/calibration/xeb_wrapper_test.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright 2021 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. - -import multiprocessing.pool - -import numpy as np -import pandas as pd -import pytest -import scipy.optimize -import scipy.optimize._minimize - -import cirq -import cirq_google as cg -from cirq.experiments import random_rotations_between_grid_interaction_layers_circuit -from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions -from cirq_google.calibration.phased_fsim import ( - LocalXEBPhasedFSimCalibrationOptions, - LocalXEBPhasedFSimCalibrationRequest, -) -from cirq_google.calibration.xeb_wrapper import ( - run_local_xeb_calibration, - _maybe_multiprocessing_pool, -) - - -def _minimize_patch( - fun, - x0, - args=(), - method=None, - jac=None, - hess=None, - hessp=None, - bounds=None, - constraints=(), - tol=None, - callback=None, - options=None, - x0_should_be=None, -): - assert method == 'nelder-mead' - np.testing.assert_allclose(x0_should_be, x0) - - return scipy.optimize.OptimizeResult( - fun=0, - nit=0, - nfev=0, - status=0, - success=True, - message='monkeypatched', - x=x0.copy(), - final_simplex=None, - ) - - -def _benchmark_patch(*args, **kwargs): - return pd.DataFrame() - - -@pytest.mark.parametrize( - ['fsim_options', 'x0_should_be'], - [ - ( - XEBPhasedFSimCharacterizationOptions( - characterize_zeta=True, - characterize_gamma=True, - characterize_chi=True, - characterize_theta=False, - characterize_phi=False, - ), - [0.0, 0.0, 0.0], - ), - (XEBPhasedFSimCharacterizationOptions(), [np.pi / 4, 0.0, 0.0, 0.0, 0.0]), - ( - XEBPhasedFSimCharacterizationOptions( - characterize_zeta=True, - characterize_chi=True, - characterize_gamma=True, - characterize_theta=False, - characterize_phi=False, - theta_default=99, - zeta_default=0.1, - chi_default=0.2, - gamma_default=0.3, - phi_default=99, - ), - [0.1, 0.2, 0.3], - ), - ], -) -def test_run_calibration(monkeypatch, fsim_options, x0_should_be): - def _minimize_patch_2(*args, **kwargs): - return _minimize_patch(*args, **kwargs, x0_should_be=x0_should_be) - - monkeypatch.setattr('scipy.optimize.minimize', _minimize_patch_2) - monkeypatch.setattr( - 'cirq_google.calibration.xeb_wrapper.xebf.benchmark_2q_xeb_fidelities', _benchmark_patch - ) - qubit_indices = [(0, 5), (0, 6), (1, 6), (2, 6)] - qubits = [cirq.GridQubit(*idx) for idx in qubit_indices] - sampler = cirq.ZerosSampler() - - circuits = [ - random_rotations_between_grid_interaction_layers_circuit( - qubits, - depth=depth, - two_qubit_op_factory=lambda a, b, _: (cirq.SQRT_ISWAP_INV.on(a, b)), - pattern=cirq.experiments.GRID_ALIGNED_PATTERN, - seed=10, - ) - for depth in [5, 10] - ] - - options = LocalXEBPhasedFSimCalibrationOptions(fsim_options=fsim_options, n_processes=1) - - characterization_requests = [] - for circuit in circuits: - _, characterization_requests = cg.prepare_characterization_for_moments( - circuit, options=options, initial=characterization_requests - ) - assert len(characterization_requests) == 2 - for cr in characterization_requests: - assert isinstance(cr, LocalXEBPhasedFSimCalibrationRequest) - - characterizations = [ - run_local_xeb_calibration(request, sampler) for request in characterization_requests - ] - - final_params = dict() - for c in characterizations: - final_params.update(c.parameters) - assert len(final_params) == 3 # pairs - - -def test_maybe_pool(): - with _maybe_multiprocessing_pool(1) as pool: - assert pool is None - - with _maybe_multiprocessing_pool(2) as pool: - assert isinstance(pool, multiprocessing.pool.Pool) diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index 44e2254fce2..c64481fc51a 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. """A helper for jobs that have been created on the Quantum Engine.""" -import datetime - from typing import Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union import duet diff --git a/cirq-google/cirq_google/engine/engine_program_test.py b/cirq-google/cirq_google/engine/engine_program_test.py index d0556e71c4f..785abdca2e3 100644 --- a/cirq-google/cirq_google/engine/engine_program_test.py +++ b/cirq-google/cirq_google/engine/engine_program_test.py @@ -91,22 +91,6 @@ def test_run_sweeps_delegation(create_job_async): assert job._job == quantum.QuantumJob() -@mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') -def test_run_calibration_delegation(create_job_async): - create_job_async.return_value = ('dogs', quantum.QuantumJob()) - program = cg.EngineProgram('woof', 'woof', EngineContext(), result_type=ResultType.Calibration) - job = program.run_calibration(processor_ids=['lazydog']) - assert job._job == quantum.QuantumJob() - - -@mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') -def test_run_calibration_no_processors(create_job_async): - create_job_async.return_value = ('dogs', quantum.QuantumJob()) - program = cg.EngineProgram('woof', 'woof', EngineContext(), result_type=ResultType.Calibration) - with pytest.raises(ValueError, match='No processors specified'): - _ = program.run_calibration(job_id='spot') - - @mock.patch('cirq_google.engine.engine_client.EngineClient.get_job_results_async') @mock.patch('cirq_google.engine.engine_client.EngineClient.create_job_async') def test_run_delegation(create_job_async, get_results_async): diff --git a/cirq-google/cirq_google/engine/simulated_local_job_test.py b/cirq-google/cirq_google/engine/simulated_local_job_test.py index ced15132452..ea55404a2c4 100644 --- a/cirq-google/cirq_google/engine/simulated_local_job_test.py +++ b/cirq-google/cirq_google/engine/simulated_local_job_test.py @@ -106,16 +106,3 @@ def test_run_async(): assert job.execution_status() == quantum.ExecutionStatus.State.RUNNING _ = job.results() assert job.execution_status() == quantum.ExecutionStatus.State.SUCCESS - - -def test_run_calibration_unsupported(): - program = ParentProgram([cirq.Circuit()], None) - job = SimulatedLocalJob( - job_id='test_job', - processor_id='test1', - parent_program=program, - repetitions=100, - sweeps=[{}], - ) - with pytest.raises(NotImplementedError): - _ = job.calibration_results() diff --git a/cirq-google/cirq_google/engine/simulated_local_processor_test.py b/cirq-google/cirq_google/engine/simulated_local_processor_test.py index d0ec70d1cfd..0622d3cb9db 100644 --- a/cirq-google/cirq_google/engine/simulated_local_processor_test.py +++ b/cirq-google/cirq_google/engine/simulated_local_processor_test.py @@ -208,9 +208,3 @@ def test_device_specification(): device_spec.valid_qubits.append('q0_1') proc = SimulatedLocalProcessor(processor_id='test_proc', device_specification=device_spec) assert proc.get_device_specification() == device_spec - - -def test_unsupported(): - proc = SimulatedLocalProcessor(processor_id='test_proc') - with pytest.raises(NotImplementedError): - _ = proc.run_calibration() diff --git a/cirq-google/cirq_google/engine/virtual_engine_factory.py b/cirq-google/cirq_google/engine/virtual_engine_factory.py index 79c02535565..451db1e00fe 100644 --- a/cirq-google/cirq_google/engine/virtual_engine_factory.py +++ b/cirq-google/cirq_google/engine/virtual_engine_factory.py @@ -402,7 +402,7 @@ def create_default_noisy_quantum_virtual_machine( if simulator_class is None: try: # pragma: no cover - import qsimcirq + import qsimcirq # type: ignore simulator_class = qsimcirq.QSimSimulator # pragma: no cover except ImportError: diff --git a/cirq-google/cirq_google/json_resolver_cache.py b/cirq-google/cirq_google/json_resolver_cache.py index 29a9b0ed6b6..8dc5d0967f3 100644 --- a/cirq-google/cirq_google/json_resolver_cache.py +++ b/cirq-google/cirq_google/json_resolver_cache.py @@ -51,15 +51,7 @@ def _old_xmon(*args, **kwargs): 'GateTabulation': TwoQubitGateTabulation, 'PhysicalZTag': cirq_google.PhysicalZTag, 'FSimGateFamily': cirq_google.FSimGateFamily, - 'FloquetPhasedFSimCalibrationOptions': cirq_google.FloquetPhasedFSimCalibrationOptions, - 'FloquetPhasedFSimCalibrationRequest': cirq_google.FloquetPhasedFSimCalibrationRequest, - 'PhasedFSimCalibrationResult': cirq_google.PhasedFSimCalibrationResult, - 'PhasedFSimCharacterization': cirq_google.PhasedFSimCharacterization, 'SycamoreTargetGateset': cirq_google.SycamoreTargetGateset, - 'XEBPhasedFSimCalibrationOptions': cirq_google.XEBPhasedFSimCalibrationOptions, - 'XEBPhasedFSimCalibrationRequest': cirq_google.XEBPhasedFSimCalibrationRequest, - 'LocalXEBPhasedFSimCalibrationOptions': cirq_google.LocalXEBPhasedFSimCalibrationOptions, - 'LocalXEBPhasedFSimCalibrationRequest': cirq_google.LocalXEBPhasedFSimCalibrationRequest, 'cirq.google.BitstringsMeasurement': cirq_google.BitstringsMeasurement, 'cirq.google.QuantumExecutable': cirq_google.QuantumExecutable, 'cirq.google.QuantumExecutableGroup': cirq_google.QuantumExecutableGroup, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json b/cirq-google/cirq_google/json_test_data/CalibrationResult.json index a7f0144793d..8baa07e7a18 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.json @@ -1,6 +1,5 @@ { "cirq_type": "CalibrationResult", - "code": 1, "error_message": "a", "token": "b", "utc_valid_until": 1606319984.041021, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward index a7f0144793d..8baa07e7a18 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward @@ -1,6 +1,5 @@ { "cirq_type": "CalibrationResult", - "code": 1, "error_message": "a", "token": "b", "utc_valid_until": 1606319984.041021, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr index c6930dc4504..ea938a3ecee 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr @@ -1,5 +1,4 @@ cirq_google.CalibrationResult( - code=1, error_message='a', token='b', valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward index c6930dc4504..ea938a3ecee 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward @@ -1,5 +1,4 @@ cirq_google.CalibrationResult( - code=1, error_message='a', token='b', valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json deleted file mode 100644 index 2cd46f91bc8..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": true, - "characterize_phi": false, - "readout_error_tolerance": 0.4, - "version": 2, - "measure_qubits": null -} diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json_inward b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json_inward deleted file mode 100644 index 8ca468fb274..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.json_inward +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": true, - "characterize_phi": false -} diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr deleted file mode 100644 index 108050dfb95..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.FloquetPhasedFSimCalibrationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=False, characterize_gamma=True, characterize_phi=False, readout_error_tolerance=0.4, version=2) diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr_inward b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr_inward deleted file mode 100644 index 1ce86026574..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationOptions.repr_inward +++ /dev/null @@ -1 +0,0 @@ -cirq_google.FloquetPhasedFSimCalibrationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=False, characterize_gamma=True, characterize_phi=False) diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json deleted file mode 100644 index 9a417265045..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "cirq_type": "FloquetPhasedFSimCalibrationRequest", - "pairs": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 1 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 2 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 3 - } - ] - ], - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "options": { - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": false, - "characterize_phi": true, - "readout_error_tolerance": 0.4, - "version": 2, - "measure_qubits": null - } -} diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json_inward b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json_inward deleted file mode 100644 index d6aeba6b090..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.json_inward +++ /dev/null @@ -1,42 +0,0 @@ -{ - "cirq_type": "FloquetPhasedFSimCalibrationRequest", - "pairs": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 1 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 2 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 3 - } - ] - ], - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "options": { - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": false, - "characterize_phi": true - } -} diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr deleted file mode 100644 index d72da849a94..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr +++ /dev/null @@ -1,13 +0,0 @@ -cirq_google.FloquetPhasedFSimCalibrationRequest( - gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), - pairs=((cirq.GridQubit(0,0), cirq.GridQubit(0,1)), (cirq.GridQubit(0,2), cirq.GridQubit(0,3))), - options=cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - readout_error_tolerance=0.4, - version=2 - ), - ) diff --git a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr_inward b/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr_inward deleted file mode 100644 index c5f9792e6a3..00000000000 --- a/cirq-google/cirq_google/json_test_data/FloquetPhasedFSimCalibrationRequest.repr_inward +++ /dev/null @@ -1,11 +0,0 @@ -cirq_google.FloquetPhasedFSimCalibrationRequest( - gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), - pairs=((cirq.GridQubit(0,0), cirq.GridQubit(0,1)), (cirq.GridQubit(0,2), cirq.GridQubit(0,3))), - options=cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) diff --git a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.json b/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.json deleted file mode 100644 index 5b91b4ff813..00000000000 --- a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "cirq_type": "LocalXEBPhasedFSimCalibrationOptions", - "n_library_circuits": 20, - "n_combinations": 10, - "cycle_depths": [ - 5, - 25, - 50, - 100, - 200, - 300 - ], - "fatol": 0.005, - "xatol": 0.005, - "fsim_options": { - "cirq_type": "XEBPhasedFSimCharacterizationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": true, - "characterize_gamma": true, - "characterize_phi": true, - "theta_default": 0.0, - "zeta_default": 0.0, - "chi_default": 0.0, - "gamma_default": 0.0, - "phi_default": 0.0 - }, - "n_processes": null -} \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.repr b/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.repr deleted file mode 100644 index fbf17f98696..00000000000 --- a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationOptions.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.LocalXEBPhasedFSimCalibrationOptions(n_library_circuits=20, n_combinations=10, cycle_depths=(5, 25, 50, 100, 200, 300), fatol=0.005, xatol=0.005, fsim_options=cirq.experiments.XEBPhasedFSimCharacterizationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=True, characterize_gamma=True, characterize_phi=True, theta_default=0.0, zeta_default=0.0, chi_default=0.0, gamma_default=0.0, phi_default=0.0), n_processes=None) \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.json b/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.json deleted file mode 100644 index 1a63f8f110f..00000000000 --- a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "cirq_type": "LocalXEBPhasedFSimCalibrationRequest", - "pairs": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 1, - "col": 0 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 2, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 3, - "col": 0 - } - ] - ], - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "options": { - "cirq_type": "LocalXEBPhasedFSimCalibrationOptions", - "n_library_circuits": 20, - "n_combinations": 10, - "cycle_depths": [ - 5, - 25, - 50, - 100, - 200, - 300 - ], - "fatol": 0.005, - "xatol": 0.005, - "fsim_options": { - "cirq_type": "XEBPhasedFSimCharacterizationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": true, - "characterize_gamma": true, - "characterize_phi": true, - "theta_default": 0.0, - "zeta_default": 0.0, - "chi_default": 0.0, - "gamma_default": 0.0, - "phi_default": 0.0 - }, - "n_processes": null - } -} \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.repr b/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.repr deleted file mode 100644 index 77b04424334..00000000000 --- a/cirq-google/cirq_google/json_test_data/LocalXEBPhasedFSimCalibrationRequest.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.LocalXEBPhasedFSimCalibrationRequest(pairs=((cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(2, 0), cirq.GridQubit(3, 0))), gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), options=cirq_google.LocalXEBPhasedFSimCalibrationOptions(n_library_circuits=20, n_combinations=10, cycle_depths=(5, 25, 50, 100, 200, 300), fatol=0.005, xatol=0.005, fsim_options=cirq.experiments.XEBPhasedFSimCharacterizationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=True, characterize_gamma=True, characterize_phi=True, theta_default=0.0, zeta_default=0.0, chi_default=0.0, gamma_default=0.0, phi_default=0.0), n_processes=None)) \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json b/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json deleted file mode 100644 index 58ab0ed5f5c..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "cirq_type": "PhasedFSimCalibrationResult", - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "parameters": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 1 - }, - { - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.1, - "zeta": 0.2, - "chi": null, - "gamma": null, - "phi": 0.3 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 2 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 3 - }, - { - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.4, - "zeta": 0.5, - "chi": null, - "gamma": null, - "phi": 0.6 - } - ] - ], - "options": { - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": false, - "characterize_phi": true, - "readout_error_tolerance": 0.4, - "version": 2, - "measure_qubits": null - }, - "project_id": "project_id", - "program_id": "program_id", - "job_id": "job_id" -} diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json_inward b/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json_inward deleted file mode 100644 index 5bc77fd8c02..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.json_inward +++ /dev/null @@ -1,58 +0,0 @@ -{ - "cirq_type": "PhasedFSimCalibrationResult", - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "parameters": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 1 - }, - { - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.1, - "zeta": 0.2, - "chi": null, - "gamma": null, - "phi": 0.3 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 2 - }, - { - "cirq_type": "GridQubit", - "row": 0, - "col": 3 - }, - { - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.4, - "zeta": 0.5, - "chi": null, - "gamma": null, - "phi": 0.6 - } - ] - ], - "options": { - "cirq_type": "FloquetPhasedFSimCalibrationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": false, - "characterize_gamma": false, - "characterize_phi": true - } -} diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr b/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr deleted file mode 100644 index 0de19e3e4b1..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr +++ /dev/null @@ -1,23 +0,0 @@ -cirq_google.PhasedFSimCalibrationResult( - parameters={ - (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)) : cirq_google.PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (cirq.GridQubit(0, 2), cirq.GridQubit(0, 3)): cirq_google.PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), - options=cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - readout_error_tolerance=0.4, - version=2 - ), - project_id='project_id', - program_id='program_id', - job_id='job_id', - ) diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr_inward b/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr_inward deleted file mode 100644 index bde2a913bc7..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCalibrationResult.repr_inward +++ /dev/null @@ -1,18 +0,0 @@ -cirq_google.PhasedFSimCalibrationResult( - parameters={ - (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)) : cirq_google.PhasedFSimCharacterization( - theta=0.1, zeta=0.2, chi=None, gamma=None, phi=0.3 - ), - (cirq.GridQubit(0, 2), cirq.GridQubit(0, 3)): cirq_google.PhasedFSimCharacterization( - theta=0.4, zeta=0.5, chi=None, gamma=None, phi=0.6 - ), - }, - gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), - options=cirq_google.FloquetPhasedFSimCalibrationOptions( - characterize_theta=True, - characterize_zeta=True, - characterize_chi=False, - characterize_gamma=False, - characterize_phi=True, - ), - ) diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json b/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json deleted file mode 100644 index 95751fb055b..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.1, - "zeta": 0.2, - "chi": 0.3, - "gamma": 0.4, - "phi": 0.5 -} diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json_inward b/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json_inward deleted file mode 100644 index 95751fb055b..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.json_inward +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cirq_type": "PhasedFSimCharacterization", - "theta": 0.1, - "zeta": 0.2, - "chi": 0.3, - "gamma": 0.4, - "phi": 0.5 -} diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr b/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr deleted file mode 100644 index 870df063962..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5) diff --git a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr_inward b/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr_inward deleted file mode 100644 index 870df063962..00000000000 --- a/cirq-google/cirq_google/json_test_data/PhasedFSimCharacterization.repr_inward +++ /dev/null @@ -1 +0,0 @@ -cirq_google.PhasedFSimCharacterization(theta=0.1, zeta=0.2, chi=0.3, gamma=0.4, phi=0.5) diff --git a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.json b/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.json deleted file mode 100644 index bdb9e41fc56..00000000000 --- a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "cirq_type": "XEBPhasedFSimCalibrationOptions", - "n_library_circuits": 20, - "n_combinations": 10, - "cycle_depths": [ - 5, - 25, - 50, - 100, - 200, - 300 - ], - "fatol": 0.005, - "xatol": 0.005, - "fsim_options": { - "cirq_type": "XEBPhasedFSimCharacterizationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": true, - "characterize_gamma": true, - "characterize_phi": true, - "theta_default": 0.0, - "zeta_default": 0.0, - "chi_default": 0.0, - "gamma_default": 0.0, - "phi_default": 0.0 - } -} \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.repr b/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.repr deleted file mode 100644 index 3f63fa97160..00000000000 --- a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationOptions.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.XEBPhasedFSimCalibrationOptions(n_library_circuits=20, n_combinations=10, cycle_depths=(5, 25, 50, 100, 200, 300), fatol=0.005, xatol=0.005, fsim_options=cirq.experiments.XEBPhasedFSimCharacterizationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=True, characterize_gamma=True, characterize_phi=True, theta_default=0.0, zeta_default=0.0, chi_default=0.0, gamma_default=0.0, phi_default=0.0)) \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.json b/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.json deleted file mode 100644 index f2b2055afca..00000000000 --- a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "cirq_type": "XEBPhasedFSimCalibrationRequest", - "pairs": [ - [ - { - "cirq_type": "GridQubit", - "row": 0, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 1, - "col": 0 - } - ], - [ - { - "cirq_type": "GridQubit", - "row": 2, - "col": 0 - }, - { - "cirq_type": "GridQubit", - "row": 3, - "col": 0 - } - ] - ], - "gate": { - "cirq_type": "FSimGate", - "theta": 0.7853981633974483, - "phi": 0.0 - }, - "options": { - "cirq_type": "XEBPhasedFSimCalibrationOptions", - "n_library_circuits": 20, - "n_combinations": 10, - "cycle_depths": [ - 5, - 25, - 50, - 100, - 200, - 300 - ], - "fatol": 0.005, - "xatol": 0.005, - "fsim_options": { - "cirq_type": "XEBPhasedFSimCharacterizationOptions", - "characterize_theta": true, - "characterize_zeta": true, - "characterize_chi": true, - "characterize_gamma": true, - "characterize_phi": true, - "theta_default": 0.0, - "zeta_default": 0.0, - "chi_default": 0.0, - "gamma_default": 0.0, - "phi_default": 0.0 - } - } -} \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.repr b/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.repr deleted file mode 100644 index 31a990a9fa1..00000000000 --- a/cirq-google/cirq_google/json_test_data/XEBPhasedFSimCalibrationRequest.repr +++ /dev/null @@ -1 +0,0 @@ -cirq_google.XEBPhasedFSimCalibrationRequest(pairs=((cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), (cirq.GridQubit(2, 0), cirq.GridQubit(3, 0))), gate=cirq.FSimGate(theta=0.7853981633974483, phi=0.0), options=cirq_google.XEBPhasedFSimCalibrationOptions(n_library_circuits=20, n_combinations=10, cycle_depths=(5, 25, 50, 100, 200, 300), fatol=0.005, xatol=0.005, fsim_options=cirq.experiments.XEBPhasedFSimCharacterizationOptions(characterize_theta=True, characterize_zeta=True, characterize_chi=True, characterize_gamma=True, characterize_phi=True, theta_default=0.0, zeta_default=0.0, chi_default=0.0, gamma_default=0.0, phi_default=0.0))) \ No newline at end of file diff --git a/cirq-google/cirq_google/json_test_data/spec.py b/cirq-google/cirq_google/json_test_data/spec.py index ad7b518c9fb..ba4945c6c72 100644 --- a/cirq-google/cirq_google/json_test_data/spec.py +++ b/cirq-google/cirq_google/json_test_data/spec.py @@ -9,32 +9,21 @@ name="cirq_google", packages=[cirq_google, cirq_google.experimental], test_data_path=pathlib.Path(__file__).parent, - not_yet_serializable=[ - 'Sycamore', - 'Sycamore23', - 'SQRT_ISWAP_INV_PARAMETERS', - 'ALL_ANGLES_FLOQUET_PHASED_FSIM_CHARACTERIZATION', - 'WITHOUT_CHI_FLOQUET_PHASED_FSIM_CHARACTERIZATION', - ], + not_yet_serializable=['Sycamore', 'Sycamore23'], should_not_be_serialized=[ 'AnnealSequenceSearchStrategy', 'CircuitOpDeserializer', 'CircuitOpSerializer', 'CircuitSerializer', 'CIRCUIT_SERIALIZER', - 'CircuitWithCalibration', 'Engine', 'EngineJob', 'EngineProcessor', 'EngineProgram', - 'FSimPhaseCorrections', 'NoiseModelFromGoogleNoiseProperties', 'ProtoVersion', 'GreedySequenceSearchStrategy', - 'PhasedFSimCalibrationError', - 'PhasedFSimEngineSimulator', 'PerQubitDepolarizingWithDampedReadoutNoiseModel', - 'THETA_ZETA_GAMMA_FLOQUET_PHASED_FSIM_CHARACTERIZATION', 'ProcessorSampler', 'ValidatingSampler', 'CouldNotPlaceError', From 2ca03de9d47aa427201bf8ed2d23367aaab286ee Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 12 Feb 2024 22:30:55 +0000 Subject: [PATCH 14/23] passing checks --- cirq-google/cirq_google/engine/engine_job.py | 1 + .../cirq_google/engine/engine_processor_test.py:20 | 14 -------------- cirq-google/cirq_google/engine/engine_program.py | 6 ++++-- .../cirq_google/engine/engine_program_test.py | 1 - .../cirq_google/engine/processor_sampler_test.py | 1 - 5 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 cirq-google/cirq_google/engine/engine_processor_test.py:20 diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index c64481fc51a..96e34742c41 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """A helper for jobs that have been created on the Quantum Engine.""" +import datetime from typing import Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union import duet diff --git a/cirq-google/cirq_google/engine/engine_processor_test.py:20 b/cirq-google/cirq_google/engine/engine_processor_test.py:20 deleted file mode 100644 index 18b3ef417aa..00000000000 --- a/cirq-google/cirq_google/engine/engine_processor_test.py:20 +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2024 smeeks -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. - diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index d5a592b51de..047829231f2 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -402,8 +402,10 @@ async def batch_size_async(self) -> int: self.project_id, self.program_id, True ) code = self._program.code - code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] - raise ValueError(f'Program was not a batch program but instead was of type {code_type}.') + code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] # pragma: no cover + raise ValueError( + f'Program was not a batch program but instead was of type {code_type}.' + ) # pragma: no cover batch_size = duet.sync(batch_size_async) diff --git a/cirq-google/cirq_google/engine/engine_program_test.py b/cirq-google/cirq_google/engine/engine_program_test.py index 785abdca2e3..226afc85193 100644 --- a/cirq-google/cirq_google/engine/engine_program_test.py +++ b/cirq-google/cirq_google/engine/engine_program_test.py @@ -26,7 +26,6 @@ from cirq_google.engine import util from cirq_google.cloud import quantum from cirq_google.engine.engine import EngineContext -from cirq_google.engine.result_type import ResultType _PROGRAM_V2 = util.pack_any( diff --git a/cirq-google/cirq_google/engine/processor_sampler_test.py b/cirq-google/cirq_google/engine/processor_sampler_test.py index d7f8232e786..ce482823664 100644 --- a/cirq-google/cirq_google/engine/processor_sampler_test.py +++ b/cirq-google/cirq_google/engine/processor_sampler_test.py @@ -155,7 +155,6 @@ def test_run_batch_differing_repetitions(): run_name=run_name, device_config_name=device_config_name, ) - processor.run_batch_async.assert_not_called() def test_processor_sampler_processor_property(): From 13805dd18a0c4f8237dff4360c1807ec5111f3ad Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 12 Feb 2024 22:51:55 +0000 Subject: [PATCH 15/23] ubuntu tests pass --- cirq-google/cirq_google/engine/engine_job.py | 4 ++-- cirq-google/cirq_google/engine/engine_program.py | 2 +- cirq-google/cirq_google/engine/virtual_engine_factory_test.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index 96e34742c41..48153c5f2ff 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -130,11 +130,11 @@ async def _refresh_job_async(self) -> quantum.QuantumJob: _refresh_job = duet.sync(_refresh_job_async) - def create_time(self) -> 'datetime.datetime': + def create_time(self) -> datetime.datetime: """Returns when the job was created.""" return self._inner_job().create_time - def update_time(self) -> 'datetime.datetime': + def update_time(self) -> datetime.datetime: """Returns when the job was last updated.""" job = self._refresh_job() return job.update_time diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index 047829231f2..a39dbb6ec10 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -404,7 +404,7 @@ async def batch_size_async(self) -> int: code = self._program.code code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] # pragma: no cover raise ValueError( - f'Program was not a batch program but instead was of type {code_type}.' + f'Program was not a batch program but instead was of type {code_type}.' # pragma: no cover ) # pragma: no cover batch_size = duet.sync(batch_size_async) diff --git a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py index e0e6c3053aa..63d9aa7824f 100644 --- a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py +++ b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py @@ -36,7 +36,7 @@ def _test_processor(processor: cg.engine.abstract_processor.AbstractProcessor): with pytest.raises(ValueError, match='Qubit not on device'): _ = processor.run(circuit, repetitions=100) circuit = cirq.Circuit(cirq.H(good_qubit), cirq.measure(good_qubit)) - with pytest.raises(ValueError, match='Cannot serialize op'): + with pytest.raises(ValueError, match='gate which is not supported'): _ = processor.run(circuit, repetitions=100) From a1fbdae243354f73d4635b742c322e9e7eacfca7 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Mon, 12 Feb 2024 23:17:44 +0000 Subject: [PATCH 16/23] lint --- cirq-google/cirq_google/engine/engine_program.py | 4 ++-- cirq-google/cirq_google/engine/virtual_engine_factory_test.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index a39dbb6ec10..f6317583816 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -403,8 +403,8 @@ async def batch_size_async(self) -> int: ) code = self._program.code code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] # pragma: no cover - raise ValueError( - f'Program was not a batch program but instead was of type {code_type}.' # pragma: no cover + raise ValueError( # pragma: no cover + f'Program was not a batch program but instead was of type {code_type}.' ) # pragma: no cover batch_size = duet.sync(batch_size_async) diff --git a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py index 63d9aa7824f..b52a49cac57 100644 --- a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py +++ b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py @@ -122,7 +122,6 @@ def test_device_zphase_bad_processor(): def test_create_from_proto(): - # Create a minimal gate specification that can handle the test. device_spec = text_format.Merge( """ From 02da8a49fb1ec2c778589267c3a1b9fcf5234f11 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 15 Feb 2024 17:38:40 +0000 Subject: [PATCH 17/23] coverage pass --- cirq-google/cirq_google/engine/engine_program.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index f6317583816..7b9b4d430a4 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -404,7 +404,8 @@ async def batch_size_async(self) -> int: code = self._program.code code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] # pragma: no cover raise ValueError( # pragma: no cover - f'Program was not a batch program but instead was of type {code_type}.' + 'Program was not a batch program but' # pragma: no cover + + f'instead was of type {code_type}.' # pragma: no cover ) # pragma: no cover batch_size = duet.sync(batch_size_async) From 22554c87b0db9ca0f33b011dbc822a235c51b64a Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 15 Feb 2024 19:30:58 +0000 Subject: [PATCH 18/23] save --- cirq-google/cirq_google/engine/calibration_result.py | 5 ++++- cirq-google/cirq_google/json_resolver_cache.py | 1 - .../cirq_google/json_test_data/CalibrationResult.json | 1 + .../cirq_google/json_test_data/CalibrationResult.json_inward | 1 + .../cirq_google/json_test_data/CalibrationResult.repr | 1 + .../cirq_google/json_test_data/CalibrationResult.repr_inward | 1 + cirq-google/cirq_google/json_test_data/spec.py | 1 + 7 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cirq-google/cirq_google/engine/calibration_result.py b/cirq-google/cirq_google/engine/calibration_result.py index fb1d0e0c17c..030e9faa9ce 100644 --- a/cirq-google/cirq_google/engine/calibration_result.py +++ b/cirq-google/cirq_google/engine/calibration_result.py @@ -32,6 +32,7 @@ class CalibrationResult: These defaults will converted to `None` by the API client. """ + code: Any error_message: Optional[str] token: Optional[str] valid_until: Optional[datetime.datetime] @@ -40,6 +41,7 @@ class CalibrationResult: @classmethod def _from_json_dict_( cls, + code: Any, error_message: Optional[str], token: Optional[str], utc_valid_until: float, @@ -52,7 +54,7 @@ def _from_json_dict_( if utc_valid_until is not None else None ) - return cls(error_message, token, valid_until, metrics) + return cls(code, error_message, token, valid_until, metrics) def _json_dict_(self) -> Dict[str, Any]: """Magic method for the JSON serialization protocol.""" @@ -62,6 +64,7 @@ def _json_dict_(self) -> Dict[str, Any]: else None ) return { + 'code': self.code, 'error_message': self.error_message, 'token': self.token, 'utc_valid_until': utc_valid_until, diff --git a/cirq-google/cirq_google/json_resolver_cache.py b/cirq-google/cirq_google/json_resolver_cache.py index 8dc5d0967f3..068c43be046 100644 --- a/cirq-google/cirq_google/json_resolver_cache.py +++ b/cirq-google/cirq_google/json_resolver_cache.py @@ -43,7 +43,6 @@ def _old_xmon(*args, **kwargs): 'Calibration': cirq_google.Calibration, 'CalibrationTag': cirq_google.CalibrationTag, 'CalibrationLayer': cirq_google.CalibrationLayer, - 'CalibrationResult': cirq_google.CalibrationResult, 'CouplerPulse': cirq_google.experimental.CouplerPulse, 'GoogleNoiseProperties': cirq_google.GoogleNoiseProperties, 'SycamoreGate': cirq_google.SycamoreGate, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json b/cirq-google/cirq_google/json_test_data/CalibrationResult.json index 8baa07e7a18..a7f0144793d 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.json @@ -1,5 +1,6 @@ { "cirq_type": "CalibrationResult", + "code": 1, "error_message": "a", "token": "b", "utc_valid_until": 1606319984.041021, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward index 8baa07e7a18..a7f0144793d 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward @@ -1,5 +1,6 @@ { "cirq_type": "CalibrationResult", + "code": 1, "error_message": "a", "token": "b", "utc_valid_until": 1606319984.041021, diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr index ea938a3ecee..c6930dc4504 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr @@ -1,4 +1,5 @@ cirq_google.CalibrationResult( + code=1, error_message='a', token='b', valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward index ea938a3ecee..c6930dc4504 100644 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward +++ b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward @@ -1,4 +1,5 @@ cirq_google.CalibrationResult( + code=1, error_message='a', token='b', valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), diff --git a/cirq-google/cirq_google/json_test_data/spec.py b/cirq-google/cirq_google/json_test_data/spec.py index ba4945c6c72..edaf5c48358 100644 --- a/cirq-google/cirq_google/json_test_data/spec.py +++ b/cirq-google/cirq_google/json_test_data/spec.py @@ -27,6 +27,7 @@ 'ProcessorSampler', 'ValidatingSampler', 'CouldNotPlaceError', + 'CalibrationResult', # Abstract: 'ExecutableSpec', ], From bdb55b3e88f1d5b96a61efd4a461996609ef2460 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Thu, 15 Feb 2024 19:32:30 +0000 Subject: [PATCH 19/23] rm CalibrationResult test data --- .../json_test_data/CalibrationResult.json | 79 ------------------- .../CalibrationResult.json_inward | 79 ------------------- .../json_test_data/CalibrationResult.repr | 18 ----- .../CalibrationResult.repr_inward | 18 ----- 4 files changed, 194 deletions(-) delete mode 100644 cirq-google/cirq_google/json_test_data/CalibrationResult.json delete mode 100644 cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward delete mode 100644 cirq-google/cirq_google/json_test_data/CalibrationResult.repr delete mode 100644 cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json b/cirq-google/cirq_google/json_test_data/CalibrationResult.json deleted file mode 100644 index a7f0144793d..00000000000 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "cirq_type": "CalibrationResult", - "code": 1, - "error_message": "a", - "token": "b", - "utc_valid_until": 1606319984.041021, - "metrics": { - "cirq_type": "Calibration", - "metrics": { - "metrics": [ - { - "name": "xeb", - "targets": [ - "0_0", - "0_1" - ], - "values": [ - { - "doubleVal": 0.9999 - } - ] - }, - { - "name": "xeb", - "targets": [ - "0_0", - "1_0" - ], - "values": [ - { - "doubleVal": 0.9998 - } - ] - }, - { - "name": "t1", - "targets": [ - "0_0" - ], - "values": [ - { - "int64Val": "321" - } - ] - }, - { - "name": "t1", - "targets": [ - "0_1" - ], - "values": [ - { - "int64Val": "911" - } - ] - }, - { - "name": "t1", - "targets": [ - "1_0" - ], - "values": [ - { - "int64Val": "505" - } - ] - }, - { - "name": "globalMetric", - "values": [ - { - "strVal": "abcd" - } - ] - } - ] - } - } -} diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward deleted file mode 100644 index a7f0144793d..00000000000 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.json_inward +++ /dev/null @@ -1,79 +0,0 @@ -{ - "cirq_type": "CalibrationResult", - "code": 1, - "error_message": "a", - "token": "b", - "utc_valid_until": 1606319984.041021, - "metrics": { - "cirq_type": "Calibration", - "metrics": { - "metrics": [ - { - "name": "xeb", - "targets": [ - "0_0", - "0_1" - ], - "values": [ - { - "doubleVal": 0.9999 - } - ] - }, - { - "name": "xeb", - "targets": [ - "0_0", - "1_0" - ], - "values": [ - { - "doubleVal": 0.9998 - } - ] - }, - { - "name": "t1", - "targets": [ - "0_0" - ], - "values": [ - { - "int64Val": "321" - } - ] - }, - { - "name": "t1", - "targets": [ - "0_1" - ], - "values": [ - { - "int64Val": "911" - } - ] - }, - { - "name": "t1", - "targets": [ - "1_0" - ], - "values": [ - { - "int64Val": "505" - } - ] - }, - { - "name": "globalMetric", - "values": [ - { - "strVal": "abcd" - } - ] - } - ] - } - } -} diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr deleted file mode 100644 index c6930dc4504..00000000000 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr +++ /dev/null @@ -1,18 +0,0 @@ -cirq_google.CalibrationResult( - code=1, - error_message='a', - token='b', - valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), - metrics=cirq_google.Calibration( - metrics={ - 'xeb': { - (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)): [0.9999], - (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)): [0.9998]}, - 't1': { - (cirq.GridQubit(0, 0),): [321], - (cirq.GridQubit(0, 1),): [911], - (cirq.GridQubit(1, 0),): [505]}, - 'globalMetric': {(): ['abcd']} - } - ) -) diff --git a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward b/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward deleted file mode 100644 index c6930dc4504..00000000000 --- a/cirq-google/cirq_google/json_test_data/CalibrationResult.repr_inward +++ /dev/null @@ -1,18 +0,0 @@ -cirq_google.CalibrationResult( - code=1, - error_message='a', - token='b', - valid_until=datetime.datetime(2020, 11, 25, 15, 59, 44, 41021), - metrics=cirq_google.Calibration( - metrics={ - 'xeb': { - (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)): [0.9999], - (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)): [0.9998]}, - 't1': { - (cirq.GridQubit(0, 0),): [321], - (cirq.GridQubit(0, 1),): [911], - (cirq.GridQubit(1, 0),): [505]}, - 'globalMetric': {(): ['abcd']} - } - ) -) From 578e01ed053b91aa15b04bea1ffa4369650d1571 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 16 Feb 2024 18:40:44 +0000 Subject: [PATCH 20/23] address all comments --- .../cirq_google/engine/calibration_result.py | 2 ++ cirq-google/cirq_google/engine/engine_job.py | 4 --- .../cirq_google/engine/engine_program.py | 32 +++---------------- .../cirq_google/engine/engine_validator.py | 11 +++++-- cirq-google/cirq_google/engine/result_type.py | 32 ------------------- .../engine/virtual_engine_factory_test.py | 2 +- 6 files changed, 15 insertions(+), 68 deletions(-) delete mode 100644 cirq-google/cirq_google/engine/result_type.py diff --git a/cirq-google/cirq_google/engine/calibration_result.py b/cirq-google/cirq_google/engine/calibration_result.py index 030e9faa9ce..8d69feda341 100644 --- a/cirq-google/cirq_google/engine/calibration_result.py +++ b/cirq-google/cirq_google/engine/calibration_result.py @@ -30,6 +30,8 @@ class CalibrationResult: they will be set to the default values in the proto, as defined here: https://developers.google.com/protocol-buffers/docs/proto3#default These defaults will converted to `None` by the API client. + + Deprecated: Calibrations are no longer supported via cirq. """ code: Any diff --git a/cirq-google/cirq_google/engine/engine_job.py b/cirq-google/cirq_google/engine/engine_job.py index 48153c5f2ff..929ea7c344f 100644 --- a/cirq-google/cirq_google/engine/engine_job.py +++ b/cirq-google/cirq_google/engine/engine_job.py @@ -22,7 +22,6 @@ from cirq_google.engine import abstract_job, calibration, engine_client from cirq_google.engine.calibration_result import CalibrationResult from cirq_google.cloud import quantum -from cirq_google.engine.result_type import ResultType from cirq_google.engine.engine_result import EngineResult from cirq_google.api import v1, v2 @@ -66,7 +65,6 @@ def __init__( job_id: str, context: 'engine_base.EngineContext', _job: Optional[quantum.QuantumJob] = None, - result_type: ResultType = ResultType.Program, job_result_future: Optional[ duet.AwaitableFuture[Union[quantum.QuantumResult, quantum.QuantumJob]] ] = None, @@ -79,7 +77,6 @@ def __init__( job_id: Unique ID of the job within the parent program. context: Engine configuration and context to use. _job: The optional current job state. - result_type: What type of results are expected. job_result_future: A future to be completed when the job result is available. If set, EngineJob will await this future when a caller asks for the job result. If the future is completed with a `QuantumJob`, it is assumed that the job has failed. @@ -92,7 +89,6 @@ def __init__( self._results: Optional[Sequence[EngineResult]] = None self._calibration_results: Optional[Sequence[CalibrationResult]] = None self._batched_results: Optional[Sequence[Sequence[EngineResult]]] = None - self.result_type = result_type self._job_result_future = job_result_future def id(self) -> str: diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index 7b9b4d430a4..aacb56660e4 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -21,7 +21,6 @@ import cirq from cirq_google.engine import abstract_program, engine_client from cirq_google.cloud import quantum -from cirq_google.engine.result_type import ResultType from cirq_google.api import v2 from cirq_google.engine import engine_job from cirq_google.serialization import circuit_serializer @@ -47,7 +46,6 @@ def __init__( program_id: str, context: 'engine_base.EngineContext', _program: Optional[quantum.QuantumProgram] = None, - result_type: ResultType = ResultType.Program, ) -> None: """A job submitted to the engine. @@ -56,13 +54,11 @@ def __init__( program_id: Unique ID of the program within the parent project. context: Engine configuration and context to use. _program: The optional current program state. - result_type: The type of program that was created. """ self.project_id = project_id self.program_id = program_id self.context = context self._program = _program - self.result_type = result_type # TODO(#6271): Deprecate and remove processor_ids before v1.4 async def run_sweep_async( @@ -365,15 +361,10 @@ async def remove_labels_async(self, keys: List[str]) -> 'EngineProgram': remove_labels = duet.sync(remove_labels_async) - async def get_circuit_async(self, program_num: Optional[int] = None) -> cirq.Circuit: + async def get_circuit_async(self) -> cirq.Circuit: """Returns the cirq Circuit for the Quantum Engine program. This is only supported if the program was created with the V2 protos. - Args: - program_num: - The program number to retrieve. This argument is zero-indexed. Negative values - indexing from the end of the list. - Returns: The program's cirq Circuit. """ @@ -381,7 +372,7 @@ async def get_circuit_async(self, program_num: Optional[int] = None) -> cirq.Cir self._program = await self.context.client.get_program_async( self.project_id, self.program_id, True ) - return _deserialize_program(self._program.code, program_num) + return _deserialize_program(self._program.code) get_circuit = duet.sync(get_circuit_async) @@ -391,22 +382,7 @@ async def batch_size_async(self) -> int: Raises: ValueError: if the program created was not a batch program. """ - if self.result_type != ResultType.Batch: - raise ValueError( - f'Program was not a batch program but instead was of type {self.result_type}.' - ) - import cirq_google.engine.engine as engine_base - - if self._program is None or self._program.code is None: - self._program = await self.context.client.get_program_async( - self.project_id, self.program_id, True - ) - code = self._program.code - code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] # pragma: no cover - raise ValueError( # pragma: no cover - 'Program was not a batch program but' # pragma: no cover - + f'instead was of type {code_type}.' # pragma: no cover - ) # pragma: no cover + raise NotImplementedError("Batch programs are no longer supported.") batch_size = duet.sync(batch_size_async) @@ -433,7 +409,7 @@ def __str__(self) -> str: return f'EngineProgram(project_id=\'{self.project_id}\', program_id=\'{self.program_id}\')' -def _deserialize_program(code: any_pb2.Any, program_num: Optional[int] = None) -> cirq.Circuit: +def _deserialize_program(code: any_pb2.Any) -> cirq.Circuit: import cirq_google.engine.engine as engine_base code_type = code.type_url[len(engine_base.TYPE_PREFIX) :] diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index 2d507edff12..aea24a7c6b7 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Callable, Sequence, Union +from google.protobuf import any_pb2 import cirq from cirq_google.engine.validating_sampler import VALIDATOR_TYPE @@ -84,6 +85,11 @@ def validate_program( Raises: RuntimeError: if compiled proto is above the maximum size. """ + packed = any_pb2.Any() + packed.Pack(serializer.serialize(circuits[0])) + message_size = len(packed.SerializeToString()) + if message_size > max_size: + raise RuntimeError("INVALID_PROGRAM: Program too long.") def create_program_validator(max_size: int = MAX_MESSAGE_SIZE) -> PROGRAM_VALIDATOR_TYPE: @@ -118,14 +124,13 @@ def validate_for_engine( Args: circuits: A sequence of `cirq.Circuit` objects to validate. For - sweeps and runs, this will be a single circuit. For batches, - this will be a list of circuits. + sweeps and runs, this will be a single circuit. sweeps: Parameters to run with each circuit. The length of the sweeps sequence should be the same as the circuits argument. repetitions: Number of repetitions to run with each sweep. max_moments: Maximum number of moments to allow. max_repetitions: Maximum number of parameter sweep values allowed - when summed across all sweeps and all batches. + when summed across all sweeps. max_duration_ns: Maximum duration of the circuit, in nanoseconds. """ _verify_reps(sweeps, repetitions, max_repetitions) diff --git a/cirq-google/cirq_google/engine/result_type.py b/cirq-google/cirq_google/engine/result_type.py deleted file mode 100644 index 3b564c00520..00000000000 --- a/cirq-google/cirq_google/engine/result_type.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2020 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -import enum - - -class ResultType(enum.Enum): - """Expected type of the results from a engine job call. - - Since programs have an embedded Any field, different types - of data can be passed into a program/job for execution. - This enum tracks the type of data that was passed in during - the initial call so that the results can be handled appropriately. - - Program: A single circuit with a single TrialResult. - Batch: A list of circuits with a list of TrialResults in a BatchResult. - Calibration: List of CalibrationLayers returning a list of CalibrationResult - """ - - Program = 1 - Batch = 2 - Calibration = 3 diff --git a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py index b52a49cac57..66c536c2e35 100644 --- a/cirq-google/cirq_google/engine/virtual_engine_factory_test.py +++ b/cirq-google/cirq_google/engine/virtual_engine_factory_test.py @@ -36,7 +36,7 @@ def _test_processor(processor: cg.engine.abstract_processor.AbstractProcessor): with pytest.raises(ValueError, match='Qubit not on device'): _ = processor.run(circuit, repetitions=100) circuit = cirq.Circuit(cirq.H(good_qubit), cirq.measure(good_qubit)) - with pytest.raises(ValueError, match='gate which is not supported'): + with pytest.raises(ValueError, match='Cannot serialize op'): _ = processor.run(circuit, repetitions=100) From f34957a92f927aa5352ba9c989eb09cbd129326a Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 16 Feb 2024 21:56:25 +0000 Subject: [PATCH 21/23] lint --- cirq-google/cirq_google/engine/abstract_program.py | 7 +------ cirq-google/cirq_google/engine/engine_program.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/cirq-google/cirq_google/engine/abstract_program.py b/cirq-google/cirq_google/engine/abstract_program.py index 834c591af22..217c80993e4 100644 --- a/cirq-google/cirq_google/engine/abstract_program.py +++ b/cirq-google/cirq_google/engine/abstract_program.py @@ -155,15 +155,10 @@ def remove_labels(self, keys: List[str]) -> 'AbstractProgram': """ @abc.abstractmethod - def get_circuit(self, program_num: Optional[int] = None) -> cirq.Circuit: + def get_circuit(self) -> cirq.Circuit: """Returns the cirq Circuit for the program. This is only supported if the program was created with the V2 protos. - Args: - program_num: if this is a batch program, the index of the circuit in - the batch. This argument is zero-indexed. Negative values - indexing from the end of the list. - Returns: The program's cirq Circuit. """ diff --git a/cirq-google/cirq_google/engine/engine_program.py b/cirq-google/cirq_google/engine/engine_program.py index aacb56660e4..f0f61340b86 100644 --- a/cirq-google/cirq_google/engine/engine_program.py +++ b/cirq-google/cirq_google/engine/engine_program.py @@ -382,7 +382,7 @@ async def batch_size_async(self) -> int: Raises: ValueError: if the program created was not a batch program. """ - raise NotImplementedError("Batch programs are no longer supported.") + raise NotImplementedError("Batch programs are no longer supported.") # pragma: no cover batch_size = duet.sync(batch_size_async) From 21ebf3538a03e7301f1cc01a7b235e73cccbb6ff Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Fri, 16 Feb 2024 23:18:48 +0000 Subject: [PATCH 22/23] add todo --- cirq-google/cirq_google/engine/engine_validator.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index aea24a7c6b7..dde106c2982 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -65,6 +65,8 @@ def _verify_measurements(circuits): raise RuntimeError('Code must measure at least one qubit.') +# TODO: update validate methods to accept a `cirq.AbstractCircuit`` +# instead of a `Sequence` since batching is no longer supported. def validate_program( circuits: Sequence[cirq.AbstractCircuit], sweeps: Sequence[cirq.Sweepable], From a2f8c74eb41f31d6dabbd4388dbc0ec43a3b17a5 Mon Sep 17 00:00:00 2001 From: Seneca Meeks Date: Wed, 21 Feb 2024 19:45:43 +0000 Subject: [PATCH 23/23] add tracking bug --- cirq-google/cirq_google/engine/engine_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq-google/cirq_google/engine/engine_validator.py b/cirq-google/cirq_google/engine/engine_validator.py index dde106c2982..edab2a26c54 100644 --- a/cirq-google/cirq_google/engine/engine_validator.py +++ b/cirq-google/cirq_google/engine/engine_validator.py @@ -65,7 +65,7 @@ def _verify_measurements(circuits): raise RuntimeError('Code must measure at least one qubit.') -# TODO: update validate methods to accept a `cirq.AbstractCircuit`` +# TODO(b/326267074): update validate methods to accept a `cirq.AbstractCircuit`` # instead of a `Sequence` since batching is no longer supported. def validate_program( circuits: Sequence[cirq.AbstractCircuit],