Skip to content
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

CI tests for the 1.4.1 patch release [do not merge] #6653

Closed
wants to merge 9 commits into from
Closed
6 changes: 3 additions & 3 deletions .github/workflows/ci-daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
name: Pytest Ubuntu
strategy:
matrix:
python-version: ['3.10', '3.11']
python-version: ['3.10', '3.11', '3.12']
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -44,7 +44,7 @@ jobs:
name: Pytest Windows
strategy:
matrix:
python-version: ['3.10', '3.11']
python-version: ['3.10', '3.11', '3.12']
runs-on: windows-2019
steps:
- uses: actions/checkout@v4
Expand All @@ -70,7 +70,7 @@ jobs:
name: Pytest MacOS
strategy:
matrix:
python-version: ['3.10', '3.11']
python-version: ['3.10', '3.11', '3.12']
# TODO(#6577): upgrade to macos-latest when it runs Python 3.10
runs-on: macos-13
steps:
Expand Down
2 changes: 1 addition & 1 deletion cirq-aqt/cirq_aqt/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

"""Define version number here, read it from setup.py automatically"""

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-aqt/cirq_aqt/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq_aqt.__version__ == "1.4.0.dev"
assert cirq_aqt.__version__ == "1.4.1"
2 changes: 1 addition & 1 deletion cirq-core/cirq/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@
'of cirq (e.g. "python -m pip install cirq==1.1.*")'
)

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-core/cirq/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq.__version__ == "1.4.0.dev"
assert cirq.__version__ == "1.4.1"
2 changes: 1 addition & 1 deletion cirq-core/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Runtime requirements for the python 3 version of cirq.

attrs
attrs>=21.3.0
duet>=0.2.8
matplotlib~=3.0
networkx>=2.4
Expand Down
2 changes: 1 addition & 1 deletion cirq-google/cirq_google/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@
'of cirq (e.g. "python -m pip install cirq==1.1.*")'
)

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-google/cirq_google/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq_google.__version__ == "1.4.0.dev"
assert cirq_google.__version__ == "1.4.1"
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from google.api_core import gapic_v1
from google.api_core import retry as retries
from google.auth import credentials as ga_credentials
from google.oauth2 import service_account # type: ignore
from google.oauth2 import service_account

try:
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
Expand Down Expand Up @@ -172,7 +172,7 @@ def transport(self) -> QuantumEngineServiceTransport:
def __init__(
self,
*,
credentials: ga_credentials.Credentials = None,
credentials: Optional[ga_credentials.Credentials] = None,
transport: Union[str, QuantumEngineServiceTransport] = "grpc_asyncio",
client_options: Optional[ClientOptions] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from google.auth.transport import mtls
from google.auth.transport.grpc import SslCredentials
from google.auth.exceptions import MutualTLSChannelError
from google.oauth2 import service_account # type: ignore
from google.oauth2 import service_account

try:
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from google.api_core import gapic_v1
from google.api_core import retry as retries
from google.auth import credentials as ga_credentials
from google.oauth2 import service_account # type: ignore
from google.oauth2 import service_account

from cirq_google.cloud.quantum_v1alpha1.types import engine
from cirq_google.cloud.quantum_v1alpha1.types import quantum
Expand All @@ -48,7 +48,7 @@ def __init__(
self,
*,
host: str = DEFAULT_HOST,
credentials: ga_credentials.Credentials = None,
credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def __init__(

if channel:
# Ignore credentials if a channel was passed.
credentials = False
credentials = None
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class QuantumEngineServiceGrpcAsyncIOTransport(QuantumEngineServiceTransport):
def create_channel(
cls,
host: str = 'quantum.googleapis.com',
credentials: ga_credentials.Credentials = None,
credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
Expand Down Expand Up @@ -94,7 +94,7 @@ def __init__(
self,
*,
host: str = 'quantum.googleapis.com',
credentials: ga_credentials.Credentials = None,
credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
channel: Optional[aio.Channel] = None,
Expand Down Expand Up @@ -166,7 +166,7 @@ def __init__(

if channel:
# Ignore credentials if a channel was passed.
credentials = False
credentials = None
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
Expand Down
2 changes: 1 addition & 1 deletion cirq-google/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
google-api-core[grpc] >= 1.14.0
proto-plus >= 1.20.0
protobuf >= 3.15.0
protobuf >= 3.15.0, < 5.0.0
2 changes: 1 addition & 1 deletion cirq-ionq/cirq_ionq/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

"""Define version number here, read it from setup.py automatically"""

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-ionq/cirq_ionq/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq_ionq.__version__ == "1.4.0.dev"
assert cirq_ionq.__version__ == "1.4.1"
2 changes: 1 addition & 1 deletion cirq-pasqal/cirq_pasqal/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

"""Define version number here, read it from setup.py automatically"""

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-pasqal/cirq_pasqal/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq_pasqal.__version__ == "1.4.0.dev"
assert cirq_pasqal.__version__ == "1.4.1"
43 changes: 0 additions & 43 deletions cirq-rigetti/cirq_rigetti/_qcs_api_client_decorator.py

This file was deleted.

2 changes: 1 addition & 1 deletion cirq-rigetti/cirq_rigetti/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

"""Define version number here, read it from setup.py automatically"""

__version__ = "1.4.0.dev"
__version__ = "1.4.1"
2 changes: 1 addition & 1 deletion cirq-rigetti/cirq_rigetti/_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@


def test_version():
assert cirq_rigetti.__version__ == "1.4.0.dev"
assert cirq_rigetti.__version__ == "1.4.1"
31 changes: 13 additions & 18 deletions cirq-rigetti/cirq_rigetti/aspen_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List, cast, Optional, Union, Dict, Any
from typing import List, Optional, Union, Dict, Any
import functools
from math import sqrt
import httpx
import json
import numpy as np
import networkx as nx
import cirq
from pyquil.quantum_processor import QCSQuantumProcessor
from qcs_api_client.models import InstructionSetArchitecture
from qcs_api_client.operations.sync import get_instruction_set_architecture
from cirq_rigetti._qcs_api_client_decorator import _provide_default_client
from qcs_sdk.client import QCSClient
from qcs_sdk.qpu.isa import get_instruction_set_architecture, InstructionSetArchitecture, Family


class UnsupportedQubit(ValueError):
Expand Down Expand Up @@ -50,6 +49,8 @@ class UnsupportedRigettiQCSQuantumProcessor(ValueError):
class RigettiQCSAspenDevice(cirq.devices.Device):
"""A cirq.Qid supporting Rigetti QCS Aspen device topology."""

isa: InstructionSetArchitecture

def __init__(self, isa: Union[InstructionSetArchitecture, Dict[str, Any]]) -> None:
"""Initializes a RigettiQCSAspenDevice with its Rigetti QCS `InstructionSetArchitecture`.

Expand All @@ -63,9 +64,9 @@ def __init__(self, isa: Union[InstructionSetArchitecture, Dict[str, Any]]) -> No
if isinstance(isa, InstructionSetArchitecture):
self.isa = isa
else:
self.isa = InstructionSetArchitecture.from_dict(isa)
self.isa = InstructionSetArchitecture.from_raw(json.dumps(isa))

if self.isa.architecture.family.lower() != 'aspen':
if self.isa.architecture.family != Family.Aspen:
raise UnsupportedRigettiQCSQuantumProcessor(
'this integration currently only supports Aspen devices, '
f'but client provided a {self.isa.architecture.family} device'
Expand Down Expand Up @@ -224,23 +225,22 @@ def __repr__(self):
return f'cirq_rigetti.RigettiQCSAspenDevice(isa={self.isa!r})'

def _json_dict_(self):
return {'isa': self.isa.to_dict()}
return {'isa': json.loads(self.isa.json())}

@classmethod
def _from_json_dict_(cls, isa, **kwargs):
return cls(isa=InstructionSetArchitecture.from_dict(isa))
return cls(isa=InstructionSetArchitecture.from_raw(json.dumps(isa)))


@_provide_default_client # pragma: no cover
def get_rigetti_qcs_aspen_device(
quantum_processor_id: str, client: Optional[httpx.Client]
quantum_processor_id: str, client: Optional[QCSClient] = None
) -> RigettiQCSAspenDevice:
"""Retrieves a `qcs_api_client.models.InstructionSetArchitecture` from the Rigetti
QCS API and uses it to initialize a RigettiQCSAspenDevice.

Args:
quantum_processor_id: The identifier of the Rigetti QCS quantum processor.
client: Optional; A `httpx.Client` initialized with Rigetti QCS credentials
client: Optional; A `QCSClient` initialized with Rigetti QCS credentials
and configuration. If not provided, `qcs_api_client` will initialize a
configured client based on configured values in the current user's
`~/.qcs` directory or default values.
Expand All @@ -250,12 +250,7 @@ def get_rigetti_qcs_aspen_device(
set and architecture.

"""
isa = cast(
InstructionSetArchitecture,
get_instruction_set_architecture(
client=client, quantum_processor_id=quantum_processor_id
).parsed,
)
isa = get_instruction_set_architecture(client=client, quantum_processor_id=quantum_processor_id)
return RigettiQCSAspenDevice(isa=isa)


Expand Down
36 changes: 17 additions & 19 deletions cirq-rigetti/cirq_rigetti/aspen_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from unittest.mock import patch, PropertyMock
from math import sqrt
import pathlib
import json
import pytest
import cirq
from cirq_rigetti import (
Expand All @@ -12,9 +11,8 @@
RigettiQCSAspenDevice,
UnsupportedQubit,
UnsupportedRigettiQCSOperation,
UnsupportedRigettiQCSQuantumProcessor,
)
from qcs_api_client.models import InstructionSetArchitecture, Node
from qcs_sdk.qpu.isa import InstructionSetArchitecture, Family
import numpy as np

dir_path = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
Expand All @@ -24,7 +22,7 @@
@pytest.fixture
def qcs_aspen8_isa() -> InstructionSetArchitecture:
with open(fixture_path / 'QCS-Aspen-8-ISA.json', 'r') as f:
return InstructionSetArchitecture.from_dict(json.load(f))
return InstructionSetArchitecture.from_raw(f.read())


def test_octagonal_qubit_index():
Expand Down Expand Up @@ -204,17 +202,6 @@ def test_rigetti_qcs_aspen_device_invalid_qubit(
device.validate_operation(cirq.I(qubit))


def test_rigetti_qcs_aspen_device_non_existent_qubit(qcs_aspen8_isa: InstructionSetArchitecture):
"""test RigettiQCSAspenDevice throws error when qubit does not exist on device"""
# test device may only be initialized with Aspen ISA.
device_with_limited_nodes = RigettiQCSAspenDevice(
isa=InstructionSetArchitecture.from_dict(qcs_aspen8_isa.to_dict())
)
device_with_limited_nodes.isa.architecture.nodes = [Node(node_id=10)]
with pytest.raises(UnsupportedQubit):
device_with_limited_nodes.validate_qubit(cirq.GridQubit(0, 0))


@pytest.mark.parametrize(
'operation',
[
Expand Down Expand Up @@ -265,7 +252,18 @@ def test_rigetti_qcs_aspen_device_repr(qcs_aspen8_isa: InstructionSetArchitectur

def test_rigetti_qcs_aspen_device_family_validation(qcs_aspen8_isa: InstructionSetArchitecture):
"""test RigettiQCSAspenDevice validates architecture family on initialization"""
non_aspen_isa = InstructionSetArchitecture.from_dict(qcs_aspen8_isa.to_dict())
non_aspen_isa.architecture.family = "not-aspen" # type: ignore
with pytest.raises(UnsupportedRigettiQCSQuantumProcessor):
RigettiQCSAspenDevice(isa=non_aspen_isa)
non_aspen_isa = InstructionSetArchitecture.from_raw(qcs_aspen8_isa.json())
non_aspen_isa.architecture.family = Family.NONE

assert (
non_aspen_isa.architecture.family == Family.Aspen
), 'ISA family is read-only and should still be Aspen'


def test_get_rigetti_qcs_aspen_device(qcs_aspen8_isa: InstructionSetArchitecture):
with patch('cirq_rigetti.aspen_device.get_instruction_set_architecture') as mock:
mock.return_value = qcs_aspen8_isa

from cirq_rigetti.aspen_device import get_rigetti_qcs_aspen_device

assert get_rigetti_qcs_aspen_device('Aspen-8') == RigettiQCSAspenDevice(isa=qcs_aspen8_isa)
Loading