nrl-tracker 1.9.2__py3-none-any.whl → 1.10.0__py3-none-any.whl
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.
- {nrl_tracker-1.9.2.dist-info → nrl_tracker-1.10.0.dist-info}/METADATA +47 -2
- {nrl_tracker-1.9.2.dist-info → nrl_tracker-1.10.0.dist-info}/RECORD +14 -7
- pytcl/__init__.py +2 -2
- pytcl/core/optional_deps.py +20 -0
- pytcl/gpu/__init__.py +153 -0
- pytcl/gpu/ekf.py +425 -0
- pytcl/gpu/kalman.py +543 -0
- pytcl/gpu/matrix_utils.py +486 -0
- pytcl/gpu/particle_filter.py +568 -0
- pytcl/gpu/ukf.py +476 -0
- pytcl/gpu/utils.py +582 -0
- {nrl_tracker-1.9.2.dist-info → nrl_tracker-1.10.0.dist-info}/LICENSE +0 -0
- {nrl_tracker-1.9.2.dist-info → nrl_tracker-1.10.0.dist-info}/WHEEL +0 -0
- {nrl_tracker-1.9.2.dist-info → nrl_tracker-1.10.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nrl-tracker
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.10.0
|
|
4
4
|
Summary: Python port of the U.S. Naval Research Laboratory's Tracker Component Library for target tracking algorithms
|
|
5
5
|
Author: Original: David F. Crouse, Naval Research Laboratory
|
|
6
6
|
Maintainer: Python Port Contributors
|
|
@@ -41,6 +41,8 @@ Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
|
41
41
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
42
42
|
Requires-Dist: pytest-xdist>=3.0.0; extra == "dev"
|
|
43
43
|
Requires-Dist: pytest-benchmark>=4.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-timeout>=2.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: nbval>=0.10.0; extra == "dev"
|
|
44
46
|
Requires-Dist: hypothesis>=6.0.0; extra == "dev"
|
|
45
47
|
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
46
48
|
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
@@ -51,9 +53,15 @@ Requires-Dist: sphinx>=6.0.0; extra == "dev"
|
|
|
51
53
|
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == "dev"
|
|
52
54
|
Requires-Dist: myst-parser>=1.0.0; extra == "dev"
|
|
53
55
|
Requires-Dist: nbsphinx>=0.9.0; extra == "dev"
|
|
56
|
+
Requires-Dist: jupyter>=1.0.0; extra == "dev"
|
|
57
|
+
Requires-Dist: ipykernel>=6.0.0; extra == "dev"
|
|
54
58
|
Provides-Extra: geodesy
|
|
55
59
|
Requires-Dist: pyproj>=3.4.0; extra == "geodesy"
|
|
56
60
|
Requires-Dist: geographiclib>=2.0; extra == "geodesy"
|
|
61
|
+
Provides-Extra: gpu
|
|
62
|
+
Requires-Dist: cupy-cuda12x>=12.0.0; extra == "gpu"
|
|
63
|
+
Provides-Extra: gpu-apple
|
|
64
|
+
Requires-Dist: mlx>=0.5.0; extra == "gpu-apple"
|
|
57
65
|
Provides-Extra: optimization
|
|
58
66
|
Requires-Dist: cvxpy>=1.3.0; extra == "optimization"
|
|
59
67
|
Provides-Extra: signal
|
|
@@ -63,7 +71,7 @@ Requires-Dist: plotly>=5.15.0; extra == "visualization"
|
|
|
63
71
|
|
|
64
72
|
# Tracker Component Library (Python)
|
|
65
73
|
|
|
66
|
-
[](https://pypi.org/project/nrl-tracker/)
|
|
67
75
|
[](https://www.python.org/downloads/)
|
|
68
76
|
[](https://en.wikipedia.org/wiki/Public_domain)
|
|
69
77
|
[](https://github.com/psf/black)
|
|
@@ -90,6 +98,7 @@ The Tracker Component Library provides building blocks for developing target tra
|
|
|
90
98
|
- **Navigation**: Geodetic calculations, INS mechanization, GNSS utilities, INS/GNSS integration
|
|
91
99
|
- **Geophysical Models**: Gravity (WGS84, EGM96/2008), magnetism (WMM, IGRF), atmosphere, tides, terrain
|
|
92
100
|
- **Signal Processing**: Digital filters, matched filtering, CFAR detection, transforms (FFT, STFT, wavelets)
|
|
101
|
+
- **GPU Acceleration**: CuPy (NVIDIA CUDA) and MLX (Apple Silicon) backends for batch Kalman filtering and particle filters
|
|
93
102
|
|
|
94
103
|
## Installation
|
|
95
104
|
|
|
@@ -111,6 +120,12 @@ pip install nrl-tracker[geodesy]
|
|
|
111
120
|
# For visualization
|
|
112
121
|
pip install nrl-tracker[visualization]
|
|
113
122
|
|
|
123
|
+
# For GPU acceleration (NVIDIA CUDA)
|
|
124
|
+
pip install nrl-tracker[gpu]
|
|
125
|
+
|
|
126
|
+
# For GPU acceleration (Apple Silicon M1/M2/M3)
|
|
127
|
+
pip install nrl-tracker[gpu-apple]
|
|
128
|
+
|
|
114
129
|
# For development
|
|
115
130
|
pip install nrl-tracker[dev]
|
|
116
131
|
|
|
@@ -183,6 +198,35 @@ assignment, total_cost = hungarian(cost_matrix)
|
|
|
183
198
|
print(f"Optimal assignment: {assignment}, Total cost: {total_cost}")
|
|
184
199
|
```
|
|
185
200
|
|
|
201
|
+
### GPU Acceleration
|
|
202
|
+
|
|
203
|
+
The library supports GPU acceleration for batch processing of multiple tracks:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
from pytcl.gpu import is_gpu_available, get_backend, to_gpu, to_cpu
|
|
207
|
+
|
|
208
|
+
# Check GPU availability (auto-detects CUDA or Apple Silicon)
|
|
209
|
+
if is_gpu_available():
|
|
210
|
+
print(f"GPU available, using {get_backend()} backend")
|
|
211
|
+
|
|
212
|
+
# Transfer data to GPU
|
|
213
|
+
x_gpu = to_gpu(states) # (n_tracks, state_dim)
|
|
214
|
+
P_gpu = to_gpu(covariances) # (n_tracks, state_dim, state_dim)
|
|
215
|
+
|
|
216
|
+
# Use batch Kalman filter operations
|
|
217
|
+
from pytcl.gpu import batch_kf_predict
|
|
218
|
+
x_pred, P_pred = batch_kf_predict(x_gpu, P_gpu, F, Q)
|
|
219
|
+
|
|
220
|
+
# Transfer results back to CPU
|
|
221
|
+
x_pred_cpu = to_cpu(x_pred)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Supported backends:**
|
|
225
|
+
- **NVIDIA CUDA**: Via CuPy (`pip install nrl-tracker[gpu]`)
|
|
226
|
+
- **Apple Silicon**: Via MLX (`pip install nrl-tracker[gpu-apple]`)
|
|
227
|
+
|
|
228
|
+
The backend is automatically selected based on your platform.
|
|
229
|
+
|
|
186
230
|
## Module Structure
|
|
187
231
|
|
|
188
232
|
```
|
|
@@ -202,6 +246,7 @@ pytcl/
|
|
|
202
246
|
├── gravity/ # Gravity models
|
|
203
247
|
├── magnetism/ # Magnetic field models
|
|
204
248
|
├── terrain/ # Terrain elevation models
|
|
249
|
+
├── gpu/ # GPU acceleration (CuPy/MLX)
|
|
205
250
|
└── misc/ # Utilities, visualization
|
|
206
251
|
```
|
|
207
252
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pytcl/__init__.py,sha256=
|
|
1
|
+
pytcl/__init__.py,sha256=DEk9yoH37UzqAZycMHTVEm6GgrN3uhXfObXQs3o28kI,2032
|
|
2
2
|
pytcl/logging_config.py,sha256=UJaYufQgNuIjpsOMTPo3ewz1XCHPk8a08jTHyP7uoI4,8956
|
|
3
3
|
pytcl/assignment_algorithms/__init__.py,sha256=kUWhmyLhZcs5GiUQA5_v7KA3qETGsvqV6wU8r7paO-k,2976
|
|
4
4
|
pytcl/assignment_algorithms/data_association.py,sha256=tsRxWJZk9aAPmE99BKXGouEpFfZrjPjb4HXvgxFUHhU,11405
|
|
@@ -56,7 +56,7 @@ pytcl/core/array_utils.py,sha256=SsgEiAoRCWxAVKq1aa5-nPdOi-2AB6XNObu0IaGClUk,139
|
|
|
56
56
|
pytcl/core/constants.py,sha256=cwkCjzCU7zG2ZsFcbqwslN632v7Lw50L85s-5q892mo,9988
|
|
57
57
|
pytcl/core/exceptions.py,sha256=6ImMiwL86BdmTt-Rc8fXLXxKUGQ-PcQQyxIvKKzw-n0,24324
|
|
58
58
|
pytcl/core/maturity.py,sha256=Sut19NfH1-6f3Qd2QSC6OAqvDcVHJDwf5-F_-oEAMJA,11596
|
|
59
|
-
pytcl/core/optional_deps.py,sha256=
|
|
59
|
+
pytcl/core/optional_deps.py,sha256=a3UK_DM2s0XQE4Lwp0agq9L0qjupl_d8o4csCYbi440,16396
|
|
60
60
|
pytcl/core/validation.py,sha256=4ay21cZVAil8udymwej7QnVQfNyjzi_5A8O1y-d-Lyw,23492
|
|
61
61
|
pytcl/dynamic_estimation/__init__.py,sha256=zxmkZIXVfHPv5AHYpQV5nwsI0PA3m-Vw7W0gkJE7j98,5191
|
|
62
62
|
pytcl/dynamic_estimation/gaussian_sum_filter.py,sha256=3Ks5-sGo3IF9p_dsIzk5u2zaXS2ZAkJFAg1mdxo8vj8,15343
|
|
@@ -90,6 +90,13 @@ pytcl/dynamic_models/process_noise/__init__.py,sha256=ZRYgV40qmBkPwU3yTbIMvxorr4
|
|
|
90
90
|
pytcl/dynamic_models/process_noise/coordinated_turn.py,sha256=0PciDXtXHjgQdaYf7qpQqIZ7qoMV4uO_kE7wjpiBe64,6483
|
|
91
91
|
pytcl/dynamic_models/process_noise/polynomial.py,sha256=w5ZW5Ouw6QpVtev_mnuCmZoj6_O6ovb2L_ENKDhHYIc,7742
|
|
92
92
|
pytcl/dynamic_models/process_noise/singer.py,sha256=ozAdzH4s0wGlBaxajdyZvSnK8_CumgsUZDKeMW-TxDs,5735
|
|
93
|
+
pytcl/gpu/__init__.py,sha256=B3t8UrMg7_1k79eeJMJqPLlb4dG8xHfttsaIDqCDk2g,4268
|
|
94
|
+
pytcl/gpu/ekf.py,sha256=Lern6c0lP9LdfL4vHM1PWvXLHl1tniNZPXq7Mw81R5A,12138
|
|
95
|
+
pytcl/gpu/kalman.py,sha256=8swMqLsnXjdl9-0vOg6wEqxtVHQRHcV4bXjHL8RwUmk,16417
|
|
96
|
+
pytcl/gpu/matrix_utils.py,sha256=FKlcZKEbWSPHUgRjsFpcvN2LgcXZncMIWmOo8GAXp2Q,12394
|
|
97
|
+
pytcl/gpu/particle_filter.py,sha256=uBK9ItCgGRfZ7WtWQIky-t3pl1oM1Fi1hZ6fmHTr4kc,16957
|
|
98
|
+
pytcl/gpu/ukf.py,sha256=NzSWOKBBpyNFKiTwj9fpDIWmO9-1-vpmFXLdkXrxM1E,13070
|
|
99
|
+
pytcl/gpu/utils.py,sha256=HAwC2cYh2UFr5hJBeabvdK3AxhJJNN9I2MFJel2FIjU,14790
|
|
93
100
|
pytcl/gravity/__init__.py,sha256=5xNdQSrrkt7-1-JPOYqR38CqvNJ7qKlPyMK36DGm6-I,3693
|
|
94
101
|
pytcl/gravity/clenshaw.py,sha256=O7yYfjHMigR1RQHR_gZe3UuMIe_WsGrXFSLzn7PLfIE,16985
|
|
95
102
|
pytcl/gravity/egm.py,sha256=LAeNbaQ7eZakk0ciwLec0_8q41MrBFouVLpDsETis6o,19683
|
|
@@ -165,8 +172,8 @@ pytcl/trackers/mht.py,sha256=osEOXMaCeTt1eVn_E08dLRhEvBroVmf8b81zO5Zp1lU,20720
|
|
|
165
172
|
pytcl/trackers/multi_target.py,sha256=RDITa0xnbgtVYAMj5XXp4lljo5lZ2zAAc02KZlOjxbQ,10526
|
|
166
173
|
pytcl/trackers/single_target.py,sha256=Yy3FwaNTArMWcaod-0HVeiioNV4xLWxNDn_7ZPVqQYs,6562
|
|
167
174
|
pytcl/transponders/__init__.py,sha256=5fL4u3lKCYgPLo5uFeuZbtRZkJPABntuKYGUvVgMMEI,41
|
|
168
|
-
nrl_tracker-1.
|
|
169
|
-
nrl_tracker-1.
|
|
170
|
-
nrl_tracker-1.
|
|
171
|
-
nrl_tracker-1.
|
|
172
|
-
nrl_tracker-1.
|
|
175
|
+
nrl_tracker-1.10.0.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
|
|
176
|
+
nrl_tracker-1.10.0.dist-info/METADATA,sha256=WUCa_SI-MIoBVkEmPW-VCR8B25wWtet0OSKMQpBMTAc,14038
|
|
177
|
+
nrl_tracker-1.10.0.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
|
|
178
|
+
nrl_tracker-1.10.0.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
|
|
179
|
+
nrl_tracker-1.10.0.dist-info/RECORD,,
|
pytcl/__init__.py
CHANGED
|
@@ -6,7 +6,7 @@ systems, dynamic models, estimation algorithms, and mathematical functions.
|
|
|
6
6
|
|
|
7
7
|
This is a Python port of the U.S. Naval Research Laboratory's Tracker Component
|
|
8
8
|
Library originally written in MATLAB.
|
|
9
|
-
**Current Version:** 1.
|
|
9
|
+
**Current Version:** 1.10.0 (January 4, 2026)
|
|
10
10
|
**Status:** Production-ready, 2,133 tests passing, 76% line coverage
|
|
11
11
|
Examples
|
|
12
12
|
--------
|
|
@@ -21,7 +21,7 @@ References
|
|
|
21
21
|
no. 5, pp. 18-27, May 2017.
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
__version__ = "1.
|
|
24
|
+
__version__ = "1.10.0"
|
|
25
25
|
__author__ = "Python Port Contributors"
|
|
26
26
|
__original_author__ = "David F. Crouse, Naval Research Laboratory"
|
|
27
27
|
|
pytcl/core/optional_deps.py
CHANGED
|
@@ -69,6 +69,10 @@ PACKAGE_EXTRAS: dict[str, tuple[str, str]] = {
|
|
|
69
69
|
"pywavelets": ("signal", "pywavelets"),
|
|
70
70
|
# Terrain data
|
|
71
71
|
"netCDF4": ("terrain", "netCDF4"),
|
|
72
|
+
# GPU acceleration
|
|
73
|
+
"cupy": ("gpu", "cupy-cuda12x"),
|
|
74
|
+
# Apple Silicon GPU acceleration
|
|
75
|
+
"mlx": ("gpu-apple", "mlx"),
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
# Friendly names for features provided by each package
|
|
@@ -82,6 +86,8 @@ PACKAGE_FEATURES: dict[str, str] = {
|
|
|
82
86
|
"pywt": "wavelet transforms",
|
|
83
87
|
"pywavelets": "wavelet transforms",
|
|
84
88
|
"netCDF4": "NetCDF file reading",
|
|
89
|
+
"cupy": "GPU acceleration",
|
|
90
|
+
"mlx": "Apple Silicon GPU acceleration",
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
|
|
@@ -374,6 +380,16 @@ class _AvailabilityFlags:
|
|
|
374
380
|
"""True if netCDF4 is available."""
|
|
375
381
|
return is_available("netCDF4")
|
|
376
382
|
|
|
383
|
+
@property
|
|
384
|
+
def HAS_CUPY(self) -> bool:
|
|
385
|
+
"""True if cupy is available."""
|
|
386
|
+
return is_available("cupy")
|
|
387
|
+
|
|
388
|
+
@property
|
|
389
|
+
def HAS_MLX(self) -> bool:
|
|
390
|
+
"""True if mlx is available (Apple Silicon)."""
|
|
391
|
+
return is_available("mlx")
|
|
392
|
+
|
|
377
393
|
|
|
378
394
|
# Create singleton instance
|
|
379
395
|
_flags = _AvailabilityFlags()
|
|
@@ -387,6 +403,8 @@ HAS_ASTROPY = property(lambda self: _flags.HAS_ASTROPY)
|
|
|
387
403
|
HAS_PYPROJ = property(lambda self: _flags.HAS_PYPROJ)
|
|
388
404
|
HAS_CVXPY = property(lambda self: _flags.HAS_CVXPY)
|
|
389
405
|
HAS_NETCDF4 = property(lambda self: _flags.HAS_NETCDF4)
|
|
406
|
+
HAS_CUPY = property(lambda self: _flags.HAS_CUPY)
|
|
407
|
+
HAS_MLX = property(lambda self: _flags.HAS_MLX)
|
|
390
408
|
|
|
391
409
|
|
|
392
410
|
# =============================================================================
|
|
@@ -525,6 +543,8 @@ __all__ = [
|
|
|
525
543
|
"HAS_PYPROJ",
|
|
526
544
|
"HAS_CVXPY",
|
|
527
545
|
"HAS_NETCDF4",
|
|
546
|
+
"HAS_CUPY",
|
|
547
|
+
"HAS_MLX",
|
|
528
548
|
# Internal (for testing)
|
|
529
549
|
"_clear_cache",
|
|
530
550
|
"_flags",
|
pytcl/gpu/__init__.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GPU-accelerated algorithms for the Tracker Component Library.
|
|
3
|
+
|
|
4
|
+
This module provides GPU-accelerated implementations of key tracking algorithms
|
|
5
|
+
using CuPy (NVIDIA GPUs) or MLX (Apple Silicon). These implementations offer
|
|
6
|
+
significant speedups (5-15x) for batch processing of multiple tracks or large
|
|
7
|
+
particle sets.
|
|
8
|
+
|
|
9
|
+
The module automatically selects the best available backend:
|
|
10
|
+
- On Apple Silicon (M1/M2/M3): Uses MLX if installed
|
|
11
|
+
- On systems with NVIDIA GPUs: Uses CuPy if installed
|
|
12
|
+
- Falls back to CPU (numpy) if no GPU backend is available
|
|
13
|
+
|
|
14
|
+
The GPU implementations mirror the CPU API but accept GPU arrays and return
|
|
15
|
+
GPU arrays. Use the utility functions to seamlessly transfer data between
|
|
16
|
+
CPU and GPU.
|
|
17
|
+
|
|
18
|
+
Requirements
|
|
19
|
+
------------
|
|
20
|
+
For NVIDIA GPUs:
|
|
21
|
+
- CUDA-capable GPU
|
|
22
|
+
- CuPy >= 12.0
|
|
23
|
+
|
|
24
|
+
For Apple Silicon:
|
|
25
|
+
- macOS with Apple Silicon (M1, M2, M3, etc.)
|
|
26
|
+
- MLX >= 0.5.0
|
|
27
|
+
|
|
28
|
+
Installation
|
|
29
|
+
------------
|
|
30
|
+
For NVIDIA CUDA:
|
|
31
|
+
pip install pytcl[gpu]
|
|
32
|
+
# or directly:
|
|
33
|
+
pip install cupy-cuda12x # For CUDA 12.x
|
|
34
|
+
|
|
35
|
+
For Apple Silicon:
|
|
36
|
+
pip install pytcl[gpu-apple]
|
|
37
|
+
# or directly:
|
|
38
|
+
pip install mlx
|
|
39
|
+
|
|
40
|
+
Examples
|
|
41
|
+
--------
|
|
42
|
+
Basic usage with automatic backend selection:
|
|
43
|
+
|
|
44
|
+
>>> from pytcl.gpu import is_gpu_available, get_backend
|
|
45
|
+
>>> if is_gpu_available():
|
|
46
|
+
... print(f"GPU available, using {get_backend()} backend")
|
|
47
|
+
|
|
48
|
+
Check platform:
|
|
49
|
+
|
|
50
|
+
>>> from pytcl.gpu import is_apple_silicon, is_mlx_available
|
|
51
|
+
>>> if is_apple_silicon():
|
|
52
|
+
... print("Running on Apple Silicon")
|
|
53
|
+
>>> if is_mlx_available():
|
|
54
|
+
... print("MLX acceleration available")
|
|
55
|
+
|
|
56
|
+
Batch processing example:
|
|
57
|
+
|
|
58
|
+
>>> from pytcl.gpu import batch_kf_predict, to_gpu, to_cpu
|
|
59
|
+
>>> # Move data to GPU (automatically uses best backend)
|
|
60
|
+
>>> x_gpu = to_gpu(x_batch) # (n_tracks, state_dim)
|
|
61
|
+
>>> P_gpu = to_gpu(P_batch) # (n_tracks, state_dim, state_dim)
|
|
62
|
+
>>> # Batch prediction
|
|
63
|
+
>>> x_pred, P_pred = batch_kf_predict(x_gpu, P_gpu, F, Q)
|
|
64
|
+
>>> # Move results back to CPU
|
|
65
|
+
>>> x_pred_cpu = to_cpu(x_pred)
|
|
66
|
+
|
|
67
|
+
See Also
|
|
68
|
+
--------
|
|
69
|
+
pytcl.dynamic_estimation.kalman : CPU Kalman filter implementations
|
|
70
|
+
pytcl.dynamic_estimation.particle_filters : CPU particle filter implementations
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
from pytcl.gpu.utils import (
|
|
74
|
+
get_array_module,
|
|
75
|
+
get_backend,
|
|
76
|
+
is_apple_silicon,
|
|
77
|
+
is_cupy_available,
|
|
78
|
+
is_gpu_available,
|
|
79
|
+
is_mlx_available,
|
|
80
|
+
to_cpu,
|
|
81
|
+
to_gpu,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
__all__ = [
|
|
85
|
+
# Platform detection
|
|
86
|
+
"is_apple_silicon",
|
|
87
|
+
"is_mlx_available",
|
|
88
|
+
"is_cupy_available",
|
|
89
|
+
"get_backend",
|
|
90
|
+
# Availability check
|
|
91
|
+
"is_gpu_available",
|
|
92
|
+
# Utility functions
|
|
93
|
+
"get_array_module",
|
|
94
|
+
"to_gpu",
|
|
95
|
+
"to_cpu",
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Lazy imports for GPU implementations (only loaded if CuPy is available)
|
|
100
|
+
def __getattr__(name: str):
|
|
101
|
+
"""Lazy import GPU implementations."""
|
|
102
|
+
if name in ("CuPyKalmanFilter", "batch_kf_predict", "batch_kf_update"):
|
|
103
|
+
from pytcl.gpu.kalman import CuPyKalmanFilter, batch_kf_predict, batch_kf_update
|
|
104
|
+
|
|
105
|
+
globals()[name] = locals()[name]
|
|
106
|
+
return locals()[name]
|
|
107
|
+
|
|
108
|
+
if name in ("CuPyExtendedKalmanFilter", "batch_ekf_predict", "batch_ekf_update"):
|
|
109
|
+
from pytcl.gpu.ekf import (
|
|
110
|
+
CuPyExtendedKalmanFilter,
|
|
111
|
+
batch_ekf_predict,
|
|
112
|
+
batch_ekf_update,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
globals()[name] = locals()[name]
|
|
116
|
+
return locals()[name]
|
|
117
|
+
|
|
118
|
+
if name in ("CuPyUnscentedKalmanFilter", "batch_ukf_predict", "batch_ukf_update"):
|
|
119
|
+
from pytcl.gpu.ukf import (
|
|
120
|
+
CuPyUnscentedKalmanFilter,
|
|
121
|
+
batch_ukf_predict,
|
|
122
|
+
batch_ukf_update,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
globals()[name] = locals()[name]
|
|
126
|
+
return locals()[name]
|
|
127
|
+
|
|
128
|
+
if name in (
|
|
129
|
+
"CuPyParticleFilter",
|
|
130
|
+
"gpu_resample_systematic",
|
|
131
|
+
"gpu_resample_multinomial",
|
|
132
|
+
):
|
|
133
|
+
from pytcl.gpu.particle_filter import (
|
|
134
|
+
CuPyParticleFilter,
|
|
135
|
+
gpu_resample_multinomial,
|
|
136
|
+
gpu_resample_systematic,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
globals()[name] = locals()[name]
|
|
140
|
+
return locals()[name]
|
|
141
|
+
|
|
142
|
+
if name in ("gpu_cholesky", "gpu_qr", "gpu_solve", "MemoryPool"):
|
|
143
|
+
from pytcl.gpu.matrix_utils import (
|
|
144
|
+
MemoryPool,
|
|
145
|
+
gpu_cholesky,
|
|
146
|
+
gpu_qr,
|
|
147
|
+
gpu_solve,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
globals()[name] = locals()[name]
|
|
151
|
+
return locals()[name]
|
|
152
|
+
|
|
153
|
+
raise AttributeError(f"module 'pytcl.gpu' has no attribute '{name}'")
|