This document covers the Python testing infrastructure for the algovivo Python package located in utils/py/algovivo/ and the code generation tests in codegen/test/. The Python package provides a native library interface to the C++/WASM physics engine through ctypes. Testing validates that the native shared library can be loaded correctly, that the FFI (Foreign Function Interface) bindings work, and that simulation trajectory output is deterministic. Additionally, the codegen tests verify the mathematical correctness of generated energy functions by compiling them into temporary shared libraries and comparing outputs against expected analytical values.
For JavaScript testing infrastructure, see page 10.1. For browser-based integration testing, see page 10.3. For details on the Python API itself, see page 11.4.
The Python testing system validates the interaction between Python wrapper classes and the compiled native libraries (.so files on Linux/macOS).
utils/py/
├── algovivo/ # Python package source
│ ├── __init__.py # Package exports
│ ├── native_instance.py # ctypes-based native library loader
│ ├── system.py # System simulation wrapper
│ ├── vertices.py # Vertices component
│ ├── muscles.py # Muscles component <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/utils/py/algovivo/muscles.py#L4-L10" min=4 max=10 file-path="utils/py/algovivo/muscles.py">Hii</FileRef>
│ ├── triangles.py # Triangles component
│ └── utils.py # ctypes pointer utilities <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/utils/py/algovivo/utils.py#L1-L15" min=1 max=15 file-path="utils/py/algovivo/utils.py">Hii</FileRef>
└── test/ # Test directory (pytest root)
├── test_load_lib.py # Native library loading test <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/utils/py/test/test_load_lib.py#L7-L11" min=7 max=11 file-path="utils/py/test/test_load_lib.py">Hii</FileRef>
└── trajectory/ # Trajectory integration test
├── test_trajectory.py # Runs simulation, writes step files <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/utils/py/test/trajectory/test_trajectory.py#L9-L45" min=9 max=45 file-path="utils/py/test/trajectory/test_trajectory.py">Hii</FileRef>
└── data/
└── mesh.json # Reference mesh for trajectory test <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/utils/py/test/trajectory/test_trajectory.py#L17-L17" min=17 file-path="utils/py/test/trajectory/test_trajectory.py">Hii</FileRef>
codegen/
└── test/ # Codegen unit tests
├── test_gravity.py # Gravity energy verification <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/codegen/test/test_gravity.py#L12-L32" min=12 max=32 file-path="codegen/test/test_gravity.py">Hii</FileRef>
├── test_collision.py # Ground collision energy verification <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/codegen/test/test_collision.py#L12-L31" min=12 max=31 file-path="codegen/test/test_collision.py">Hii</FileRef>
├── test_friction.py # Ground friction energy verification <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/codegen/test/test_friction.py#L12-L33" min=12 max=33 file-path="codegen/test/test_friction.py">Hii</FileRef>
└── test_inertia.py # Inertial energy verification <FileRef file-url="https://github.com/juniorrojas/algovivo/blob/a52c55da/codegen/test/test_inertia.py#L42-L63" min=42 max=63 file-path="codegen/test/test_inertia.py">Hii</FileRef>
Sources: utils/py/algovivo/muscles.py4-10 utils/py/algovivo/utils.py1-15 utils/py/test/test_load_lib.py7-11 utils/py/test/trajectory/test_trajectory.py9-45 codegen/test/test_gravity.py12-32 codegen/test/test_collision.py12-31 codegen/test/test_friction.py12-33 codegen/test/test_inertia.py42-63
The following diagram maps the Natural Language concepts of "Loading" and "Simulation" to the specific code entities in the Python testing suite.
Code Entity Space Mapping
Sources: utils/py/test/test_load_lib.py7-11 utils/py/test/trajectory/test_trajectory.py9-14 utils/py/algovivo/muscles.py12-19 codegen/test/test_gravity.py13-14
Python tests are integrated into the GitHub Actions workflow to ensure library stability across changes.
| Workflow File | Purpose | Key Commands |
|---|---|---|
.github/workflows/py.yml | Native lib integration tests | pytest ./utils/py/test .github/workflows/py.yml57 |
.github/workflows/py.yml | Trajectory generation check | python utils/py/test/trajectory/test_trajectory.py .github/workflows/py.yml61 |
.github/workflows/build.yml | Native lib build matrix | docker run -e NATIVE=true ... ./build.sh .github/workflows/build.yml104-109 |
The test-py workflow builds the native library using a Dockerized environment containing LLVM 18 and Enzyme before running the Python test suite .github/workflows/py.yml35-41
Sources: .github/workflows/py.yml35-61 .github/workflows/build.yml104-109
The primary test validates that the native library can be loaded and that essential functions are accessible through the FFI.
The test is implemented in utils/py/test/test_load_lib.py:7-11():
ALGOVIVO_LIB_FILENAME to find the .so file utils/py/test/test_load_lib.py9backward_euler_update is present in the loaded library utils/py/test/test_load_lib.py11Sources: utils/py/test/test_load_lib.py7-11
A critical part of the testing infrastructure is the automated verification of generated C++ code. This process involves generating source code, compiling it with clang++, and executing it via ctypes.
The codegen/test/ scripts follow a unified pattern for testing energy functions:
algovivo_codegen.Fun (or potential classes like Gravity, Collision, or Friction) to create a function object and call codegen() codegen/test/test_gravity.py13-24gravity.h, inertia.h, collision.h, or friction.h) to a temporary directory and compile it into a shared library using clang++ -shared -fPIC -nostdlib codegen/test/test_gravity.py44-60.so with ctypes.CDLL and define argtypes and restype for the specific energy function codegen/test/test_gravity.py67-75| Test Function | Component Logic | Logic Verified |
|---|---|---|
test_gravity_energy_forward | Gravity | $m \cdot g \cdot y$ for each vertex codegen/test/test_gravity.py98-102 |
test_collision_energy_forward | Collision | $k \cdot py^2$ for vertices where $py < 0$ codegen/test/test_collision.py99-106 |
test_friction_energy_forward | Friction | $k \cdot vx^2 \cdot (-height)$ for vertices below threshold $\epsilon$ codegen/test/test_friction.py113-125 |
test_inertial_energy_forward | Inertia | Sum of $m \cdot |
Sources: codegen/test/test_gravity.py80-105 codegen/test/test_collision.py78-107 codegen/test/test_friction.py82-126 codegen/test/test_inertia.py112-150 codegen/algovivo_codegen/potentials/gravity.py3-32
The Python component classes interface with the native library using torch.Tensor objects converted to C-style pointers.
The utils.py module provides critical FFI functions that convert PyTorch tensors to ctypes pointers.
| Function | Source | Purpose |
|---|---|---|
as_float_ptr(x) | utils/py/algovivo/utils.py7-10 | Casts PyTorch tensor data to ctypes.POINTER(ctypes.c_float) |
as_int_ptr(x) | utils/py/algovivo/utils.py12-15 | Casts PyTorch tensor data to ctypes.POINTER(ctypes.c_int32) |
Each component prepares its internal torch.Tensor data for the native backward_euler_update call via to_step_args():
num_muscles, indices, k (stiffness), a (activations), and l0 (rest lengths) pointers utils/py/algovivo/muscles.py27-35Muscles.set method allows initializing rest lengths l0 either directly or by calculating them from vertex positions using the native l0_of_pos function utils/py/algovivo/muscles.py37-62Sources: utils/py/algovivo/muscles.py27-62 utils/py/algovivo/utils.py7-15
The script utils/py/test/trajectory/test_trajectory.py serves as a high-level integration test. It exercises the entire stack from loading a JSON mesh to running simulation steps and exporting state.
build/ directory utils/py/test/trajectory/test_trajectory.py10-12algovivo.System utils/py/test/trajectory/test_trajectory.py14mesh.json and populates Vertices, Muscles, and Triangles components utils/py/test/trajectory/test_trajectory.py17-30system.step() utils/py/test/trajectory/test_trajectory.py36-38pos0) and muscle activations (a0) to JSON files in steps.out/ for deterministic verification utils/py/test/trajectory/test_trajectory.py40-45Simulation Data Flow
Sources: utils/py/test/trajectory/test_trajectory.py17-45 utils/py/algovivo/muscles.py12-19
The Python testing suite focuses on structural and functional correctness:
space_dim, g, num_vertices) codegen/test/test_gravity.py17-22Muscles.set enforces that indices and either pos or l0 are provided utils/py/algovivo/muscles.py38-51Sources: utils/py/test/test_load_lib.py11 codegen/test/test_gravity.py17-22 utils/py/algovivo/muscles.py38-51 codegen/test/test_gravity.py102 codegen/test/test_collision.py104-106 codegen/test/test_friction.py123-125
Refresh this wiki