Skip to content
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
6 changes: 0 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,7 @@ jobs:
run: |
python -m pip install -U .[cpu,dev,docs]

- name: Doctest
if: ${{ github.event_name == 'pull_request' && github.ref == 'refs/heads/main' }}
run: |
make -C docs doctest

- name: Build Docs
if: ${{ github.ref == 'refs/heads/main' }}
run: |
sphinx-build docs/source _build

Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,21 @@ jobs:
key: pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
restore-keys: |
pip-${{ matrix.python-version }}-
- name: Cache apt packages
uses: actions/cache@v4
id: cache-apt
with:
path: /var/cache/apt/archives
key: apt-${{ runner.os }}-libboost-cmake-${{ hashFiles('.github/workflows/tests.yml') }}
restore-keys: |
apt-${{ runner.os }}-libboost-cmake-
- name: Install dependencies
if: steps.cache-apt.outputs.cache-hit != 'true'
run: |
sudo apt-get update && sudo apt-get install -y -qq libboost-all-dev cmake
sudo apt-get update -qq
sudo apt-get install -y -qq libboost-all-dev cmake
- name: Install qlbm
id: pip-install
run: |
pip install --upgrade pip
pip install -e .[cpu,dev]
Expand Down
6 changes: 3 additions & 3 deletions demos/simulation/ms_simulation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"from qiskit_aer import AerSimulator\n",
"\n",
"from qlbm.components import (\n",
" CQLBM,\n",
" MSQLBM,\n",
" EmptyPrimitive,\n",
" GridMeasurement,\n",
" MSInitialConditions,\n",
Expand Down Expand Up @@ -64,7 +64,7 @@
"source": [
"cfg = SimulationConfig(\n",
" initial_conditions=MSInitialConditions(lattice),\n",
" algorithm=CQLBM(lattice),\n",
" algorithm=MSQLBM(lattice, group_velocities=True),\n",
" postprocessing=EmptyPrimitive(lattice),\n",
" measurement=GridMeasurement(lattice),\n",
" target_platform=\"QISKIT\",\n",
Expand All @@ -73,7 +73,7 @@
" statevector_sampling=True,\n",
" execution_backend=AerSimulator(method=\"statevector\"),\n",
" sampling_backend=AerSimulator(method=\"statevector\"),\n",
")\n"
")"
]
},
{
Expand Down
5 changes: 2 additions & 3 deletions demos/visualization/amplitude_components.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@
"source": [
"# Import the required packages from the qlbm framework\n",
"from qlbm.components import (\n",
" CQLBM,\n",
" ABStreamingOperator,\n",
" ControlledIncrementer,\n",
" MSStreamingOperator,\n",
" SpeedSensitivePhaseShift,\n",
" ParameterizedPhaseShift,\n",
")\n",
"from qlbm.components.ab import ABStreamingOperator\n",
"from qlbm.lattice import ABLattice, MSLattice"
Expand Down Expand Up @@ -61,7 +60,7 @@
"outputs": [],
"source": [
"# Define an example which uses 4 velocity qubits and the qubits with speed 2 will stream\n",
"speed_shift_primitive = SpeedSensitivePhaseShift(5, 1, True)"
"speed_shift_primitive = ParameterizedPhaseShift(5, 1, True)"
]
},
{
Expand Down
62 changes: 60 additions & 2 deletions demos/visualization/geometry.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"metadata": {},
"outputs": [],
"source": [
"from qlbm.lattice.lattices.ab_lattice import ABLattice\n",
"\n",
"\n",
"lattice_2d = MSLattice(\n",
" {\n",
" \"lattice\": {\n",
Expand Down Expand Up @@ -73,6 +76,23 @@
" }\n",
" ],\n",
" }\n",
")\n",
"\n",
"ab_lattice_2d = ABLattice(\n",
" {\n",
" \"lattice\": {\n",
" \"dim\": {\"x\": 64, \"y\": 256},\n",
" \"velocities\": \"d2q9\",\n",
" },\n",
" \"geometry\": [\n",
" {\n",
" \"shape\": \"ymonomial\",\n",
" \"comparator\": \"<=\",\n",
" \"exponent\": 2,\n",
" \"boundary\": \"bounceback\",\n",
" },\n",
" ],\n",
" }\n",
")"
]
},
Expand All @@ -83,8 +103,10 @@
"outputs": [],
"source": [
"root_directory_2d = \"qlbm-output/visualization-components-2d\"\n",
"root_directory_2d_monomial = \"qlbm-output/visualization-components-2d-monomial\"\n",
"root_directory_3d = \"qlbm-output/visualization-components-3d\"\n",
"create_directory_and_parents(root_directory_2d)\n",
"create_directory_and_parents(root_directory_2d_monomial)\n",
"create_directory_and_parents(root_directory_3d)"
]
},
Expand All @@ -98,6 +120,16 @@
"AmplitudeResult(lattice_2d, root_directory_2d).visualize_geometry()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Will output seven 2D stl files under `qlbm-output/visualization-components-2d-monomial/paraview`\n",
"AmplitudeResult(ab_lattice_2d, root_directory_2d_monomial).visualize_geometry()"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -122,6 +154,25 @@
").plot(cpos=\"xy\", show_scalar_bar=True, jupyter_backend=\"static\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pl = pv.Plotter()\n",
"mesh = pv.read(\n",
" [\n",
" f\"{root_directory_2d_monomial}/paraview/{fname}\"\n",
" for fname in listdir(f\"{root_directory_2d_monomial}/paraview\")\n",
" ]\n",
").plot(show_scalar_bar=True, jupyter_backend=\"interactive\")\n",
"\n",
"# pl.add_mesh(mesh)\n",
"# pl.camera_position = \"xy\"\n",
"# pl.save_graphic(\"ymonomial.pdf\")"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -135,11 +186,18 @@
" ]\n",
").plot(show_scalar_bar=True, jupyter_backend=\"static\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "qlbm-cpu-venv",
"language": "python",
"name": "python3"
},
Expand All @@ -153,7 +211,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.13.9"
}
},
"nbformat": 4,
Expand Down
4 changes: 3 additions & 1 deletion qlbm/components/cqlbm.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ def create_circuit(self):
if isinstance(self.lattice, MSLattice):
if self.use_agnostic_bcs:
raise CircuitException("Agnostic BCs are not supported for the MSQLBM.")
return MSQLBM(cast(MSLattice, self.lattice), self.logger).circuit
return MSQLBM(
cast(MSLattice, self.lattice), group_velocities=True, logger=self.logger
).circuit
elif isinstance(self.lattice, ABLattice):
return ABQLBM(
cast(ABLattice, self.lattice),
Expand Down
11 changes: 9 additions & 2 deletions qlbm/components/ms/msqlbm.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@ class MSQLBM(LBMAlgorithm):
========================= ======================================================================
:attr:`lattice` The :class:`.MSLattice` based on which the properties of the operator are inferred.
:attr:`logger` The performance logger, by default ``getLogger("qlbm")``.
:attr:`group_velocities` Whether to group velocities into 1 streaming step in the CFL series.
========================= ======================================================================
"""

def __init__(
self,
lattice: MSLattice,
group_velocities: bool = False,
logger: Logger = getLogger("qlbm"),
) -> None:
super().__init__(lattice, logger)
self.lattice: MSLattice = lattice
self.group_velocities = group_velocities

self.logger.info(f"Creating circuit {str(self)}...")
circuit_creation_start_time = perf_counter_ns()
Expand All @@ -55,8 +58,12 @@ def __init__(
@override
def create_circuit(self):
# Assumes equal velocities in all dimensions
# ! TODO adapt to DnQm discretization
time_series = get_time_series(2 ** self.lattice.num_velocities[0].bit_length())
time_series = get_time_series(
2 ** self.lattice.num_velocities[0].bit_length(),
group_velocities=self.group_velocities,
)

print(time_series)
circuit = QuantumCircuit(
*self.lattice.registers,
)
Expand Down
45 changes: 45 additions & 0 deletions qlbm/tools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,50 @@ def is_two_pow(num: int) -> bool:
return (num & (num - 1) == 0) and num != 0


def greedy_grouping(schedule: List[List[int]]) -> List[List[int]]:
"""
Greedily groups schedule into maximally sized groups.

This function is designed to be used with the ordered output of
get_time_series. Using this function with arbitrary schedules
might not give optimal groupings.

Parameters
----------
schedule : List[List[int]]
The ouput of the cfl counter in get_time_series

Returns
-------
List[List[int]]
Maximally grouped schedule
"""
flattened_schedule = np.concatenate(schedule).tolist()

groups = []
current_group: List[int] = []
seen = set()

for mag in flattened_schedule:
if mag in seen:
groups.append(current_group)
current_group = [mag]
seen = {mag}
else:
current_group.append(mag)
seen.add(mag)

if current_group:
groups.append(current_group)

return groups


def get_time_series(
num_discrete_velocities: int,
max_allowed_iters: int = 10000,
tolerance: float = 1e-6,
group_velocities: bool = True,
) -> List[List[int]]:
"""
Compute a time series of the streaming velocities for a given number of discrete velocities.
Expand All @@ -198,6 +238,8 @@ def get_time_series(
The number of iterations before truncating the time series, by default 10000
tolerance : float, optional
The level of precision required to truncate the time sries, by default 1e-6
group_velocities : bool, optional
When True, runs greedy grouping before returning schedule

Returns
-------
Expand Down Expand Up @@ -256,6 +298,9 @@ def get_time_series(
):
break

if group_velocities:
speed_controls = greedy_grouping(speed_controls)

return speed_controls # type: ignore


Expand Down
Loading