Skip to content

Commit cf7e2dd

Browse files
committed
Add AGENTS.md guide for AI coding agents
Summary: Add `AGENTS.md`, a self-contained guide for AI coding agents working in the repository. It documents the repository layout, the `pixi` build and test tasks, C++ and PyMomentum coding conventions, platform notes, test helpers and deterministic seeding, and the wheel packaging variants, so an agent has the project's conventions available without external context. `AGENTS.md` is the vendor-neutral filename that a range of AI coding tools read by default. Differential Revision: D110946447
1 parent 8569ded commit cf7e2dd

1 file changed

Lines changed: 225 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
# Momentum AI Assistant Guide
2+
3+
Momentum is a C++ library for human kinematic motion, character representation,
4+
and numerical optimization solvers. The repository also contains PyMomentum,
5+
the Python bindings and Python utilities built on top of the C++ library.
6+
7+
This guide is for AI coding agents working in the public repository. Keep future
8+
instructions codebase-focused and self-contained: use public paths, public
9+
commands, and public documentation. Do not add private organization-specific
10+
workflow, review, source-control, or infrastructure rules here.
11+
12+
For end-user installation, building from source, and the contribution workflow,
13+
see `README.md` and `CONTRIBUTING.md`.
14+
15+
## Repository Map
16+
17+
- `momentum/` - C++ core library.
18+
- `common/` - exceptions, checks, logging, shared utilities.
19+
- `math/` - transforms, meshes, random utilities, numerical helpers.
20+
- `character/` - skeletons, characters, skinning, collision geometry.
21+
- `solver/` - generic solver framework.
22+
- `character_solver/` - character-specific inverse kinematics solvers.
23+
- `character_solver_simd/` - SIMD-accelerated solver error functions.
24+
- `character_sequence_solver/` - multi-frame sequence solvers.
25+
- `diff_ik/` - differentiable inverse kinematics support.
26+
- `simd/` - SIMD helpers and abstractions shared by the compute paths.
27+
- `io/` - file I/O including FBX, glTF, URDF, C3D, and related formats.
28+
- `marker_tracking/`, `rasterizer/`, `camera/`, `gui/` - application-facing
29+
support libraries.
30+
- `test/` - C++ unit tests and test helpers.
31+
- `examples/`, `tutorials/` - example applications and tutorials.
32+
- `website/` - documentation site sources.
33+
- `pymomentum/` - Python bindings and Python modules.
34+
- `geometry/` - NumPy-oriented character and geometry bindings.
35+
- `diff_geometry/`, `solver/`, `tensor_momentum/` - PyTorch-backed modules.
36+
- `solver2/`, `marker_tracking/`, `renderer/`, `camera/`, `axel/` - Python
37+
extension modules and helpers.
38+
- `test/` - Python tests.
39+
- `axel/` - bundled Axel acceleration library (sources under `axel/axel/`).
40+
- `cmake/` - CMake helper functions and source lists. `cmake/mt_defs.cmake`
41+
defines the `mt_library`, `mt_test`, and `mt_executable` helpers used
42+
throughout `CMakeLists.txt`.
43+
- `scripts/` - wheel, packaging, and CI helper scripts.
44+
- `.github/workflows/` - GitHub Actions CI, nightly, wheel, and docs workflows.
45+
- `CMakeLists.txt`, `pixi.toml`, `pyproject.toml` - top-level build, task, and
46+
Python packaging entry points.
47+
48+
## Build And Test
49+
50+
Use Pixi tasks for normal development. Dependencies install automatically on the
51+
first run.
52+
53+
```bash
54+
pixi run build # Release C++ build, with Python bindings enabled
55+
pixi run build_dev # Debug C++ build
56+
pixi run test # Release C++ tests
57+
pixi run test_dev # Debug C++ tests
58+
pixi run test_verbose # Release C++ tests with verbose output
59+
pixi run build_py # Build Python bindings
60+
pixi run test_py # Python tests
61+
pixi run lint # Format C++ code with clang-format
62+
pixi run lint-check # Check C++ formatting
63+
pixi task list # Show all available tasks
64+
```
65+
66+
Useful environment-specific commands:
67+
68+
```bash
69+
pixi run -e py313 build_py
70+
pixi run -e py313 test_py
71+
pixi run -e gpu build_py
72+
```
73+
74+
Windows developers can use `pixi run open_vs` to open the configured Visual
75+
Studio project.
76+
77+
## Platform Notes
78+
79+
- macOS builds are supported on both Intel and Apple Silicon.
80+
- On Linux the FBX SDK is downloaded automatically during environment setup
81+
(the `install_fbxsdk` task).
82+
- FBX I/O is available on Linux, macOS, and Windows (x86_64); USD I/O requires
83+
the optional USD dependencies.
84+
- SIMD-accelerated paths target x86_64 (AVX2/FMA); other architectures such as
85+
ARM fall back to scalar implementations.
86+
87+
## Source Lists And Generated Files
88+
89+
- When adding, removing, or renaming C++ files under `momentum/`, update
90+
`cmake/build_variables.bzl`. CMake reads these lists through
91+
`cmake/mt_defs.cmake`.
92+
- When adding, removing, or renaming PyMomentum C++ binding files, update
93+
`pymomentum/cmake/build_variables.bzl`.
94+
- When adding new public C++ classes that need forward declarations, update
95+
`momentum/gen_fwd_input.toml`. The per-module `fwd.h` files are generated from
96+
it — each class gets `_p`/`_u`/`_w` (and `_const_*`) smart-pointer aliases. Do
97+
not hand-edit `fwd.h`; change the TOML source instead.
98+
- When changing PyPI packaging, edit `pyproject-pypi.toml.j2` and regenerate the
99+
derived files with `pixi run generate_pyproject`.
100+
- Do not hand-edit generated build or packaging outputs when a source template
101+
exists.
102+
103+
## C++ Conventions
104+
105+
- Follow the C++ style guide in the developer guide on the documentation site:
106+
https://facebookresearch.github.io/momentum/docs_cpp/developer_guide/style_guide
107+
- Use Doxygen-style `///` comments in public headers. Use `@param` and `@return`
108+
tags, and document new public classes, structs, and functions.
109+
- Use `camelCase` for functions, variables, and members; `PascalCase` for class
110+
names; `ALL_CAPS` for macros; `snake_case` for files and directories; and a
111+
trailing underscore for private members.
112+
- Write abbreviations in `PascalCase` too, e.g. `Fbx` and `Gltf`, not `FBX` or
113+
`GLTF`.
114+
- Prefer early return, `continue`, or `break` over deeply nested control flow.
115+
- Prefer `std::span` for read-only or mutable contiguous ranges accepted by
116+
function parameters.
117+
- Use `MT_THROW("message: {}", value)` for exceptions and `MT_CHECK(cond, ...)`
118+
for runtime assertions, both from `<momentum/common/exception.h>`.
119+
- Use `momentum::pi<T>()` and `momentum::twopi<T>()` from
120+
`<momentum/math/constants.h>` instead of `M_PI` for Windows compatibility.
121+
- Include ordering:
122+
1. Corresponding header.
123+
2. Momentum headers.
124+
3. Third-party headers.
125+
4. Standard library headers.
126+
- Public headers should include Momentum headers with angle brackets, for
127+
example `#include <momentum/common/checks.h>`. Implementation files usually
128+
include local Momentum headers with quotes.
129+
130+
## PyMomentum Conventions
131+
132+
- Python-facing argument names use `snake_case`, even when the C++ API uses
133+
`camelCase`.
134+
- Bind multi-dimensional Eigen inputs as `pybind11::array_t<float>` to avoid
135+
NumPy row-major versus Eigen column-major confusion. One-dimensional vectors
136+
can use pybind11 Eigen conversion.
137+
- For quaternion inputs and outputs, include
138+
`pymomentum/python_utility/eigen_quaternion.h`; the Python format is
139+
`[x, y, z, w]`.
140+
- For optional Eigen arguments, prefer `std::optional<Eigen::...>` instead of
141+
default Eigen values in the binding declaration.
142+
- Use `py::ssize_t`, not POSIX `ssize_t`, in pybind11 code so Windows builds
143+
compile.
144+
- For constructors or option structs with multiple arguments, prefer
145+
`py::kw_only()` plus a lambda-based `py::init` to avoid silent bugs from
146+
positional argument reordering.
147+
- Public bindings should have Sphinx-friendly docstrings. Keep `:param:`,
148+
`:return:`, and cross-reference names aligned with the exposed Python
149+
argument names.
150+
- Format Python with `black` and follow PEP 8, including type hints on public
151+
APIs.
152+
- `pymomentum.geometry` is NumPy-oriented and should stay suitable for fast
153+
forward operations, visualization, and non-differentiable workflows.
154+
- `pymomentum.diff_geometry` and `pymomentum.solver` are PyTorch-backed modules
155+
for differentiable operations and must respect the supported PyTorch ABI.
156+
- After changing C++ bindings, rebuild before testing Python: `pixi run
157+
build_py`. Pure Python changes do not require a rebuild.
158+
159+
## Tests
160+
161+
- Add or update tests with behavior changes.
162+
- C++ tests live under `momentum/test/`; Python tests live under
163+
`pymomentum/test/`.
164+
- Prefer existing test helpers:
165+
- `createTestCharacter(numJoints)` (minimum 3 joints) from
166+
`<momentum/test/character/character_helpers.h>` instead of manually
167+
assembling skeletons, parameter transforms, meshes, locators, and collision
168+
geometry.
169+
- `temporaryFile()` and `temporaryDirectory()` from
170+
`<momentum/test/io/io_helpers.h>` instead of directly using
171+
`std::filesystem::temp_directory_path()`.
172+
- Seed random tests deterministically. Prefer a fixture-owned
173+
`Random<> rng{12345};` from `<momentum/math/random.h>`. When extending an
174+
older test that already uses the singleton helpers, seed
175+
`Random<>::GetSingleton()` at the start of each test. Do not use Eigen's
176+
`Random()` / `UnitRandom()` — they seed from `std::random_device` and produce
177+
different values every run.
178+
- For optional Python dependencies, gate the whole `unittest.TestCase` class
179+
behind an import flag rather than using per-test skip decorators. This keeps
180+
pytest collection clean when optional dependencies are unavailable.
181+
- To run a single Python test, enter `pixi shell` and invoke `pytest` directly
182+
with a `-k` filter.
183+
184+
## Documentation
185+
186+
- Keep code examples out of the `momentum/website/` docs — they go stale.
187+
Describe the approach and reference a test or example instead; when code is
188+
unavoidable, prefer pseudocode.
189+
- Public documentation lives on the docs site: the Python and C++ API references
190+
and the getting-started guides linked from `README.md`.
191+
192+
## CI And Packaging
193+
194+
- GitHub Actions workflows live in `.github/workflows/`. Keep platform matrices
195+
intentional and use existing workflow patterns before adding new mechanisms.
196+
- Wheel builds have three variants:
197+
- `core` - NumPy/SciPy modules and torch-backed pure Python helpers, without
198+
Torch C++ extension modules.
199+
- `cpu` - includes Torch C++ extension modules for CPU PyTorch.
200+
- `gpu` - includes Torch C++ extension modules for CUDA PyTorch.
201+
- Build and test wheel variants with:
202+
203+
```bash
204+
pixi run -e py313 generate_pyproject
205+
PYMOMENTUM_VARIANT=core pixi run -e py313 wheel_build
206+
PYMOMENTUM_VARIANT=core pixi run -e py313 wheel_check
207+
PYMOMENTUM_VARIANT=core pixi run -e py313 wheel_test
208+
```
209+
210+
Use `PYMOMENTUM_VARIANT=cpu` or `PYMOMENTUM_VARIANT=gpu` for the other wheel
211+
families. `wheel_check` validates the generated packaging; `wheel_test` checks
212+
clean-environment imports and PyTorch import-order compatibility.
213+
214+
## Change Checklist
215+
216+
Before handing off code changes, run the smallest relevant checks first, then a
217+
broader pass when the change affects shared behavior.
218+
219+
- C++ changes: `pixi run lint`, relevant C++ test target or `pixi run test`.
220+
- PyMomentum binding changes: `pixi run build_py`, relevant Python tests, then
221+
`pixi run test_py` when practical.
222+
- Packaging changes: `pixi run generate_pyproject`, then relevant
223+
`wheel_build`, `wheel_check`, and `wheel_test` tasks.
224+
- CI changes: inspect the affected workflow and, when possible, run the command
225+
the workflow invokes locally.

0 commit comments

Comments
 (0)