1# Copyright 2019 The Cirq Developers 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Common Serializers that can be used by APIs. 15 16This file contains the following serializers (and corresponding deserializers) 17 18 - SINGLE_QUBIT_SERIALIZERS: A list of GateOpSerializer for single qubit 19 rotations using cirq Gates. 20 - MEASUREMENT_SERIALIZER: Single GateOpSerializer for the measurement gate 21 - SINGLE_QUBIT_SERIALIZERS: A list of GateOpSerializer for single qubit 22 rotations confined to half-pi increments using cirq Gates. 23 24""" 25from typing import cast, List, Union 26 27import numpy as np 28import sympy 29 30import cirq 31from cirq_google.api import v2 32from cirq_google.experimental.ops import CouplerPulse 33from cirq_google.ops import PhysicalZTag 34from cirq_google.serialization import op_deserializer, op_serializer 35 36# Type strings used in serialization for the two types of Z operations 37PHYSICAL_Z = 'physical' 38VIRTUAL_Z = 'virtual_propagates_forward' 39 40# Strings used for phase matching args 41PHASE_MATCH_PHYS_Z = 'phys_z' 42 43 44# Default tolerance for differences in floating point 45# Note that Google protocol buffers use floats 46# which trigger a conversion from double precision to single precision 47# This results in errors possibly up to 1e-6 48# (23 bits for mantissa in single precision) 49_DEFAULT_ATOL = 1e-6 50 51 52def _near_mod_n(e, t, n, atol=_DEFAULT_ATOL): 53 """Returns whether a value, e, translated by t, is equal to 0 mod n.""" 54 if isinstance(e, sympy.Symbol): 55 return False 56 return abs((e - t + 1) % n - 1) <= atol 57 58 59def _near_mod_2pi(e, t, atol=_DEFAULT_ATOL): 60 """Returns whether a value, e, translated by t, is equal to 0 mod 2 * pi.""" 61 return _near_mod_n(e, t, n=2 * np.pi, atol=atol) 62 63 64def _near_mod_2(e, t, atol=_DEFAULT_ATOL): 65 """Returns whether a value, e, translated by t, is equal to 0 mod 2.""" 66 return _near_mod_n(e, t, n=2, atol=atol) 67 68 69def _convert_physical_z(op: cirq.Operation, proto: v2.program_pb2.Operation): 70 if 'type' in proto.args: 71 if proto.args['type'].arg_value.string_value == PHYSICAL_Z: 72 return op.with_tags(PhysicalZTag()) 73 return op 74 75 76############################################# 77# 78# Single qubit serializers and deserializers 79# 80############################################# 81 82# 83# Single qubit serializers for arbitrary rotations 84# 85SINGLE_QUBIT_SERIALIZERS = [ 86 op_serializer.GateOpSerializer( 87 gate_type=cirq.PhasedXPowGate, 88 serialized_gate_id='xy', 89 args=[ 90 op_serializer.SerializingArg( 91 serialized_name='axis_half_turns', 92 serialized_type=float, 93 op_getter='phase_exponent', 94 ), 95 op_serializer.SerializingArg( 96 serialized_name='half_turns', 97 serialized_type=float, 98 op_getter='exponent', 99 ), 100 ], 101 ), 102 op_serializer.GateOpSerializer( 103 gate_type=cirq.XPowGate, 104 serialized_gate_id='xy', 105 args=[ 106 op_serializer.SerializingArg( 107 serialized_name='axis_half_turns', 108 serialized_type=float, 109 op_getter=lambda op: 0.0, 110 ), 111 op_serializer.SerializingArg( 112 serialized_name='half_turns', 113 serialized_type=float, 114 op_getter='exponent', 115 ), 116 ], 117 ), 118 op_serializer.GateOpSerializer( 119 gate_type=cirq.YPowGate, 120 serialized_gate_id='xy', 121 args=[ 122 op_serializer.SerializingArg( 123 serialized_name='axis_half_turns', 124 serialized_type=float, 125 op_getter=lambda op: 0.5, 126 ), 127 op_serializer.SerializingArg( 128 serialized_name='half_turns', 129 serialized_type=float, 130 op_getter='exponent', 131 ), 132 ], 133 ), 134 op_serializer.GateOpSerializer( 135 gate_type=cirq.ZPowGate, 136 serialized_gate_id='z', 137 args=[ 138 op_serializer.SerializingArg( 139 serialized_name='half_turns', 140 serialized_type=float, 141 op_getter='exponent', 142 ), 143 op_serializer.SerializingArg( 144 serialized_name='type', 145 serialized_type=str, 146 op_getter=lambda op: PHYSICAL_Z if PhysicalZTag() in op.tags else VIRTUAL_Z, 147 ), 148 ], 149 ), 150 op_serializer.GateOpSerializer( 151 gate_type=cirq.PhasedXZGate, 152 serialized_gate_id='xyz', 153 args=[ 154 op_serializer.SerializingArg( 155 serialized_name='x_exponent', 156 serialized_type=float, 157 op_getter='x_exponent', 158 ), 159 op_serializer.SerializingArg( 160 serialized_name='z_exponent', 161 serialized_type=float, 162 op_getter='z_exponent', 163 ), 164 op_serializer.SerializingArg( 165 serialized_name='axis_phase_exponent', 166 serialized_type=float, 167 op_getter='axis_phase_exponent', 168 ), 169 ], 170 ), 171] 172 173# 174# Single qubit deserializers for arbitrary rotations 175# 176SINGLE_QUBIT_DESERIALIZERS = [ 177 op_deserializer.GateOpDeserializer( 178 serialized_gate_id='xy', 179 gate_constructor=cirq.PhasedXPowGate, 180 args=[ 181 op_deserializer.DeserializingArg( 182 serialized_name='axis_half_turns', 183 constructor_arg_name='phase_exponent', 184 default=0.0, 185 ), 186 op_deserializer.DeserializingArg( 187 serialized_name='half_turns', 188 constructor_arg_name='exponent', 189 default=1.0, 190 ), 191 ], 192 ), 193 op_deserializer.GateOpDeserializer( 194 serialized_gate_id='z', 195 gate_constructor=cirq.ZPowGate, 196 args=[ 197 op_deserializer.DeserializingArg( 198 serialized_name='half_turns', 199 constructor_arg_name='exponent', 200 default=1.0, 201 ), 202 ], 203 op_wrapper=lambda op, proto: _convert_physical_z(op, proto), 204 ), 205 op_deserializer.GateOpDeserializer( 206 serialized_gate_id='xyz', 207 gate_constructor=cirq.PhasedXZGate, 208 args=[ 209 op_deserializer.DeserializingArg( 210 serialized_name='x_exponent', 211 constructor_arg_name='x_exponent', 212 default=0.0, 213 ), 214 op_deserializer.DeserializingArg( 215 serialized_name='z_exponent', 216 constructor_arg_name='z_exponent', 217 default=0.0, 218 ), 219 op_deserializer.DeserializingArg( 220 serialized_name='axis_phase_exponent', 221 constructor_arg_name='axis_phase_exponent', 222 default=0.0, 223 ), 224 ], 225 ), 226] 227 228 229# 230# Measurement Serializer and Deserializer 231# 232MEASUREMENT_SERIALIZER = op_serializer.GateOpSerializer( 233 gate_type=cirq.MeasurementGate, 234 serialized_gate_id='meas', 235 args=[ 236 op_serializer.SerializingArg( 237 serialized_name='key', serialized_type=str, op_getter=cirq.measurement_key_name 238 ), 239 op_serializer.SerializingArg( 240 serialized_name='invert_mask', serialized_type=List[bool], op_getter='invert_mask' 241 ), 242 ], 243) 244MEASUREMENT_DESERIALIZER = op_deserializer.GateOpDeserializer( 245 serialized_gate_id='meas', 246 gate_constructor=cirq.MeasurementGate, 247 args=[ 248 op_deserializer.DeserializingArg(serialized_name='key', constructor_arg_name='key'), 249 op_deserializer.DeserializingArg( 250 serialized_name='invert_mask', 251 constructor_arg_name='invert_mask', 252 value_func=lambda x: tuple(cast(list, x)), 253 ), 254 ], 255 num_qubits_param='num_qubits', 256) 257 258 259# 260# Serializers for single qubit rotations confined to half-pi increments 261# 262SINGLE_QUBIT_HALF_PI_SERIALIZERS = [ 263 op_serializer.GateOpSerializer( 264 gate_type=cirq.PhasedXPowGate, 265 serialized_gate_id='xy_pi', 266 args=[ 267 op_serializer.SerializingArg( 268 serialized_name='axis_half_turns', serialized_type=float, op_getter='phase_exponent' 269 ), 270 ], 271 can_serialize_predicate=lambda op: _near_mod_2( 272 cast(cirq.PhasedXPowGate, op.gate).exponent, 1 273 ), 274 ), 275 op_serializer.GateOpSerializer( 276 gate_type=cirq.XPowGate, 277 serialized_gate_id='xy_pi', 278 args=[ 279 op_serializer.SerializingArg( 280 serialized_name='axis_half_turns', 281 serialized_type=float, 282 op_getter=lambda op: (cast(cirq.XPowGate, op.gate).exponent - 1) / 2, 283 ) 284 ], 285 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.XPowGate, op.gate).exponent, 1), 286 ), 287 op_serializer.GateOpSerializer( 288 gate_type=cirq.YPowGate, 289 serialized_gate_id='xy_pi', 290 args=[ 291 op_serializer.SerializingArg( 292 serialized_name='axis_half_turns', 293 serialized_type=float, 294 op_getter=lambda op: cast(cirq.YPowGate, op.gate).exponent / 2, 295 ) 296 ], 297 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.YPowGate, op.gate).exponent, 1), 298 ), 299 op_serializer.GateOpSerializer( 300 gate_type=cirq.XPowGate, 301 serialized_gate_id='xy_half_pi', 302 args=[ 303 op_serializer.SerializingArg( 304 serialized_name='axis_half_turns', 305 serialized_type=float, 306 op_getter=lambda op: cast(cirq.XPowGate, op.gate).exponent - 0.5, 307 ) 308 ], 309 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.XPowGate, op.gate).exponent, 0.5), 310 ), 311 op_serializer.GateOpSerializer( 312 gate_type=cirq.YPowGate, 313 serialized_gate_id='xy_half_pi', 314 args=[ 315 op_serializer.SerializingArg( 316 serialized_name='axis_half_turns', 317 serialized_type=float, 318 op_getter=lambda op: cast(cirq.YPowGate, op.gate).exponent, 319 ) 320 ], 321 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.YPowGate, op.gate).exponent, 0.5), 322 ), 323 op_serializer.GateOpSerializer( 324 gate_type=cirq.PhasedXPowGate, 325 serialized_gate_id='xy_half_pi', 326 args=[ 327 op_serializer.SerializingArg( 328 serialized_name='axis_half_turns', serialized_type=float, op_getter='phase_exponent' 329 ), 330 ], 331 can_serialize_predicate=lambda op: _near_mod_2( 332 cast(cirq.PhasedXPowGate, op.gate).exponent, 0.5 333 ), 334 ), 335] 336 337# 338# Deserializers for single qubit rotations confined to half-pi increments 339# 340SINGLE_QUBIT_HALF_PI_DESERIALIZERS = [ 341 op_deserializer.GateOpDeserializer( 342 serialized_gate_id='xy_pi', 343 gate_constructor=cirq.PhasedXPowGate, 344 args=[ 345 op_deserializer.DeserializingArg( 346 serialized_name='axis_half_turns', 347 constructor_arg_name='phase_exponent', 348 ), 349 op_deserializer.DeserializingArg( 350 serialized_name='axis_half_turns', 351 constructor_arg_name='exponent', 352 value_func=lambda _: 1, 353 ), 354 ], 355 ), 356 op_deserializer.GateOpDeserializer( 357 serialized_gate_id='xy_half_pi', 358 gate_constructor=cirq.PhasedXPowGate, 359 args=[ 360 op_deserializer.DeserializingArg( 361 serialized_name='axis_half_turns', constructor_arg_name='phase_exponent' 362 ), 363 op_deserializer.DeserializingArg( 364 serialized_name='axis_half_turns', 365 constructor_arg_name='exponent', 366 value_func=lambda _: 0.5, 367 ), 368 ], 369 ), 370] 371 372############################################# 373# 374# Two qubit serializers and deserializers 375# 376############################################# 377 378_phase_match_arg = op_serializer.SerializingArg( 379 serialized_name='phase_match', 380 serialized_type=str, 381 op_getter=lambda op: PHASE_MATCH_PHYS_Z if PhysicalZTag() in op.tags else None, 382 required=False, 383) 384 385 386def _add_phase_match(op: cirq.Operation, proto: v2.program_pb2.Operation): 387 if 'phase_match' in proto.args: 388 if proto.args['phase_match'].arg_value.string_value == PHASE_MATCH_PHYS_Z: 389 return op.with_tags(PhysicalZTag()) 390 return op 391 392 393# 394# CZ Serializer and deserializer 395# 396 397# Only CZ 398CZ_SERIALIZER = op_serializer.GateOpSerializer( 399 gate_type=cirq.CZPowGate, 400 serialized_gate_id='cz', 401 args=[ 402 op_serializer.SerializingArg( 403 serialized_name='half_turns', serialized_type=float, op_getter='exponent' 404 ), 405 _phase_match_arg, 406 ], 407 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.CZPowGate, op.gate).exponent, 1.0), 408) 409 410# CZ to any power 411CZ_POW_SERIALIZER = op_serializer.GateOpSerializer( 412 gate_type=cirq.CZPowGate, 413 serialized_gate_id='cz', 414 args=[ 415 op_serializer.SerializingArg( 416 serialized_name='half_turns', serialized_type=float, op_getter='exponent' 417 ), 418 _phase_match_arg, 419 ], 420) 421 422CZ_POW_DESERIALIZER = op_deserializer.GateOpDeserializer( 423 serialized_gate_id='cz', 424 gate_constructor=cirq.CZPowGate, 425 args=[ 426 op_deserializer.DeserializingArg( 427 serialized_name='half_turns', 428 constructor_arg_name='exponent', 429 default=1.0, 430 ), 431 ], 432 op_wrapper=lambda op, proto: _add_phase_match(op, proto), 433) 434 435# 436# Sycamore Gate Serializer and deserializer 437# 438SYC_SERIALIZER = op_serializer.GateOpSerializer( 439 gate_type=cirq.FSimGate, 440 serialized_gate_id='syc', 441 args=[_phase_match_arg], 442 can_serialize_predicate=( 443 lambda op: _near_mod_2pi(cast(cirq.FSimGate, op.gate).theta, np.pi / 2) 444 and _near_mod_2pi(cast(cirq.FSimGate, op.gate).phi, np.pi / 6) 445 ), 446) 447 448SYC_DESERIALIZER = op_deserializer.GateOpDeserializer( 449 serialized_gate_id='syc', 450 gate_constructor=lambda: cirq.FSimGate(theta=np.pi / 2, phi=np.pi / 6), 451 args=[], 452 op_wrapper=lambda op, proto: _add_phase_match(op, proto), 453) 454 455# 456# sqrt(ISWAP) serializer and deserializer 457# (e.g. ISWAP ** 0.5) 458# 459SQRT_ISWAP_SERIALIZERS = [ 460 op_serializer.GateOpSerializer( 461 gate_type=cirq.FSimGate, 462 serialized_gate_id='fsim_pi_4', 463 args=[_phase_match_arg], 464 can_serialize_predicate=( 465 lambda op: _near_mod_2pi(cast(cirq.FSimGate, op.gate).theta, np.pi / 4) 466 and _near_mod_2pi(cast(cirq.FSimGate, op.gate).phi, 0) 467 ), 468 ), 469 op_serializer.GateOpSerializer( 470 gate_type=cirq.ISwapPowGate, 471 serialized_gate_id='fsim_pi_4', 472 args=[_phase_match_arg], 473 can_serialize_predicate=( 474 lambda op: _near_mod_n(cast(cirq.ISwapPowGate, op.gate).exponent, -0.5, 4) 475 ), 476 ), 477 op_serializer.GateOpSerializer( 478 gate_type=cirq.FSimGate, 479 serialized_gate_id='inv_fsim_pi_4', 480 args=[_phase_match_arg], 481 can_serialize_predicate=( 482 lambda op: _near_mod_2pi(cast(cirq.FSimGate, op.gate).theta, -np.pi / 4) 483 and _near_mod_2pi(cast(cirq.FSimGate, op.gate).phi, 0) 484 ), 485 ), 486 op_serializer.GateOpSerializer( 487 gate_type=cirq.ISwapPowGate, 488 serialized_gate_id='inv_fsim_pi_4', 489 args=[_phase_match_arg], 490 can_serialize_predicate=( 491 lambda op: _near_mod_n(cast(cirq.ISwapPowGate, op.gate).exponent, +0.5, 4) 492 ), 493 ), 494] 495 496SQRT_ISWAP_DESERIALIZERS = [ 497 op_deserializer.GateOpDeserializer( 498 serialized_gate_id='fsim_pi_4', 499 gate_constructor=lambda: cirq.FSimGate(theta=np.pi / 4, phi=0), 500 args=[], 501 op_wrapper=lambda op, proto: _add_phase_match(op, proto), 502 ), 503 op_deserializer.GateOpDeserializer( 504 serialized_gate_id='inv_fsim_pi_4', 505 gate_constructor=lambda: cirq.FSimGate(theta=-np.pi / 4, phi=0), 506 args=[], 507 op_wrapper=lambda op, proto: _add_phase_match(op, proto), 508 ), 509] 510 511 512# 513# FSim serializer 514# Only allows iswap, sqrt_iswap and their inverses, iswap, CZ, identity, and sycamore 515# Note that not all combinations may not be available on all processors 516def _can_serialize_limited_fsim(theta: float, phi: float): 517 # Symbols for LIMITED_FSIM are allowed, but may fail server-side 518 # if an incorrect run context is specified 519 if _near_mod_2pi(phi, 0) or isinstance(phi, sympy.Symbol): 520 if isinstance(theta, sympy.Symbol): 521 return True 522 # Identity 523 if _near_mod_2pi(theta, 0): 524 return True 525 # sqrt ISWAP 526 if _near_mod_2pi(theta, -np.pi / 4): 527 return True 528 # inverse sqrt ISWAP 529 if _near_mod_2pi(theta, np.pi / 4): 530 return True 531 # ISWAP 532 if _near_mod_2pi(theta, -np.pi / 2): 533 return True 534 # Inverse ISWAP 535 if _near_mod_2pi(theta, np.pi / 2): 536 return True 537 # Sycamore 538 if ( 539 (_near_mod_2pi(theta, np.pi / 2) or isinstance(theta, sympy.Symbol)) 540 and (_near_mod_2pi(phi, np.pi / 6)) 541 or isinstance(phi, sympy.Symbol) 542 ): 543 return True 544 # CZ 545 if ( 546 (_near_mod_2pi(theta, 0) or isinstance(theta, sympy.Symbol)) 547 and (_near_mod_2pi(phi, np.pi)) 548 or isinstance(phi, sympy.Symbol) 549 ): 550 return True 551 return False 552 553 554def _can_serialize_limited_iswap(exponent: float): 555 # Symbols for LIMITED_FSIM are allowed, but may fail server-side 556 # if an incorrect run context is specified 557 if isinstance(exponent, sympy.Symbol): 558 return True 559 # Sqrt ISWAP 560 if _near_mod_n(exponent, 0.5, 4): 561 return True 562 # Inverse Sqrt ISWAP 563 if _near_mod_n(exponent, -0.5, 4): 564 return True 565 # ISWAP 566 if _near_mod_n(exponent, -1.0, 4): 567 return True 568 # Inverse ISWAP 569 if _near_mod_n(exponent, 1.0, 4): 570 return True 571 # Identity 572 if _near_mod_n(exponent, 0.0, 4): 573 return True 574 return False 575 576 577LIMITED_FSIM_SERIALIZERS = [ 578 op_serializer.GateOpSerializer( 579 gate_type=cirq.FSimGate, 580 serialized_gate_id='fsim', 581 args=[ 582 op_serializer.SerializingArg( 583 serialized_name='theta', serialized_type=float, op_getter='theta' 584 ), 585 op_serializer.SerializingArg( 586 serialized_name='phi', serialized_type=float, op_getter='phi' 587 ), 588 _phase_match_arg, 589 ], 590 can_serialize_predicate=( 591 lambda op: _can_serialize_limited_fsim( 592 cast(cirq.FSimGate, op.gate).theta, cast(cirq.FSimGate, op.gate).phi 593 ) 594 ), 595 ), 596 op_serializer.GateOpSerializer( 597 gate_type=cirq.ISwapPowGate, 598 serialized_gate_id='fsim', 599 args=[ 600 op_serializer.SerializingArg( 601 serialized_name='theta', 602 serialized_type=float, 603 # Note that ISWAP ** 0.5 is Fsim(-pi/4,0) 604 op_getter=(lambda op: cast(cirq.ISwapPowGate, op.gate).exponent * -np.pi / 2), 605 ), 606 op_serializer.SerializingArg( 607 serialized_name='phi', serialized_type=float, op_getter=lambda e: 0 608 ), 609 _phase_match_arg, 610 ], 611 can_serialize_predicate=( 612 lambda op: _can_serialize_limited_iswap(cast(cirq.ISwapPowGate, op.gate).exponent) 613 ), 614 ), 615 op_serializer.GateOpSerializer( 616 gate_type=cirq.CZPowGate, 617 serialized_gate_id='fsim', 618 args=[ 619 op_serializer.SerializingArg( 620 serialized_name='theta', serialized_type=float, op_getter=lambda e: 0 621 ), 622 op_serializer.SerializingArg( 623 serialized_name='phi', serialized_type=float, op_getter=lambda e: np.pi 624 ), 625 _phase_match_arg, 626 ], 627 can_serialize_predicate=lambda op: _near_mod_2(cast(cirq.CZPowGate, op.gate).exponent, 1.0), 628 ), 629] 630 631 632LIMITED_FSIM_DESERIALIZER = op_deserializer.GateOpDeserializer( 633 serialized_gate_id='fsim', 634 gate_constructor=cirq.FSimGate, 635 args=[ 636 op_deserializer.DeserializingArg( 637 serialized_name='theta', 638 constructor_arg_name='theta', 639 default=0.0, 640 ), 641 op_deserializer.DeserializingArg( 642 serialized_name='phi', 643 constructor_arg_name='phi', 644 default=0.0, 645 ), 646 ], 647 op_wrapper=lambda op, proto: _add_phase_match(op, proto), 648) 649 650############################################# 651# 652# Miscellaneous serializers and deserializers 653# 654############################################# 655 656# 657# Coupler Pulse serializer and deserializer 658# 659 660COUPLER_PULSE_SERIALIZER = op_serializer.GateOpSerializer( 661 gate_type=CouplerPulse, 662 serialized_gate_id='coupler_pulse', 663 args=[ 664 op_serializer.SerializingArg( 665 serialized_name='coupling_mhz', serialized_type=float, op_getter='coupling_mhz' 666 ), 667 op_serializer.SerializingArg( 668 serialized_name='hold_time_ns', 669 serialized_type=float, 670 op_getter=lambda op: cast(CouplerPulse, op.gate).hold_time.total_nanos(), 671 ), 672 op_serializer.SerializingArg( 673 serialized_name='rise_time_ns', 674 serialized_type=float, 675 op_getter=lambda op: cast(CouplerPulse, op.gate).rise_time.total_nanos(), 676 ), 677 op_serializer.SerializingArg( 678 serialized_name='padding_time_ns', 679 serialized_type=float, 680 op_getter=lambda op: cast(CouplerPulse, op.gate).padding_time.total_nanos(), 681 ), 682 ], 683) 684COUPLER_PULSE_DESERIALIZER = op_deserializer.GateOpDeserializer( 685 serialized_gate_id='coupler_pulse', 686 gate_constructor=CouplerPulse, 687 args=[ 688 op_deserializer.DeserializingArg( 689 serialized_name='coupling_mhz', 690 constructor_arg_name='coupling_mhz', 691 ), 692 op_deserializer.DeserializingArg( 693 serialized_name='hold_time_ns', 694 constructor_arg_name='hold_time', 695 value_func=lambda nanos: cirq.Duration( 696 nanos=cast(Union[int, float, sympy.Basic], nanos) 697 ), 698 ), 699 op_deserializer.DeserializingArg( 700 serialized_name='rise_time_ns', 701 constructor_arg_name='rise_time', 702 value_func=lambda nanos: cirq.Duration( 703 nanos=cast(Union[int, float, sympy.Basic], nanos) 704 ), 705 ), 706 op_deserializer.DeserializingArg( 707 serialized_name='padding_time_ns', 708 constructor_arg_name='padding_time', 709 value_func=lambda nanos: cirq.Duration( 710 nanos=cast(Union[int, float, sympy.Basic], nanos) 711 ), 712 ), 713 ], 714) 715 716# 717# WaitGate serializer and deserializer 718# 719WAIT_GATE_SERIALIZER = op_serializer.GateOpSerializer( 720 gate_type=cirq.WaitGate, 721 serialized_gate_id='wait', 722 args=[ 723 op_serializer.SerializingArg( 724 serialized_name='nanos', 725 serialized_type=float, 726 op_getter=lambda op: cast(cirq.WaitGate, op.gate).duration.total_nanos(), 727 ), 728 ], 729) 730WAIT_GATE_DESERIALIZER = op_deserializer.GateOpDeserializer( 731 serialized_gate_id='wait', 732 gate_constructor=cirq.WaitGate, 733 args=[ 734 op_deserializer.DeserializingArg( 735 serialized_name='nanos', 736 constructor_arg_name='duration', 737 value_func=lambda nanos: cirq.Duration( 738 nanos=cast(Union[int, float, sympy.Basic], nanos) 739 ), 740 ) 741 ], 742 num_qubits_param='num_qubits', 743) 744 745# 746# CircuitOperation serializer and deserializer 747# 748CIRCUIT_OP_SERIALIZER = op_serializer.CircuitOpSerializer() 749CIRCUIT_OP_DESERIALIZER = op_deserializer.CircuitOpDeserializer() 750