Core owns portable inference contracts and MLX Metal execution. Source-model capture, source-framework operation translation, checkpoint admission and model comparison recipes belong to medmlx-convert. Model topology, labels, prompts and image preprocessing/postprocessing belong to the individual model package.
This source tree is version 0.2.0. Until that version is released, install its local wheel or checkout. The base runtime requires only MLX and NumPy. Torch, TensorFlow, Core AI, Core ML and medmlx-convert are not inference dependencies. Metal is required; model execution never falls back to CPU.
pip install ./medmlx-core
from pathlib import Path
import mlx.core as mx
from medmlx_core.graph.runtime import Session
session = Session.load(Path("build/my-native-lungmask"))
log_probs, = session(mx.zeros((1, 1, 256, 256), dtype=mx.float32))
schema.py defines graph schema 2: tensor roles, static shapes, float32/int32/bool dtypes, producer provenance, named calls and explicit tensor references. The single codec rejects unknown fields, operations and invalid references. Each operation owns one required parameter list. Neither the format nor the loader executes source code.
Operation names are independent of ATen. The converter translates source signatures and removes source-only options before serialization. A schema-1 pilot bundle must be regenerated by its source recipe; core carries no compatibility loader. Producer name/version are descriptive provenance and are never imported.
Bundles contain graph.json and weights.safetensors. The loader enforces exact state keys, shapes and dtypes. Inputs and outputs are flat ordered tensors retaining the graph's declared axes. File loading is explicitly a host operation; arithmetic executes in an explicit Metal stream.
| Operations | Current scope |
|---|---|
| Convolution and normalization | 2D/3D convolution and transpose convolution; supported groups/dilation variants; inference BatchNorm and InstanceNorm. The stride-2, kernel-2 3D decoder reuses core's one-matmul implementation. BatchNorm-with-aux returns normalized values and two empty FP32 training-statistic outputs. |
| Sampling and tensor operations | Unpadded floor-mode 2D average pooling; positive integral-factor bilinear upsampling; activation, concatenation, slicing, LogSoftmax, arithmetic, reshape, chunk-size split, dtype cast, metadata assertions and tuple selection. |
| Unsupported variants | Raise explicitly. Dynamic shapes, training, mutable input/state, output pytree reconstruction and whole image pipelines are outside this experimental fixed-shape FP32 path. |
registration.py exposes dense_warp3d(volume, displacement, fill_value=None) and integrate_stationary_velocity(velocity, steps=7). Arrays are nonempty float32 DHWC; displacement and velocity have three channels. Coordinates are zero-based ij voxel indices. A pull field samples input at x + displacement[x]. Border extension and whole-sample constant fill outside the domain match the recorded official TensorFlow functions.
The independent synthetic oracle and regeneration instructions retain their original provenance. Tests compare border sampling, constant fill and seven-step scaling-and-squaring to pinned original VoxelMorph/Neurite TensorFlow CPU outputs. This qualifies those tested operations, not a learned SynthMorph model, affine fitting, patient data or clinical accuracy.
Keeping shared execution inside the converter was rejected because it made inference installation depend on the source-model and Apple conversion stack. Duplicating operators in individual model packages was rejected because numerical fixes would diverge. Core owns execution once; converter frontends depend on core, and core never depends on a converter.