README, rustdoc, and examples must not claim capabilities beyond the current public surface.- When the public API changes, check for stale names, stale capability claims, and deleted paths in
README, rustdoc, and examples before considering the work complete.
- Do not add or keep an AD
fruleorrrulein the mainline without a corresponding oracle family. - Prefer oracle families with both Torch reference data and finite-difference checks.
- If a Torch reference is not available, a finite-difference-only oracle is acceptable.
- If no corresponding oracle exists yet, add it to
tensor-ad-oraclesbefore treating the rule as a supported mainline AD rule.
PrimitiveOp::linearizeandPrimitiveOp::transpose_rule(intenferro-ops/src/ad/) are the semantic source of truth for AD rules.- These are graph-level rules that emit ops into a
FragmentBuilder.tidu::differentiatecallslinearize;tidu::transposecallstranspose_rule. - Reference JAX's implementations (
jax/_src/lax/lax.py,jax/_src/lax/linalg.py) when implementing new AD rules.
- Every
linearize/transpose_ruleimplementation must have a corresponding finite-difference integration test that verifies numerical correctness. - For linalg ops, prefer oracle families with both Torch reference data and
finite-difference checks when available in
third_party/tensor-ad-oracles/.
- Do not add ad hoc fixes that violate DRY, KISS, or layering.
- Do not introduce compatibility shims, duplicated logic, or downstream reach-through into lower layers when the correct fix belongs in an existing seam or high-level API.
- For faer-backed CPU ops,
CpuContextis the single source of truth for thread-pool policy. - Do not derive faer parallelism independently inside individual ops or helper functions.
- Execute faer-backed work only inside
ctx.install(...)so the owned rayon context is preserved. - Use
Par::Seqfor one-thread contexts andPar::rayon(0)for multi-thread contexts so faer follows the currentCpuContext.
- Source code is the source of truth for internal design (op catalog, backend contract, AD rules, compilation pipeline).
- Online docs are user-facing only — how to use the
tenferrofacade crate. - AGENTS.md is the entry point for developers and AI agents. It contains pointers to source code locations.
- Do NOT duplicate source-code-level information in online docs. If it can be learned by reading the source, put a pointer instead of a copy.
- Development assumes AI agentic coding. Keep machine-readable sources (code + doc comments) authoritative.
- User docs target PyTorch/JAX users who interact with the
tenferrofacade crate. - All imports must use
use tenferro::{...}— never reference internal crates (tenferro-tensor,tenferro-ops,computegraph, etc.) in user-facing docs. - Do NOT expose internal jargon (Fragment, StableHLO, ExecOp, ValRef, etc.) in user-facing pages.
- Provide PyTorch/JAX equivalents when introducing tenferro concepts.
- Doc examples (
/// # Examples) must NOT useignoreorno_runattributes. - Every example must compile AND run as a doctest.
- Use
compile_failonly for examples that intentionally demonstrate compile errors. - If an example cannot run as a doctest, refactor it until it can.
- Use generic constructors with sealed traits instead of per-type functions.
- Bad:
TracedTensor::from_f64(...),TracedTensor::from_f32(...), etc. - Good:
TracedTensor::new<T: TensorScalar>(shape, data)— type inference selects the variant. - Sealed traits (
TensorScalar,PoolScalar, etc.) restrict to supported dtypes (f64, f32, Complex64, Complex32).
- Unary single-output ops: methods on
TracedTensor(e.g.,x.exp(),x.reshape(shape)) - Binary single-output ops: operator overloads where natural (
&a + &b,&a * &b), methods otherwise (a.dot_general(&b, config)) - Multi-output ops: free functions (e.g.,
svd(&a),qr(&a),eigh(&a)) - Linalg ops: free functions (e.g.,
solve(&a, &b),cholesky(&a)) - Einsum: free function
einsum(engine, inputs, subscripts) - No
traced_prefix on methods.TracedTensormethods are inherently traced.