fullwave25 1.2.2.dev0__tar.gz → 1.2.3__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.2.2.dev0 → fullwave25-1.2.3}/.bumpversion.toml +1 -1
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/PKG-INFO +1 -1
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/__init__.py +1 -1
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/grid.py +3 -3
- fullwave25-1.2.3/fullwave/solver/binary_manager.py +150 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124 +0 -0
- {fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu → fullwave25-1.2.3/fullwave/solver/bins/_gpu}/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda129 +0 -0
- fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130 +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/input_file_writer.py +12 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/launcher.py +20 -1
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/pml_builder.py +14 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/solver.py +17 -1
- fullwave25-1.2.3/fullwave/source.py +326 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/transducer.py +177 -173
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/pyproject.toml +2 -2
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/uv.lock +1 -1
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_multi_gpu_cuda129 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_multi_gpu_cuda130 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_multi_gpu_cuda129 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_multi_gpu_cuda130 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124 +0 -0
- fullwave25-1.2.2.dev0/fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130 +0 -0
- fullwave25-1.2.2.dev0/fullwave/source.py +0 -206
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/.gitignore +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/.pre-commit-config.yaml +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/.python-version +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/20260120_0844.log +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/CITATION.cff +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/CLAUDE.md +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/CONTRIBUTING.md +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/LICENSE +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/Makefile +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/README.md +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/beamformer.m +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/experiments/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/experiments/exp_scatterer_diameter.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/beamformer/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/beamformer/beamformer.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/constants/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/constants/material_properties.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/domain.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/medium_builder.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/data/.keep +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/data/abdominal_wall/i2365f_etfw1.mat +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/domain_abdominal_wall.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/domain_background.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/domain_scatterer.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/domain_simple.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/medium_builder/presets/domain_water_gel.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/sensor.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/bins/database/relaxation_params_database_num_relax=2_20260113_0957.mat +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/cuda_utils.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/solver/utils.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/__init__.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/check_functions.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/coordinates.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/memory_tempfile.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/numerical.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/plot_utils.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/pulse.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/relaxation_parameters.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/scatterer.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/fullwave/utils/signal_process.py +0 -0
- {fullwave25-1.2.2.dev0 → fullwave25-1.2.3}/ruff.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fullwave25
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
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
|
|
@@ -60,7 +60,7 @@ try:
|
|
|
60
60
|
__version__ = version("fullwave")
|
|
61
61
|
except PackageNotFoundError:
|
|
62
62
|
# Update via bump-my-version, not manually
|
|
63
|
-
__version__ = "1.2.
|
|
63
|
+
__version__ = "1.2.3"
|
|
64
64
|
|
|
65
65
|
VERSION = __version__ # for convenience
|
|
66
66
|
logger.info("Fullwave version: %s", __version__)
|
|
@@ -183,9 +183,9 @@ class Grid:
|
|
|
183
183
|
else " Grid spacing (grid.dx, grid.dy): "
|
|
184
184
|
)
|
|
185
185
|
grid_spacing_str = (
|
|
186
|
-
f"({self.dx * 1e3:.2e}
|
|
186
|
+
f"({self.dx * 1e3:.2e} mm, {self.dy * 1e3:.2e} mm, {self.dz * 1e3:.2e} mm)"
|
|
187
187
|
if self.is_3d
|
|
188
|
-
else f"({self.dx * 1e3:.2e}
|
|
188
|
+
else f"({self.dx * 1e3:.2e} mm, {self.dy * 1e3:.2e} mm)"
|
|
189
189
|
)
|
|
190
190
|
|
|
191
191
|
num_grid_points_str_desc = (
|
|
@@ -203,7 +203,7 @@ class Grid:
|
|
|
203
203
|
f" Speed of sound (grid.c0): {self.c0} m/s\n"
|
|
204
204
|
f" Points per wavelength (PPW) (grid.ppw): {self.ppw}\n"
|
|
205
205
|
f" Courant-Friedrichs-Lewy (CFL) number (grid.cfl): {self.cfl}\n"
|
|
206
|
-
f" Wavelength (grid.wavelength): {self.wavelength * 1e3:.2e}
|
|
206
|
+
f" Wavelength (grid.wavelength): {self.wavelength * 1e3:.2e} mm\n"
|
|
207
207
|
+ grid_spacing_str_desc
|
|
208
208
|
+ grid_spacing_str
|
|
209
209
|
+ "\n"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""Binary manager for fullwave solver executables.
|
|
2
|
+
|
|
3
|
+
Handles locating, caching, and downloading solver binaries from GitHub releases.
|
|
4
|
+
|
|
5
|
+
Priority order when resolving a binary:
|
|
6
|
+
1. Bundled binary (shipped with the package or dev install).
|
|
7
|
+
2. Local cache at ``~/.cache/fullwave25/bins/``.
|
|
8
|
+
3. Download from the GitHub release pinned by ``BINARY_RELEASE_TAG``.
|
|
9
|
+
|
|
10
|
+
Binaries are versioned independently from the Python package — update
|
|
11
|
+
``BINARY_RELEASE_TAG`` only when new binaries are published.
|
|
12
|
+
|
|
13
|
+
The release tag can be overridden at runtime with the environment variable
|
|
14
|
+
``FULLWAVE25_BINARY_TAG`` (e.g. ``export FULLWAVE25_BINARY_TAG=v1.2.2``).
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
import os
|
|
19
|
+
import stat
|
|
20
|
+
import urllib.error
|
|
21
|
+
import urllib.request
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger("__main__." + __name__)
|
|
25
|
+
|
|
26
|
+
GITHUB_REPO = "pinton-lab/fullwave25"
|
|
27
|
+
CACHE_DIR = Path.home() / ".cache" / "fullwave25" / "bins"
|
|
28
|
+
|
|
29
|
+
# Pinned release tag for the solver binaries.
|
|
30
|
+
# Update this only when new binaries are uploaded to a GitHub release.
|
|
31
|
+
BINARY_RELEASE_TAG = "fullwave_bin_v1.1"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _download_url(filename: str, tag: str) -> str:
|
|
35
|
+
return f"https://github.com/{GITHUB_REPO}/releases/download/{tag}/{filename}"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _download_binary(url: str, dest: Path) -> None:
|
|
39
|
+
"""Download *url* to *dest*, showing a tqdm progress bar when available."""
|
|
40
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
tmp = dest.with_suffix(".download_tmp")
|
|
42
|
+
try:
|
|
43
|
+
try:
|
|
44
|
+
from tqdm import tqdm
|
|
45
|
+
|
|
46
|
+
class _Hook:
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
self._bar: tqdm | None = None
|
|
49
|
+
|
|
50
|
+
def __call__(self, block: int, block_size: int, total: int) -> None: # noqa: ARG002
|
|
51
|
+
if self._bar is None:
|
|
52
|
+
self._bar = tqdm(
|
|
53
|
+
total=total if total > 0 else None,
|
|
54
|
+
unit="B",
|
|
55
|
+
unit_scale=True,
|
|
56
|
+
desc=dest.name,
|
|
57
|
+
)
|
|
58
|
+
self._bar.update(block_size)
|
|
59
|
+
|
|
60
|
+
def close(self) -> None:
|
|
61
|
+
if self._bar is not None:
|
|
62
|
+
self._bar.close()
|
|
63
|
+
|
|
64
|
+
hook = _Hook()
|
|
65
|
+
try:
|
|
66
|
+
urllib.request.urlretrieve(url, tmp, reporthook=hook) # noqa: S310
|
|
67
|
+
finally:
|
|
68
|
+
hook.close()
|
|
69
|
+
|
|
70
|
+
except ImportError:
|
|
71
|
+
urllib.request.urlretrieve(url, tmp) # noqa: S310
|
|
72
|
+
|
|
73
|
+
tmp.rename(dest)
|
|
74
|
+
dest.chmod(dest.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
75
|
+
logger.info("Binary saved to %s", dest)
|
|
76
|
+
|
|
77
|
+
except Exception:
|
|
78
|
+
tmp.unlink(missing_ok=True)
|
|
79
|
+
raise
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def ensure_binary(local_path: Path) -> Path:
|
|
83
|
+
"""Return an executable path for the solver binary.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
local_path:
|
|
88
|
+
The expected bundled path (as computed by ``_retrieve_fullwave_simulation_path``).
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
Path
|
|
93
|
+
Resolved path to an executable binary.
|
|
94
|
+
|
|
95
|
+
Raises
|
|
96
|
+
------
|
|
97
|
+
RuntimeError
|
|
98
|
+
If the binary cannot be found locally and the download fails.
|
|
99
|
+
|
|
100
|
+
"""
|
|
101
|
+
# 1. Bundled binary present (dev install or package that still ships binaries).
|
|
102
|
+
if local_path.exists():
|
|
103
|
+
logger.debug("Using bundled binary: %s", local_path)
|
|
104
|
+
return local_path
|
|
105
|
+
|
|
106
|
+
filename = local_path.name
|
|
107
|
+
|
|
108
|
+
# Resolve the required tag first so cache lookup is always tag-specific.
|
|
109
|
+
# This ensures that when BINARY_RELEASE_TAG is bumped (e.g. after a package
|
|
110
|
+
# update) the old cached binary is not silently reused — each tag gets its
|
|
111
|
+
# own subdirectory under CACHE_DIR.
|
|
112
|
+
tag = os.environ.get("FULLWAVE25_BINARY_TAG", BINARY_RELEASE_TAG)
|
|
113
|
+
cached = CACHE_DIR / tag / filename
|
|
114
|
+
|
|
115
|
+
# 2. Previously downloaded and cached for this exact tag.
|
|
116
|
+
if cached.exists():
|
|
117
|
+
logger.debug("Using cached binary: %s", cached)
|
|
118
|
+
return cached
|
|
119
|
+
|
|
120
|
+
# 3. Download from GitHub releases.
|
|
121
|
+
url = _download_url(filename, tag)
|
|
122
|
+
|
|
123
|
+
logger.info(
|
|
124
|
+
"Binary '%s' not found locally. Downloading from GitHub release '%s' …",
|
|
125
|
+
filename,
|
|
126
|
+
tag,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
_download_binary(url, cached)
|
|
131
|
+
except urllib.error.HTTPError as e:
|
|
132
|
+
msg = (
|
|
133
|
+
f"Could not download binary '{filename}' from:\n {url}\n"
|
|
134
|
+
f"HTTP error: {e.code} {e.reason}\n\n"
|
|
135
|
+
"Possible fixes:\n"
|
|
136
|
+
f" • Check that release '{tag}' exists and contains '{filename}'.\n"
|
|
137
|
+
f" • Override the tag: export FULLWAVE25_BINARY_TAG=<tag>\n"
|
|
138
|
+
f" • Place the binary manually at: {cached}\n"
|
|
139
|
+
)
|
|
140
|
+
raise RuntimeError(msg) from e
|
|
141
|
+
except Exception as e:
|
|
142
|
+
msg = (
|
|
143
|
+
f"Failed to download binary '{filename}' from:\n {url}\n"
|
|
144
|
+
f"Error: {e}\n\n"
|
|
145
|
+
f" • Place the binary manually at: {cached}\n"
|
|
146
|
+
f" • Or override the tag: export FULLWAVE25_BINARY_TAG=<tag>\n"
|
|
147
|
+
)
|
|
148
|
+
raise RuntimeError(msg) from e
|
|
149
|
+
|
|
150
|
+
return cached
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118
ADDED
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124
ADDED
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129
ADDED
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130
ADDED
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118
ADDED
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124
ADDED
|
Binary file
|
|
Binary file
|
fullwave25-1.2.3/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130
ADDED
|
Binary file
|
|
@@ -160,6 +160,15 @@ class InputFileWriter:
|
|
|
160
160
|
simulation_dir / "icmat.dat",
|
|
161
161
|
np.transpose(self.source.icmat),
|
|
162
162
|
)
|
|
163
|
+
p0_additive = getattr(self.source, "p0_additive", None)
|
|
164
|
+
incoords_add = getattr(self.source, "incoords_add", None)
|
|
165
|
+
if p0_additive is not None:
|
|
166
|
+
self._queue_ic_write(
|
|
167
|
+
simulation_dir / "icmat_add.dat",
|
|
168
|
+
np.transpose(p0_additive),
|
|
169
|
+
)
|
|
170
|
+
if incoords_add is not None:
|
|
171
|
+
self._queue_coords_write(simulation_dir / "icc_add.dat", incoords_add)
|
|
163
172
|
self._queue_coords_write(simulation_dir / "icc.dat", self.source.incoords)
|
|
164
173
|
self._copy_simulation_bin_file(simulation_dir)
|
|
165
174
|
|
|
@@ -1035,6 +1044,9 @@ class InputFileWriter:
|
|
|
1035
1044
|
("nTic", nt_ic),
|
|
1036
1045
|
("modT", self.sensor.sampling_modulus_time),
|
|
1037
1046
|
]
|
|
1047
|
+
n_sources_add = getattr(self.source, "n_sources_add", 0)
|
|
1048
|
+
if n_sources_add > 0:
|
|
1049
|
+
var_list.append(("ncoords_add", n_sources_add))
|
|
1038
1050
|
if self.is_3d:
|
|
1039
1051
|
var_list.extend(
|
|
1040
1052
|
[
|
|
@@ -30,6 +30,7 @@ class Launcher:
|
|
|
30
30
|
is_3d: bool = False,
|
|
31
31
|
use_gpu: bool = True,
|
|
32
32
|
cuda_device_id: str | int | list | None = None,
|
|
33
|
+
save_gpu_memory: bool = False,
|
|
33
34
|
) -> None:
|
|
34
35
|
"""Initialize a FullwaveLauncher instance.
|
|
35
36
|
|
|
@@ -50,6 +51,17 @@ class Launcher:
|
|
|
50
51
|
for multiple GPUs, provide a list of device IDs.
|
|
51
52
|
example 1: [0, 1] for using GPU 0 and GPU 1. or "0,1" as a string.
|
|
52
53
|
example 2: 2 for using GPU 2 or "2" as a string.
|
|
54
|
+
save_gpu_memory : bool, optional
|
|
55
|
+
Whether to save GPU memory by using ICMAT_MEMORY_SAVING flag in the simulation.
|
|
56
|
+
The simulation does not load initial conditions into GPU memory and
|
|
57
|
+
it loads the slice of the wavefield needed for the current time step
|
|
58
|
+
from CPU memory at each time step.
|
|
59
|
+
Defaults to False. If True, it may significantly reduce GPU memory usage,
|
|
60
|
+
but it may also increase the simulation time
|
|
61
|
+
due to the overhead of data transfer between CPU and GPU
|
|
62
|
+
depending on the hardware and the simulation settings.
|
|
63
|
+
useful in 3D simulations with large grid sizes
|
|
64
|
+
where GPU memory is a limiting factor.
|
|
53
65
|
|
|
54
66
|
"""
|
|
55
67
|
self._path_fullwave_simulation_bin = path_fullwave_simulation_bin
|
|
@@ -58,6 +70,7 @@ class Launcher:
|
|
|
58
70
|
self.is_3d = is_3d
|
|
59
71
|
self.use_gpu = use_gpu
|
|
60
72
|
self.cuda_device_id = self._configure_cuda_device_id(cuda_device_id)
|
|
73
|
+
self.save_gpu_memory = save_gpu_memory
|
|
61
74
|
logger.debug("Launcher instance created.")
|
|
62
75
|
|
|
63
76
|
@staticmethod
|
|
@@ -203,7 +216,12 @@ class Launcher:
|
|
|
203
216
|
logger.info("Running simulation...")
|
|
204
217
|
with (simulation_dir / "fw2_execution.log").open("w", encoding="utf-8") as file:
|
|
205
218
|
time_start = time()
|
|
206
|
-
|
|
219
|
+
env = os.environ.copy()
|
|
220
|
+
env["CUDA_VISIBLE_DEVICES"] = self.cuda_device_id
|
|
221
|
+
if self.save_gpu_memory:
|
|
222
|
+
env["ICMAT_MEMORY_SAVING"] = "1"
|
|
223
|
+
else:
|
|
224
|
+
env["ICMAT_MEMORY_SAVING"] = "0"
|
|
207
225
|
subprocess.run( # noqa: S603
|
|
208
226
|
command,
|
|
209
227
|
check=True,
|
|
@@ -211,6 +229,7 @@ class Launcher:
|
|
|
211
229
|
stdout=file,
|
|
212
230
|
stderr=file,
|
|
213
231
|
text=True,
|
|
232
|
+
env=env,
|
|
214
233
|
# check=False,
|
|
215
234
|
)
|
|
216
235
|
time_passed = time() - time_start
|
|
@@ -317,10 +317,17 @@ class PMLBuilder:
|
|
|
317
317
|
extended_grid_shape = tuple(
|
|
318
318
|
s + 2 * self.num_boundary_points for s in self.source_org.grid_shape
|
|
319
319
|
)
|
|
320
|
+
incoords_add_ext = (
|
|
321
|
+
self.source_org.incoords_add + self.num_boundary_points
|
|
322
|
+
if getattr(self.source_org, "incoords_add", None) is not None
|
|
323
|
+
else None
|
|
324
|
+
)
|
|
320
325
|
self.extended_source = fullwave.Source(
|
|
321
326
|
p0=self.source_org.p0,
|
|
322
327
|
coords=self.source_org.incoords + self.num_boundary_points,
|
|
323
328
|
grid_shape=extended_grid_shape,
|
|
329
|
+
p0_additive=self.source_org.p0_additive,
|
|
330
|
+
coords_additive=incoords_add_ext,
|
|
324
331
|
)
|
|
325
332
|
logger.debug("building extended source for pml...done")
|
|
326
333
|
|
|
@@ -1582,10 +1589,17 @@ class PMLBuilderExponentialAttenuation(PMLBuilder):
|
|
|
1582
1589
|
extended_grid_shape = tuple(
|
|
1583
1590
|
s + 2 * self.num_boundary_points for s in self.source_org.grid_shape
|
|
1584
1591
|
)
|
|
1592
|
+
incoords_add_ext = (
|
|
1593
|
+
self.source_org.incoords_add + self.num_boundary_points
|
|
1594
|
+
if getattr(self.source_org, "incoords_add", None) is not None
|
|
1595
|
+
else None
|
|
1596
|
+
)
|
|
1585
1597
|
self.extended_source = fullwave.Source(
|
|
1586
1598
|
p0=self.source_org.p0,
|
|
1587
1599
|
coords=self.source_org.incoords + self.num_boundary_points,
|
|
1588
1600
|
grid_shape=extended_grid_shape,
|
|
1601
|
+
p0_additive=self.source_org.p0_additive,
|
|
1602
|
+
coords_additive=incoords_add_ext,
|
|
1589
1603
|
)
|
|
1590
1604
|
extended_sensor_grid_shape = tuple(
|
|
1591
1605
|
s + 2 * self.num_boundary_points for s in self.sensor_org.grid_shape
|
|
@@ -16,6 +16,7 @@ from fullwave.utils import (
|
|
|
16
16
|
check_functions,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
+
from .binary_manager import ensure_binary
|
|
19
20
|
from .cuda_utils import get_cuda_architecture, retrieve_cuda_version
|
|
20
21
|
|
|
21
22
|
logger = logging.getLogger("__main__." + __name__)
|
|
@@ -326,6 +327,7 @@ class Solver:
|
|
|
326
327
|
use_exponential_attenuation: bool = False,
|
|
327
328
|
use_isotropic_relaxation: bool = True,
|
|
328
329
|
cuda_device_id: str | int | list | None = None,
|
|
330
|
+
save_gpu_memory: bool = False,
|
|
329
331
|
) -> None:
|
|
330
332
|
"""Initialize a Solver instance for the fullwave simulation.
|
|
331
333
|
|
|
@@ -401,6 +403,17 @@ class Solver:
|
|
|
401
403
|
for multiple GPUs, provide a list of device IDs.
|
|
402
404
|
example 1: [0, 1] for using GPU 0 and GPU 1. or "0,1" as a string.
|
|
403
405
|
example 2: 2 for using GPU 2 or "2" as a string.
|
|
406
|
+
save_gpu_memory : bool, optional
|
|
407
|
+
Whether to save GPU memory by using ICMAT_MEMORY_SAVING flag in the simulation.
|
|
408
|
+
The simulation does not load initial conditions into GPU memory and
|
|
409
|
+
it loads the slice of the wavefield needed for the current time step
|
|
410
|
+
from CPU memory at each time step.
|
|
411
|
+
Defaults to False. If True, it may significantly reduce GPU memory usage,
|
|
412
|
+
but it may also increase the simulation time
|
|
413
|
+
due to the overhead of data transfer between CPU and GPU
|
|
414
|
+
depending on the hardware and the simulation settings.
|
|
415
|
+
useful in 3D simulations with large grid sizes
|
|
416
|
+
where GPU memory is a limiting factor.
|
|
404
417
|
|
|
405
418
|
Raises
|
|
406
419
|
------
|
|
@@ -417,6 +430,7 @@ class Solver:
|
|
|
417
430
|
self.medium: fullwave.Medium
|
|
418
431
|
self.grid: fullwave.Grid
|
|
419
432
|
self.input_file_writer: InputFileWriter
|
|
433
|
+
self.save_gpu_memory = save_gpu_memory
|
|
420
434
|
|
|
421
435
|
self.run_on_memory = run_on_memory
|
|
422
436
|
if run_on_memory:
|
|
@@ -461,13 +475,14 @@ class Solver:
|
|
|
461
475
|
self.n_relax_mechanisms = medium.n_relaxation_mechanisms
|
|
462
476
|
|
|
463
477
|
if path_fullwave_simulation_bin is None:
|
|
464
|
-
|
|
478
|
+
local_path = _retrieve_fullwave_simulation_path(
|
|
465
479
|
use_gpu=use_gpu,
|
|
466
480
|
is_3d=self.is_3d,
|
|
467
481
|
use_exponential_attenuation=self.use_exponential_attenuation,
|
|
468
482
|
use_isotropic_relaxation=use_isotropic_relaxation,
|
|
469
483
|
n_relax_mechanisms=self.n_relax_mechanisms,
|
|
470
484
|
)
|
|
485
|
+
path_fullwave_simulation_bin = ensure_binary(local_path)
|
|
471
486
|
else:
|
|
472
487
|
check_functions.check_path_exists(path_fullwave_simulation_bin)
|
|
473
488
|
|
|
@@ -538,6 +553,7 @@ class Solver:
|
|
|
538
553
|
is_3d=self.is_3d,
|
|
539
554
|
use_gpu=self.use_gpu,
|
|
540
555
|
cuda_device_id=self.cuda_device_id,
|
|
556
|
+
save_gpu_memory=self.save_gpu_memory,
|
|
541
557
|
)
|
|
542
558
|
|
|
543
559
|
if use_exponential_attenuation:
|