CPU (Apple Accelerate-backed) concrete IBackend.
Every public method satisfies the IBackend contract; the
private section holds low-level type-dispatch helpers (unary_op,
binary_op, reduce_axes) plus per-op compute routines that
delegate to the Accelerate helpers in Blas.h,
Lapack.h, Norm.h, Pool.h, Reduce.h,
Vdsp.h, and Vforce.h.
See Also
IBackend — abstract base.
GpuBackend — MLX/Metal counterpart.
Dispatcher — owns the singleton instance.
Notes
Marked final — there is exactly one CPU backend at runtime,
installed by CpuBackendRegistrar at static-init time.
Static methods
38conv_nd_im2col_f32
void conv_nd_im2col_f32(const float * x, float * cols, int C, const int * S, const int * K, const int * O, const int * stride, const int * pad, const int * dilation, int N)Dispatches im2col to the 1-D, 2-D, or 3-D variant based on N. S/K/O are input spatial sizes, kernel sizes, and output sizes indexed 0..N-1.
Registers this backend with the Dispatcher for Device::CPU.
Invoked exactly once at process start by BackendInit.cpp.
See Also
Dispatcher::register_backend — receiving end.
Virtual methods
1Methods
251── astype ────────────────────────────────────────────────────────────────
Generic Cartesian-product cast over the supported scalar dtypes. Earlier
versions of this file hand-spelled every supported (src, dst) pair, which
left holes (notably Bool -> I64) that surfaced during the 3.0.2 +
followup smoke runs — bool reductions need to promote through I64 first
and that promotion was silently NotImplementedError. The dispatch below
covers every pair among {F16, F32, F64, I8, I16, I32, I64, Bool}. C64
and BF16 are not handled here because their host representation isn't a
simple static_cast-able scalar (F16 uses the IEEE half decoder from
item() indirectly via the F32 path — handled with a small helper).
Generic binary dispatch: allocates output, calls fn32/fn64/fni32/fni64 based on dt.
── Complex viewing (interleaved [re, im, re, im, ...] storage) ────────
ctc_loss_forward
int ctc_loss_forward(const int & log_probs, const int & targets, const int & input_lengths, const int & target_lengths, const int & lp_shape, int blank, bool zero_infinity, Dtype dt)── ctc_loss ──────────────────────────────────────────────────────────────
embedding_bag_forward
int embedding_bag_forward(const int & weight, const int & indices, const int & offsets, const int & weight_shape, const int & indices_shape, int mode, int padding_idx, bool include_last_offset, Dtype dt)EmbeddingBag: gather + reduce per bag
Fills ptr with the scalar value 1 for dtype dt. Used by ones().
── flip ──────────────────────────────────────────────────────────────────
Wraps an incoming CpuStorage into the variant directly.
The CPU backend already operates on CpuStorage natively, so
this is a move with no copy. The shape argument is ignored.
Parameters
cpuCpuStorageReturns
Storagecpu re-wrapped as a Storage variant.
── masked_select ─────────────────────────────────────────────────────────
nn_fold
int nn_fold(const int & x, const int & x_shape, const int & out_shape, const int & kernel_size, const int & stride, const int & padding, const int & dilation, Dtype dt)fold (col2im): scatter-add (N, CkHkW, L) → (N, C, outH, outW)
reduce_axes
int reduce_axes(const int & a, const int & in_shape, const ReduceOpts & opts, Dtype dt, ReduceOp op)Reduces a over the axes in opts by iterating axes from largest to smallest (descending sort ensures that axis indices remain valid after each step). Each single-axis pass calls the appropriate cpu::sum_axis / max_axis / min_axis primitive. Mean divides by the reduce dimension after summing.
relu_backward
int relu_backward(const int & g, const int & x, const int & shape, Dtype dt)3.4+ Phase A.1: fused ReLU backward. Single-pass loop replacing positive_mask + multiply, eliminating one intermediate buffer. See GpuBackend::relu_backward for the GPU rationale.
scatter_add
int scatter_add(const int & base, const int & indices, const int & src, const int & base_shape, const int & idx_shape, int dim, Dtype dt)User-facing scatter-add: copies base then adds src at positions given by indices.
Generic scatter-reduce loop shared by scatter_amax / scatter_amin / scatter_prod. Op is a binary functor: (T& dst_elem, T src_elem) → void (modifies dst in-place).
Generic unary dispatch: allocates output, calls fn32/fn64/fni32 based on dt. I64 falls back to a scalar loop via static_cast<double>.
unfold_dim
int unfold_dim(const int & a, const int & in_shape, int dim, int size, int step, Dtype dt)Sliding-window view: out shape is (*in_shape[:dim], L, *in_shape[dim+1:], size)