A Julia interface to Apple's Accelerate framework, providing:
- Vectorized array operations via vDSP and vForce — element-wise math, reductions, compound arithmetic, clipping, interpolation — 2–19× faster than Base Julia for transcendentals (
sin,cos,exp,log) - Dense linear algebra — all of
LinearAlgebra(lu,qr,svd,cholesky,eigen, …) accelerated transparently via libblastrampoline — 6–13× faster single-threaded GEMM than OpenBLAS on Apple Silicon (SME/AMX co-processor), plus 2–4× faster factorizations and solves - Sparse linear algebra via
libSparse— direct (Cholesky / LDLᵀ / LU / QR) and iterative (CG / GMRES / LSMR) solvers, real and complex - Signal processing — 1D/2D real & complex FFT (batched, mixed-radix), DCT, convolution, biquad filtering, window functions; cached setups make no-plan
fft(x)competitive with FFTW and drop the FFTW dependency - SIMD math inside
@simdloops viaAppleAccelerate.SIMDMath— scalar math functions that LLVM turns into SIMD calls, for loops the array API can't express (fused reductions, values computed on the fly, no temporaries);@simdmathrewrites the calls in a loop for you — 2–4× faster than a scalar Base loop - Neural-network primitives via BNNS — Core ML model inference through the BNNS Graph API (
Float16/Float32), plus reductions, top-k, and random generation - Image processing via vImage — geometry (scale, rotate, affine warp), convolution, morphology, histogram, alpha compositing, and format/colorspace conversion (incl. Y′CbCr)
See the benchmarks for full performance comparisons and methodology.
Requires macOS 13.4+ and Julia 1.11+.
using Pkg
Pkg.add("AppleAccelerate")One self-contained, copy-pasteable example per subsystem. Every function lives under the
AppleAccelerate. prefix — the package intentionally exports nothing, so it never shadows
Base/LinearAlgebra.
using AppleAccelerate, LinearAlgebra
A = randn(1000, 1000)
F = lu(A) # BLAS/LAPACK routed to Accelerateusing AppleAccelerate
X = randn(10_000)
Y = AppleAccelerate.exp(X) # also sin, cos, log, sqrt, tanh, …
AppleAccelerate.sincos(X) # fused, both results in one passFor loops the array API can't express. Prefer AppleAccelerate.exp/log on whole arrays
when you can — they're faster.
using AppleAccelerate
using AppleAccelerate.SIMDMath: @simdmath # rewrites log, exp, x^y, … in this loop only
function weighted_logsum(X, W) # no temporary for log.(X), unlike the array API
u = zero(eltype(X))
@simdmath @simd for i in eachindex(X, W)
@inbounds u += W[i] * log(X[i])
end
u
endUnit-stride loops vectorise everywhere; strided loops depend on the Julia/LLVM version (see the SIMDMath docs).
using AppleAccelerate
x = randn(ComplexF64, 1024)
X = AppleAccelerate.fft(x) # cached setup; also rfft, fft2d, dctusing AppleAccelerate
z = randn(ComplexF64, 1000)
mags = AppleAccelerate.vmags(z) # squared magnitudes (abs2)
ang = AppleAccelerate.vphase(z) # phase anglesusing AppleAccelerate, LinearAlgebra, SparseArrays
S = sprandn(500, 500, 0.01); S = S*S' + 500I # symmetric positive-definite
F = AppleAccelerate.factor(S) # takes a SparseMatrixCSC directly; also :ldlt, :lu, :qr
xs = AppleAccelerate.solve(F, randn(500)) # or one-shot: AppleAccelerate.solve(S, b)using AppleAccelerate
logits = randn(Float32, 4, 6) # 4 classes × 6 samples
sums = AppleAccelerate.bnns_reduce(:sum, logits; dim = 1) # column-wise reduction
vals, idx = AppleAccelerate.bnns_topk(logits, 2; dim = 1) # top-2 classes per sampleusing AppleAccelerate
img = rand(Float32, 64, 48) # a 64×48 planar (grayscale) image
small = AppleAccelerate.scale_PlanarF(img, 32, 24) # resize to 32×24
flip = AppleAccelerate.horizontalReflect_PlanarF(img)See the full documentation for the complete API reference.
