smartg 2.0.2__tar.gz → 2.0.4__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.
- {smartg-2.0.2/smartg.egg-info → smartg-2.0.4}/PKG-INFO +6 -1
- {smartg-2.0.2 → smartg-2.0.4}/README.md +5 -0
- {smartg-2.0.2 → smartg-2.0.4}/pyproject.toml +1 -1
- {smartg-2.0.2 → smartg-2.0.4}/smartg/smartg.py +173 -22
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/communs.h +0 -4
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/device.cu +92 -96
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/shapes.h +120 -40
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/transform.h +0 -6
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_iprt_phase3.py +23 -6
- smartg-2.0.4/smartg/tests/test_jax_context.py +46 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_objects3d.py +7 -3
- smartg-2.0.4/smartg/tests/test_shapes.py +326 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_smartg.py +173 -1
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_smartg_host.py +12 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_smartg_jax.py +28 -0
- smartg-2.0.4/smartg/tests/test_surface.py +328 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_view.py +20 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/view.py +7 -0
- {smartg-2.0.2 → smartg-2.0.4/smartg.egg-info}/PKG-INFO +6 -1
- {smartg-2.0.2 → smartg-2.0.4}/smartg.egg-info/SOURCES.txt +2 -0
- smartg-2.0.2/smartg/tests/test_surface.py +0 -47
- {smartg-2.0.2 → smartg-2.0.4}/LICENSE.TXT +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/LICENSE_RNG.TXT +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/MANIFEST.in +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/setup.cfg +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/__init__.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/albedo.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/atmosphere.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/auxdata.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/bandset.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/cdf.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/config.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/conftest.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/diff.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/environ.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/grid3d.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/histories.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/interp.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/iprt/__init__.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/iprt/common.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/iprt/phase3.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/iprt/phase_a.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/iprt/phase_b.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/kdis.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/demo_notebook.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/demo_notebook_objects.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/demo_notebook_photons_histories.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/validation_smartg_iprt_phase3.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/validation_smartg_iprt_phase_a.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/notebooks/validation_smartg_iprt_phase_b_c2.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/objects3d.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/phase.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/postprocess.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/progress.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/reptran.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/rrs.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/sensor.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/device.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/geometry.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/helper_math.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/MicroURNG.hpp +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/ReinterpretCtr.hpp +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/aes.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/array.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/ars.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/conventional/Engine.hpp +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/conventional/gsl_cbrng.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/clangfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/compilerfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/gccfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/iccfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/msvcfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/nvccfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/open64features.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/openclfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/pgccfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/sse.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/sunprofeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/features/xlcfeatures.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/gsl_microrng.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/philox.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/incRNGs/Random123/threefry.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/kernel2.cu +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/kernel2.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/math_constants.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/src/phase_grid.h +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/surface.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/__init__.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/conftest.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/iprt_checks.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/logs/.gitkeep +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_aerosol.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_atm3d.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_auxdata.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_bandset.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_cdf.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_chowdhary_aos.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_conftest.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_cuda.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_environ.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_histories.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_iprt_checks.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_iprt_phase_b_c2.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_iprt_phase_b_c3.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_kdis.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_kokhanovsky_natraj.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_notebook.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_objects3d_geometry.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_opac.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_phase_grid.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_phase_grid_ice.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_phase_mix.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_phase_readers.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_postprocess.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_profile.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_progress.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_quick_iprt_phase_a.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_reptran.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_rrs.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_self_consistency.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_thermal.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_truncation.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_truncation_components.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_vrs.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_water.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/tests/test_xarray.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/truncation.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/typing.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/vrs.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/water.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg/xarray.py +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg.egg-info/dependency_links.txt +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg.egg-info/requires.txt +0 -0
- {smartg-2.0.2 → smartg-2.0.4}/smartg.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: smartg
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: SMART-G (Speed-up Monte Carlo Advanced Radiative Transfer Code using GPU) is a radiative transfer code using a Monte-Carlo technique to simulate the propagation of the polarized light in the atmosphere and/or ocean, and using GPU acceleration.
|
|
5
5
|
Author-email: Mustapha Moulana <mm@hygeos.com>, Didier Ramon <dr@hygeos.com>, François Steinmetz <fs@hygeos.com>, Dominique Jolivet <dj@hygeos.com>, Mathieu Compiègne <mc@hygeos.com>
|
|
6
6
|
Project-URL: Source, https://github.com/hygeos/smartg
|
|
@@ -326,6 +326,11 @@ environment. Without them it skips itself with a message rather than
|
|
|
326
326
|
failing, so run it with `pixi run -e extra pytest
|
|
327
327
|
smartg/tests/test_smartg_jax.py`.
|
|
328
328
|
|
|
329
|
+
`test_jax_context.py` needs JAX on a GPU, in the same environment, and
|
|
330
|
+
a pytest process of its own: `test_smartg_jax.py` keeps JAX on the CPU
|
|
331
|
+
for the whole process, and the test then skips itself. Run it with
|
|
332
|
+
`pixi run -e extra pytest smartg/tests/test_jax_context.py`.
|
|
333
|
+
|
|
329
334
|
To avoid repeating some pytest arguments, a `pytest.ini` file can be created at the root of the project. The following is an example of the contents of such a file:
|
|
330
335
|
|
|
331
336
|
```
|
|
@@ -275,6 +275,11 @@ environment. Without them it skips itself with a message rather than
|
|
|
275
275
|
failing, so run it with `pixi run -e extra pytest
|
|
276
276
|
smartg/tests/test_smartg_jax.py`.
|
|
277
277
|
|
|
278
|
+
`test_jax_context.py` needs JAX on a GPU, in the same environment, and
|
|
279
|
+
a pytest process of its own: `test_smartg_jax.py` keeps JAX on the CPU
|
|
280
|
+
for the whole process, and the test then skips itself. Run it with
|
|
281
|
+
`pixi run -e extra pytest smartg/tests/test_jax_context.py`.
|
|
282
|
+
|
|
278
283
|
To avoid repeating some pytest arguments, a `pytest.ini` file can be created at the root of the project. The following is an example of the contents of such a file:
|
|
279
284
|
|
|
280
285
|
```
|
|
@@ -4,7 +4,7 @@ requires = ["setuptools>=61"]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "smartg"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.4"
|
|
8
8
|
description = """
|
|
9
9
|
SMART-G (Speed-up Monte Carlo Advanced Radiative Transfer Code using GPU) is a radiative \
|
|
10
10
|
transfer code using a Monte-Carlo technique to simulate the propagation of the polarized \
|
|
@@ -32,6 +32,8 @@ reduce_diff
|
|
|
32
32
|
Post-process ALIS finite-difference runs into sensitivities.
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
|
+
import atexit
|
|
36
|
+
import functools
|
|
35
37
|
import os
|
|
36
38
|
import subprocess
|
|
37
39
|
import tempfile
|
|
@@ -402,7 +404,7 @@ class Alis:
|
|
|
402
404
|
"""
|
|
403
405
|
The options of the ALIS method, for Smartg.run.
|
|
404
406
|
|
|
405
|
-
ALIS (Emde et al.
|
|
407
|
+
ALIS (Emde et al. 2011) computes the spectrum of a whole band from
|
|
406
408
|
a single set of photon paths, by weighting each path with the
|
|
407
409
|
absorption of every wavelength. The Smartg object must have been
|
|
408
410
|
compiled with alis=True, together with alt_pp=True or pp=False.
|
|
@@ -562,7 +564,10 @@ def _check_alis_kernel(
|
|
|
562
564
|
|
|
563
565
|
|
|
564
566
|
def _check_objects_kernel(
|
|
565
|
-
my_objects:
|
|
567
|
+
my_objects: Sequence[Entity | GroupE] | None,
|
|
568
|
+
alis: bool,
|
|
569
|
+
pp: bool,
|
|
570
|
+
opt3d: bool,
|
|
566
571
|
) -> None:
|
|
567
572
|
"""
|
|
568
573
|
Refuse the 3D objects in a kernel whose move does not follow them.
|
|
@@ -850,6 +855,122 @@ class LocalEstimate:
|
|
|
850
855
|
)
|
|
851
856
|
|
|
852
857
|
|
|
858
|
+
# The CUDA contexts that clear_context destroyed, kept referenced so
|
|
859
|
+
# that no new context takes the place of one of them. The Smartg objects
|
|
860
|
+
# of a process share the context of pycuda.autoinit: once one of them
|
|
861
|
+
# clears it, the others must not make it current again, which crashes
|
|
862
|
+
# the driver.
|
|
863
|
+
_RELEASED_CONTEXTS: list[Any] = []
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def _released(ctx: Any) -> bool:
|
|
867
|
+
"""Return whether ctx is a context that clear_context destroyed."""
|
|
868
|
+
return any(c is ctx for c in _RELEASED_CONTEXTS)
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
def _make_current(ctx: Any) -> bool:
|
|
872
|
+
"""Make the CUDA context ctx the current one, if it is not.
|
|
873
|
+
|
|
874
|
+
Another library of the process (JAX for instance) may have made its
|
|
875
|
+
own context current, where the kernels of SMART-G are unknown
|
|
876
|
+
('invalid resource handle'). Returns True if ctx was pushed, to be
|
|
877
|
+
popped by the caller. Raises a RuntimeError if ctx was destroyed by
|
|
878
|
+
the clear_context of another Smartg object that shared it.
|
|
879
|
+
"""
|
|
880
|
+
if ctx is None:
|
|
881
|
+
return False
|
|
882
|
+
if _released(ctx):
|
|
883
|
+
raise RuntimeError(
|
|
884
|
+
'The CUDA context of this Smartg object was destroyed by the '
|
|
885
|
+
'clear_context of another Smartg object that shared it: '
|
|
886
|
+
'create a new Smartg object.')
|
|
887
|
+
# PyCUDA only knows the contexts it pushed itself: ask the driver
|
|
888
|
+
if _driver_current_context() == ctx.handle:
|
|
889
|
+
return False
|
|
890
|
+
ctx.push()
|
|
891
|
+
return True
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
def _autoinit_current_at_exit(sg: 'Smartg') -> None:
|
|
895
|
+
"""At exit, make the pycuda.autoinit context of sg current again.
|
|
896
|
+
|
|
897
|
+
The exit handler of pycuda.autoinit pops its context, which fails
|
|
898
|
+
('cannot pop non-current context') if another library (JAX) made
|
|
899
|
+
its own context current in the meantime.
|
|
900
|
+
"""
|
|
901
|
+
import sys
|
|
902
|
+
mod = sys.modules.get('pycuda.autoinit')
|
|
903
|
+
if (sg.ctx is None or _released(sg.ctx) or mod is None
|
|
904
|
+
or getattr(mod, 'context', None) is not sg.ctx):
|
|
905
|
+
return
|
|
906
|
+
# set it current at the driver level: pushing it would leave it
|
|
907
|
+
# twice on the stack of PyCUDA, which aborts at the module cleanup
|
|
908
|
+
if _driver_current_context() == sg.ctx.handle:
|
|
909
|
+
return
|
|
910
|
+
try:
|
|
911
|
+
import ctypes
|
|
912
|
+
for name in ('libcuda.so.1', 'libcuda.so', 'nvcuda.dll'):
|
|
913
|
+
try:
|
|
914
|
+
set_current = ctypes.CDLL(name).cuCtxSetCurrent
|
|
915
|
+
break
|
|
916
|
+
except (OSError, AttributeError):
|
|
917
|
+
continue
|
|
918
|
+
else:
|
|
919
|
+
return
|
|
920
|
+
set_current(ctypes.c_void_p(sg.ctx.handle))
|
|
921
|
+
# an exit handler must not raise: the one of pycuda.autoinit, which
|
|
922
|
+
# runs next, reports a context that is still not current
|
|
923
|
+
except Exception: # noqa: BLE001, S110
|
|
924
|
+
pass
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
def _driver_current_context() -> int | None:
|
|
928
|
+
"""Handle of the current CUDA context of the driver, or None."""
|
|
929
|
+
global _CU_CTX_GET_CURRENT
|
|
930
|
+
if _CU_CTX_GET_CURRENT is None:
|
|
931
|
+
import ctypes
|
|
932
|
+
import ctypes.util
|
|
933
|
+
names = ('libcuda.so.1', 'libcuda.so', 'nvcuda.dll',
|
|
934
|
+
ctypes.util.find_library('cuda'))
|
|
935
|
+
for name in names:
|
|
936
|
+
if not name:
|
|
937
|
+
continue
|
|
938
|
+
try:
|
|
939
|
+
_CU_CTX_GET_CURRENT = ctypes.CDLL(name).cuCtxGetCurrent
|
|
940
|
+
break
|
|
941
|
+
except (OSError, AttributeError):
|
|
942
|
+
continue
|
|
943
|
+
else:
|
|
944
|
+
_CU_CTX_GET_CURRENT = False
|
|
945
|
+
if not _CU_CTX_GET_CURRENT:
|
|
946
|
+
return None
|
|
947
|
+
import ctypes
|
|
948
|
+
handle = ctypes.c_void_p()
|
|
949
|
+
if _CU_CTX_GET_CURRENT(ctypes.byref(handle)) != 0:
|
|
950
|
+
return None
|
|
951
|
+
return handle.value
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
_CU_CTX_GET_CURRENT = None
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
def _in_context(method: Callable[..., Any]) -> Callable[..., Any]:
|
|
958
|
+
"""Run a method of Smartg with its CUDA context current."""
|
|
959
|
+
|
|
960
|
+
@functools.wraps(method)
|
|
961
|
+
def wrapper(self: 'Smartg', *args: Any, **kwargs: Any) -> Any:
|
|
962
|
+
pushed = _make_current(self.ctx)
|
|
963
|
+
try:
|
|
964
|
+
return method(self, *args, **kwargs)
|
|
965
|
+
finally:
|
|
966
|
+
# run may have popped and released the context itself
|
|
967
|
+
# (autoinit=False, keep_context=False)
|
|
968
|
+
if pushed and self.ctx is not None:
|
|
969
|
+
cuda.Context.pop() # pyright: ignore[reportAttributeAccessIssue]
|
|
970
|
+
|
|
971
|
+
return wrapper
|
|
972
|
+
|
|
973
|
+
|
|
853
974
|
class Smartg:
|
|
854
975
|
"""Initialize the Smartg object.
|
|
855
976
|
|
|
@@ -872,7 +993,7 @@ class Smartg:
|
|
|
872
993
|
double : bool, optional
|
|
873
994
|
Accumulate photons table in double precision (default double).
|
|
874
995
|
alis : bool, optional
|
|
875
|
-
Use the ALIS method (Emde et al.
|
|
996
|
+
Use the ALIS method (Emde et al. 2011) for treating gaseous
|
|
876
997
|
absorption and perturbed profile. Needs alt_pp=True or
|
|
877
998
|
pp=False. The 3D objects are not available with it.
|
|
878
999
|
back : bool, optional
|
|
@@ -906,7 +1027,8 @@ class Smartg:
|
|
|
906
1027
|
Include the Sun Induced Fluorescence, an experimental option.
|
|
907
1028
|
Needs alis=True, together with alt_pp=True or pp=False.
|
|
908
1029
|
thermal : bool, optional
|
|
909
|
-
Still in dev...
|
|
1030
|
+
Still in dev... The forward mode (back=False) needs alt_pp=True
|
|
1031
|
+
in the plane parallel geometry.
|
|
910
1032
|
rng : str, optional
|
|
911
1033
|
The pseudo-random number generator to use, only 2 choice:
|
|
912
1034
|
- PHILOX
|
|
@@ -1027,6 +1149,13 @@ class Smartg:
|
|
|
1027
1149
|
"geometry (pp=True): the spherical move does not follow "
|
|
1028
1150
|
"its cells"
|
|
1029
1151
|
)
|
|
1152
|
+
if thermal and not back and pp and not alt_pp:
|
|
1153
|
+
raise ValueError(
|
|
1154
|
+
"The forward thermal emission (thermal=True, back=False) "
|
|
1155
|
+
"needs alt_pp=True in the plane parallel geometry: the "
|
|
1156
|
+
"fast move does not start the emitted photons at their "
|
|
1157
|
+
"altitude"
|
|
1158
|
+
)
|
|
1030
1159
|
|
|
1031
1160
|
if device is not None:
|
|
1032
1161
|
env_modif = {'CUDA_DEVICE': str(device)}
|
|
@@ -1091,6 +1220,10 @@ class Smartg:
|
|
|
1091
1220
|
self.ctx = make_default_context()
|
|
1092
1221
|
|
|
1093
1222
|
self.autoinit = autoinit
|
|
1223
|
+
if autoinit:
|
|
1224
|
+
# registered after the exit handler of pycuda.autoinit, so
|
|
1225
|
+
# run before it: its context must be current to be popped
|
|
1226
|
+
atexit.register(_autoinit_current_at_exit, self)
|
|
1094
1227
|
self.pp = pp
|
|
1095
1228
|
self.double = double
|
|
1096
1229
|
self.alis = alis
|
|
@@ -1197,6 +1330,9 @@ class Smartg:
|
|
|
1197
1330
|
# 3D Object mode
|
|
1198
1331
|
options.append('-DOBJ3D')
|
|
1199
1332
|
options.append('-D' + rng)
|
|
1333
|
+
# CUDA 13 deprecates double4 (warning 1444) for double4_16a and
|
|
1334
|
+
# double4_32a, which older toolkits lack
|
|
1335
|
+
options.append('-diag-suppress=1444')
|
|
1200
1336
|
# options.append('-lineinfo')
|
|
1201
1337
|
|
|
1202
1338
|
#
|
|
@@ -1208,23 +1344,29 @@ class Smartg:
|
|
|
1208
1344
|
with open(SRC_DEVICE, encoding='ascii', errors='ignore') as f:
|
|
1209
1345
|
src_device_content = f.read()
|
|
1210
1346
|
|
|
1211
|
-
# kernel compilation
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
str(
|
|
1221
|
-
|
|
1222
|
-
|
|
1347
|
+
# kernel compilation, in the context of this object (another
|
|
1348
|
+
# library may have made its own context current)
|
|
1349
|
+
pushed = _make_current(self.ctx)
|
|
1350
|
+
try:
|
|
1351
|
+
self.mod = SourceModule(
|
|
1352
|
+
src_device_content,
|
|
1353
|
+
nvcc='nvcc',
|
|
1354
|
+
options=options,
|
|
1355
|
+
no_extern_c=True,
|
|
1356
|
+
cache_dir=str(cache_dir),
|
|
1357
|
+
include_dirs=[
|
|
1358
|
+
str(DIR_SRC),
|
|
1359
|
+
str(DIR_SRC / 'incRNGs' / 'Random123'),
|
|
1360
|
+
],
|
|
1361
|
+
)
|
|
1223
1362
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1363
|
+
# load the kernel
|
|
1364
|
+
self.kernel = self.mod.get_function('launchKernel')
|
|
1365
|
+
# self.kernel2 = self.mod.get_function('launchKernel2')
|
|
1366
|
+
self.kernel2 = self.mod.get_function('reduce_absorption_gpu')
|
|
1367
|
+
finally:
|
|
1368
|
+
if pushed:
|
|
1369
|
+
cuda.Context.pop() # pyright: ignore[reportAttributeAccessIssue]
|
|
1228
1370
|
|
|
1229
1371
|
#
|
|
1230
1372
|
# common attributes
|
|
@@ -1280,25 +1422,34 @@ class Smartg:
|
|
|
1280
1422
|
Notes
|
|
1281
1423
|
-----
|
|
1282
1424
|
Once this method has been called, the run method can no longer
|
|
1283
|
-
be used: the Smartg object must be reinitialized.
|
|
1425
|
+
be used: the Smartg object must be reinitialized. The Smartg
|
|
1426
|
+
objects with autoinit share one context: once one of them has
|
|
1427
|
+
cleared it, the others can no longer run, and their own
|
|
1428
|
+
clear_context only prints that there is no context to clear.
|
|
1284
1429
|
"""
|
|
1285
1430
|
try:
|
|
1286
1431
|
assert self.ctx is not None
|
|
1432
|
+
# another library (JAX) may have made its context current
|
|
1433
|
+
_make_current(self.ctx)
|
|
1287
1434
|
self.ctx.pop()
|
|
1288
1435
|
self.ctx.detach()
|
|
1436
|
+
_RELEASED_CONTEXTS.append(self.ctx)
|
|
1289
1437
|
self.ctx = None
|
|
1290
1438
|
from pycuda.tools import clear_context_caches
|
|
1291
1439
|
|
|
1292
1440
|
clear_context_caches()
|
|
1293
1441
|
if self.autoinit:
|
|
1294
|
-
#
|
|
1442
|
+
# With autoinit, delete pycuda.autoinit and its exit
|
|
1443
|
+
# handler, which would pop the destroyed context
|
|
1295
1444
|
import pycuda.autoinit
|
|
1296
1445
|
|
|
1446
|
+
atexit.unregister(pycuda.autoinit._finish_up)
|
|
1297
1447
|
del pycuda.autoinit
|
|
1298
1448
|
# pycuda's own error classes again, nothing else to do here
|
|
1299
1449
|
except Exception: # noqa: BLE001
|
|
1300
1450
|
print("There is no current context to clear.")
|
|
1301
1451
|
|
|
1452
|
+
@_in_context
|
|
1302
1453
|
def run(
|
|
1303
1454
|
self,
|
|
1304
1455
|
wavelength: NumericArrayLike | BandSet | Sequence[BandLike],
|