Device properties and a two-plugin force manifest

Device properties and a two-plugin force manifest#

Needs a CUDA GPU. A standalone, self-contained task: read the current device’s raw + derived properties, then combine two compiled force plugins — gravity and a per-sample drag model — from one manifest into a single accumulated acceleration, the way a propagator step would.

from eagle import device_props

props = device_props()
{
    "name": props.name,
    "compute_capability": f"{props.cc_major}.{props.cc_minor}",
    "sm_count": props.sm_count,
    "warp_size": props.warp_size,
    "fp64_ratio": props.fp64_ratio,
}
{'name': 'Quadro P2000',
 'compute_capability': '6.1',
 'sm_count': 8,
 'warp_size': 32,
 'fp64_ratio': 32.0}

Combining two plugins from one manifest#

gravity and drag_ps are both "vector"-pattern plugins declared in the same manifest; loading it returns both, keyed by their manifest id.

import json
import pathlib
import shutil
import tempfile

import numpy as np

FIXTURES = pathlib.Path("../_fixtures").resolve()
workdir = pathlib.Path(tempfile.mkdtemp())
for stem in ("gravity", "drag_ps"):
    shutil.copy(FIXTURES / f"{stem}.ptx", workdir / f"{stem}.ptx")
    shutil.copy(FIXTURES / f"{stem}.json", workdir / f"{stem}.json")

manifest = {
    "schema_version": 1,
    "pattern": "vector",
    "aether_abi": "aether-abi/1",
    "plugins": [
        {"id": "gravity", "order": 0, "enabled": True, "artifact": "gravity.ptx",
         "sidecar": "gravity.json", "format": "ptx"},
        {"id": "drag", "order": 1, "enabled": True, "artifact": "drag_ps.ptx",
         "sidecar": "drag_ps.json", "format": "ptx"},
    ],
}
(workdir / "manifest.json").write_text(json.dumps(manifest, indent=2))
426
from eagle.registry import load_manifest

reg = load_manifest(workdir / "manifest.json")
reg.names()
['gravity', 'drag']
MU = 3.986004418e5
N = 32
rng = np.random.default_rng(3)
position = rng.uniform(7.0e3, 4.2e4, size=(3, N))
velocity = rng.uniform(1.0, 8.0, size=(3, N))
mass = rng.uniform(100.0, 1200.0, N)
area = rng.uniform(1.0, 20.0, N)
cd = rng.uniform(2.0, 2.4, N)

a_gravity = reg["gravity"](position=position, mu=MU)
a_drag = reg["drag"](velocity=velocity, mass=mass, area=area, cd=cd)
a_total = a_gravity + a_drag
a_total.shape
(3, 32)
r = np.linalg.norm(position, axis=0)
expected_gravity = -MU * position / r**3
s = np.linalg.norm(velocity, axis=0)
expected_drag = -0.5 * (cd * area / mass) * s * velocity

np.testing.assert_allclose(a_gravity, expected_gravity)
np.testing.assert_allclose(a_drag, expected_drag)
print("both plugins, loaded from one manifest, match their closed forms")
both plugins, loaded from one manifest, match their closed forms