mars

Rust Migration and ABI Compatibility

This page defines the non-breaking migration posture for future Rust-first work. The project should keep the Python API stable while moving more shared runtime behavior behind explicit Rust-owned boundaries.

Current Boundary

Rust is already authoritative for portable runtime behavior that can be represented through ModelSpec:

Python remains the stable public adapter:

ABI Recommendation

Adopt a narrow ABI only for stable runtime primitives. Do not freeze training internals yet.

Recommended first ABI scope:

Do not include initially:

API-Preserving Migration

The user-facing API remains unchanged:

import pymars as earth

model = earth.Earth()
model.fit(X, y)
model.predict(X)

Adapters can route through Rust, CLI, FFI, or a future ABI without changing the public surface. That requires:

ABI Design Rules

Rule Rationale
Opaque handles only avoids exposing Rust internals across ABI boundaries
Versioned symbols or version query allows host wrappers to fail clearly on incompatible runtime versions
Caller-owned inputs, runtime-owned outputs keeps memory ownership understandable
Explicit free functions required for safe C ABI use from R, Julia, C#, Go, and Python
JSON-compatible errors keeps error reporting portable across bindings
Fixture-backed conformance prevents ABI drift from changing model semantics

Future Migration Slices

  1. ABI proof-of-concept for validate/predict/export.
  2. Host-wrapper experiment in one non-Python binding.
  3. Cross-language conformance tests through the ABI path.
  4. Training ABI decision after parity and ownership rules are stable.
  5. Optional Arrow input/output helpers once memory ownership is proven.

Review Gates

No future Rust migration slice should land without:

References