fullwave25 1.4.0.dev0__tar.gz → 1.4.1.dev1__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.dev0 → fullwave25-1.4.1.dev1}/.bumpversion.toml +1 -1
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/PKG-INFO +1 -1
- fullwave25-1.4.1.dev1/docker/Dockerfile +59 -0
- fullwave25-1.4.1.dev1/docker/Dockerfile.dockerignore +10 -0
- fullwave25-1.4.1.dev1/docker/README.md +78 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/__init__.py +1 -1
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/binary_manager.py +1 -1
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/cuda_utils.py +36 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/launcher.py +46 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/pyproject.toml +1 -1
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/uv.lock +1 -1
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/.gitignore +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/.pre-commit-config.yaml +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/.python-version +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/CITATION.cff +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/CONTRIBUTING.md +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/LICENSE +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/Makefile +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/README.md +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/attenuation.png +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/beamformer.m +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/experiments/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/experiments/exp_scatterer_diameter.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/beamformer/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/beamformer/beamformer.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/constants/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/constants/material_properties.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/grid.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/domain.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/medium_builder.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/data/.keep +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/data/abdominal_wall/i2365f_etfw1.mat +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_abdominal_wall.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_background.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_scatterer.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_simple.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_water_gel.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/sensor.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda129 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130 +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/database/relaxation_params_database_num_relax=3_20260828_1513.mat +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/database/relaxation_params_database_num_relax=3_20260828_1513_invalid_cells.json +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/database/relaxation_params_database_num_relax=4_20260828_1456.mat +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/bins/database/relaxation_params_database_num_relax=4_20260828_1456_invalid_cells.json +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/input_file_writer.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/pml_builder.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/shipped_database.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/solver.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/source_type.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/solver/utils.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/source.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/transducer.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/transmit.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/__init__.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/check_functions.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/coordinates.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/memory_tempfile.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/numerical.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/plot_utils.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/pulse.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/relaxation_parameters.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/scatterer.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/signal_filter.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/utils/signal_process.py +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/ruff.toml +0 -0
- {fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/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-dev1
|
|
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
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# fullwave25 with the released solver binaries, for Linux systems whose glibc is older than
|
|
2
|
+
# the binaries need (2.34, for example Ubuntu 20.04 or RHEL 8).
|
|
3
|
+
#
|
|
4
|
+
# Build from the repository root:
|
|
5
|
+
# docker build -f docker/Dockerfile -t fullwave25 .
|
|
6
|
+
#
|
|
7
|
+
# See docker/README.md for how to run it with Docker or Apptainer.
|
|
8
|
+
|
|
9
|
+
FROM ubuntu:22.04
|
|
10
|
+
|
|
11
|
+
# The release tag of the solver binaries, and the CUDA versions to include. The wrapper
|
|
12
|
+
# picks the binary that matches the CUDA version of the host driver.
|
|
13
|
+
ARG FULLWAVE_BIN_TAG=fullwave_bin_v1.5.2
|
|
14
|
+
ARG FULLWAVE_BIN_CUDA_VERSIONS="118 124 129 130"
|
|
15
|
+
ARG PYTHON_VERSION=3.12
|
|
16
|
+
|
|
17
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
18
|
+
RUN apt-get update \
|
|
19
|
+
&& apt-get install -y --no-install-recommends ca-certificates curl ffmpeg \
|
|
20
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
21
|
+
|
|
22
|
+
COPY --from=ghcr.io/astral-sh/uv:0.9.9 /uv /usr/local/bin/uv
|
|
23
|
+
|
|
24
|
+
ENV UV_PYTHON_INSTALL_DIR=/opt/python \
|
|
25
|
+
UV_LINK_MODE=copy \
|
|
26
|
+
UV_COMPILE_BYTECODE=1 \
|
|
27
|
+
VIRTUAL_ENV=/opt/venv \
|
|
28
|
+
PATH=/opt/venv/bin:${PATH}
|
|
29
|
+
RUN uv venv --python ${PYTHON_VERSION} /opt/venv
|
|
30
|
+
|
|
31
|
+
COPY . /opt/fullwave25-src
|
|
32
|
+
# The [ctk] extra installs the CUDA libraries and headers that CuPy needs at run time.
|
|
33
|
+
RUN uv pip install --no-cache /opt/fullwave25-src \
|
|
34
|
+
&& uv pip install --no-cache "cupy-cuda12x[ctk]==$(python -c "import importlib.metadata as m; print(m.version('cupy-cuda12x'))")"
|
|
35
|
+
|
|
36
|
+
# Put the solver binaries where the installed package looks first, so a run needs no
|
|
37
|
+
# download and works when the home directory is mounted from the host (Apptainer).
|
|
38
|
+
RUN set -eu; \
|
|
39
|
+
bins="$(python -c "import importlib.util; print(importlib.util.find_spec('fullwave').submodule_search_locations[0])")/solver/bins"; \
|
|
40
|
+
url="https://github.com/pinton-lab/fullwave25/releases/download/${FULLWAVE_BIN_TAG}"; \
|
|
41
|
+
for cuda in ${FULLWAVE_BIN_CUDA_VERSIONS}; do \
|
|
42
|
+
for dim in 2d 3d; do \
|
|
43
|
+
mkdir -p "${bins}/gpu/${dim}" "${bins}/exponential_attenuation/gpu/${dim}"; \
|
|
44
|
+
curl -fsSL -o "${bins}/gpu/${dim}/fullwave2_${dim}_n_relax_multi_gpu_cuda${cuda}" \
|
|
45
|
+
"${url}/fullwave2_${dim}_n_relax_multi_gpu_cuda${cuda}"; \
|
|
46
|
+
curl -fsSL -o "${bins}/exponential_attenuation/gpu/${dim}/fullwave2_${dim}_exponential_attenuation_multi_gpu_cuda${cuda}" \
|
|
47
|
+
"${url}/fullwave2_${dim}_exponential_attenuation_multi_gpu_cuda${cuda}"; \
|
|
48
|
+
done; \
|
|
49
|
+
done; \
|
|
50
|
+
chmod 755 "${bins}"/gpu/*/* "${bins}"/exponential_attenuation/gpu/*/*; \
|
|
51
|
+
echo "${FULLWAVE_BIN_TAG}" > "${bins}/RELEASE_TAG"
|
|
52
|
+
|
|
53
|
+
# A container started with --user has no home of its own, so the caches of CuPy,
|
|
54
|
+
# matplotlib and numba go to /tmp. Apptainer sets HOME to the host home instead.
|
|
55
|
+
ENV HOME=/tmp \
|
|
56
|
+
NUMBA_CACHE_DIR=/tmp/numba
|
|
57
|
+
|
|
58
|
+
WORKDIR /work
|
|
59
|
+
CMD ["python"]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# fullwave25 in a container
|
|
2
|
+
|
|
3
|
+
The released solver binaries need glibc 2.34 or newer (for example Ubuntu 22.04, Debian 12 or RHEL 9). On an older system, such as Ubuntu 20.04 or RHEL 8, they stop at start with an error like:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This image runs fullwave25 and the released solver binaries on such a system. The host needs only an NVIDIA driver for CUDA 12.0 or newer, and Docker with the NVIDIA Container Toolkit, or Apptainer.
|
|
10
|
+
|
|
11
|
+
The image contains:
|
|
12
|
+
|
|
13
|
+
- Ubuntu 22.04
|
|
14
|
+
- Python 3.12 and fullwave25, installed from this repository checkout, with the CUDA 12 libraries that CuPy needs
|
|
15
|
+
- the solver binaries of the release `fullwave_bin_v1.5.2`, for CUDA 11.8, 12.4, 12.9 and 13.0
|
|
16
|
+
- `ffmpeg`, for the video export of the plotting functions
|
|
17
|
+
|
|
18
|
+
## Build
|
|
19
|
+
|
|
20
|
+
Run from the repository root:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
docker build -f docker/Dockerfile -t fullwave25 .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
To use another release of the solver binaries:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
docker build -f docker/Dockerfile -t fullwave25 --build-arg FULLWAVE_BIN_TAG=<release tag> .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Run with Docker
|
|
33
|
+
|
|
34
|
+
Mount your working directory at `/work` and run your script there. The outputs are written to your working directory, owned by your user.
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
docker run --rm --gpus all --user "$(id -u):$(id -g)" \
|
|
38
|
+
-v "$PWD":/work fullwave25 python my_simulation.py
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `--gpus all` is not available, use `--device nvidia.com/gpu=all` (CDI).
|
|
42
|
+
|
|
43
|
+
To use selected GPUs, pass them to fullwave25 as usual with `cuda_device_id` in `fullwave.Solver`.
|
|
44
|
+
|
|
45
|
+
## Run with Apptainer
|
|
46
|
+
|
|
47
|
+
Apptainer runs the same image without Docker. Build the image on a machine with Docker, and save it to a file:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
docker save fullwave25 -o fullwave25.tar
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Copy `fullwave25.tar` to the target machine, and convert it there:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
apptainer build fullwave25.sif docker-archive://fullwave25.tar
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The saved image is about 4.3 GB and the `.sif` file about 2.3 GB, and the conversion needs temporary space of several GB in addition. If `/tmp` is small, set `APPTAINER_TMPDIR` and `APPTAINER_CACHEDIR` to a folder on a larger disk.
|
|
60
|
+
|
|
61
|
+
Then run your script. `--nv` gives the container the GPUs and the driver of the host. Apptainer mounts your home and the current directory by default.
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
apptainer exec --nv fullwave25.sif python my_simulation.py
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If Apptainer prints `Error changing the container working directory`, your working directory is reached through a link to another disk. Run from its real path:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
cd "$(pwd -P)"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Check the installation
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
apptainer exec --nv fullwave25.sif python -c "import fullwave; print(fullwave.__version__)"
|
|
77
|
+
docker run --rm --gpus all fullwave25 nvidia-smi -L
|
|
78
|
+
```
|
|
@@ -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-dev1"
|
|
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.2"
|
|
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-dev1" # 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
|
|
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
|
{fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_background.py
RENAMED
|
File without changes
|
{fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_scatterer.py
RENAMED
|
File without changes
|
{fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/fullwave/medium_builder/presets/domain_simple.py
RENAMED
|
File without changes
|
{fullwave25-1.4.0.dev0 → fullwave25-1.4.1.dev1}/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
|