fullwave25 1.2.6.dev8__tar.gz → 1.2.6.dev9__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.
Files changed (75) hide show
  1. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/.bumpversion.toml +1 -1
  2. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/PKG-INFO +1 -1
  3. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/__init__.py +1 -1
  4. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/pml_builder.py +48 -11
  5. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/pyproject.toml +1 -1
  6. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/uv.lock +1 -1
  7. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/.gitignore +0 -0
  8. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/.pre-commit-config.yaml +0 -0
  9. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/.python-version +0 -0
  10. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/20260120_0844.log +0 -0
  11. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/CITATION.cff +0 -0
  12. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/CLAUDE.md +0 -0
  13. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/CONTRIBUTING.md +0 -0
  14. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/LICENSE +0 -0
  15. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/Makefile +0 -0
  16. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/README.md +0 -0
  17. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/beamformer.m +0 -0
  18. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
  19. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu +0 -0
  20. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124 +0 -0
  21. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_2d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
  22. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124 +0 -0
  23. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/debug_solver_bin/fullwave2_3d_exponential_attenuation_multi_gpu_cuda124_ +0 -0
  24. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/experiments/__init__.py +0 -0
  25. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/experiments/exp_scatterer_diameter.py +0 -0
  26. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/beamformer/__init__.py +0 -0
  27. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/beamformer/beamformer.py +0 -0
  28. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/constants/__init__.py +0 -0
  29. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/constants/material_properties.py +0 -0
  30. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/grid.py +0 -0
  31. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium.py +0 -0
  32. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/__init__.py +0 -0
  33. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/domain.py +0 -0
  34. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/medium_builder.py +0 -0
  35. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/__init__.py +0 -0
  36. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/data/.keep +0 -0
  37. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/data/abdominal_wall/i2365f_etfw1.mat +0 -0
  38. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/domain_abdominal_wall.py +0 -0
  39. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/domain_background.py +0 -0
  40. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/domain_scatterer.py +0 -0
  41. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/domain_simple.py +0 -0
  42. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/medium_builder/presets/domain_water_gel.py +0 -0
  43. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/sensor.py +0 -0
  44. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/__init__.py +0 -0
  45. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/binary_manager.py +0 -0
  46. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda118 +0 -0
  47. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda124 +0 -0
  48. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda129 +0 -0
  49. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_cuda130 +0 -0
  50. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda118 +0 -0
  51. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda124 +0 -0
  52. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda129 +0 -0
  53. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/_gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_cuda130 +0 -0
  54. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/bins/database/relaxation_params_database_num_relax=2_20260113_0957.mat +0 -0
  55. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/cuda_utils.py +0 -0
  56. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/input_file_writer.py +0 -0
  57. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/launcher.py +0 -0
  58. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/solver.py +0 -0
  59. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/solver/utils.py +0 -0
  60. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/source.py +0 -0
  61. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/transducer.py +0 -0
  62. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/__init__.py +0 -0
  63. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/check_functions.py +0 -0
  64. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/coordinates.py +0 -0
  65. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/memory_tempfile.py +0 -0
  66. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/numerical.py +0 -0
  67. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/plot_utils.py +0 -0
  68. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/pulse.py +0 -0
  69. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/relaxation_parameters.py +0 -0
  70. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/scatterer.py +0 -0
  71. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/signal_filter.py +0 -0
  72. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/fullwave/utils/signal_process.py +0 -0
  73. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/ruff.log +0 -0
  74. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/ruff.toml +0 -0
  75. {fullwave25-1.2.6.dev8 → fullwave25-1.2.6.dev9}/signal_filter_example.png +0 -0
@@ -1,5 +1,5 @@
1
1
  [tool.bumpversion]
2
- current_version = "1.2.6-dev8"
2
+ current_version = "1.2.6-dev9"
3
3
  parse = """(?x)
4
4
  (?P<major>0|[1-9]\\d*)\\.
5
5
  (?P<minor>0|[1-9]\\d*)\\.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fullwave25
3
- Version: 1.2.6.dev8
3
+ Version: 1.2.6.dev9
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.6-dev8"
63
+ __version__ = "1.2.6-dev9"
64
64
 
65
65
  VERSION = __version__ # for convenience
66
66
  logger.info("Fullwave version: %s", __version__)
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import concurrent.futures
6
+ import gc
6
7
  import logging
7
8
  from collections import OrderedDict
8
9
  from dataclasses import dataclass, field
@@ -563,6 +564,33 @@ class PMLBuilder:
563
564
 
564
565
  return output
565
566
 
567
+ def _move_named_arrays_to_cpu(
568
+ self,
569
+ named_arrays: list[tuple[str, NDArray]],
570
+ attr_names: list[str] | None = None,
571
+ ) -> list[tuple[str, NDArray]]:
572
+ """Convert CuPy arrays to numpy and free GPU memory pools.
573
+
574
+ Also replaces the corresponding ``medium_org`` attributes (given by
575
+ *attr_names*) so the original GPU arrays can be garbage-collected.
576
+ """
577
+ import cupy as cp # noqa: PLC0415
578
+
579
+ numpy_arrays = []
580
+ for name, arr in named_arrays:
581
+ if hasattr(arr, "get"):
582
+ arr_np = arr.get()
583
+ numpy_arrays.append((name, arr_np))
584
+ # Update medium_org so the CuPy array can be freed
585
+ if attr_names and name in attr_names:
586
+ setattr(self.medium_org, name, arr_np)
587
+ else:
588
+ numpy_arrays.append((name, arr))
589
+ gc.collect()
590
+ cp.get_default_memory_pool().free_all_blocks()
591
+ cp.get_default_pinned_memory_pool().free_all_blocks()
592
+ return numpy_arrays
593
+
566
594
  def _extend_arrays_gpu(
567
595
  self,
568
596
  named_arrays: list[tuple[str, NDArray]],
@@ -571,8 +599,8 @@ class PMLBuilder:
571
599
 
572
600
  Parameters
573
601
  ----------
574
- named_arrays : list of (name, numpy_array) pairs
575
- Arrays to extend. Must be numpy arrays (CPU).
602
+ named_arrays : list of (name, numpy_array) or (name, cupy_array) pairs
603
+ Arrays to extend.
576
604
 
577
605
  Returns
578
606
  -------
@@ -585,6 +613,8 @@ class PMLBuilder:
585
613
  n_gpus = cp.cuda.runtime.getDeviceCount()
586
614
  logger.info("CUDA devices available: %d", n_gpus)
587
615
 
616
+ attr_names = [name for name, _ in named_arrays]
617
+
588
618
  # Strategy 1: Multi-GPU parallel
589
619
  if n_gpus > 1:
590
620
  n_workers = min(n_gpus, len(named_arrays))
@@ -597,16 +627,15 @@ class PMLBuilder:
597
627
  )
598
628
  return self._extend_arrays_multi_gpu(named_arrays, n_gpus)
599
629
  except Exception:
600
- logger.warning("Multi-GPU extension failed. Falling back to sequential single-GPU.")
630
+ logger.warning(
631
+ "Multi-GPU extension failed. Falling back to CPU.",
632
+ exc_info=True,
633
+ )
601
634
 
602
- # Strategy 2: Sequential single-GPU (extend one, free, repeat)
603
- try:
604
- logger.info("Extending %d medium arrays sequentially on GPU 0.", len(named_arrays))
605
- return self._extend_arrays_sequential_gpu(named_arrays)
606
- except Exception:
607
- logger.warning("Single-GPU extension failed. Falling back to CPU.")
635
+ # Move arrays to CPU and free GPU memory before CPU fallback.
636
+ # The original medium arrays may still occupy GPU memory.
637
+ named_arrays = self._move_named_arrays_to_cpu(named_arrays, attr_names)
608
638
 
609
- # Strategy 3: CPU
610
639
  logger.info("Extending %d medium arrays on CPU.", len(named_arrays))
611
640
  return self._extend_arrays_cpu(named_arrays)
612
641
 
@@ -669,13 +698,21 @@ class PMLBuilder:
669
698
  named_arrays: list[tuple[str, NDArray]],
670
699
  ) -> dict[str, NDArray]:
671
700
  """Extend arrays on CPU using ThreadPoolExecutor."""
701
+ # Convert any CuPy arrays to numpy before CPU fallback
702
+ numpy_arrays = []
703
+ for name, arr in named_arrays:
704
+ if hasattr(arr, "get"):
705
+ numpy_arrays.append((name, arr.get()))
706
+ else:
707
+ numpy_arrays.append((name, arr))
708
+
672
709
  orig_xp = self.xp
673
710
  self.xp = np
674
711
  try:
675
712
  with concurrent.futures.ThreadPoolExecutor() as executor:
676
713
  futures = {
677
714
  name: executor.submit(self._extend_map_for_pml, arr)
678
- for name, arr in named_arrays
715
+ for name, arr in numpy_arrays
679
716
  }
680
717
  return {name: future.result() for name, future in futures.items()}
681
718
  finally:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fullwave25"
3
- version = "1.2.6-dev8" # Update via bump-my-version, not manually
3
+ version = "1.2.6-dev9" # 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"
@@ -735,7 +735,7 @@ wheels = [
735
735
 
736
736
  [[package]]
737
737
  name = "fullwave25"
738
- version = "1.2.6.dev8"
738
+ version = "1.2.6.dev9"
739
739
  source = { editable = "." }
740
740
  dependencies = [
741
741
  { name = "matplotlib" },
File without changes