Skip to content

Commit

Permalink
Merge branch 'main' into routine-show-method
Browse files Browse the repository at this point in the history
  • Loading branch information
weinbe58 authored Oct 24, 2023
2 parents 4ef485e + b22ff47 commit 9ed3dcc
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/bloqade/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from bloqade.serialize import load, save, loads, dumps

from bloqade.factory import (
get_capabilities,
piecewise_linear,
piecewise_constant,
linear,
Expand All @@ -11,7 +12,6 @@
)
import bloqade.ir as _ir
from bloqade.constants import RB_C6
from bloqade.submission.capabilities import get_capabilities

import importlib.metadata

Expand Down
6 changes: 4 additions & 2 deletions src/bloqade/codegen/hardware/quera.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,10 @@ def visit_parallel_register(self, ast: ParallelRegister) -> Any:
"Cannot parallelize register without device capabilities."
)

height_max = self.capabilities.capabilities.lattice.area.height / 1e-6
width_max = self.capabilities.capabilities.lattice.area.width / 1e-6
height_max = self.capabilities.capabilities.lattice.area.height / Decimal(
"1e-6"
)
width_max = self.capabilities.capabilities.lattice.area.width / Decimal("1e-6")
number_sites_max = (
self.capabilities.capabilities.lattice.geometry.number_sites_max
)
Expand Down
140 changes: 139 additions & 1 deletion src/bloqade/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,145 @@
from bloqade.ir.control.waveform import Waveform, Linear, Constant
from bloqade.builder.typing import ScalarType
from beartype import beartype
from beartype.typing import List, Optional, Union, Dict, Any
from beartype.typing import TYPE_CHECKING, List, Optional, Union, Dict, Any
from decimal import Decimal

if TYPE_CHECKING:
from bloqade.submission.ir.capabilities import QuEraCapabilities


def get_capabilities() -> "QuEraCapabilities":
"""Get the device capabilities for Aquila
Returns:
QuEraCapabilities: capabilities object for Aquila device.
Note:
Units of time, distance, and energy are microseconds (us),
micrometers (um), and rad / us, respectively.
"""

from bloqade.submission.capabilities import get_capabilities
import bloqade.submission.ir.capabilities as cp

capabilities_schema = get_capabilities()

capabilities = capabilities_schema.capabilities

# manually convert to units
return cp.QuEraCapabilities(
version=capabilities_schema.version,
capabilities=cp.DeviceCapabilities(
task=cp.TaskCapabilities(
number_shots_max=capabilities.task.number_shots_max,
number_shots_min=capabilities.task.number_shots_min,
),
lattice=cp.LatticeCapabilities(
number_qubits_max=capabilities.lattice.number_qubits_max,
area=cp.LatticeAreaCapabilities(
width=(capabilities.lattice.area.width * Decimal("1e6")), # m
height=(capabilities.lattice.area.height * Decimal("1e6")), # m
),
geometry=cp.LatticeGeometryCapabilities(
number_sites_max=capabilities.lattice.geometry.number_sites_max,
spacing_radial_min=(
capabilities.lattice.geometry.spacing_radial_min
* Decimal("1e6")
), # m
spacing_vertical_min=(
capabilities.lattice.geometry.spacing_vertical_min
* Decimal("1e6")
), # m
position_resolution=(
capabilities.lattice.geometry.position_resolution
* Decimal("1e6")
), # m
),
),
rydberg=cp.RydbergCapabilities(
c6_coefficient=capabilities.rydberg.c6_coefficient
* Decimal("1e30"), # rad * m^6 / s
global_=cp.RydbergGlobalCapabilities(
phase_max=(capabilities.rydberg.global_.phase_max), # rad
phase_min=(capabilities.rydberg.global_.phase_min), # rad
phase_resolution=(
capabilities.rydberg.global_.phase_resolution
), # rad
rabi_frequency_max=(
capabilities.rydberg.global_.rabi_frequency_max / Decimal("1e6")
), # rad / s
rabi_frequency_min=(
capabilities.rydberg.global_.rabi_frequency_min / Decimal("1e6")
), # rad / s
rabi_frequency_resolution=(
capabilities.rydberg.global_.rabi_frequency_resolution
/ Decimal("1e6")
), # rad / s
rabi_frequency_slew_rate_max=(
capabilities.rydberg.global_.rabi_frequency_slew_rate_max
/ Decimal("1e6") ** 2
), # rad / s^2
detuning_max=(
capabilities.rydberg.global_.detuning_max / Decimal("1e6")
), # rad / s
detuning_min=(
capabilities.rydberg.global_.detuning_min / Decimal("1e6")
), # rad / s
detuning_resolution=(
capabilities.rydberg.global_.detuning_resolution
/ Decimal("1e6")
), # rad / s
detuning_slew_rate_max=(
capabilities.rydberg.global_.detuning_slew_rate_max
/ Decimal("1e6") ** 2
), # rad / s^2
time_min=(
capabilities.rydberg.global_.time_min * Decimal("1e6")
), # s
time_max=(
capabilities.rydberg.global_.time_max * Decimal("1e6")
), # s
time_resolution=(
capabilities.rydberg.global_.time_resolution * Decimal("1e6")
), # s
time_delta_min=(
capabilities.rydberg.global_.time_delta_min * Decimal("1e6")
), # s
),
local=cp.RydbergLocalCapabilities(
number_local_detuning_sites=(
capabilities.rydberg.local.number_local_detuning_sites
),
site_coefficient_max=(
capabilities.rydberg.local.site_coefficient_max
),
site_coefficient_min=(
capabilities.rydberg.local.site_coefficient_min
),
spacing_radial_min=(
capabilities.rydberg.local.spacing_radial_min * Decimal("1e6")
), # rad / s
detuning_min=(
capabilities.rydberg.local.detuning_min / Decimal("1e6")
), # rad / s
detuning_max=(
capabilities.rydberg.local.detuning_max / Decimal("1e6")
), # rad / s
detuning_slew_rate_max=(
capabilities.rydberg.local.detuning_slew_rate_max
/ Decimal("1e6") ** 2
), # rad / s^2
time_delta_min=(
capabilities.rydberg.local.time_delta_min * Decimal("1e6")
), # s
time_resolution=(
capabilities.rydberg.local.time_resolution * Decimal("1e6")
), # s
),
),
),
)


@beartype
Expand Down
7 changes: 1 addition & 6 deletions src/bloqade/submission/capabilities.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import json
import simplejson as json
import os
from bloqade.submission.ir.capabilities import QuEraCapabilities


# TODO: Create unit converter for capabilities
def get_capabilities() -> QuEraCapabilities:
"""Get the device capabilities for Aquila
Returns:
QuEraCapabilities: capabilities object for Aquila
"""
base_path = os.path.dirname(__file__)
full_path = os.path.join(
base_path, "quera_api_client", "config", "capabilities.json"
Expand Down
59 changes: 30 additions & 29 deletions src/bloqade/submission/ir/capabilities.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
from pydantic import BaseModel
from decimal import Decimal

__all__ = ["QuEraCapabilities"]


class RydbergGlobalCapabilities(BaseModel):
rabi_frequency_min: float
rabi_frequency_max: float
rabi_frequency_resolution: float
rabi_frequency_slew_rate_max: float
detuning_min: float
detuning_max: float
detuning_resolution: float
detuning_slew_rate_max: float
phase_min: float
phase_max: float
phase_resolution: float
time_min: float
time_max: float
time_resolution: float
time_delta_min: float
rabi_frequency_min: Decimal
rabi_frequency_max: Decimal
rabi_frequency_resolution: Decimal
rabi_frequency_slew_rate_max: Decimal
detuning_min: Decimal
detuning_max: Decimal
detuning_resolution: Decimal
detuning_slew_rate_max: Decimal
phase_min: Decimal
phase_max: Decimal
phase_resolution: Decimal
time_min: Decimal
time_max: Decimal
time_resolution: Decimal
time_delta_min: Decimal


class RydbergLocalCapabilities(BaseModel):
detuning_min: float
detuning_max: float
detuning_slew_rate_max: float
site_coefficient_min: float
site_coefficient_max: float
detuning_min: Decimal
detuning_max: Decimal
detuning_slew_rate_max: Decimal
site_coefficient_min: Decimal
site_coefficient_max: Decimal
number_local_detuning_sites: int
spacing_radial_min: float
time_resolution: float
time_delta_min: float
spacing_radial_min: Decimal
time_resolution: Decimal
time_delta_min: Decimal


class RydbergCapabilities(BaseModel):
c6_coefficient: float
c6_coefficient: Decimal
global_: RydbergGlobalCapabilities
local: RydbergLocalCapabilities

Expand All @@ -44,15 +45,15 @@ class Config:


class LatticeGeometryCapabilities(BaseModel):
spacing_radial_min: float
spacing_vertical_min: float
position_resolution: float
spacing_radial_min: Decimal
spacing_vertical_min: Decimal
position_resolution: Decimal
number_sites_max: int


class LatticeAreaCapabilities(BaseModel):
width: float
height: float
width: Decimal
height: Decimal


class LatticeCapabilities(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions src/bloqade/submission/quera_api_client/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import json
import simplejson as json
import logging
import uuid
from typing import Optional, Union, Dict, Tuple
Expand Down Expand Up @@ -49,7 +49,7 @@ def __init__(
self.logger = logging.getLogger(self.__class__.__name__)

@staticmethod
def _result_as_json(result: requests.Response) -> Dict:
def _result_as_json(result: requests.Response, **options) -> Dict:
content_type = result.headers["Content-Type"]
if content_type != "application/json":
raise ApiRequest.InvalidResponseError(
Expand All @@ -59,7 +59,7 @@ def _result_as_json(result: requests.Response) -> Dict:
if len(result.content) == 0:
return {}

return json.loads(result.content)
return json.loads(result.content, **options)

def _generate_headers(self, base: Optional[dict] = None) -> Dict:
if base is None:
Expand Down Expand Up @@ -375,7 +375,7 @@ def get_capabilities(self) -> Dict:
self.logger.error(message)
raise QueueApi.QueueApiError(message)

return ApiRequest._result_as_json(result)
return ApiRequest._result_as_json(result, use_decimal=True)

def validate_task(self, task_json: Union[str, dict]) -> None:
result = self.api_http_request.post("task", "validate", content=task_json)
Expand Down
73 changes: 73 additions & 0 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
var,
cast,
start,
get_capabilities,
)
from bloqade.atom_arrangement import Chain
from bloqade.ir import (
Expand All @@ -24,6 +25,78 @@
from bloqade.ir.routine.base import Routine
from bloqade.ir.routine.params import Params
import numpy as np
from decimal import Decimal


def test_get_capabilities():
capabilities = get_capabilities()

assert capabilities.version == "0.6"
assert capabilities.capabilities.task.number_shots_min == 1
assert capabilities.capabilities.task.number_shots_max == 1000
assert capabilities.capabilities.lattice.number_qubits_max == 256
assert capabilities.capabilities.lattice.area.width == Decimal("75.0")
assert capabilities.capabilities.lattice.area.height == Decimal("76.0")
assert capabilities.capabilities.lattice.geometry.spacing_radial_min == Decimal(
"4.0"
)
assert capabilities.capabilities.lattice.geometry.spacing_vertical_min == Decimal(
"4.0"
)
assert capabilities.capabilities.lattice.geometry.position_resolution == Decimal(
"0.1"
)
assert capabilities.capabilities.lattice.geometry.number_sites_max == 256
assert capabilities.capabilities.rydberg.c6_coefficient == Decimal("5.42e6")
assert capabilities.capabilities.rydberg.global_.rabi_frequency_min == Decimal(
"0.0"
)
assert capabilities.capabilities.rydberg.global_.rabi_frequency_max == Decimal(
"15.8"
)
assert (
capabilities.capabilities.rydberg.global_.rabi_frequency_resolution
== Decimal("4.0e-4")
)
assert (
capabilities.capabilities.rydberg.global_.rabi_frequency_slew_rate_max
== Decimal("250.0")
)
assert capabilities.capabilities.rydberg.global_.detuning_min == Decimal("-125.0")
assert capabilities.capabilities.rydberg.global_.detuning_max == Decimal("125.0")
assert capabilities.capabilities.rydberg.global_.detuning_resolution == Decimal(
"2.0e-7"
)
assert capabilities.capabilities.rydberg.global_.detuning_slew_rate_max == Decimal(
"2500.0"
)
assert capabilities.capabilities.rydberg.global_.phase_min == Decimal("-99.0")
assert capabilities.capabilities.rydberg.global_.phase_max == Decimal("99.0")
assert capabilities.capabilities.rydberg.global_.phase_resolution == Decimal(
"5.0E-7"
)
assert capabilities.capabilities.rydberg.global_.time_min == Decimal("0.0")
assert capabilities.capabilities.rydberg.global_.time_max == Decimal("4.0")
assert capabilities.capabilities.rydberg.global_.time_resolution == Decimal("1e-3")
assert capabilities.capabilities.rydberg.global_.time_delta_min == Decimal("5e-2")
assert capabilities.capabilities.rydberg.local.detuning_min == Decimal("0.0")
assert capabilities.capabilities.rydberg.local.detuning_max == Decimal("125.0")
assert capabilities.capabilities.rydberg.local.detuning_slew_rate_max == Decimal(
"1.2566e3"
)
assert capabilities.capabilities.rydberg.local.site_coefficient_min == Decimal(
"0.0"
)
assert capabilities.capabilities.rydberg.local.site_coefficient_max == Decimal(
"1.0"
)
assert (
capabilities.capabilities.rydberg.local.number_local_detuning_sites
== Decimal("200")
)
assert capabilities.capabilities.rydberg.local.spacing_radial_min == Decimal("5.0")
assert capabilities.capabilities.rydberg.local.time_resolution == Decimal("1e-3")
assert capabilities.capabilities.rydberg.local.time_delta_min == Decimal("5e-2")


def test_ir_piecewise_linear():
Expand Down
Loading

0 comments on commit 9ed3dcc

Please sign in to comment.