From db91c60d1e2add254596752bc04bc2cd2ae1eee8 Mon Sep 17 00:00:00 2001 From: MattCordoba Date: Tue, 5 Apr 2022 14:45:43 -0700 Subject: [PATCH] feat: Add standardized device calibration data for OQC and Rigetti * feat: Add standardized device calibration data for OQC and Rigetti * feat: Add standardized device calibration data for OQC and Rigetti Co-authored-by: Matt Cordoba --- src/braket/device_schema/__init__.py | 3 + .../oqc/oqc_device_capabilities_v1.py | 9 + .../rigetti/rigetti_device_capabilities_v1.py | 9 + ...zed_gate_model_qpu_device_properties_v1.py | 205 ++++++++++++++++++ .../oqc/test_oqc_device_capabilities_v1.py | 38 ++++ .../test_rigetti_device_capabilities_v1.py | 38 ++++ ...zed_gate_model_qpu_device_properties_v1.py | 95 ++++++++ 7 files changed, 397 insertions(+) create mode 100644 src/braket/device_schema/standardized_gate_model_qpu_device_properties_v1.py create mode 100644 test/unit_tests/braket/device_schema/test_standardized_gate_model_qpu_device_properties_v1.py diff --git a/src/braket/device_schema/__init__.py b/src/braket/device_schema/__init__.py index abfb02c9..90a1f465 100644 --- a/src/braket/device_schema/__init__.py +++ b/src/braket/device_schema/__init__.py @@ -32,3 +32,6 @@ from braket.device_schema.openqasm_device_action_properties import ( # noqa: F401 OpenQASMDeviceActionProperties, ) +from braket.device_schema.standardized_gate_model_qpu_device_properties_v1 import ( # noqa: F401 + StandardizedGateModelQpuDeviceProperties, +) diff --git a/src/braket/device_schema/oqc/oqc_device_capabilities_v1.py b/src/braket/device_schema/oqc/oqc_device_capabilities_v1.py index 087ab2ee..045cd2ef 100644 --- a/src/braket/device_schema/oqc/oqc_device_capabilities_v1.py +++ b/src/braket/device_schema/oqc/oqc_device_capabilities_v1.py @@ -23,6 +23,9 @@ from braket.device_schema.jaqcd_device_action_properties import JaqcdDeviceActionProperties from braket.device_schema.openqasm_device_action_properties import OpenQASMDeviceActionProperties from braket.device_schema.oqc.oqc_provider_properties_v1 import OqcProviderProperties +from braket.device_schema.standardized_gate_model_qpu_device_properties_v1 import ( + StandardizedGateModelQpuDeviceProperties, +) from braket.schema_common import BraketSchemaBase, BraketSchemaHeader # TODO: Update the device and topology details when we have information from the provider @@ -38,6 +41,9 @@ class OqcDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): OQC device can support paradigm(GateModelQpuParadigmProperties): Paradigm properties provider(Optional[OqcProviderProperties]): OQC provider specific properties + standardized + (StandardizedGateModelQpuDeviceProperties): Braket standarized device + properties for OQC Examples: >>> import json @@ -97,6 +103,8 @@ class OqcDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): ... }, ... }, ... "deviceParameters": {OqcDeviceParameters.schema_json()}, + ... "standardized": \ + ... {StandardizedGateModelQpuDeviceProperties.schema_json()},, ... } >>> OqcDeviceCapabilities.parse_raw_schema(json.dumps(input_json)) """ @@ -111,3 +119,4 @@ class OqcDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): ] paradigm: GateModelQpuParadigmProperties provider: Optional[OqcProviderProperties] + standardized: Optional[StandardizedGateModelQpuDeviceProperties] diff --git a/src/braket/device_schema/rigetti/rigetti_device_capabilities_v1.py b/src/braket/device_schema/rigetti/rigetti_device_capabilities_v1.py index 688313f0..671da5dc 100644 --- a/src/braket/device_schema/rigetti/rigetti_device_capabilities_v1.py +++ b/src/braket/device_schema/rigetti/rigetti_device_capabilities_v1.py @@ -23,6 +23,9 @@ from braket.device_schema.jaqcd_device_action_properties import JaqcdDeviceActionProperties from braket.device_schema.openqasm_device_action_properties import OpenQASMDeviceActionProperties from braket.device_schema.rigetti.rigetti_provider_properties_v1 import RigettiProviderProperties +from braket.device_schema.standardized_gate_model_qpu_device_properties_v1 import ( + StandardizedGateModelQpuDeviceProperties, +) from braket.schema_common import BraketSchemaBase, BraketSchemaHeader @@ -36,6 +39,9 @@ class RigettiDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): Rigetti device can support paradigm(GateModelQpuParadigmProperties): Paradigm properties of a Rigetti provider(Optional[RigettiProviderProperties]): Rigetti provider specific properties + standardized + (StandardizedGateModelQpuDeviceProperties): Braket standarized device + properties for Rigetti Examples: >>> import json @@ -95,6 +101,8 @@ class RigettiDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): ... }, ... }, ... "deviceParameters": {RigettiDeviceParameters.schema_json()}, + ... "standardized": \ + ... {StandardizedGateModelQpuDeviceProperties.schema_json()}, ... } >>> RigettiDeviceCapabilities.parse_raw_schema(json.dumps(input_json)) @@ -110,3 +118,4 @@ class RigettiDeviceCapabilities(BraketSchemaBase, DeviceCapabilities): ] paradigm: GateModelQpuParadigmProperties provider: Optional[RigettiProviderProperties] + standardized: Optional[StandardizedGateModelQpuDeviceProperties] diff --git a/src/braket/device_schema/standardized_gate_model_qpu_device_properties_v1.py b/src/braket/device_schema/standardized_gate_model_qpu_device_properties_v1.py new file mode 100644 index 00000000..d9ef8237 --- /dev/null +++ b/src/braket/device_schema/standardized_gate_model_qpu_device_properties_v1.py @@ -0,0 +1,205 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, 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 enum import Enum +from typing import Dict, List, Optional + +from pydantic import BaseModel, Field, confloat + +from braket.schema_common import BraketSchemaBase, BraketSchemaHeader + + +class QubitDirection(str, Enum): + """ + Enum for qubit direction labels for two-qubit fidelity details + """ + + CONTROL = "control" + TARGET = "target" + + +class FidelityType(BaseModel): + """ + Fidelity measurement types + Attributes: + name (str): description of the fidelity measurement + description (Optional[str]): Optional description for how the fidelity + measurement was performed + """ + + name: str + description: Optional[str] + + +class GateFidelity2Q(BaseModel): + """ + Describes the fidelity of two-qubit pairing + Attributes: + direction (Optional[Dict[QubitDirection, int]]): Describes which qubit is + control/target for the pair. If direction is None the pair is considered + bi-directional. + gateName (str): the 2-qubit gate that the fidelity measurement was performed on + fidelity (float): the fidelity value + standardError (Optional[float]): Describes the error value on the fidelity measurement + fidelityType (FidelityType): The fidelity measurement technique used + for the presented value + """ + + direction: Optional[Dict[QubitDirection, int]] = None + gateName: str + fidelity: confloat(ge=0, le=1) + standardError: Optional[confloat(ge=0, le=1)] = None + fidelityType: FidelityType + + +class TwoQubitProperties(BaseModel): + """ + The standard two-qubit calibration details for a quantum hardware provider + Attributes: + twoQubitGateFidelity: two qubit fidelity properties + """ + + twoQubitGateFidelity: List[GateFidelity2Q] + + +class Fidelity1Q(BaseModel): + """ + Describes one qubit fidelity measured on a qubit + Attributes: + fidelityType (FidelityType): The fidelity measurement technique used + for the presented value + fidelity (float): The measured fidelity value + standardError (Optional[float]) The expected error value reported + on the measurement + """ + + fidelityType: FidelityType + fidelity: confloat(ge=0, le=1) + standardError: Optional[confloat(ge=0, le=1)] = None + + +class CoherenceTime(BaseModel): + """ + The coherence time values provided for the device + Attributes: + value (str): The coherence time value + standardError (str): The error/confidence in coherence measurement provided + unit (str): The unit for the described value + """ + + value: float + standardError: Optional[float] + unit: str + + +class OneQubitProperties(BaseModel): + """ + The standard one-qubit calibration details for a quantum hardware provider + Attributes: + T1: The T1 decoherence/relaxation time data structure + T2: The T2 coherence/dephasing time + oneQubitFidelity: one qubit fidelity properties + """ + + T1: CoherenceTime + T2: CoherenceTime + oneQubitFidelity: List[Fidelity1Q] + + +class StandardizedGateModelQpuDeviceProperties(BraketSchemaBase): + """ + + Braket standarized gate model device qpu properties for the given quantum hardware + + Attributes: + oneQubitProperties (Dict[str, OneQubitProperties]): Dictionary describing a qubit + identifier (ex: '1'), to the calibration property set + twoQubitProperties (Dict[str, TwoQubitProperties]): Dictionary describing the + two-qubit identifier (ex: '0-1'), to the calibration property set + Examples: + >>> import json + >>> valid_input = { + ... "braketSchemaHeader": { + ... "name": \ + ... "braket.device_schema.standardized_gate_model_qpu_device_properties", + ... "version": "1", + ... }, + ... "oneQubitProperties": { + ... "0": { + ... "T1": {"value": 28.9, "standardError": 0.01, "unit": "us"}, + ... "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + ... "oneQubitFidelity": [ + ... { + ... "fidelityType": { + ... "name": "RANDOMIZED_BENCHMARKING", + ... "description": "uses a standard RB technique", + ... }, + ... "fidelity": 0.9993, + ... }, + ... { + ... "fidelityType": {"name": "READOUT"}, + ... "fidelity": 0.903, + ... "standardError": None, + ... }, + ... ], + ... }, + ... "1": { + ... "T1": {"value": 28.9, "unit": "us"}, + ... "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + ... "oneQubitFidelity": [ + ... { + ... "fidelityType": {"name": "RANDOMIZED_BENCHMARKING"}, + ... "fidelity": 0.9986, + ... "standardError": None, + ... }, + ... { + ... "fidelityType": {"name": "READOUT"}, + ... "fidelity": 0.867, + ... "standardError": None, + ... }, + ... ], + ... }, + ... }, + ... "twoQubitProperties": { + ... "0-1": { + ... "twoQubitGateFidelity": [ + ... { + ... "direction": {"control": 0, "target": 1}, + ... "gateName": "CNOT", + ... "fidelity": 0.877, + ... "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + ... } + ... ] + ... }, + ... "0-7": { + ... "twoQubitGateFidelity": [ + ... { + ... "direction": {"control": 0, "target": 7}, + ... "gateName": "CNOT", + ... "fidelity": 0.877, + ... "standardError": 0.001, + ... "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + ... } + ... ] + ... }, + ... }, + ... } + >>> StandardizedGateModelQpuDeviceProperties.parse_raw_schema(json.dumps(valid_input)) + """ + + _PROGRAM_HEADER = BraketSchemaHeader( + name="braket.device_schema.standardized_gate_model_qpu_device_properties", version="1" + ) + braketSchemaHeader: BraketSchemaHeader = Field(default=_PROGRAM_HEADER, const=_PROGRAM_HEADER) + oneQubitProperties: Dict[str, OneQubitProperties] + twoQubitProperties: Dict[str, TwoQubitProperties] diff --git a/test/unit_tests/braket/device_schema/oqc/test_oqc_device_capabilities_v1.py b/test/unit_tests/braket/device_schema/oqc/test_oqc_device_capabilities_v1.py index c38a5712..2d6ea42f 100644 --- a/test/unit_tests/braket/device_schema/oqc/test_oqc_device_capabilities_v1.py +++ b/test/unit_tests/braket/device_schema/oqc/test_oqc_device_capabilities_v1.py @@ -18,6 +18,43 @@ from braket.device_schema.oqc.oqc_device_capabilities_v1 import OqcDeviceCapabilities +device_properties_data = { + "braketSchemaHeader": { + "name": "braket.device_schema.standardized_gate_model_qpu_device_properties", + "version": "1", + }, + "oneQubitProperties": { + "0": { + "T1": {"value": 28.9, "standardError": 0.01, "unit": "us"}, + "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + "oneQubitFidelity": [ + { + "fidelityType": {"name": "READOUT"}, + "fidelity": 0.9993, + "standardError": None, + }, + { + "fidelityType": {"name": "RANDOMIZED_BENCHMARKING"}, + "fidelity": 0.903, + "standardError": None, + }, + ], + } + }, + "twoQubitProperties": { + "0-1": { + "twoQubitGateFidelity": [ + { + "direction": {"control": 0, "target": 1}, + "gateName": "CNOT", + "fidelity": 0.877, + "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + } + ] + } + }, +} + jaqcd_valid_input = { "braketSchemaHeader": { "name": "braket.device_schema.oqc.oqc_device_capabilities", @@ -124,6 +161,7 @@ "connectivity": {"fullyConnected": False, "connectivityGraph": {"1": ["2", "3"]}}, }, "deviceParameters": {}, + "standardized": device_properties_data, } diff --git a/test/unit_tests/braket/device_schema/rigetti/test_rigetti_device_capabilities_v1.py b/test/unit_tests/braket/device_schema/rigetti/test_rigetti_device_capabilities_v1.py index 8dcf5ff9..a60b0e11 100644 --- a/test/unit_tests/braket/device_schema/rigetti/test_rigetti_device_capabilities_v1.py +++ b/test/unit_tests/braket/device_schema/rigetti/test_rigetti_device_capabilities_v1.py @@ -18,6 +18,43 @@ from braket.device_schema.rigetti.rigetti_device_capabilities_v1 import RigettiDeviceCapabilities +device_properties_data = { + "braketSchemaHeader": { + "name": "braket.device_schema.standardized_gate_model_qpu_device_properties", + "version": "1", + }, + "oneQubitProperties": { + "0": { + "T1": {"value": 28.9, "standardError": 0.01, "unit": "us"}, + "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + "oneQubitFidelity": [ + { + "fidelityType": {"name": "READOUT"}, + "fidelity": 0.9993, + "standardError": None, + }, + { + "fidelityType": {"name": "RANDOMIZED_BENCHMARKING"}, + "fidelity": 0.903, + "standardError": None, + }, + ], + } + }, + "twoQubitProperties": { + "0-1": { + "twoQubitGateFidelity": [ + { + "direction": {"control": 0, "target": 1}, + "gateName": "CNOT", + "fidelity": 0.877, + "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + } + ] + } + }, +} + jaqcd_valid_input = { "braketSchemaHeader": { "name": "braket.device_schema.rigetti.rigetti_device_capabilities", @@ -66,6 +103,7 @@ "connectivity": {"fullyConnected": False, "connectivityGraph": {"1": ["2", "3"]}}, }, "deviceParameters": {}, + "standardized": device_properties_data, } diff --git a/test/unit_tests/braket/device_schema/test_standardized_gate_model_qpu_device_properties_v1.py b/test/unit_tests/braket/device_schema/test_standardized_gate_model_qpu_device_properties_v1.py new file mode 100644 index 00000000..a54f9db0 --- /dev/null +++ b/test/unit_tests/braket/device_schema/test_standardized_gate_model_qpu_device_properties_v1.py @@ -0,0 +1,95 @@ +import json + +import pytest +from pydantic import ValidationError + +from braket.device_schema.standardized_gate_model_qpu_device_properties_v1 import ( + StandardizedGateModelQpuDeviceProperties, +) + + +@pytest.fixture(scope="module") +def valid_input(): + input = { + "braketSchemaHeader": { + "name": "braket.device_schema.standardized_gate_model_qpu_device_properties", + "version": "1", + }, + "oneQubitProperties": { + "0": { + "T1": {"value": 28.9, "standardError": 0.01, "unit": "us"}, + "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + "oneQubitFidelity": [ + { + "fidelityType": { + "name": "RANDOMIZED_BENCHMARKING", + "description": "uses a standard RB technique", + }, + "fidelity": 0.9993, + }, + { + "fidelityType": {"name": "READOUT"}, + "fidelity": 0.903, + "standardError": None, + }, + ], + }, + "1": { + "T1": {"value": 28.9, "unit": "us"}, + "T2": {"value": 44.5, "standardError": 0.02, "unit": "us"}, + "oneQubitFidelity": [ + { + "fidelityType": {"name": "RANDOMIZED_BENCHMARKING"}, + "fidelity": 0.9986, + "standardError": None, + }, + { + "fidelityType": {"name": "READOUT"}, + "fidelity": 0.867, + "standardError": None, + }, + ], + }, + }, + "twoQubitProperties": { + "0-1": { + "twoQubitGateFidelity": [ + { + "direction": {"control": 0, "target": 1}, + "gateName": "CNOT", + "fidelity": 0.877, + "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + } + ] + }, + "0-7": { + "twoQubitGateFidelity": [ + { + "direction": {"control": 0, "target": 7}, + "gateName": "CNOT", + "fidelity": 0.877, + "standardError": 0.001, + "fidelityType": {"name": "INTERLEAVED_RANDOMIZED_BENCHMARKING"}, + } + ] + }, + }, + } + return input + + +def test_valid(valid_input): + result = StandardizedGateModelQpuDeviceProperties.parse_raw_schema(json.dumps(valid_input)) + assert ( + result.braketSchemaHeader.name + == "braket.device_schema.standardized_gate_model_qpu_device_properties" + ) + + +@pytest.mark.parametrize( + "missing_field", ["braketSchemaHeader", "oneQubitProperties", "twoQubitProperties"] +) +def test_missing_field(valid_input, missing_field): + with pytest.raises(ValidationError): + valid_input.pop(missing_field) + StandardizedGateModelQpuDeviceProperties.parse_raw_schema(json.dumps(valid_input))