Skip to content

Commit

Permalink
Deprecate json_serializable_dataclass (quantumlib#5208)
Browse files Browse the repository at this point in the history
  • Loading branch information
maffoo authored and tonybruguier committed Apr 19, 2022
1 parent 69a55dd commit 203035a
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 32 deletions.
5 changes: 4 additions & 1 deletion cirq-core/cirq/experiments/cross_entropy_benchmarking.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def purity(self) -> float:
return self.cycle_depolarization**2


@protocols.json_serializable_dataclass(frozen=True)
@dataclasses.dataclass(frozen=True)
class CrossEntropyResult:
"""Results from a cross-entropy benchmarking (XEB) experiment.
Expand Down Expand Up @@ -208,6 +208,9 @@ def _from_json_dict_(cls, data, repetitions, **kwargs):
purity_data=purity_data,
)

def _json_dict_(self):
return protocols.dataclass_json_dict(self)

def __repr__(self) -> str:
args = f'data={[tuple(p) for p in self.data]!r}, repetitions={self.repetitions!r}'
if self.purity_data is not None:
Expand Down
14 changes: 8 additions & 6 deletions cirq-core/cirq/experiments/grid_parallel_two_qubit_xeb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
by executing circuits that act on many pairs simultaneously.
"""

from typing import Any, Iterable, List, Optional, Sequence, TYPE_CHECKING, Tuple, cast
from typing import Any, Dict, Iterable, List, Optional, Sequence, TYPE_CHECKING, Tuple, cast
import collections
from concurrent.futures import ThreadPoolExecutor
import dataclasses
Expand All @@ -46,7 +46,6 @@
)

if TYPE_CHECKING:
from typing import Dict
import cirq

DEFAULT_BASE_DIR = os.path.expanduser(
Expand Down Expand Up @@ -101,22 +100,25 @@ def load(params: Any, base_dir: str) -> Any:
return protocols.read_json(filename)


@protocols.json_serializable_dataclass
@dataclasses.dataclass
class GridParallelXEBMetadata:
"""Metadata for a grid parallel XEB experiment.
Attributes:
data_collection_id: The data collection ID of the experiment.
"""

qubits: List['cirq.Qid']
qubits: Sequence['cirq.Qid']
two_qubit_gate: 'cirq.Gate'
num_circuits: int
repetitions: int
cycles: List[int]
layers: List[GridInteractionLayer]
cycles: Sequence[int]
layers: Sequence[GridInteractionLayer]
seed: Optional[int]

def _json_dict_(self):
return protocols.dataclass_json_dict(self)

def __repr__(self) -> str:
return (
'cirq.experiments.grid_parallel_two_qubit_xeb.'
Expand Down
3 changes: 2 additions & 1 deletion cirq-core/cirq/protocols/json_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import sympy
from typing_extensions import Protocol

from cirq._compat import deprecated_parameter
from cirq._compat import deprecated, deprecated_parameter
from cirq._doc import doc_private
from cirq.type_workarounds import NotImplementedType

Expand Down Expand Up @@ -190,6 +190,7 @@ class name via a dot (.)

# Copying the Python API, whose usage of `repr` annoys pylint.
# pylint: disable=redefined-builtin
@deprecated(deadline='v0.15', fix='Implement _json_dict_ using cirq.dataclass_json_dict()')
def json_serializable_dataclass(
_cls: Optional[Type] = None,
*,
Expand Down
38 changes: 25 additions & 13 deletions cirq-core/cirq/protocols/json_serialization_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,10 +855,14 @@ def test_pathlib_paths(tmpdir):


def test_json_serializable_dataclass():
@cirq.json_serializable_dataclass
class MyDC:
q: cirq.LineQubit
desc: str
with cirq.testing.assert_deprecated(
"Implement _json_dict_ using cirq.dataclass_json_dict()", deadline="v0.15"
):

@cirq.json_serializable_dataclass
class MyDC:
q: cirq.LineQubit
desc: str

my_dc = MyDC(cirq.LineQubit(4), 'hi mom')

Expand All @@ -885,10 +889,14 @@ def custom_resolver(name):


def test_json_serializable_dataclass_parenthesis():
@cirq.json_serializable_dataclass()
class MyDC:
q: cirq.LineQubit
desc: str
with cirq.testing.assert_deprecated(
"Implement _json_dict_ using cirq.dataclass_json_dict()", deadline="v0.15"
):

@cirq.json_serializable_dataclass()
class MyDC:
q: cirq.LineQubit
desc: str

def custom_resolver(name):
if name == 'MyDC':
Expand Down Expand Up @@ -918,11 +926,15 @@ def custom_resolver(name):


def test_json_serializable_dataclass_namespace():
@cirq.json_serializable_dataclass(namespace='cirq.experiments')
class QuantumVolumeParams:
width: int
depth: int
circuit_i: int
with cirq.testing.assert_deprecated(
"Implement _json_dict_ using cirq.dataclass_json_dict()", deadline="v0.15"
):

@cirq.json_serializable_dataclass(namespace='cirq.experiments')
class QuantumVolumeParams:
width: int
depth: int
circuit_i: int

qvp = QuantumVolumeParams(width=5, depth=5, circuit_i=0)

Expand Down
35 changes: 24 additions & 11 deletions cirq-google/cirq_google/calibration/phased_fsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@
if TYPE_CHECKING:
import cirq_google

# Workaround for mypy custom dataclasses (python/mypy#5406)
from dataclasses import dataclass as json_serializable_dataclass
else:
from cirq.protocols import json_serializable_dataclass


_FLOQUET_PHASED_FSIM_HANDLER_NAME = 'floquet_phased_fsim_characterization'
_XEB_PHASED_FSIM_HANDLER_NAME = 'xeb_phased_fsim_characterization'
Expand Down Expand Up @@ -94,7 +89,7 @@ def _create_pairs_from_moment(
return tuple(pairs), gate


@json_serializable_dataclass(frozen=True)
@dataclasses.dataclass(frozen=True)
class PhasedFSimCharacterization:
"""Holder for the unitary angles of the cirq.PhasedFSimGate.
Expand Down Expand Up @@ -202,6 +197,9 @@ def override_by(self, other: 'PhasedFSimCharacterization') -> 'PhasedFSimCharact
"""
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
Expand Down Expand Up @@ -429,7 +427,7 @@ def parse_result(
"""Decodes the characterization result issued for this request."""


@json_serializable_dataclass(frozen=True)
@dataclasses.dataclass(frozen=True)
class XEBPhasedFSimCalibrationOptions(PhasedFSimCalibrationOptions):
"""Options for configuring a PhasedFSim calibration using XEB.
Expand Down Expand Up @@ -496,8 +494,11 @@ def _from_json_dict_(cls, **kwargs):
kwargs['cycle_depths'] = tuple(kwargs['cycle_depths'])
return cls(**kwargs)

def _json_dict_(self):
return cirq.dataclass_json_dict(self)

@json_serializable_dataclass(frozen=True)

@dataclasses.dataclass(frozen=True)
class LocalXEBPhasedFSimCalibrationOptions(XEBPhasedFSimCalibrationOptions):
"""Options for configuring a PhasedFSim calibration using a local version of XEB.
Expand Down Expand Up @@ -542,8 +543,11 @@ def create_phased_fsim_request(
):
return LocalXEBPhasedFSimCalibrationRequest(pairs=pairs, gate=gate, options=self)

def _json_dict_(self):
return cirq.dataclass_json_dict(self)


@json_serializable_dataclass(frozen=True)
@dataclasses.dataclass(frozen=True)
class FloquetPhasedFSimCalibrationOptions(PhasedFSimCalibrationOptions):
"""Options specific to Floquet PhasedFSimCalibration.
Expand Down Expand Up @@ -590,6 +594,9 @@ def create_phased_fsim_request(
) -> '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."""
Expand Down Expand Up @@ -821,7 +828,7 @@ def _parse_characterized_angles(
return dict(records)


@json_serializable_dataclass(frozen=True)
@dataclasses.dataclass(frozen=True)
class LocalXEBPhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest):
"""PhasedFSim characterization request for local cross entropy benchmarking (XEB) calibration.
Expand Down Expand Up @@ -856,8 +863,11 @@ def _from_json_dict_(
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)

@json_serializable_dataclass(frozen=True)

@dataclasses.dataclass(frozen=True)
class XEBPhasedFSimCalibrationRequest(PhasedFSimCalibrationRequest):
"""PhasedFSim characterization request for cross entropy benchmarking (XEB) calibration.
Expand Down Expand Up @@ -915,6 +925,9 @@ def _from_json_dict_(
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."""
Expand Down

0 comments on commit 203035a

Please sign in to comment.