Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] jit/core redesign #7

Open
wants to merge 347 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
347 commits
Select commit Hold shift + click to select a range
fab3b44
rm dead code
s-m-e Jan 13, 2024
08cf5f0
rm class
s-m-e Jan 13, 2024
9aec248
rm class
s-m-e Jan 13, 2024
bd4b8cb
cleanup
s-m-e Jan 13, 2024
3546e03
exports
s-m-e Jan 13, 2024
c585852
rm arg
s-m-e Jan 14, 2024
0bbb453
types, const, cleanup
s-m-e Jan 14, 2024
57a963c
revert solver
s-m-e Jan 14, 2024
f43d4c9
rm vectorized support
s-m-e Jan 14, 2024
ee77d07
rm first step
s-m-e Jan 14, 2024
81d5611
rm oo k decl
s-m-e Jan 14, 2024
203357e
fixed array sizes, prep for tuples
s-m-e Jan 14, 2024
0c548af
nb compile cache clean
s-m-e Jan 15, 2024
7cbfeae
explicit nopython
s-m-e Jan 15, 2024
7c5defc
assert shapes; unroll loop
s-m-e Jan 15, 2024
adb7ca6
rm A,B,C props and args, turn into const
s-m-e Jan 15, 2024
bd49a33
eliminate func wrapper
s-m-e Jan 15, 2024
0322830
pass k to func, prep for inline compile and eliminate last wrapper
s-m-e Jan 15, 2024
d2225c8
rm dead consts
s-m-e Jan 15, 2024
bceaa1a
prep for tuples without numpy in rk step
s-m-e Jan 15, 2024
10266a2
prep for tuples without numpy in rk step (2)
s-m-e Jan 15, 2024
2fb74e5
state parser
s-m-e Jan 15, 2024
3de598b
cowell has its own jit
s-m-e Jan 15, 2024
78bfccb
Merge remote-tracking branch 'origin/jit_redesign_solveivp' into jit_…
s-m-e Jan 16, 2024
06dd537
jit planetocentric_to_AltAz
s-m-e Jan 16, 2024
83ce58d
deactivate trap
s-m-e Jan 16, 2024
86bb3ae
jit line_of_sight
s-m-e Jan 16, 2024
af83602
cleanup
s-m-e Jan 16, 2024
fdf616d
jit J2_perturbation
s-m-e Jan 16, 2024
9591b67
jit J3_perturbation_hf
s-m-e Jan 16, 2024
41e3c67
jit atmospheric_drag
s-m-e Jan 16, 2024
1f7832a
independent implementation of interp1d, prep for jit
s-m-e Jan 20, 2024
0a557f1
cleanup
s-m-e Jan 20, 2024
f794b4b
asserts
s-m-e Jan 20, 2024
2a18406
cleanup
s-m-e Jan 21, 2024
0fea680
cleanup
s-m-e Jan 21, 2024
70a6eeb
jit interp_hf
s-m-e Jan 21, 2024
a05f5be
jit third_body
s-m-e Jan 21, 2024
691a449
jit radiation_pressure
s-m-e Jan 21, 2024
d6ac5cd
jit change_a_inc
s-m-e Jan 21, 2024
25c12e3
mask hf funcs
s-m-e Jan 21, 2024
fbe752c
fix typo
s-m-e Jan 21, 2024
a083ab9
jit change_argp
s-m-e Jan 21, 2024
efb3414
rm exports
s-m-e Jan 21, 2024
21e9518
jit change_ecc_inc
s-m-e Jan 21, 2024
f52f8b6
jit change_ecc_quasioptimal
s-m-e Jan 21, 2024
77a6ce3
no state type? two vectors instead?
s-m-e Jan 21, 2024
1dab907
isolate rkstep
s-m-e Jan 22, 2024
6ece659
run on tuples
s-m-e Jan 22, 2024
000faa7
run rkstep on tuples without side effects
s-m-e Jan 22, 2024
16f28e5
assert shapes, swap dot to matmul
s-m-e Jan 22, 2024
59f022d
rm matmul, swap for tuple ops
s-m-e Jan 22, 2024
545745c
rm comments
s-m-e Jan 22, 2024
d6469e3
attempt nopython for rkstep, failing
s-m-e Jan 22, 2024
ab90536
compiles, tests break
s-m-e Jan 22, 2024
f36157c
fix var name
s-m-e Jan 22, 2024
a7038ef
fix DOP853 by forcing f8; make PRECISION a setting
s-m-e Jan 23, 2024
3393fdf
consolidate coesa core code, jited
s-m-e Jan 23, 2024
4382f6f
mv atmospheric data into core, keep units in high level api
s-m-e Jan 23, 2024
0ca0b76
compiled coesa76 core functions, now works for cowell's method
s-m-e Jan 24, 2024
486c556
use compiled coesa76 funcs in modell class
s-m-e Jan 24, 2024
af48adb
rm notations
s-m-e Jan 24, 2024
b7b178f
rk initial step
s-m-e Jan 24, 2024
d62994d
rm comment
s-m-e Jan 24, 2024
6b7af5d
consolidate
s-m-e Jan 24, 2024
f0fe33c
rm method
s-m-e Jan 24, 2024
1b8a4f5
prep for compiled estimator
s-m-e Jan 24, 2024
ed05028
jit error
s-m-e Jan 24, 2024
c30450a
rm msg
s-m-e Jan 24, 2024
09914f6
cleanup
s-m-e Jan 24, 2024
350bf67
cleanup
s-m-e Jan 24, 2024
0f38b9d
more linalg
s-m-e Jan 24, 2024
7babf7f
move eps
s-m-e Jan 24, 2024
ce44979
rm numpy dep
s-m-e Jan 24, 2024
4d753a8
less numpy
s-m-e Jan 24, 2024
19d593f
use vectors
s-m-e Jan 24, 2024
80fd3ce
mv step impl out of class
s-m-e Jan 24, 2024
b30315c
f to fr fv
s-m-e Jan 24, 2024
54ddf59
y to rr vv
s-m-e Jan 24, 2024
04bd4bb
side-effect free step impl
s-m-e Jan 24, 2024
e317130
jit step impl
s-m-e Jan 24, 2024
55e057c
mv function
s-m-e Jan 24, 2024
bc319cb
cleanup
s-m-e Jan 24, 2024
81de503
cleanup
s-m-e Jan 24, 2024
73215b6
cleanup
s-m-e Jan 24, 2024
256c4cc
cleanup
s-m-e Jan 24, 2024
3d9aeb9
cleanup
s-m-e Jan 25, 2024
466867a
fix const
s-m-e Jan 25, 2024
b6eba2d
fix const
s-m-e Jan 25, 2024
4613d1b
rename norm func
s-m-e Jan 25, 2024
efdaeb0
rename norm vec func
s-m-e Jan 25, 2024
a38e968
allow args in gjit
s-m-e Jan 25, 2024
4b9e5bf
add logging to djit
s-m-e Jan 25, 2024
10da212
fix exports
s-m-e Jan 25, 2024
816ddae
fix docs
s-m-e Jan 25, 2024
b943b24
fix astropy depr warning
s-m-e Jan 25, 2024
3cb926d
fix matplotlib max plots warning during tests
s-m-e Jan 25, 2024
6320dd1
fix numba obj mode warn
s-m-e Jan 25, 2024
dad958f
do not attempt to cache dynamically generated functions, i.e. elimina…
s-m-e Jan 25, 2024
b0bc653
pylint
s-m-e Jan 25, 2024
c818264
less wrapping for events
s-m-e Jan 25, 2024
51f7eeb
more r and v in solver
s-m-e Jan 25, 2024
980f84d
cleanup args
s-m-e Jan 25, 2024
bda6ba9
compile threebody helper
s-m-e Jan 25, 2024
f6117c8
cleanup
s-m-e Jan 25, 2024
f6e7adc
cleanup
s-m-e Jan 25, 2024
d4b1ab3
cleanup
s-m-e Jan 25, 2024
47f49e8
events cleanup
s-m-e Jan 25, 2024
0331c58
jit eclipse_function
s-m-e Jan 25, 2024
f7745ee
jit cartesian_to_ellipsoidal
s-m-e Jan 25, 2024
96affb0
cleanup
s-m-e Jan 25, 2024
08c51e9
evaluating umbra events is based on interpolation vs calling get_body…
s-m-e Jan 25, 2024
47e43f5
fix name
s-m-e Jan 25, 2024
988a91c
los event runs on 1D linear interpolation function for secondary body…
s-m-e Jan 28, 2024
b2ba64a
events get compiled
s-m-e Jan 28, 2024
62f3ef5
deactivate test for warning as compiled code currently can not raise …
s-m-e Jan 28, 2024
2978c39
less arrays, more tuples
s-m-e Jan 28, 2024
c5cd8e6
cleanup
s-m-e Jan 28, 2024
73cc39c
cleanup
s-m-e Jan 28, 2024
b7cd3a1
prep for cleanup
s-m-e Jan 28, 2024
b0ecb22
cleanup dense output so it relies on 4 unchanged states
s-m-e Jan 28, 2024
96f3908
dense output entirely on tuples
s-m-e Jan 28, 2024
5afe560
isolate ieee754 stuff
s-m-e Jan 29, 2024
e94b8cd
structure rk
s-m-e Jan 29, 2024
bb87d6b
rm K_extended
s-m-e Jan 29, 2024
a93c70f
cleanup
s-m-e Jan 29, 2024
0a123f0
K becomes tuple
s-m-e Jan 29, 2024
60f5d3e
cleanup
s-m-e Jan 29, 2024
f575fc3
new dense interp
s-m-e Jan 29, 2024
4af915f
compiled wrapper around events for brentq
s-m-e Jan 29, 2024
98d7fec
rm dense output class
s-m-e Jan 29, 2024
84d5ab4
run on compiled wrapper, keep track of last_t manually
s-m-e Jan 29, 2024
1c14927
events are not directly callable anymore, compiled implementation to …
s-m-e Jan 29, 2024
c2ce6e2
secondary brentq implementation that wrapps dense output funcs
s-m-e Jan 29, 2024
b91442b
expose dense output wrappers
s-m-e Jan 29, 2024
eae5d54
use new dense output wrapper
s-m-e Jan 29, 2024
aba2cec
dense parameter signature
s-m-e Jan 29, 2024
43d04d2
unroll loop
s-m-e Jan 29, 2024
22b2242
isolate dense output prep
s-m-e Jan 29, 2024
953ea99
isolate dense output further
s-m-e Jan 29, 2024
7289753
cleanup
s-m-e Jan 29, 2024
e62f66b
loop unroll
s-m-e Jan 29, 2024
ea2ace5
cleanup
s-m-e Jan 29, 2024
44c54f4
arrays to tuples
s-m-e Jan 29, 2024
377c507
arrays to tuples
s-m-e Jan 29, 2024
c7b2286
replace np.dot
s-m-e Jan 29, 2024
f5645ae
mv tuple decl
s-m-e Jan 29, 2024
8ab797d
passing k through
s-m-e Jan 29, 2024
2836195
rm np.dot
s-m-e Jan 29, 2024
39cec0a
rm np.dot
s-m-e Jan 29, 2024
ce3a68a
rm np.dot
s-m-e Jan 29, 2024
d5acb42
rm numpy dep
s-m-e Jan 29, 2024
f03c22b
add compiler
s-m-e Jan 29, 2024
2c48d56
name fix
s-m-e Jan 29, 2024
db26595
mv module
s-m-e Jan 29, 2024
fe8fdc4
dop853 class to functional via tuple
s-m-e Jan 29, 2024
f27565b
rk core compiled
s-m-e Jan 29, 2024
694a1e6
cleanup
s-m-e Jan 29, 2024
cb6a3a6
cleanup
s-m-e Jan 29, 2024
df53a1a
cleanup
s-m-e Jan 29, 2024
2e19322
cleanup
s-m-e Jan 29, 2024
dc6b2b2
scalar is active
s-m-e Jan 30, 2024
7ffff09
fix name
s-m-e Jan 30, 2024
2145760
allow to force inline
s-m-e Jan 30, 2024
94f6dca
simplify roots
s-m-e Jan 30, 2024
52bdf1d
force inline
s-m-e Jan 30, 2024
c1df0ec
times increase, except if they're zero
s-m-e Jan 31, 2024
6944557
refine assertion
s-m-e Jan 31, 2024
4b39933
cleanup
s-m-e Jan 31, 2024
daacb79
indicators
s-m-e Feb 1, 2024
1e45f9c
rm ode solution class
s-m-e Feb 1, 2024
9b07188
assumptions
s-m-e Feb 1, 2024
9353d2f
add note
s-m-e Feb 1, 2024
8929622
fix link
s-m-e Feb 1, 2024
81957b9
name fix
s-m-e Feb 2, 2024
5b1ea67
notes
s-m-e Feb 2, 2024
4489db7
rm numpy from handling events
s-m-e Feb 3, 2024
4294b6b
cleanup
s-m-e Feb 3, 2024
c6916b5
workaround: https://github.com/numba/numba/issues/9420
s-m-e Feb 4, 2024
7cc7707
mv event handling into solver
s-m-e Feb 4, 2024
ab9aaa6
fix type
s-m-e Feb 4, 2024
253b008
rm last allocs; mv all of event handling into solver
s-m-e Feb 4, 2024
ed011c9
cleanup
s-m-e Feb 4, 2024
ba10b2f
fix error handling
s-m-e Feb 4, 2024
65430db
fix names
s-m-e Feb 4, 2024
dc4cd82
jit cowell
s-m-e Feb 5, 2024
69405e1
typing
s-m-e Feb 5, 2024
6e365a7
fix name
s-m-e Feb 6, 2024
406934d
fix call into brentq_hf to gf
s-m-e Feb 6, 2024
f60f96a
vectorized eclipse
s-m-e Feb 6, 2024
99ffacb
run on new event implementation
s-m-e Feb 6, 2024
4fd1537
force obj option
s-m-e Feb 11, 2024
a122014
force obj option
s-m-e Feb 11, 2024
d35c101
draft fix
s-m-e Feb 13, 2024
98eedfa
rm nextafter; use fabs instead of abs
s-m-e Feb 13, 2024
df4e1c1
temp fix: use nextafter from numpy, wait for math impl in numba
s-m-e Feb 13, 2024
fab9b82
add note on nextafter
s-m-e Feb 13, 2024
600cee9
use better nextafter; use fabs instead of abs
s-m-e Feb 13, 2024
3d5c0d8
rm pow; add missing export; add safe divs
s-m-e Feb 14, 2024
fc1a73d
add safe divs; abs to fabs
s-m-e Feb 14, 2024
363932f
clean up pows
s-m-e Feb 14, 2024
19eef13
rm todo
s-m-e Feb 14, 2024
83e691a
asserts
s-m-e Feb 14, 2024
8ca6d24
safe pows
s-m-e Feb 14, 2024
2808c9a
fix pertubation calls
s-m-e Feb 14, 2024
529ee3c
update notebook
s-m-e Feb 14, 2024
43014c6
fix arg; fix missing import
s-m-e Feb 14, 2024
7dabc12
fix quick cowell
s-m-e Feb 14, 2024
c0c6940
fix quick pert
s-m-e Feb 14, 2024
dd9569f
handle u.one
s-m-e Feb 14, 2024
2b87fc1
f_geo
s-m-e Feb 14, 2024
80dba2a
fix plot; fix lambert
s-m-e Feb 14, 2024
49ad96d
trigger plot
s-m-e Feb 14, 2024
61b74c2
missing matmul op
s-m-e Feb 19, 2024
ab87ea8
jit elevation function
s-m-e Feb 19, 2024
984df4e
jit mean_motion
s-m-e Feb 23, 2024
576a55c
jit period
s-m-e Feb 23, 2024
2b5752c
jit t_p cleanup
s-m-e Feb 23, 2024
9793a8d
fix core import contract
s-m-e Feb 23, 2024
eba7058
tox prevents numba cache, i.e. parallel compile causes segfaults -> r…
s-m-e Feb 23, 2024
2d9e3b0
parallel CI without cache?
s-m-e Feb 23, 2024
1f3a910
fix plots
s-m-e Mar 2, 2024
bce3039
fix urls
s-m-e Mar 2, 2024
89a3b67
add changes
s-m-e Mar 6, 2024
009b718
fix copyright
s-m-e Mar 6, 2024
17b6493
details
s-m-e Mar 6, 2024
b6dac8a
draft core doc
s-m-e Mar 6, 2024
0a49ca9
clarifications
s-m-e Mar 7, 2024
284604f
fix headline
s-m-e Mar 7, 2024
c131f30
cleanup
s-m-e Mar 7, 2024
3cf6724
fix doc build issues
s-m-e Mar 7, 2024
13a9994
rm type S entirely; inline array to vector
s-m-e Mar 7, 2024
cbc1acd
more changes
s-m-e Mar 7, 2024
72b7572
ieee754; errors; kwargs
s-m-e Mar 7, 2024
82794a8
inlining broke CI
s-m-e Mar 7, 2024
2dfc5f2
fix imports
s-m-e Apr 21, 2024
f04baff
simplify exception for numba
s-m-e Apr 21, 2024
2a57e7b
fix doc strings
s-m-e Apr 22, 2024
61afbe3
fix doc strings
s-m-e Apr 22, 2024
4a914d4
cleanup
s-m-e Apr 25, 2024
0750ff4
doc strings
s-m-e Apr 25, 2024
c1790aa
doc strings; param name cleanup
s-m-e Apr 25, 2024
545c3f0
doc strings
s-m-e Apr 25, 2024
2924237
doc strings
s-m-e Apr 25, 2024
2b16b5d
doc strings
s-m-e Apr 25, 2024
d9eac1e
scipy ref
s-m-e Apr 25, 2024
e4cba2e
prep doc
s-m-e Apr 26, 2024
2c5fbc4
doc strings
s-m-e Apr 26, 2024
eff4f8a
doc string
s-m-e Apr 29, 2024
97b4c93
doc string
s-m-e Apr 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ _clean_coverage:
coverage erase

_clean_py:
find src/ tests/ contrib/ -name '*.nbi' -exec rm -f {} +
find src/ tests/ contrib/ -name '*.nbc' -exec rm -f {} +
find src/ tests/ contrib/ -name '*.pyc' -exec rm -f {} +
find src/ tests/ contrib/ -name '*.pyo' -exec rm -f {} +
find src/ tests/ contrib/ -name '*~' -exec rm -f {} +
Expand Down Expand Up @@ -49,6 +51,6 @@ upload:
done

test:
DISPLAY= tox
DISPLAY= HAPSIRA_CACHE=0 tox -e style,tests-fast,tests-slow,docs

.PHONY: docs docker image release upload
3 changes: 2 additions & 1 deletion contrib/CR3BP/CR3BP.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
from numba import njit as jit
import numpy as np

from hapsira._math.ivp import DOP853, solve_ivp
# from hapsira.core.math.ivp import solve_ivp
from scipy.integrate import solve_ivp, DOP853


@jit
Expand Down
31 changes: 29 additions & 2 deletions docs/source/changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
# What's new
# Changes

## hapsira 0.19.0 - 2024-XX-XX

**CAUTION**: A number changes at least partially **BREAK BACKWARDS COMPATIBILITY** for certain use cases.

This release features a significant refactoring of `core`, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7) for details. All relevant `core` functions are now designed to work equally on CPUs and GPUs as either [universal functions](https://numba.readthedocs.io/en/stable/user/vectorize.html#the-vectorize-decorator) or [generalized universal functions](https://numba.readthedocs.io/en/stable/user/vectorize.html#the-guvectorize-decorator). As a "side-effect", all relevant `core` functions allow parallel operation with full [broadcasting semantics](https://numpy.org/doc/stable/user/basics.broadcasting.html). Their single-thread performance was also increased depending on use-case by around two orders of magnitude. All refactored **functions** in `core` were **renamed**, now carrying additional suffixes to indicate how they can or can not be invoked.

Critical fix changing behaviour: The Loss of Signal (LOS) event would previously produce wrong results.

Module layout change: `core.earth_atmosphere` became `core.earth.atmosphere`.

- FEATURE: New `core.math` module, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7), including fast replacements for many `numpy` and some `scipy` functions, most notably:
- [scipy.interpolate.interp1d](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html) is replaced by `core.math.interpolate.interp_hb`. It custom-compiles 1D linear interpolators, embedding data statically into the compiled functions.
- [scipy.integrate.solve_ivp](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html), [scipy.integrate.DOP853](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.DOP853.html) and [scipy.optimize.brentq](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html) are replaced by `core.math.ivp`, a purely functional compiled implementation running entirely on the stack.
- FEATURE: New `core.jit` module, wrapping a number of `numba` functions to have a central place to apply settings, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- FEATURE: New `settings` module, mainly for handling JIT compiler settings, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- FEATURE: New `debug` module, including logging capabilities, mainly logging JIT compiler issues, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- FEATURE: Significant portions of the COESA76 atmophere model are now compiled and available as part of `core`, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7). `core.earth_atmosphere` was renamed into `core.earth.atmosphere`.
- DOCS: The `core` module is technically user-facing and as such now explicitly documented, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- DOCS: The "quickstart" section received an update and now includes all previously missing imports.
- FIX: The Loss of Signal (LOS) event would misshandle the position of the secondary body i.e. producing wrong results, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7) as well as the [relevant commit](https://github.com/pleiszenburg/hapsira/commit/988a91cd22ff1de285c33af35b13d288963fcaf7)
- FIX: The Cowell propagator could produce wrong results if times of flight (tof) where provided in units other than seconds, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- FIX: Broken plots in example notebooks, see [hapsira #7](https://github.com/pleiszenburg/hapsira/pull/7)
- FIX: Typo in `bodies`, see [hapsira #6](https://github.com/pleiszenburg/hapsira/pull/6)
- FIX: Some notebooks in the documentation had disappeared due to incomplete rebranding
- DEV: Parallel (multi-core) testing enabled by default, see [hapsira #5](https://github.com/pleiszenburg/hapsira/pull/5)
- DEV: Deactivated warning due to too many simultaneously opened `matplotlib` plots

## hapsira 0.18.0 - 2023-12-24

Expand Down Expand Up @@ -233,7 +260,7 @@ as well as the results from Google Summer of Code 2021.
The interactive orbit plotters {py:class}`~poliastro.plotting.OrbitPlotter2D`
and {py:class}`~poliastro.plotting.OrbitPlotter3D`
now have a new method to easily display impulsive burns.
See {doc}`/examples/going-to-jupiter-with-python-using-jupyter-and-poliastro`
See {doc}`/examples/going-to-jupiter-with-python-using-jupyter-and-hapsira`
for an example.
- **Many performance improvements**
Several contributors have helped accelerate more algorithms
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
}

project = "hapsira"
copyright = "2023 Sebastian M. Ernst"
copyright = "2023-2024 Sebastian M. Ernst"

project_ver = version(project)
version = ".".join(project_ver.split(".")[:2])
Expand Down
227 changes: 227 additions & 0 deletions docs/source/core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
(coremodule)=
# Core module

The `core` module handles most actual heavy computations. It is compiled via [numba](https://numba.readthedocs.io). For both working with functions from `core` directly and contributing to it, it is highly recommended to gain some basic understanding of how `numba` works.

`core` is designed to work equally on CPUs and GPUs. (Most) exported `core` APIs interfacing with the rest of `hapsira` are either [universal functions](https://numba.readthedocs.io/en/stable/user/vectorize.html#the-vectorize-decorator) or [generalized universal functions](https://numba.readthedocs.io/en/stable/user/vectorize.html#the-guvectorize-decorator), which allow parallel operation with full [broadcasting semantics](https://numpy.org/doc/stable/user/basics.broadcasting.html).

```{warning}
Some `core` functions have yet not been refactored into this shape and will soon follow the same approach.
```

## Compiler targets

There are three compiler targets, which can be controlled through settings and/or environment variables:

- `cpu`: Single-threaded on CPUs
- `parallel`: Parallelized by `numba` via [threading layers](https://numba.readthedocs.io/en/stable/user/threading-layer.html) on CPUs
- `cuda`: Parallelized by `numba` via CUDA on Nvidia GPUs

All code of `core` will be compiled for one of the above listed targets. If multiple targets are supposed to be used simultaneously, this can only be achieved by multiple Python processes running in parallel.

## Compiler decorators

`core` offers the follwing JIT compiler decorators provided via `core.jit`:

- `vjit`: Wraps `numba.vectorize`. Functions decorated by it carry the suffix `_vf`.
- `gjit`: Wraps `numba.guvectorize`. Functions decorated by it carry the suffix `_gf`.
- `hjit`: Wraps `numba.jit` or `numba.cuda.jit`, depending on compiler target. Functions decorated by it carry the suffix `_hf`.
- `djit`: Variation of `hjit` with fixed function signature for user-provided functions used by `Cowell`

`core` functions dynamically generating (and compiling) functions within their scope carry `_hb`, `_vb` and `_gb` suffixes.

Wrapping `numba` functions allows to centralize compiler options and target switching as well as to simplify typing.

The decorators are applied in a **hierarchy**:

- Functions decorated by either `vjit` and `gjit` serve as the **only** interface between regular uncompiled Python code and `core`
- Functions decorated by `vjit` and `hjit` only call functions decorated by `hjit`
- Functions decorated by `hjit` can only call each other.

```{note}
The "hierarchy" of decorators is imposed by CUDA-compatibility. While functions decorated by `numba.jit` (targets `cpu` and `parallel`) can be called from uncompiled Python code, functions decorated by `numba.cuda.jit` (target `cuda`) are considered [device functions](https://numba.readthedocs.io/en/stable/cuda/device-functions.html) and can not be called by uncompiled Python code directly. They are supposed to be called by CUDA-kernels (or other device functions) only (slightly simplifying the actual situation as implemented by `numba`). If the target is set to `cuda`, functions decorated by `numba.vectorize` and `numba.guvectorize` become CUDA kernels.
```

```{warning}
As a result of name suffixes as of version `0.19.0`, many `core` module functions have been renamed making the package intentionally backwards-incompatible. Functions not yet using the new infrastructure can be recognized based on lack of suffix. Eventually all `core` functions will use this infrastructure and carry matching suffixes.
```

```{note}
Some functions decorated by `gjit` must receive a dummy parameter, also explicitly named `dummy`. It is usually an empty `numpy` array of shape `(3,)` of data type `u1` (unsigned one-byte integer). This is a work-around for [numba #2797](https://github.com/numba/numba/issues/2797).
```

## Compiler errors

Misconfigured compiler decorators or unavailable targets raise an `errors.JitError` exception.

## Keyword arguments and defaults

Due to incompletely documented limitations in `numba`, see [documentation](https://numba.readthedocs.io/en/stable/reference/pysupported.html#function-calls) and [numba #7870](https://github.com/numba/numba/issues/7870), functions decorated by `hjit`, `vjit` and `gjit` can not have defaults for any of their arguments. In this context, those functions can not reliably be called with keyword arguments, too, which must therefore be avoided. Defaults are provided as constants within the same submodule, usually the function name in capital letters followed by the name of the argument, also in capital letters.

## Dependencies

Functions decorated by `vjit`, `gjit` and `hjit` are only allowed to depend on Python's standard library's [math module](https://docs.python.org/3/library/math.html), but **not** on other third-party packages like [numpy](https://numpy.org/doc/stable/) or [scipy](https://docs.scipy.org/doc/scipy/) for that matter - except for certain details like [enforcing floating point precision](https://numpy.org/doc/stable/user/basics.types.html) as provided by `core.math.ieee754`

```{note}
Eliminating `numpy` and other dependencies serves two purposes. While it is critical for [CUDA-compatiblity](https://numba.readthedocs.io/en/stable/cuda/cudapysupported.html), it additionally makes the code significantly faster on CPUs.
```

## Typing

All functions decorated by `hjit`, `vjit` and `gjit` must by typed using [signatures similar to those of numba](https://numba.readthedocs.io/en/stable/reference/types.html).

All compiled code enforces a single floating point precision level, which can be configured. The default is FP64 / double precision. For simplicity, the type shortcut is `f`, replacing `f2`, `f4` or `f8`. Consider the following example:

```python
from numba import vectorize
from hapsira.core.jit import vjit

@vectorize("f8(f8)")
def foo(x):
return x ** 2

@vjit("f(f)")
def bar_vf(x):
return x ** 2
```

Additional infrastructure can be found in `core.math.ieee754`. The default floating point type is exposed as `core.math.ieee754.float_` for explicit conversions. A matching epsilon is exposed as `core.math.ieee754.EPS`.

```{note}
Divisions by zero should, regardless of compiler target or even entirely deactivated compiler, always result in `inf` (infinity) instead of `ZeroDivisionError` exceptions. Most divisions within `core` are therefore explicitly guarded.
```

3D vectors are expressed as tuples, type shortcut `V`, replacing `Tuple([f,f,f])`. Consider the following example:

```python
from numba import njit
from hapsira.core.jit import hjit

@njit("f8(Tuple([f8,f8,f8]))")
def foo(x):
return x[0] + x[1] + x[2]

@hjit("f(V)")
def bar_hf(x):
return x[0] + x[1] + x[2]
```

Matrices are expressed as tuples of tuples, type shortcut `M`, replacing `Tuple([V,V,V])`. Consider the following example:

```python
from numba import njit
from hapsira.core.jit import hjit

@njit("f8(Tuple([Tuple([f8,f8,f8]),Tuple([f8,f8,f8]),Tuple([f8,f8,f8])]))")
def foo(x):
sum_ = 0
for idx in range(3):
for jdx in range(3):
sum_ += x[idx][jdx]
return sum_

@hjit("f(M)")
def bar_hf(x):
sum_ = 0
for idx in range(3):
for jdx in range(3):
sum_ += x[idx][jdx]
return sum_
```

Function types use the shortcut `F`, replacing `FunctionType`.

## Cowell’s formulation

Cowell’s formulation is one of the few places where `core` is exposed directly to the user.

### Two-body function

In its most simple form, the `CowellPropagator` relies on a variation of `func_twobody_hf` as a parameter, a function compiled by `hjit`, which can technically be omitted:

```python
from hapsira.core.propagation.base import func_twobody_hf
from hapsira.twobody.propagation import CowellPropagator

prop = CowellPropagator(f=func_twobody_hf)
prop = CowellPropagator() # identical to the above
```

If perturbations are applied, however, `func_twobody_hf` needs to be altered. It is important that the new altered function is compiled via the `hjit` decorator and that is has the correct signature. To simplify the matter for users, a variation of `hjit` named `djit` carries the correct signature implicitly:

```python
from hapsira.core.jit import djit, hjit
from hapsira.core.math.linalg import mul_Vs_hf
from hapsira.core.propagation.base import func_twobody_hf
from hapsira.twobody.propagation import CowellPropagator

@hjit("Tuple([V,V])(f,V,V,f)")
def foo_hf(t0, rr, vv, k):
du_kep_rr, du_kep_vv = func_twobody_hf(t0, rr, vv, k)
return du_kep_rr, mul_Vs_hf(du_kep_vv, 1.1) # multiply speed vector by 1.1

@djit
def bar_hf(t0, rr, vv, k):
du_kep_rr, du_kep_vv = func_twobody_hf(t0, rr, vv, k)
return du_kep_rr, mul_Vs_hf(du_kep_vv, 1.1) # multiply speed vector by 1.1

prop = CowellPropagator(f=foo_hf)
prop = CowellPropagator(f=bar_hf) # identical to the above
```

### Events

The core of each event's implementation must also be compiled by `hjit`. New events must inherit from `BaseEvent`. The compiled implementation should be an attribute, a function or a static method, named `_impl_hf`. Once this attribute is specified, an explicit call to the `_wrap` method, most likely from the constructor, automatically generates a second version of `_impl_hf` named `_impl_dense_hf` that is used to not only evaluate but also to approximate the exact time of flight of an event based on dense output of the underlying solver.

## Settings

The following settings, available via `settings.settings`, allow to alter the compiler's behaviour:

- `DEBUG`: `bool`, default `False`
- `CACHE`: `bool`, default `not DEBUG`
- `TARGET`: `str`, default `cpu`, alternatives `parallel` and `cuda`
- `INLINE`: `bool`, default `TARGET == "cuda"`
- `NOPYTHON`: `bool`, default `True`
- `FORCEOBJ`: `bool`, default `False`
- `PRECISION`: `str`, default `f8`, alternatives `f2` and `f4`

```{note}
Settings can be switched by either setting environment variables or importing the `settings` module **before** any other (sub-) module is imported.
```

The `DEBUG` setting disables caching and enables the highest log level, among other things.

`CACHE` only works for `cpu` and `parallel` targets. It speeds up import times drastically if the package gets reused. Dynamically generated functions can not be cached and must be exempt from caching by passing `cache = False` as a parameter to the JIT compiler decorator.

```{warning}
Building the cache should not be done in parallel processes - this will most likely result in non-deterministic segmentation faults, see [numba #4807](https://github.com/numba/numba/issues/4807). Once `core` is fully compiled and cached, it can however be used in parallel processes. Rebuilding the cache can usually reliably resolve segmentation faults.
```

Inlining via `INLINE` drastically increases performance but also compile times. It is the default behaviour for target `cuda`. See [relevant chapter in numba documentation](https://numba.readthedocs.io/en/stable/developer/inlining.html#notes-on-inlining) for details.

`NOPYTHON` and `FORCEOBJ` provide additional debugging capabilities but should not be changed for regular use. For details, see [nopython mode](https://numba.readthedocs.io/en/stable/glossary.html#term-nopython-mode) and [object mode](https://numba.readthedocs.io/en/stable/glossary.html#term-object-mode) in `numba`'s documentation.

The default `PRECISION` of all floating point operations is FP64 / double precision float.

```{warning}
`hapsira`, formerly `poliastro`, was validated for FP64. Certain parts like Cowell reliably operate at this precision only. Other parts like for instance atmospheric models can easily handle single precision. This option is therefore provided for experimental purposes only.
```

## Logging

Compiler issues are logged via logging channel `hapsira` using Python's standard library's [logging module](https://docs.python.org/3/howto/logging.html), also available as `debug.logger`. All compiler activity can be observed by enabling log level `debug`.

## Math

The former `_math` module, version `0.18` and earlier, has become a first-class citizen as `core.math`, fully compiled by the above mentioned infrastructure. `core.math` contains a number of replacements for `numpy` operations, mostly found in `core.math.linalg`. All of those functions do not allocate memory and are free of side-effects including a lack of changes to their parameters.

Functions in `core.math` follow a loose naming convention, indicating for what types of parameters they can be used. `mul_Vs_hf` for instance is a multiplication of a vector `V` and a scalar `s` (floating point). `M` indicates matricis.

`core.math` also replaces (some) required `scipy` functions:

- [scipy.interpolate.interp1d](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html) is replaced by `core.math.interpolate.interp_hb`. It custom-compiles 1D linear interpolators, embedding data statically into the compiled functions.
- [scipy.integrate.solve_ivp](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html), [scipy.integrate.DOP853](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.DOP853.html) and [scipy.optimize.brentq](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html) are replaced by `core.math.ivp`.

```{note}
Future releases might remove more dependencies to `scipy` from `core` for full CUDA compatibility and additional performance.
```
Loading
Loading