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

Rydberg h factory #654

Merged
merged 20 commits into from
Sep 29, 2023
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
8 changes: 4 additions & 4 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ classifiers = [
dependencies = [
"juliacall>=0.9.14",
"numpy>=1.25.2",
"pydantic>=1.10.12",
"pydantic>=1.10.13",
"scipy>=1.9.3",
"pandas>=2.1.0",
"bokeh>=3.2.2",
Expand Down
6 changes: 5 additions & 1 deletion src/bloqade/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from bloqade.ir import var, cast, Variable, Literal, start
from bloqade.ir import to_waveform as waveform
from bloqade.serialize import load, save, loads, dumps

from bloqade.builder.factory import (
from bloqade.factory import (
piecewise_linear,
piecewise_constant,
linear,
constant,
rydberg_h,
)
import bloqade.ir as _ir
from bloqade.constants import RB_C6
Expand Down Expand Up @@ -44,4 +46,6 @@ def tree_depth(depth: int = None):
"save",
"loads",
"dumps",
"rydberg_h",
"waveform",
]
4 changes: 4 additions & 0 deletions src/bloqade/builder/assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def __init__(

super().__init__(parent)

if len(assignments) == 0:
self._batch_params = []
return

circuit = self.parse_circuit()
variables = ScanVariablesAnalogCircuit().emit(circuit)

Expand Down
6 changes: 4 additions & 2 deletions src/bloqade/builder/backend/quera.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def cloud_mock(self):
"""
return self.parse().quera.cloud_mock()

def mock(self, state_file: str = ".mock_state.txt"):
def mock(self, state_file: str = ".mock_state.txt", submission_error: bool = False):
"""
Specify mock, testing locally.

Expand All @@ -123,4 +123,6 @@ def mock(self, state_file: str = ".mock_state.txt"):


"""
return self.parse().quera.mock(state_file)
return self.parse().quera.mock(
state_file=state_file, submission_error=submission_error
)
42 changes: 0 additions & 42 deletions src/bloqade/builder/factory.py

This file was deleted.

166 changes: 166 additions & 0 deletions src/bloqade/factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
from bloqade.ir.routine.base import Routine
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


@beartype
def linear(duration: ScalarType, start: ScalarType, stop: ScalarType) -> Linear:
"""Create a Linear waveform.

Args:
duration (ScalarType): duration of linear waveform
start (ScalarType): starting value of linear waveform
stop (ScalarType): ending value of linear waveform

Returns:
Linear: Linear waveform
"""
return Linear(start, stop, duration)


@beartype
def constant(duration: ScalarType, value: ScalarType) -> Constant:
"""Create a Constant waveform.

Args:
duration (ScalarType): _description_
value (ScalarType): _description_

Returns:
Constant: A Constant waveform.
"""
return Constant(value, duration)


@beartype
def piecewise_linear(durations: List[ScalarType], values: List[ScalarType]) -> Waveform:
"""Create a piecewise linear waveform.

Create a piecewise linear waveform from a list of durations and values. The
value `duration[i]` is of the linear segment between `values[i]` and `values[i+1]`.

Args:
durations (List[ScalarType]): The duration of each segment
values (List[ScalarType]): The values for each segment

Raises:
ValueError: If the length of `values` is not one greater than the length of
`durations`.

Returns:
Waveform: The piecewise linear waveform.
"""

if len(durations) + 1 != len(values):
raise ValueError(
"The length of values must be one greater than the length of durations"
)

pwl_wf = None
for duration, start, stop in zip(durations, values[:-1], values[1:]):
if pwl_wf is None:
pwl_wf = Linear(start, stop, duration)
else:
pwl_wf = pwl_wf.append(Linear(start, stop, duration))

return pwl_wf


@beartype
def piecewise_constant(
durations: List[ScalarType], values: List[ScalarType]
) -> Waveform:
"""Create a piecewise linear waveform.

Create a piecewise constant waveform from a list of durations and values. The
value `duration[i]` corresponds to the length of time for the i'th segment
with a value of `values[i]`.

Args:
durations (List[ScalarType]): The duration of each segment
values (List[ScalarType]): The values for each segment

Raises:
ValueError: If the length of `values` is not the same as the length of
`durations`.

Returns:
Waveform: The piecewise linear waveform.
"""
if len(durations) != len(values):
raise ValueError(
"The length of values must be the same as the length of durations"
)

pwc_wf = None
for duration, value in zip(durations, values):
if pwc_wf is None:
pwc_wf = Constant(value, duration)
else:
pwc_wf = pwc_wf.append(Constant(value, duration))

return pwc_wf


@beartype
def rydberg_h(
atoms_positions: Any,
detuning: Optional[Waveform] = None,
amplitude: Optional[Waveform] = None,
phase: Optional[Waveform] = None,
static_params: Dict[str, Any] = {},
batch_params: Union[List[Dict[str, Any]], Dict[str, Any]] = [],
args: List[str] = [],
) -> Routine:
"""Create a rydberg program with uniform detuning, amplitude, and phase.

Args:
atoms_positions (Any): Description of geometry of atoms in system.
detuning (Optional[Waveform], optional): Waveform for detuning.
Defaults to None.
amplitude (Optional[Waveform], optional): Waveform describing the amplitude of
the rabi term. Defaults to None.
phase (Optional[Waveform], optional): Waveform describing the phase of rabi
term. Defaults to None.
static_params (Dict[str, Any], optional): Define static parameters of your
program. Defaults to {}.
batch_params (Union[List[Dict[str, Any]], Dict[str, Any]], optional):
Parmaters for a batch of tasks. Defaults to [].
args (List[str], optional): List of arguments to leave till runtime.
Defaults to [].

Returns:
Routine: An object that can be used to dispatch a rydberg program to
multiple backends.
"""
from bloqade import start
from bloqade.atom_arrangement import AtomArrangement

print(type(atoms_positions))

if isinstance(atoms_positions, AtomArrangement):
prog = atoms_positions
else:
prog = start.add_position(atoms_positions)

if detuning is not None:
prog = prog.rydberg.detuning.uniform.apply(detuning)

if amplitude is not None:
prog = prog.amplitude.uniform.apply(amplitude)

if phase is not None:
prog = prog.phase.uniform.apply(phase)

prog = prog.assign(**static_params)

if isinstance(batch_params, dict):
prog = prog.batch_assign(**batch_params)
else:
prog = prog.batch_assign(batch_params)

prog = prog.args(args)

return prog.parse()
4 changes: 2 additions & 2 deletions src/bloqade/ir/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Interpolation,
Sample,
PythonFn,
instruction,
to_waveform,
GaussianKernel,
LogisticKernel,
SigmoidKernel,
Expand Down Expand Up @@ -68,7 +68,7 @@
"Sample",
"Interpolation",
"PythonFn",
"instruction",
"to_waveform",
"GaussianKernel",
"LogisticKernel",
"SigmoidKernel",
Expand Down
10 changes: 9 additions & 1 deletion src/bloqade/ir/control/waveform.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from numbers import Real
from bloqade.builder.typing import ScalarType
from bloqade.ir.tree_print import Printer
from bloqade.ir.scalar import (
Scalar,
Expand All @@ -14,6 +15,7 @@
from decimal import Decimal
from pydantic.dataclasses import dataclass
from beartype.typing import Any, Tuple, Union, List, Callable, Dict
from beartype import beartype
from enum import Enum

import numpy as np
Expand All @@ -23,7 +25,8 @@
from bloqade.visualization import display_ir


def instruction(duration: Any) -> "PythonFn":
@beartype
def to_waveform(duration: ScalarType) -> Callable[[Callable], "PythonFn"]:
# turn python function into a waveform instruction."""

def waveform_wrapper(fn: Callable) -> "PythonFn":
Expand Down Expand Up @@ -486,6 +489,11 @@ def print_node(self):
def children(self):
return {"duration": self.duration, **{p.name: p for p in self.parameters}}

def sample(
self, dt: ScalarType, interpolation: Union[str, "Interpolation"]
) -> "Sample":
return Sample(self, interpolation, cast(dt))


@dataclass
class SmoothingKernel:
Expand Down
11 changes: 7 additions & 4 deletions src/bloqade/ir/routine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from bloqade.builder.base import Builder
from bloqade.ir.routine.params import Params


from dataclasses import dataclass
from pydantic import ConfigDict
from pydantic.dataclasses import dataclass
from typing import TYPE_CHECKING, Union

if TYPE_CHECKING:
Expand All @@ -29,7 +29,10 @@ def parse(self: "RoutineBase") -> "Routine":
return self


@dataclass(frozen=True)
__pydantic_dataclass_config__ = ConfigDict(arbitrary_types_allowed=True)


@dataclass(frozen=True, config=__pydantic_dataclass_config__)
class RoutineBase(RoutineParse):
source: Builder
circuit: AnalogCircuit
Expand All @@ -43,7 +46,7 @@ def __str__(self):
return out


@dataclass(frozen=True)
@dataclass(frozen=True, config=__pydantic_dataclass_config__)
class Routine(RoutineBase):
"""Result of parsing a completed Builder string."""

Expand Down
Loading