Skip to content

Commit

Permalink
Merge branch 'main' into mhucka-add-recommended-files
Browse files Browse the repository at this point in the history
  • Loading branch information
mhucka authored Jan 9, 2025
2 parents 94de29a + ecf9ed7 commit 1e4e2a7
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 30 deletions.
50 changes: 44 additions & 6 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
name: "Mark and close stale issues"
# Summary: perform stale issue & PR handling on a schedule
# For more info, see https://github.com/actions/stale/

name: "Label and close stale issues & PRs"

on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
inputs:
debug:
# Note: the job body sets `debug-only` to false by default. The value
# of inputs.debug is an empty string unless this workflow is invoked
# manually. When it's invoked manually, GitHub's GUI presents the user
# with a checkbox for this flag; we default that checkbox to true
# because the most likely reason for a manual run is debugging.
description: "Run in debug mode (dry run)"
type: boolean
default: true

jobs:
stale:
name: Label and/or close stale issues and PRs
runs-on: ubuntu-20.04
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days'
days-before-stale: 30
days-before-close: 30
close-issue-message: 'Issue closed due to inactivity.'
repo-token: ${{secrets.GITHUB_TOKEN}}
debug-only: ${{inputs.debug || false}}
days-before-stale: 90
days-before-close: 60
stale-issue-label: 'status/stale'
stale-pr-label: 'status/stale'
exempt-issue-labels: 'triage/accepted,triage/discuss,kind/design-issue,kind/health,kind/roadmap-item,kind/task'
stale-issue-message: >
This issue has been automatically labeled as stale because 90 days
have passed without comments or other activity. If no further
activity occurs and the `status/stale` label is not removed within
60 days, it will be closed. If you believe this is in error or would
like to discuss it further, please leave a comment here.
stale-pr-message: >
This pull request has been automatically labeled as stale because 90
days have passed without comments or other activity. If no further
activity occurs and the `status/stale` label is not removed within 60
days, it will be closed. If you believe this is in error or would
like to discuss it further, please leave a comment here.
close-issue-message: >
This issue has been closed due to inactivity for 60 days since the
time the stale label was applied. If you believe this is in error or
would like to discuss it further, please either open a new issue
(and reference this one in it, for continuity) or reach out to the
Cirq project maintainers at [email protected].
close-pr-message: >
This pull-request has been closed due to inactivity for 60 days
since the time the stale label was applied. If you believe this is
in error or would like to discuss it further, please reach out to
the Cirq project maintainers at [email protected].
1 change: 1 addition & 0 deletions cirq-core/cirq/experiments/xeb_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ def _fit_exponential_decay(
fidelities,
p0=(a_0, layer_fid_0),
bounds=((0, 0), (1, 1)),
maxfev=1000,
)
except ValueError: # pragma: no cover
return 0, 0, np.inf, np.inf
Expand Down
22 changes: 13 additions & 9 deletions cirq-core/cirq/experiments/z_phase_calibration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions

_ANGLES = ['theta', 'phi', 'chi', 'zeta', 'gamma']
# fix random generator seed to ensure reproducibility and faster convergence
_SEED = 276154030


def _create_tests(n, seed, with_options: bool = False):
rng = np.random.default_rng(seed)
def _create_tests(n, with_options: bool = False):
rng = np.random.default_rng(_SEED)
angles = (rng.random((n, 5)) * 2 - 1) * np.pi
# Add errors to the last 3 angles (chi, zeta, gamma).
# The errors are in the union (-2, -1) U (1, 2).
Expand Down Expand Up @@ -86,8 +88,7 @@ def _core_iterator(


@pytest.mark.parametrize(
['angles', 'error', 'characterization_flags'],
_create_tests(n=10, seed=32432432, with_options=True),
['angles', 'error', 'characterization_flags'], _create_tests(n=10, with_options=True)
)
def test_calibrate_z_phases(angles, error, characterization_flags):

Expand All @@ -98,7 +99,7 @@ def test_calibrate_z_phases(angles, error, characterization_flags):
**{f'{n}_default': t for n, t in zip(_ANGLES, angles)}, **characterization_flags
)

sampler = _TestSimulator(original_gate, actual_gate, seed=0)
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
qubits = cirq.q(0, 0), cirq.q(0, 1)
calibrated_gate = calibrate_z_phases(
sampler,
Expand All @@ -109,6 +110,7 @@ def test_calibrate_z_phases(angles, error, characterization_flags):
n_combinations=10,
n_circuits=10,
cycle_depths=range(3, 10),
random_state=_SEED,
)[qubits]

initial_unitary = cirq.unitary(original_gate)
Expand All @@ -126,13 +128,13 @@ def test_calibrate_z_phases(angles, error, characterization_flags):
assert new_dist < original_dist or new_dist < 1e-6


@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3, seed=32432432))
@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3))
def test_calibrate_z_phases_no_options(angles, error):

original_gate = cirq.PhasedFSimGate(**{k: v for k, v in zip(_ANGLES, angles)})
actual_gate = cirq.PhasedFSimGate(**{k: v + e for k, v, e in zip(_ANGLES, angles, error)})

sampler = _TestSimulator(original_gate, actual_gate, seed=0)
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
qubits = cirq.q(0, 0), cirq.q(0, 1)
calibrated_gate = calibrate_z_phases(
sampler,
Expand All @@ -143,6 +145,7 @@ def test_calibrate_z_phases_no_options(angles, error):
n_combinations=10,
n_circuits=10,
cycle_depths=range(3, 10),
random_state=_SEED,
)[qubits]

initial_unitary = cirq.unitary(original_gate)
Expand All @@ -160,13 +163,13 @@ def test_calibrate_z_phases_no_options(angles, error):
assert new_dist < original_dist or new_dist < 1e-6


@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3, seed=32432432))
@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3))
def test_calibrate_z_phases_workflow_no_options(angles, error):

original_gate = cirq.PhasedFSimGate(**{k: v for k, v in zip(_ANGLES, angles)})
actual_gate = cirq.PhasedFSimGate(**{k: v + e for k, v, e in zip(_ANGLES, angles, error)})

sampler = _TestSimulator(original_gate, actual_gate, seed=0)
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
qubits = cirq.q(0, 0), cirq.q(0, 1)
result, _ = z_phase_calibration_workflow(
sampler,
Expand All @@ -177,6 +180,7 @@ def test_calibrate_z_phases_workflow_no_options(angles, error):
n_combinations=1,
n_circuits=1,
cycle_depths=(1, 2),
random_state=_SEED,
)

for params in result.final_params.values():
Expand Down
2 changes: 2 additions & 0 deletions cirq-core/cirq/ops/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ def _mul_with_qubits(self, qubits: Tuple['cirq.Qid', ...], other):
_rmul_with_qubits = _mul_with_qubits

def _circuit_diagram_info_(self, args) -> Tuple[str, ...]:
if self.num_qubits() <= 0:
return NotImplemented
return ('I',) * self.num_qubits()

def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optional[str]:
Expand Down
18 changes: 18 additions & 0 deletions cirq-core/cirq/ops/identity_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,21 @@ def test_identity_commutes():
assert cirq.commutes(cirq.I, cirq.X)
with pytest.raises(TypeError):
cirq.commutes(cirq.I, "Gate")


def test_identity_diagram():
cirq.testing.assert_has_diagram(
cirq.Circuit(cirq.IdentityGate(3).on_each(cirq.LineQubit.range(3))),
"""
0: ───I───
1: ───I───
2: ───I───
""",
)
cirq.testing.assert_has_diagram(
cirq.Circuit(cirq.IdentityGate(0)()),
"""
I(0)""",
)
4 changes: 2 additions & 2 deletions cirq-core/cirq/ops/phased_x_z_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ def __init__(

@classmethod
def from_zyz_angles(cls, z0_rad: float, y_rad: float, z1_rad: float) -> 'cirq.PhasedXZGate':
"""Create a PhasedXZGate from ZYZ angles.
r"""Create a PhasedXZGate from ZYZ angles.
The returned gate is equivalent to $Rz(z0_rad) Ry(y_rad) Rz(z1_rad)$ (in time order).
The returned gate is equivalent to $Rz(z0\_rad) Ry(y\_rad) Rz(z1\_rad)$ (in time order).
"""
return cls.from_zyz_exponents(z0=z0_rad / np.pi, y=y_rad / np.pi, z1=z1_rad / np.pi)

Expand Down
2 changes: 1 addition & 1 deletion cirq-core/cirq/protocols/circuit_diagram_info_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def _op_info_with_fallback(
rows: List[LabelEntity] = list(op.qubits)
if args.label_map is not None:
rows += protocols.measurement_keys_touched(op) & args.label_map.keys()
if info is not None:
if info is not None and info.wire_symbols:
if max(1, len(rows)) != len(info.wire_symbols):
raise ValueError(f'Wanted diagram info from {op!r} for {rows!r}) but got {info!r}')
return info
Expand Down
15 changes: 10 additions & 5 deletions cirq-core/cirq/transformers/gauge_compiling/gauge_compiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class SameGateGauge(Gauge):
default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
)
swap_qubits: bool = False
support_sweep: bool = False

def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
return ConstantGauge(
Expand All @@ -127,6 +128,7 @@ def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
post_q0=self.post_q0,
post_q1=self.post_q1,
swap_qubits=self.swap_qubits,
support_sweep=self.support_sweep,
)


Expand Down Expand Up @@ -332,6 +334,13 @@ def _parameterize(num_qubits: int, symbol_id: int) -> Dict[str, sympy.Symbol]:
def _gate_sequence_to_phxz_params(
gates: Tuple[ops.Gate, ...], xza_by_symbols: Dict[str, sympy.Symbol]
) -> Dict[str, float]:
identity_gate_in_phxz = {
str(xza_by_symbols["x_exponent"]): 0.0,
str(xza_by_symbols["z_exponent"]): 0.0,
str(xza_by_symbols["axis_phase_exponent"]): 0.0,
}
if not gates:
return identity_gate_in_phxz
for gate in gates:
if not has_unitary(gate) or gate.num_qubits() != 1:
raise ValueError(
Expand All @@ -347,11 +356,7 @@ def _gate_sequence_to_phxz_params(
or ops.I
)
if phxz is ops.I: # Identity gate
return {
str(xza_by_symbols["x_exponent"]): 0.0,
str(xza_by_symbols["z_exponent"]): 0.0,
str(xza_by_symbols["axis_phase_exponent"]): 0.0,
}
return identity_gate_in_phxz
# Check the gate type, needs to be a PhasedXZ gate.
if not isinstance(phxz, ops.PhasedXZGate):
raise ValueError("Failed to convert the gate sequence to a PhasedXZ gate.")
Expand Down
8 changes: 7 additions & 1 deletion cirq-core/cirq/transformers/gauge_compiling/iswap_gauge.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def _rz(self, theta, sgn: int) -> ConstantGauge:
pre_q1=n_rz if flip_diangonal else rz,
post_q0=rz if flip_diangonal else n_rz,
post_q1=n_rz,
support_sweep=True,
)

def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
Expand Down Expand Up @@ -88,7 +89,12 @@ def _xy_gauge(self, a: float, b: float) -> ConstantGauge:
xy_a = self._xy(a)
xy_b = self._xy(b)
return ConstantGauge(
two_qubit_gate=ops.ISWAP, pre_q0=xy_a, pre_q1=xy_b, post_q0=xy_b, post_q1=xy_a
two_qubit_gate=ops.ISWAP,
pre_q0=xy_a,
pre_q1=xy_b,
post_q0=xy_b,
post_q1=xy_a,
support_sweep=True,
)

def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
class TestISWAPGauge(GaugeTester):
two_qubit_gate = cirq.ISWAP
gauge_transformer = ISWAPGaugeTransformer
sweep_must_pass = True
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

SpinInversionGaugeSelector = GaugeSelector(
gauges=[
SameGateGauge(pre_q0=ops.X, post_q0=ops.X, pre_q1=ops.X, post_q1=ops.X),
SameGateGauge(),
SameGateGauge(pre_q0=ops.X, post_q0=ops.X, pre_q1=ops.X, post_q1=ops.X, support_sweep=True),
SameGateGauge(support_sweep=True),
]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@
class TestSpinInversionGauge_0(GaugeTester):
two_qubit_gate = cirq.ZZ
gauge_transformer = SpinInversionGaugeTransformer
sweep_must_pass = True


class TestSpinInversionGauge_1(GaugeTester):
two_qubit_gate = cirq.ZZ**0.1
gauge_transformer = SpinInversionGaugeTransformer
sweep_must_pass = True


class TestSpinInversionGauge_2(GaugeTester):
two_qubit_gate = cirq.ZZ**-1
gauge_transformer = SpinInversionGaugeTransformer
sweep_must_pass = True


class TestSpinInversionGauge_3(GaugeTester):
two_qubit_gate = cirq.ZZ**0.3
gauge_transformer = SpinInversionGaugeTransformer
sweep_must_pass = True
14 changes: 12 additions & 2 deletions cirq-core/cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ def _rz(self, theta: float) -> ConstantGauge:
rz = ops.rz(theta)
n_rz = ops.rz(-theta)
return ConstantGauge(
two_qubit_gate=ops.SQRT_ISWAP, pre_q0=rz, pre_q1=rz, post_q0=n_rz, post_q1=n_rz
two_qubit_gate=ops.SQRT_ISWAP,
pre_q0=rz,
pre_q1=rz,
post_q0=n_rz,
post_q1=n_rz,
support_sweep=True,
)

def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
Expand Down Expand Up @@ -80,7 +85,12 @@ def _xy(self, theta: float) -> ops.PhasedXZGate:
def _xy_gauge(self, theta: float) -> ConstantGauge:
xy = self._xy(theta)
return ConstantGauge(
two_qubit_gate=ops.SQRT_ISWAP, pre_q0=xy, pre_q1=xy, post_q0=xy, post_q1=xy
two_qubit_gate=ops.SQRT_ISWAP,
pre_q0=xy,
pre_q1=xy,
post_q0=xy,
post_q1=xy,
support_sweep=True,
)

def sample(self, gate: ops.Gate, prng: np.random.Generator) -> ConstantGauge:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
class TestSqrtISWAPGauge(GaugeTester):
two_qubit_gate = cirq.SQRT_ISWAP
gauge_transformer = SqrtISWAPGaugeTransformer
sweep_must_pass = True
3 changes: 1 addition & 2 deletions cirq-google/cirq_google/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ def __init__(
timeout: Optional[int] = None,
serializer: Serializer = CIRCUIT_SERIALIZER,
# TODO(#5996) Remove enable_streaming once the feature is stable.
# TODO(#6817): Reenable streaming by default once there's a fix.
enable_streaming: bool = False,
enable_streaming: bool = True,
) -> None:
"""Context and client for using Quantum Engine.
Expand Down

0 comments on commit 1e4e2a7

Please sign in to comment.