Skip to content

Deprecate json_serializable_dataclass #5208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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