yggdrax 0.0.1__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.
- yggdrax-0.0.1/LICENSE +21 -0
- yggdrax-0.0.1/PKG-INFO +251 -0
- yggdrax-0.0.1/README.md +218 -0
- yggdrax-0.0.1/pyproject.toml +89 -0
- yggdrax-0.0.1/setup.cfg +4 -0
- yggdrax-0.0.1/yggdrax/__init__.py +199 -0
- yggdrax-0.0.1/yggdrax/_geometry_impl.py +403 -0
- yggdrax-0.0.1/yggdrax/_interactions_impl.py +6301 -0
- yggdrax-0.0.1/yggdrax/_tree_impl.py +1384 -0
- yggdrax-0.0.1/yggdrax/bounds.py +21 -0
- yggdrax-0.0.1/yggdrax/dense_interactions.py +208 -0
- yggdrax-0.0.1/yggdrax/dtypes.py +49 -0
- yggdrax-0.0.1/yggdrax/geometry.py +66 -0
- yggdrax-0.0.1/yggdrax/grouped_interactions.py +159 -0
- yggdrax-0.0.1/yggdrax/interactions.py +403 -0
- yggdrax-0.0.1/yggdrax/kdtree.py +1348 -0
- yggdrax-0.0.1/yggdrax/morton.py +96 -0
- yggdrax-0.0.1/yggdrax/multipole_utils.py +189 -0
- yggdrax-0.0.1/yggdrax/octree.py +671 -0
- yggdrax-0.0.1/yggdrax/policies.py +18 -0
- yggdrax-0.0.1/yggdrax/protocols.py +56 -0
- yggdrax-0.0.1/yggdrax/py.typed +0 -0
- yggdrax-0.0.1/yggdrax/traversal.py +90 -0
- yggdrax-0.0.1/yggdrax/tree.py +1813 -0
- yggdrax-0.0.1/yggdrax/tree_moments.py +831 -0
- yggdrax-0.0.1/yggdrax/types.py +84 -0
- yggdrax-0.0.1/yggdrax.egg-info/PKG-INFO +251 -0
- yggdrax-0.0.1/yggdrax.egg-info/SOURCES.txt +29 -0
- yggdrax-0.0.1/yggdrax.egg-info/dependency_links.txt +1 -0
- yggdrax-0.0.1/yggdrax.egg-info/requires.txt +11 -0
- yggdrax-0.0.1/yggdrax.egg-info/top_level.txt +1 -0
yggdrax-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AstroAI Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
yggdrax-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yggdrax
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Tree generation and traversal package for hierarchical solvers
|
|
5
|
+
Author: AstroAI Lab
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AstroAI-Lab/yggdrax
|
|
8
|
+
Project-URL: Repository, https://github.com/AstroAI-Lab/yggdrax
|
|
9
|
+
Project-URL: Issues, https://github.com/AstroAI-Lab/yggdrax/issues
|
|
10
|
+
Keywords: fmm,hierarchical,n-body,jax,treecode
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: jax>=0.8.0
|
|
23
|
+
Requires-Dist: jaxlib>=0.4.0
|
|
24
|
+
Requires-Dist: jaxtyping>=0.2.23
|
|
25
|
+
Requires-Dist: beartype>=0.14.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: black>=24.8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: isort>=5.13.2; extra == "dev"
|
|
29
|
+
Requires-Dist: pydoclint>=0.6.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest>=8.3.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Yggdrax
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
Yggdrax is a JAX-first tree toolkit for hierarchical N-body solvers. It
|
|
43
|
+
provides Morton ordering, radix tree builders, per-node geometry, and dual-tree
|
|
44
|
+
interaction traversal primitives designed for downstream FMM and treecode
|
|
45
|
+
pipelines. The public `octree` backend now layers explicit octree-cell metadata
|
|
46
|
+
on top of the existing Morton/radix construction path so downstream FMM code
|
|
47
|
+
can consume both the proven traversal buffers and octree-style child tables.
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- Morton encode/decode and stable Morton sorting for 3D points
|
|
52
|
+
- LBVH and fixed-depth radix tree construction
|
|
53
|
+
- Explicit octree metadata derived from Morton/radix topology
|
|
54
|
+
- Tree geometry extraction (bounds, centers, extents, radii)
|
|
55
|
+
- Dual-tree far-field and near-field interaction builders
|
|
56
|
+
- Dense and grouped interaction buffer transforms for batched kernels
|
|
57
|
+
- Prepared artifact utilities for downstream solver integrations
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
Install from source:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install -e .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Install with development tools:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install -e ".[dev]"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Quick Start
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import jax
|
|
77
|
+
import jax.numpy as jnp
|
|
78
|
+
|
|
79
|
+
from yggdrax import (
|
|
80
|
+
DualTreeTraversalConfig,
|
|
81
|
+
build_interactions_and_neighbors,
|
|
82
|
+
build_octree,
|
|
83
|
+
compute_tree_geometry,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
key = jax.random.PRNGKey(0)
|
|
87
|
+
key_pos, key_mass = jax.random.split(key)
|
|
88
|
+
positions = jax.random.uniform(key_pos, (512, 3), minval=-1.0, maxval=1.0)
|
|
89
|
+
masses = jax.random.uniform(key_mass, (512,), minval=0.5, maxval=1.5)
|
|
90
|
+
|
|
91
|
+
tree = build_octree(positions, masses, leaf_size=16)
|
|
92
|
+
positions_sorted = positions[tree.particle_indices]
|
|
93
|
+
geom = compute_tree_geometry(tree, positions_sorted)
|
|
94
|
+
traversal_cfg = DualTreeTraversalConfig(
|
|
95
|
+
max_pair_queue=8192,
|
|
96
|
+
process_block=256,
|
|
97
|
+
max_interactions_per_node=2048,
|
|
98
|
+
max_neighbors_per_leaf=2048,
|
|
99
|
+
)
|
|
100
|
+
interactions, neighbors = build_interactions_and_neighbors(
|
|
101
|
+
tree,
|
|
102
|
+
geom,
|
|
103
|
+
theta=0.6,
|
|
104
|
+
mac_type="dehnen",
|
|
105
|
+
traversal_config=traversal_cfg,
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`build_tree(...)` continues to expose the radix/LBVH backend directly. The
|
|
110
|
+
octree wrappers (`build_octree(...)`, `build_fixed_depth_octree(...)`) preserve
|
|
111
|
+
the same compatibility fields while additionally exposing explicit octree
|
|
112
|
+
buffers such as `oct_children`, `oct_node_depths`, and `radix_node_to_oct`.
|
|
113
|
+
|
|
114
|
+
Advanced users can override the built-in MAC with a JAX-traceable pair policy:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
def pair_policy(policy_state, **pair_data):
|
|
118
|
+
action = ...
|
|
119
|
+
tag = ...
|
|
120
|
+
return action, tag
|
|
121
|
+
|
|
122
|
+
interactions, neighbors, result = build_interactions_and_neighbors(
|
|
123
|
+
tree,
|
|
124
|
+
geom,
|
|
125
|
+
pair_policy=pair_policy,
|
|
126
|
+
policy_state=...,
|
|
127
|
+
return_result=True,
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The policy receives generic pair geometry/state and returns:
|
|
132
|
+
- `action`: one of accept-far / accept-near / refine
|
|
133
|
+
- `tag`: integer metadata stored for accepted far pairs
|
|
134
|
+
|
|
135
|
+
When `return_result=True`, raw far-pair tags are available on
|
|
136
|
+
`result.interaction_tags`. This is intended for downstream solvers that need
|
|
137
|
+
solver-side scheduling or adaptive-order bucketing without moving solver logic
|
|
138
|
+
into `yggdrax`.
|
|
139
|
+
|
|
140
|
+
See `examples/getting_started.ipynb` for a runnable walkthrough.
|
|
141
|
+
For the locked high-performance GPU benchmark configuration, see
|
|
142
|
+
`docs/gpu_benchmark_recommended_setup.md` and
|
|
143
|
+
`examples/tree_gpu_performance_scaling.ipynb`.
|
|
144
|
+
|
|
145
|
+
## KD-Tree MAC Note
|
|
146
|
+
|
|
147
|
+
When comparing Radix vs Octree vs KD-tree traversal outputs, use the same MAC settings as
|
|
148
|
+
your downstream solver.
|
|
149
|
+
|
|
150
|
+
- For FMM-style runs (e.g. jaccpot), `mac_type="dehnen"` is the recommended
|
|
151
|
+
path for apples-to-apples parity checks.
|
|
152
|
+
- Octree builds currently share the radix traversal core, so interaction-count
|
|
153
|
+
parity between `radix` and `octree` should hold for the same build settings.
|
|
154
|
+
- KD-tree traversal uses a calibrated default effective radius scale for
|
|
155
|
+
Dehnen MAC (`dehnen_radius_scale=1.2`) to match near-field/far-field split
|
|
156
|
+
behavior more closely with radix trees.
|
|
157
|
+
- If you benchmark with `mac_type="bh"`, expect different KD/Radix split
|
|
158
|
+
behavior unless you tune parameters explicitly.
|
|
159
|
+
|
|
160
|
+
## Backend Extensibility
|
|
161
|
+
|
|
162
|
+
Yggdrax now supports backend-oriented tree dispatch and capability-based
|
|
163
|
+
topology contracts:
|
|
164
|
+
|
|
165
|
+
- Register builders via `register_tree_builder(...)`
|
|
166
|
+
- Inspect available builders via `available_tree_types()`
|
|
167
|
+
- Use `resolve_tree_topology(...)` for container/topology adapters
|
|
168
|
+
- Use derivation helpers (`get_node_levels`, `get_level_offsets`,
|
|
169
|
+
`get_nodes_by_level`) when a backend does not precompute level metadata
|
|
170
|
+
- Octree consumers can additionally use explicit buffers like `oct_children`
|
|
171
|
+
and `oct_level_offsets` when level-wise FMM scheduling is preferable to
|
|
172
|
+
binary traversal over `left_child` / `right_child`
|
|
173
|
+
|
|
174
|
+
Contract details and required/optional fields are documented in
|
|
175
|
+
`docs/backend_contract.md`.
|
|
176
|
+
|
|
177
|
+
## Build And Traversal Configs
|
|
178
|
+
|
|
179
|
+
Public config dataclasses provide a stable way to reuse tuned settings across
|
|
180
|
+
repeated builds and traversals:
|
|
181
|
+
|
|
182
|
+
- `TreeBuildConfig`: adaptive radix-tree settings (`leaf_size`,
|
|
183
|
+
`return_reordered`, reusable workspace handling)
|
|
184
|
+
- `FixedDepthTreeBuildConfig`: fixed-depth tree settings, including local
|
|
185
|
+
Morton refinement controls
|
|
186
|
+
- `DualTreeTraversalConfig`: traversal queue, block size, interaction capacity,
|
|
187
|
+
and neighbor capacity
|
|
188
|
+
|
|
189
|
+
When a `config=...` object is passed to `build_tree(...)` or
|
|
190
|
+
`build_fixed_depth_tree(...)`, or their octree counterparts, it takes precedence over the equivalent
|
|
191
|
+
individual keyword arguments.
|
|
192
|
+
|
|
193
|
+
Conformance tests:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
pytest -q --no-cov tests/unit/test_backend_conformance.py
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Development
|
|
200
|
+
|
|
201
|
+
Local quality gates:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
pytest
|
|
205
|
+
black --check .
|
|
206
|
+
isort --check-only .
|
|
207
|
+
pydoclint .
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Or run the same checks via pre-commit:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
pre-commit run --all-files
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Coverage is enforced via `pytest-cov`:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
pytest --cov=yggdrax --cov-report=term-missing
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Project Structure
|
|
223
|
+
|
|
224
|
+
- `yggdrax/tree.py`, `yggdrax/_tree_impl.py`: tree building and radix internals
|
|
225
|
+
- `yggdrax/octree.py`: explicit octree metadata derived from Morton/radix trees
|
|
226
|
+
- `yggdrax/protocols.py`: backend capability protocols
|
|
227
|
+
- `yggdrax/geometry.py`, `yggdrax/_geometry_impl.py`: geometry wrappers and implementations
|
|
228
|
+
- `yggdrax/interactions.py`, `yggdrax/_interactions_impl.py`: traversal and interaction generation
|
|
229
|
+
- `yggdrax/dense_interactions.py`, `yggdrax/grouped_interactions.py`: interaction layout utilities
|
|
230
|
+
- `tests/unit`: unit test suite for API and implementation behavior
|
|
231
|
+
- `examples`: runnable examples and notebooks
|
|
232
|
+
|
|
233
|
+
## CI
|
|
234
|
+
|
|
235
|
+
GitHub Actions runs:
|
|
236
|
+
|
|
237
|
+
- unit tests with coverage threshold
|
|
238
|
+
- `black --check`
|
|
239
|
+
- `isort --check-only`
|
|
240
|
+
- `pydoclint`
|
|
241
|
+
|
|
242
|
+
Workflow file: `.github/workflows/ci.yml`.
|
|
243
|
+
|
|
244
|
+
## Relationship to Rubix
|
|
245
|
+
|
|
246
|
+
This repository follows the same engineering principles used in the Rubix codebase:
|
|
247
|
+
|
|
248
|
+
- strict formatting and lint automation
|
|
249
|
+
- tested public APIs
|
|
250
|
+
- explicit artifact contracts
|
|
251
|
+
- examples that reflect real usage paths
|
yggdrax-0.0.1/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Yggdrax
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Yggdrax is a JAX-first tree toolkit for hierarchical N-body solvers. It
|
|
10
|
+
provides Morton ordering, radix tree builders, per-node geometry, and dual-tree
|
|
11
|
+
interaction traversal primitives designed for downstream FMM and treecode
|
|
12
|
+
pipelines. The public `octree` backend now layers explicit octree-cell metadata
|
|
13
|
+
on top of the existing Morton/radix construction path so downstream FMM code
|
|
14
|
+
can consume both the proven traversal buffers and octree-style child tables.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- Morton encode/decode and stable Morton sorting for 3D points
|
|
19
|
+
- LBVH and fixed-depth radix tree construction
|
|
20
|
+
- Explicit octree metadata derived from Morton/radix topology
|
|
21
|
+
- Tree geometry extraction (bounds, centers, extents, radii)
|
|
22
|
+
- Dual-tree far-field and near-field interaction builders
|
|
23
|
+
- Dense and grouped interaction buffer transforms for batched kernels
|
|
24
|
+
- Prepared artifact utilities for downstream solver integrations
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Install from source:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Install with development tools:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install -e ".[dev]"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import jax
|
|
44
|
+
import jax.numpy as jnp
|
|
45
|
+
|
|
46
|
+
from yggdrax import (
|
|
47
|
+
DualTreeTraversalConfig,
|
|
48
|
+
build_interactions_and_neighbors,
|
|
49
|
+
build_octree,
|
|
50
|
+
compute_tree_geometry,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
key = jax.random.PRNGKey(0)
|
|
54
|
+
key_pos, key_mass = jax.random.split(key)
|
|
55
|
+
positions = jax.random.uniform(key_pos, (512, 3), minval=-1.0, maxval=1.0)
|
|
56
|
+
masses = jax.random.uniform(key_mass, (512,), minval=0.5, maxval=1.5)
|
|
57
|
+
|
|
58
|
+
tree = build_octree(positions, masses, leaf_size=16)
|
|
59
|
+
positions_sorted = positions[tree.particle_indices]
|
|
60
|
+
geom = compute_tree_geometry(tree, positions_sorted)
|
|
61
|
+
traversal_cfg = DualTreeTraversalConfig(
|
|
62
|
+
max_pair_queue=8192,
|
|
63
|
+
process_block=256,
|
|
64
|
+
max_interactions_per_node=2048,
|
|
65
|
+
max_neighbors_per_leaf=2048,
|
|
66
|
+
)
|
|
67
|
+
interactions, neighbors = build_interactions_and_neighbors(
|
|
68
|
+
tree,
|
|
69
|
+
geom,
|
|
70
|
+
theta=0.6,
|
|
71
|
+
mac_type="dehnen",
|
|
72
|
+
traversal_config=traversal_cfg,
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`build_tree(...)` continues to expose the radix/LBVH backend directly. The
|
|
77
|
+
octree wrappers (`build_octree(...)`, `build_fixed_depth_octree(...)`) preserve
|
|
78
|
+
the same compatibility fields while additionally exposing explicit octree
|
|
79
|
+
buffers such as `oct_children`, `oct_node_depths`, and `radix_node_to_oct`.
|
|
80
|
+
|
|
81
|
+
Advanced users can override the built-in MAC with a JAX-traceable pair policy:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
def pair_policy(policy_state, **pair_data):
|
|
85
|
+
action = ...
|
|
86
|
+
tag = ...
|
|
87
|
+
return action, tag
|
|
88
|
+
|
|
89
|
+
interactions, neighbors, result = build_interactions_and_neighbors(
|
|
90
|
+
tree,
|
|
91
|
+
geom,
|
|
92
|
+
pair_policy=pair_policy,
|
|
93
|
+
policy_state=...,
|
|
94
|
+
return_result=True,
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The policy receives generic pair geometry/state and returns:
|
|
99
|
+
- `action`: one of accept-far / accept-near / refine
|
|
100
|
+
- `tag`: integer metadata stored for accepted far pairs
|
|
101
|
+
|
|
102
|
+
When `return_result=True`, raw far-pair tags are available on
|
|
103
|
+
`result.interaction_tags`. This is intended for downstream solvers that need
|
|
104
|
+
solver-side scheduling or adaptive-order bucketing without moving solver logic
|
|
105
|
+
into `yggdrax`.
|
|
106
|
+
|
|
107
|
+
See `examples/getting_started.ipynb` for a runnable walkthrough.
|
|
108
|
+
For the locked high-performance GPU benchmark configuration, see
|
|
109
|
+
`docs/gpu_benchmark_recommended_setup.md` and
|
|
110
|
+
`examples/tree_gpu_performance_scaling.ipynb`.
|
|
111
|
+
|
|
112
|
+
## KD-Tree MAC Note
|
|
113
|
+
|
|
114
|
+
When comparing Radix vs Octree vs KD-tree traversal outputs, use the same MAC settings as
|
|
115
|
+
your downstream solver.
|
|
116
|
+
|
|
117
|
+
- For FMM-style runs (e.g. jaccpot), `mac_type="dehnen"` is the recommended
|
|
118
|
+
path for apples-to-apples parity checks.
|
|
119
|
+
- Octree builds currently share the radix traversal core, so interaction-count
|
|
120
|
+
parity between `radix` and `octree` should hold for the same build settings.
|
|
121
|
+
- KD-tree traversal uses a calibrated default effective radius scale for
|
|
122
|
+
Dehnen MAC (`dehnen_radius_scale=1.2`) to match near-field/far-field split
|
|
123
|
+
behavior more closely with radix trees.
|
|
124
|
+
- If you benchmark with `mac_type="bh"`, expect different KD/Radix split
|
|
125
|
+
behavior unless you tune parameters explicitly.
|
|
126
|
+
|
|
127
|
+
## Backend Extensibility
|
|
128
|
+
|
|
129
|
+
Yggdrax now supports backend-oriented tree dispatch and capability-based
|
|
130
|
+
topology contracts:
|
|
131
|
+
|
|
132
|
+
- Register builders via `register_tree_builder(...)`
|
|
133
|
+
- Inspect available builders via `available_tree_types()`
|
|
134
|
+
- Use `resolve_tree_topology(...)` for container/topology adapters
|
|
135
|
+
- Use derivation helpers (`get_node_levels`, `get_level_offsets`,
|
|
136
|
+
`get_nodes_by_level`) when a backend does not precompute level metadata
|
|
137
|
+
- Octree consumers can additionally use explicit buffers like `oct_children`
|
|
138
|
+
and `oct_level_offsets` when level-wise FMM scheduling is preferable to
|
|
139
|
+
binary traversal over `left_child` / `right_child`
|
|
140
|
+
|
|
141
|
+
Contract details and required/optional fields are documented in
|
|
142
|
+
`docs/backend_contract.md`.
|
|
143
|
+
|
|
144
|
+
## Build And Traversal Configs
|
|
145
|
+
|
|
146
|
+
Public config dataclasses provide a stable way to reuse tuned settings across
|
|
147
|
+
repeated builds and traversals:
|
|
148
|
+
|
|
149
|
+
- `TreeBuildConfig`: adaptive radix-tree settings (`leaf_size`,
|
|
150
|
+
`return_reordered`, reusable workspace handling)
|
|
151
|
+
- `FixedDepthTreeBuildConfig`: fixed-depth tree settings, including local
|
|
152
|
+
Morton refinement controls
|
|
153
|
+
- `DualTreeTraversalConfig`: traversal queue, block size, interaction capacity,
|
|
154
|
+
and neighbor capacity
|
|
155
|
+
|
|
156
|
+
When a `config=...` object is passed to `build_tree(...)` or
|
|
157
|
+
`build_fixed_depth_tree(...)`, or their octree counterparts, it takes precedence over the equivalent
|
|
158
|
+
individual keyword arguments.
|
|
159
|
+
|
|
160
|
+
Conformance tests:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
pytest -q --no-cov tests/unit/test_backend_conformance.py
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Development
|
|
167
|
+
|
|
168
|
+
Local quality gates:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pytest
|
|
172
|
+
black --check .
|
|
173
|
+
isort --check-only .
|
|
174
|
+
pydoclint .
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Or run the same checks via pre-commit:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pre-commit run --all-files
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Coverage is enforced via `pytest-cov`:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
pytest --cov=yggdrax --cov-report=term-missing
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Project Structure
|
|
190
|
+
|
|
191
|
+
- `yggdrax/tree.py`, `yggdrax/_tree_impl.py`: tree building and radix internals
|
|
192
|
+
- `yggdrax/octree.py`: explicit octree metadata derived from Morton/radix trees
|
|
193
|
+
- `yggdrax/protocols.py`: backend capability protocols
|
|
194
|
+
- `yggdrax/geometry.py`, `yggdrax/_geometry_impl.py`: geometry wrappers and implementations
|
|
195
|
+
- `yggdrax/interactions.py`, `yggdrax/_interactions_impl.py`: traversal and interaction generation
|
|
196
|
+
- `yggdrax/dense_interactions.py`, `yggdrax/grouped_interactions.py`: interaction layout utilities
|
|
197
|
+
- `tests/unit`: unit test suite for API and implementation behavior
|
|
198
|
+
- `examples`: runnable examples and notebooks
|
|
199
|
+
|
|
200
|
+
## CI
|
|
201
|
+
|
|
202
|
+
GitHub Actions runs:
|
|
203
|
+
|
|
204
|
+
- unit tests with coverage threshold
|
|
205
|
+
- `black --check`
|
|
206
|
+
- `isort --check-only`
|
|
207
|
+
- `pydoclint`
|
|
208
|
+
|
|
209
|
+
Workflow file: `.github/workflows/ci.yml`.
|
|
210
|
+
|
|
211
|
+
## Relationship to Rubix
|
|
212
|
+
|
|
213
|
+
This repository follows the same engineering principles used in the Rubix codebase:
|
|
214
|
+
|
|
215
|
+
- strict formatting and lint automation
|
|
216
|
+
- tested public APIs
|
|
217
|
+
- explicit artifact contracts
|
|
218
|
+
- examples that reflect real usage paths
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yggdrax"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Tree generation and traversal package for hierarchical solvers"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
dependencies = [
|
|
13
|
+
"jax>=0.8.0",
|
|
14
|
+
"jaxlib>=0.4.0",
|
|
15
|
+
"jaxtyping>=0.2.23",
|
|
16
|
+
"beartype>=0.14.0",
|
|
17
|
+
]
|
|
18
|
+
authors = [{ name = "AstroAI Lab" }]
|
|
19
|
+
keywords = ["fmm", "hierarchical", "n-body", "jax", "treecode"]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 3 - Alpha",
|
|
22
|
+
"Intended Audience :: Science/Research",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/AstroAI-Lab/yggdrax"
|
|
33
|
+
Repository = "https://github.com/AstroAI-Lab/yggdrax"
|
|
34
|
+
Issues = "https://github.com/AstroAI-Lab/yggdrax/issues"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"black>=24.8.0",
|
|
39
|
+
"isort>=5.13.2",
|
|
40
|
+
"pydoclint>=0.6.0",
|
|
41
|
+
"pytest>=8.3.0",
|
|
42
|
+
"pytest-cov>=5.0.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools]
|
|
46
|
+
packages = ["yggdrax"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-dir]
|
|
49
|
+
yggdrax = "yggdrax"
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.package-data]
|
|
52
|
+
yggdrax = ["py.typed"]
|
|
53
|
+
|
|
54
|
+
[tool.black]
|
|
55
|
+
line-length = 88
|
|
56
|
+
target-version = ["py310", "py311", "py312"]
|
|
57
|
+
include = "\\.pyi?$"
|
|
58
|
+
exclude = '''
|
|
59
|
+
/(
|
|
60
|
+
\.git
|
|
61
|
+
|\.venv
|
|
62
|
+
|build
|
|
63
|
+
|dist
|
|
64
|
+
)/
|
|
65
|
+
'''
|
|
66
|
+
|
|
67
|
+
[tool.isort]
|
|
68
|
+
profile = "black"
|
|
69
|
+
line_length = 88
|
|
70
|
+
skip_gitignore = true
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
minversion = "7.4"
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
addopts = "-q --strict-markers --cov=yggdrax --cov-report=term-missing --cov-report=xml --cov-fail-under=85"
|
|
76
|
+
|
|
77
|
+
[tool.coverage.run]
|
|
78
|
+
source = ["yggdrax"]
|
|
79
|
+
branch = true
|
|
80
|
+
|
|
81
|
+
[tool.coverage.report]
|
|
82
|
+
show_missing = true
|
|
83
|
+
skip_empty = true
|
|
84
|
+
fail_under = 85
|
|
85
|
+
exclude_lines = [
|
|
86
|
+
"pragma: no cover",
|
|
87
|
+
"if TYPE_CHECKING:",
|
|
88
|
+
"if __name__ == .__main__.:",
|
|
89
|
+
]
|
yggdrax-0.0.1/setup.cfg
ADDED