Skip to content
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
49 changes: 47 additions & 2 deletions cirq-google/cirq_google/calibration/phased_fsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
MutableMapping,
Optional,
Tuple,
Type,
TypeVar,
TYPE_CHECKING,
Generic,
Expand All @@ -40,8 +41,15 @@
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
from cirq_google.ops import FSimGateFamily
from cirq_google.engine import (
Calibration,
CalibrationLayer,
CalibrationResult,
Engine,
EngineJob,
util,
)
from cirq_google.ops import FSimGateFamily, SycamoreGate

if TYPE_CHECKING:
import cirq_google
Expand All @@ -50,6 +58,11 @@
_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')

Expand Down Expand Up @@ -331,6 +344,38 @@ def _json_dict_(self) -> Dict[str, Any]:
}


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]:
Expand Down
59 changes: 59 additions & 0 deletions cirq-google/cirq_google/calibration/phased_fsim_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
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,
Expand Down Expand Up @@ -625,6 +626,64 @@ def test_get_parameters():
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)
Expand Down