fullwave25 1.4.0__tar.gz → 1.4.1.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/.bumpversion.toml +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/PKG-INFO +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/__init__.py +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/binary_manager.py +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/cuda_utils.py +36 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/launcher.py +46 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/pyproject.toml +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/uv.lock +1 -1
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/.gitignore +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/.pre-commit-config.yaml +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/.python-version +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/CITATION.cff +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/CONTRIBUTING.md +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/LICENSE +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/Makefile +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/README.md +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/attenuation.png +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/beamformer.m +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/experiments/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/experiments/exp_scatterer_diameter.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/beamformer/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/beamformer/beamformer.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/constants/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/constants/material_properties.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/grid.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/domain.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/medium_builder.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/data/.keep +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/data/abdominal_wall/i2365f_etfw1.mat +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_abdominal_wall.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_background.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_scatterer.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_simple.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_water_gel.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/sensor.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda129 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130 +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/database/relaxation_params_database_num_relax=3_20260828_1513.mat +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/database/relaxation_params_database_num_relax=3_20260828_1513_invalid_cells.json +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/database/relaxation_params_database_num_relax=4_20260828_1456.mat +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/bins/database/relaxation_params_database_num_relax=4_20260828_1456_invalid_cells.json +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/input_file_writer.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/pml_builder.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/shipped_database.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/solver.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/source_type.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/solver/utils.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/source.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/transducer.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/transmit.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/__init__.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/check_functions.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/coordinates.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/memory_tempfile.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/numerical.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/plot_utils.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/pulse.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/relaxation_parameters.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/scatterer.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/signal_filter.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/utils/signal_process.py +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/ruff.toml +0 -0
- {fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/signal_filter_example.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fullwave25
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.1-dev0
|
|
4
4
|
Summary: Fullwave 2.5: Ultrasound wave propagation simulation with heterogeneous power law attenuation modelling capabilities
|
|
5
5
|
Author: Masashi Sode, Gianmarco Pinton
|
|
6
6
|
Maintainer: Masashi Sode
|
|
@@ -66,7 +66,7 @@ try:
|
|
|
66
66
|
__version__ = version("fullwave")
|
|
67
67
|
except PackageNotFoundError:
|
|
68
68
|
# Update via bump-my-version, not manually
|
|
69
|
-
__version__ = "1.4.
|
|
69
|
+
__version__ = "1.4.1-dev0"
|
|
70
70
|
|
|
71
71
|
VERSION = __version__ # for convenience
|
|
72
72
|
logger.info("Fullwave version: %s", __version__)
|
|
@@ -28,7 +28,7 @@ CACHE_DIR = Path.home() / ".cache" / "fullwave25" / "bins"
|
|
|
28
28
|
|
|
29
29
|
# Pinned release tag for the solver binaries.
|
|
30
30
|
# Update this only when new binaries are uploaded to a GitHub release.
|
|
31
|
-
BINARY_RELEASE_TAG = "fullwave_bin_v1.5"
|
|
31
|
+
BINARY_RELEASE_TAG = "fullwave_bin_v1.5.1"
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _download_url(filename: str, tag: str) -> str:
|
|
@@ -213,6 +213,42 @@ def cuCtxDetach(ctx): # noqa: ANN001, ANN201, D103, N802
|
|
|
213
213
|
return cuda.cuCtxDetach(ctx)
|
|
214
214
|
|
|
215
215
|
|
|
216
|
+
@cuda_api_call
|
|
217
|
+
def cuDeviceCanAccessPeer(can_access, dev, peer_dev): # noqa: ANN001, ANN201, D103, N802
|
|
218
|
+
return cuda.cuDeviceCanAccessPeer(can_access, dev, peer_dev)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def find_consecutive_gpus_without_peer_access(ordinals: list[int]) -> list[tuple[int, int]]:
|
|
222
|
+
"""Return the consecutive GPU pairs that cannot access each other's memory directly.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
ordinals : list[int]
|
|
227
|
+
CUDA device ordinals as this process sees them, in the requested order.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
list[tuple[int, int]]
|
|
232
|
+
Each consecutive pair (a, b) of ``ordinals`` where a cannot access b or b
|
|
233
|
+
cannot access a.
|
|
234
|
+
|
|
235
|
+
"""
|
|
236
|
+
cuInit(0)
|
|
237
|
+
pairs = []
|
|
238
|
+
for first, second in zip(ordinals, ordinals[1:], strict=False):
|
|
239
|
+
device_first = ctypes.c_int()
|
|
240
|
+
device_second = ctypes.c_int()
|
|
241
|
+
cuDeviceGet(ctypes.byref(device_first), first)
|
|
242
|
+
cuDeviceGet(ctypes.byref(device_second), second)
|
|
243
|
+
forward = ctypes.c_int()
|
|
244
|
+
backward = ctypes.c_int()
|
|
245
|
+
cuDeviceCanAccessPeer(ctypes.byref(forward), device_first, device_second)
|
|
246
|
+
cuDeviceCanAccessPeer(ctypes.byref(backward), device_second, device_first)
|
|
247
|
+
if not forward.value or not backward.value:
|
|
248
|
+
pairs.append((first, second))
|
|
249
|
+
return pairs
|
|
250
|
+
|
|
251
|
+
|
|
216
252
|
# Main function to get CUDA device specs
|
|
217
253
|
@lru_cache(maxsize=1)
|
|
218
254
|
def get_cuda_device_specs() -> list[dict[str, Any]]:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Module for launching Fullwave simulation."""
|
|
2
2
|
|
|
3
|
+
import ctypes
|
|
3
4
|
import logging
|
|
4
5
|
import os
|
|
5
6
|
import re
|
|
@@ -79,6 +80,8 @@ class Launcher:
|
|
|
79
80
|
cuda_device_id,
|
|
80
81
|
verify_gpu=verify_gpu,
|
|
81
82
|
)
|
|
83
|
+
if use_gpu and verify_gpu:
|
|
84
|
+
self._warn_if_gpus_lack_peer_access(self.cuda_device_id)
|
|
82
85
|
self.save_gpu_memory = save_gpu_memory
|
|
83
86
|
logger.debug("Launcher instance created.")
|
|
84
87
|
|
|
@@ -160,6 +163,49 @@ class Launcher:
|
|
|
160
163
|
message = f"CUDA device ID {device_id} does not exist."
|
|
161
164
|
raise ValueError(message)
|
|
162
165
|
|
|
166
|
+
@staticmethod
|
|
167
|
+
def _warn_if_gpus_lack_peer_access(device_id_str: str) -> None:
|
|
168
|
+
"""Warn when consecutive GPUs of a multi-GPU run have no peer-to-peer access.
|
|
169
|
+
|
|
170
|
+
Without peer access (no NVLink, and a PCIe chipset or GPU that refuses it,
|
|
171
|
+
as on GeForce cards), a multi-GPU run is much slower than with peer access.
|
|
172
|
+
|
|
173
|
+
The binary runs with ``CUDA_VISIBLE_DEVICES`` set to ``device_id_str``. The
|
|
174
|
+
CUDA ordinals of this process name the same GPUs only when this process has
|
|
175
|
+
no ``CUDA_VISIBLE_DEVICES`` of its own, so the check is skipped otherwise.
|
|
176
|
+
It never raises: if the CUDA driver cannot answer, it logs at debug level.
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
device_id_str : str
|
|
181
|
+
The CUDA device ID(s) in string format, for example "0,1,2,3".
|
|
182
|
+
|
|
183
|
+
"""
|
|
184
|
+
device_ids = [int(device_id) for device_id in device_id_str.split(",")]
|
|
185
|
+
if len(device_ids) < 2:
|
|
186
|
+
return
|
|
187
|
+
if "CUDA_VISIBLE_DEVICES" in os.environ:
|
|
188
|
+
logger.debug(
|
|
189
|
+
"Peer access check skipped: CUDA_VISIBLE_DEVICES is set in this process.",
|
|
190
|
+
)
|
|
191
|
+
return
|
|
192
|
+
try:
|
|
193
|
+
from .cuda_utils import find_consecutive_gpus_without_peer_access # noqa: PLC0415
|
|
194
|
+
|
|
195
|
+
pairs = find_consecutive_gpus_without_peer_access(device_ids)
|
|
196
|
+
except (AttributeError, NameError, OSError, RuntimeError, ctypes.ArgumentError) as error:
|
|
197
|
+
logger.debug("Peer access check skipped: %s", error)
|
|
198
|
+
return
|
|
199
|
+
if not pairs:
|
|
200
|
+
return
|
|
201
|
+
pair_text = ", ".join(f"GPU {first} <-> GPU {second}" for first, second in pairs)
|
|
202
|
+
logger.warning(
|
|
203
|
+
"No peer-to-peer access between %s. A multi-GPU run on these GPUs is much "
|
|
204
|
+
"slower than on GPUs with NVLink or PCIe peer access. Check with a short "
|
|
205
|
+
"run whether fewer GPUs give a faster simulation.",
|
|
206
|
+
pair_text,
|
|
207
|
+
)
|
|
208
|
+
|
|
163
209
|
@staticmethod
|
|
164
210
|
def _configure_cuda_device_id(
|
|
165
211
|
cuda_device_id: str | int | list | None,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "fullwave25"
|
|
3
|
-
version = "1.4.
|
|
3
|
+
version = "1.4.1-dev0" # Update via bump-my-version, not manually
|
|
4
4
|
description = "Fullwave 2.5: Ultrasound wave propagation simulation with heterogeneous power law attenuation modelling capabilities"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/debug_solver_bin/fullwave2_2d_2_relax_multi_gpu_cuda124
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_abdominal_wall.py
RENAMED
|
File without changes
|
{fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_background.py
RENAMED
|
File without changes
|
{fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_scatterer.py
RENAMED
|
File without changes
|
|
File without changes
|
{fullwave25-1.4.0 → fullwave25-1.4.1.dev0}/fullwave/medium_builder/presets/domain_water_gel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|