Neural Network Primitives (BNNS)

AppleAccelerate wraps the current, non-deprecated slice of Apple's BNNS (Basic Neural Network Subroutines) library — 61 of the ~136 BNNS* C entry points. The bulk of the remainder are APIs Apple deprecated in macOS 15 / iOS 18: the classic filter/layer construction API and the deprecated classic + DirectApply tensor kernels (BNNSMatMul, BNNSTile, BNNSGather/BNNSScatter, the clip / norm family, BNNSOptimizerStep, …). Those are intentionally not wrapped — target the BNNS Graph API instead. The wrappers are Float32-centric, matching BNNS's native precision for inference. Numerically verified helpers (transpose, copy, reductions, top-k, random generation, nearest neighbors) are cross-checked here against plain-Julia references; the remaining thin wrappers expose the rest of the current surface with exact FFI signatures for callers who need them.

Namespace

These functions are not exported. Access them via the AppleAccelerate. prefix (e.g. AppleAccelerate.bnns_reduce).

Deprecated APIs are excluded

Apple deprecated the classic BNNS filter/layer API and much of the classic tensor/DirectApply surface (macOS 15 / iOS 18) in favour of the newer BNNS Graph API (BNNSGraph). This package does not wrap any of those deprecated entry points; use the Graph API for that functionality. The "What's left to the raw layer" section below lists the full excluded set.

Descriptors

BNNSArray builds a GC-safe BNNSNDArrayDescriptor view of a dense, contiguous Julia array. Internally the N-D op wrappers map a column-major Julia Array onto a BNNSDataLayout{N}DLastMajor descriptor with explicit strides, so BNNS axis k corresponds to Julia dimension k+1 (axis 0 is the contiguous/fastest axis).

AppleAccelerate.BNNSArrayType
BNNSArray(A::AbstractArray)

A GC-safe BNNSNDArrayDescriptor view of a Julia array A, suitable for passing to BNNS routines via Ref. The wrapper keeps a reference to the backing array so it is not collected while the descriptor is alive; pass the underlying descriptor with Base.cconvert/Ref only inside a GC.@preserve block guarding A.

BNNS descriptors are layout aware. Julia stores arrays in column-major order, so this constructor reports the array using a column-major-friendly BNNS layout:

  • 1D Vector -> BNNSDataLayoutVector
  • 2D Matrix -> BNNSDataLayoutColumnMajorMatrix (BNNS size = (rows, cols)).

Only Float32 (and Int32) dense, contiguous arrays are supported here; other element types or strided/transposed arrays should use the raw LibAccelerate layer directly.

source

Tensor manipulation

Stateless tensor ops that remain current, cross-validated against permutedims and plain copies.

FunctionMeaning
bnns_transposeswap two axes
bnns_copy!copy with BNNS layout rules
M = Float32[1 2 3; 4 5 6]
@assert AppleAccelerate.bnns_transpose(M, 1, 2) == permutedims(M, (2, 1))
@assert AppleAccelerate.bnns_copy!(zeros(Float32, 2, 3), M) == M
AppleAccelerate.bnns_transposeFunction
bnns_transpose(A::Array, dim0, dim1) -> Array

Swap Julia dimensions dim0 and dim1 of A (1-based) via BNNSTranspose, equivalent to a permutedims that exchanges those two axes.

source
AppleAccelerate.bnns_copy!Function
bnns_copy!(dest::Array, src::Array) -> dest

Copy (with BNNS's broadcasting / layout conversion rules) src into dest via BNNSCopy. For equal shapes this is a plain element copy.

source

Reductions

AppleAccelerate.bnns_reduceFunction
bnns_reduce(func::Symbol, input::Array{Float32}; dim=1) -> Array{Float32}

Reduce input along Julia dimension dim with func (:sum, :mean, :max, :min, :sumsquare, :l1, :l2, :product, :logsumexp) via BNNSDirectApplyReduction. The reduced axis collapses to length 1.

source

DirectApply kernels

Fused kernels that run without an explicit filter handle.

AppleAccelerate.bnns_topkFunction
bnns_topk(input::Array{Float32}, K; dim=1) -> (values, indices)

Top-K values and their 0-based indices along Julia dimension dim via BNNSDirectApplyTopK. values is Float32, indices is Int32. Comparable to sort-based partialsortperm per slice.

source
AppleAccelerate.bnns_in_topkFunction
bnns_in_topk(input::Array{Float32}, targets::Array{Int32}, K; dim=1) -> Array{Bool}

For each batch column, test whether the targets class index is among the top-K scores of input along Julia dimension dim (BNNSDirectApplyInTopK).

source

Utility queries

AppleAccelerate.bnns_layout_rankFunction
bnns_layout_rank(layout::BNNSDataLayout) -> Int

Rank (number of dimensions) encoded by a BNNSDataLayout constant, via BNNSDataLayoutGetRank.

source
AppleAccelerate.bnns_tensor_allocation_sizeFunction
bnns_tensor_allocation_size(A::Array) -> Int

Bytes required to allocate a BNNSTensor describing A (BNNSTensorGetAllocationSize). Uses the modern BNNSTensor struct (rank + shape/stride), distinct from the legacy BNNSNDArrayDescriptor.

source

Random number generation

BNNSRandomGenerator is an AES-CTR generator with an optional seed; the fill functions populate arrays in place and the state can be snapshot and restored for reproducibility.

AppleAccelerate.BNNSRandomGeneratorType
BNNSRandomGenerator([seed]) -> BNNSRandomGenerator

A BNNS random number generator handle (AES-CTR method). Construct with an optional 64-bit seed for reproducibility (BNNSCreateRandomGeneratorWithSeed, or BNNSCreateRandomGenerator when omitted). The handle is destroyed automatically by a finalizer (BNNSDestroyRandomGenerator).

Use with bnns_random_fill_uniform!, bnns_random_fill_normal!, bnns_random_fill_uniform_int!, bnns_random_fill_categorical! and the bnns_random_state/bnns_random_state! round-trip.

source
AppleAccelerate.bnns_random_fill_uniform_int!Function
bnns_random_fill_uniform_int!(g::BNNSRandomGenerator, A::Array{Int32}, lo, hi) -> A

Fill integer array A with i.i.d. uniform samples on the half-open range [lo, hi) (BNNSRandomFillUniformInt).

source
AppleAccelerate.bnns_random_fill_categorical!Function
bnns_random_fill_categorical!(g::BNNSRandomGenerator, out::Array{Float32}, probs::Vector{Float32}; log_probs=false) -> out

Draw categorical samples (0-based category indices, stored as Float32) into out using per-category weights probs (BNNSRandomFillCategoricalFloat). Pass log_probs=true if probs holds log probabilities.

source

Nearest neighbors

AppleAccelerate.BNNSNearestNeighborsType
BNNSNearestNeighbors(max_samples, n_features, n_neighbors; T=Float32) -> BNNSNearestNeighbors

A brute-force k-nearest-neighbours index (BNNSCreateNearestNeighbors) holding up to max_samples reference points of dimension n_features, answering n_neighbors-NN queries. Destroyed automatically (BNNSDestroyNearestNeighbors).

Add reference points with bnns_knn_load! and query with bnns_knn_query.

source
AppleAccelerate.bnns_knn_load!Function
bnns_knn_load!(knn::BNNSNearestNeighbors, data::Matrix{Float32}) -> Int

Append reference samples to the index (BNNSNearestNeighborsLoad). data is n_features × n_new_samples (each column is one sample, matching BNNS's feature-major layout). Returns the number of samples loaded.

source
AppleAccelerate.bnns_knn_queryFunction
bnns_knn_query(knn::BNNSNearestNeighbors, sample_number) -> (indices, distances)

Return the n_neighbors nearest reference points to the (0-based) loaded sample sample_number (BNNSNearestNeighborsGetInfo): their 0-based indices (Vector{Int32}) and Float32 distances.

source

BNNS Graph API

The modern, non-deprecated pipeline: build compile options, compile a serialized graph package into a BNNSGraph, make an executable BNNSGraphContext, then introspect and execute. Compiling requires an on-disk graph package (there is no in-memory graph builder in this API).

AppleAccelerate.BNNSGraphCompileOptionsType
BNNSGraphCompileOptions(; single_thread=nothing, generate_debug_info=nothing,
                          optimization=nothing, log_mask=nothing,
                          output_path=nothing, output_fd=nothing) -> BNNSGraphCompileOptions

Options controlling BNNSGraphCompileFromFile, backed by BNNSGraphCompileOptionsMakeDefault and destroyed by a finalizer (BNNSGraphCompileOptionsDestroy). Any keyword left nothing keeps the BNNS default. optimization is :performance or :ir_size. Individual fields can also be read/written with the accessor functions below.

source
AppleAccelerate.BNNSGraphType
BNNSGraph(filename; func=nothing, options=BNNSGraphCompileOptions()) -> BNNSGraph

Compile a serialized BNNS graph package at filename (optionally selecting a named func inside it) into an executable graph via BNNSGraphCompileFromFile. The returned handle feeds BNNSGraphContext and the graph-introspection helpers.

source

The compile-options accessors (bnns_compile_options_set_single_thread!, …_set_optimization!, …_set_output_path!, and their getters) and the graph introspection helpers (bnns_graph_input_count, bnns_graph_argument_names, bnns_graph_argument_intents, …) round out the family.

What's left to the raw layer

Everything not wrapped above is reachable through the raw AppleAccelerate.LibAccelerate layer. It falls into three groups:

  • Deprecated classic tensor / DirectApply kernels (macOS 15 / iOS 18) — BNNSMatMul, the activation-filter path, BNNSTile/BNNSTileBackward, BNNSCompareTensor, BNNSBandPart, BNNSGather/BNNSScatter (and their ND forms), BNNSShuffle, the clip family (BNNSClipByValue/…ByNorm/ …ByGlobalNorm), BNNSComputeNorm, BNNSOptimizerStep, and the BNNSDirectApply{ActivationBatch,BroadcastMatMul,Quantizer} kernels. Superseded by the BNNS Graph API; intentionally not given an idiomatic wrapper.
  • The deprecated classic filter/layer API — the BNNSFilterCreate* / BNNSFilterCreateLayer* constructors and their *FilterApply* / BNNSFusedFilterApply* execute paths (including the two-input / fused / loss / normalization / pooling / permute batch variants).
  • Exotic, training-only entry points that need training caches or opaque multi-kilobyte parameter blocks that cannot be validated generically: multi-head attention (BNNSApplyMultiheadAttention and its backward), the LSTM training-cache path (BNNSComputeLSTMTrainingCacheCapacity, BNNSDirectApplyLSTMBatchTrainingCaching / …Backward), BNNSComputeNormBackward, image crop/resize (BNNSCropResize / BNNSCropResizeBackward), and the fully-connected sparsification helpers (BNNSNDArrayFullyConnectedSparsifySparse{COO,CSR}).