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

[Unitary-Hack][Task-Base] Docstring for "tasks/base" #970

Merged
merged 12 commits into from
Jun 3, 2024
122 changes: 104 additions & 18 deletions src/bloqade/task/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
@Serializer.register
@dataclass(frozen=True)
class Geometry:
"""Class representing geometry of an atom arrangement.

Attributes:
sites (List[Tuple[float, float]]): Atom site arrangement
filling (List[int]): Which sites are filled
parallel_decoder: Decoder object for decoding Geometry object
"""

sites: List[Tuple[float, float]]
filling: List[int]
parallel_decoder: Optional[ParallelDecoder] = None
Expand All @@ -48,6 +56,10 @@ def geometry(self) -> Geometry:


class RemoteTask(Task):
"""`Task` to use for remote executions to run the program on Quera
Quantum Computers.
"""

def validate(self) -> None:
raise NotImplementedError

Expand Down Expand Up @@ -86,6 +98,8 @@ def _result_exists(self) -> bool:


class LocalTask(Task):
"""`Task` to use for local executions for simulation purposes.."""

def result(self):
# need a new results type
# for emulator jobs
Expand All @@ -95,9 +109,57 @@ def run(self, **kwargs):
raise NotImplementedError


# Report is now just a helper class for
# organize and analysis data:
class Report:
"""Report is a helper class for organizing and analysing data

### Analyzing Results using `Report` object
When you've retrieved your results from either emulation
or hardware you can generate a `.report()`:

```python
report = results.report()
```

For the examples below we analyze the results of a two atom program.

The report contains useful information such as:

* The raw bitstrings measured per each execution of the program
Manvi-Agrawal marked this conversation as resolved.
Show resolved Hide resolved
```python
report.bitstrings()
```
Manvi-Agrawal marked this conversation as resolved.
Show resolved Hide resolved

```text
[array([[1, 1],
[1, 1],
[1, 1],
...,
[1, 1],
[1, 1],
[1, 0]], dtype=int8)]
```

* The number of times each unique bitstring occurred:
```python
report.counts()
```

```text
[OrderedDict([('11', 892), ('10', 59), ('01', 49)])]
```

* The Rydberg Density for each atom
```python
report.rydberg_densities()
```

```text
0 1
task_number
0 0.053 0.054
```
"""

dataframe: pd.DataFrame
metas: List[Dict]
geos: List[Geometry]
Expand Down Expand Up @@ -133,6 +195,7 @@ def cast(x):

@property
def markdown(self) -> str:
"""Get the markdown representation of the dataframe"""
return self.dataframe.to_markdown()

def _filter(
Expand Down Expand Up @@ -172,16 +235,26 @@ def bitstrings(

Args:
filter_perfect_filling (bool): whether return will
only contain perfect filling shots. Defaults to True.
only contain perfect filling shots. Defaults to True.
clusters: (tuple[int, int], Sequence[Tuple[int, int]]):
cluster index to filter shots from. If none are provided
all clusters are used, defaults to [].
cluster index to filter shots from. If none are provided
all clusters are used, defaults to [].

Returns:
bitstrings (list of ndarray): list corresponding to each
task in the report. Each element is an ndarray of shape
(nshots, nsites) where nshots is the number of shots for
the task and nsites is the number of sites in the task.
task in the report. Each element is an ndarray of shape
(nshots, nsites) where nshots is the number of shots for
the task and nsites is the number of sites in the task.
For example:
```text
[array([[1, 1],
[1, 1],
[1, 1],
...,
[1, 1],
[1, 1],
[1, 0]], dtype=int8)]
```

Note:
Note that nshots may vary between tasks if filter_perfect_filling
Expand Down Expand Up @@ -216,24 +289,29 @@ def counts(

Args:
filter_perfect_filling (bool): whether return will
only contain perfect filling shots. Defaults to True.
only contain perfect filling shots. Defaults to True.
clusters: (tuple[int, int], Sequence[Tuple[int, int]]):
cluster index to filter shots from. If none are provided
all clusters are used, defaults to [].
cluster index to filter shots from. If none are provided
all clusters are used, defaults to [].
Roger-luo marked this conversation as resolved.
Show resolved Hide resolved

Returns:
bitstrings (list of ndarray): list corresponding to each
task in the report. Each element is an ndarray of shape
(nshots, nsites) where nshots is the number of shots for
the task and nsites is the number of sites in the task.
task in the report. Each element is an ndarray of shape
(nshots, nsites) where nshots is the number of shots for
the task and nsites is the number of sites in the task.
For example:

```text
[OrderedDict([('11', 892), ('10', 59), ('01', 49)])]
```

Note:
Note that nshots may vary between tasks if filter_perfect_filling
is set to True.

"""

def generate_counts(bitstring):
def _generate_counts(bitstring):
output = np.unique(bitstring, axis=0, return_counts=True)

count_list = [
Expand All @@ -246,7 +324,7 @@ def generate_counts(bitstring):
return count

return list(
map(generate_counts, self.bitstrings(filter_perfect_filling, clusters))
map(_generate_counts, self.bitstrings(filter_perfect_filling, clusters))
)

@beartype
Expand All @@ -259,11 +337,19 @@ def rydberg_densities(

Args:
filter_perfect_filling (bool, optional): whether return will
only contain perfect filling shots. Defaults to True.
only contain perfect filling shots. Defaults to True.
clusters: (tuple[int, int], Sequence[Tuple[int, int]]):
cluster index to filter shots from. If none are provided
all clusters are used, defaults to [].

Return:
per-site rydberg density for each task as a pandas DataFrame or Series.

For example:
```text
0 1
task_number
0 0.053 0.054
````
"""
mask = self._filter(
filter_perfect_filling=filter_perfect_filling, clusters=clusters
Expand Down