TensorOps is a Metal Shading Language library that lets developers write optimized custom machine learning kernels—including matrix multiplication, convolution, and FlashAttention—with automatic hardware acceleration across all Apple Silicon GPU generations, including the new M5 neural accelerator. iOS/macOS 27 extends its quantized data type support to FP8, 2-bit integers, and MX scaling formats.
• Added FP8 (E4M3, E5M2) and 2-bit integer quantized data types on top of the 4/8-bit integers added in iOS 26
• Single MTLTensor can now carry an auxiliary scale plane in FP8 E8M0 block-wise format alongside quantized data
• Cooperative tensors can now be fed directly as inputs to matmul2d ops without a threadgroup memory store/reload step
• Full neural accelerator utilization on M5 via TensorOps without any code changes
• Enables plug-in custom ML operations for high-level frameworks like Core AI and MLX without sacrificing GPU performance
• New FP8/2-bit quantization and E8M0 block-wise scale factors reduce memory bandwidth and let larger models fit on device
• Cooperative tensors can now be passed directly as matmul inputs, eliminating costly threadgroup memory round-trips in fused kernels like FlashAttention
Shows how to allocate an MTLTensor with a 4-bit integer data plane and an FP8 E8M0 scale plane on the host side, then dispatch a Metal compute pipeline that uses TensorOps to perform dequantized matrix multiplication entirely on the GPU.
import Metal
import MetalPerformanceShadersGraph
// MARK: - Host-side MTLTensor setup for quantized matmul (iOS 27 / macOS 27)
final class QuantizedMatMulDemo {
let device: MTLDevice
let commandQueue: MTLCommandQueue
init?() {
guard let dev = MTLCreateSystemDefaultDevice(),
let queue = dev.makeCommandQueue() else { return nil }
self.device = dev
self.commandQueue = queue
}
// Build an MTLTensor holding 4-bit integer weights + FP8-E8M0 block scales
func makeQuantizedWeightTensor(rows: Int, cols: Int, blockSize: Int = 32) throws -> MTLTensor {
// 1. Describe the primary data plane: 4-bit signed integers
let dataDescriptor = MTLTensorDescriptor()
dataDescriptor.dataType = .int4 // New in iOS 26; FP8 added iOS 27
dataDescriptor.dimensions = [rows as NSNumber, cols as NSNumber]
// 2. Describe the auxiliary scale plane: FP8 E8M0, one scale per block of 32
let scaleDescriptor = MTLTensorAuxiliaryPlaneDescriptor()
scaleDescriptor.dataType = .float8E8M0 // New in iOS 27
scaleDescriptor.blockFactors = [blockSize as NSNumber, 1]
// 3. Wire the scale plane into the main tensor descriptor
let auxMap = MTLTensorAuxiliaryPlaneMap()
auxMap.scalePlaneDescriptor = scaleDescriptor
dataDescriptor.auxiliaryPlaneMap = auxMap
// 4. Allocate the tensor (data + scales packed together)
guard let tensor = device.makeTensor(descriptor: dataDescriptor) else {
throw NSError(domain: "QuantizedMatMulDemo",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "Failed to allocate MTLTensor"])
}
return tensor
}
// Dispatch the custom MSL TensorOps kernel that performs dequantized matmul
func runMatMul(weightTensor: MTLTensor,
activationTensor: MTLTensor,
outputTensor: MTLTensor,
library: MTLLibrary) throws {
guard let kernelFn = library.makeFunction(name: "quantized_matmul_kernel"),
let pipeline = try? device.makeComputePipelineState(function: kernelFn),
let cmdBuf = commandQueue.makeCommandBuffer(),
let encoder = cmdBuf.makeComputeCommandEncoder() else {
throw NSError(domain: "QuantizedMatMulDemo", code: -2, userInfo: nil)
}
encoder.setComputePipelineState(pipeline)
// Bind MTLTensors to buffer indices; the MSL kernel reads planes via tensor_handle
encoder.setTensor(weightTensor, index: 0)
encoder.setTensor(activationTensor, index: 1)
encoder.setTensor(outputTensor, index: 2)
// Threadgroup geometry — tune to your tile size
let threadgroupSize = MTLSize(width: 32, height: 4, depth: 1)
let rows = outputTensor.descriptor.dimensions[0].intValue
let cols = outputTensor.descriptor.dimensions[1].intValue
let gridSize = MTLSize(
width: (cols + threadgroupSize.width - 1) / threadgroupSize.width,
height: (rows + threadgroupSize.height - 1) / threadgroupSize.height,
depth: 1
)
encoder.dispatchThreadgroups(gridSize, threadsPerThreadgroup: threadgroupSize)
encoder.endEncoding()
cmdBuf.commit()
cmdBuf.waitUntilCompleted()
}
}
/* ---------- MSL kernel (quantized_matmul_kernel.metal) ----------
// Runs on-GPU with TensorOps; shown here as a Swift raw string for reference.
// In a real project this lives in a .metal file.
#include <metal_stdlib>
#include <metal_tensor_ops>
using namespace metal;
using scale_plane_t = tensor_plane<fp8_e8m0_, block_factors<32, 1>>;
using quant_tensor_t = tensor_handle<fp8_e4m3_, scale_plane_t>; // FP8 weights
using float_tensor_t = tensor_handle<half>;
[[kernel]]
void quantized_matmul_kernel(
quant_tensor_t weights [[tensor(0)]],
float_tensor_t activations [[tensor(1)]],
float_tensor_t output [[tensor(2)]],
uint2 tgid [[threadgroup_position_in_grid]])
{
// Slice tiles for this threadgroup
auto w_tile = weights.slice(tgid);
auto a_tile = activations.slice(tgid);
auto out_tile = output.slice(tgid);
// TensorOps handles FP8+E8M0 dequantization automatically
matmul2d_descriptor desc;
desc.M_tile = 32; desc.N_tile = 32; desc.K_tile = 64;
auto op = matmul2d<4>(desc); // 4 simdgroups per threadgroup
op.run(w_tile, a_tile, out_tile);
}
---------------------------------------------------------------- */Foundation Models is a new Apple framework introduced in iOS 27 that gives developers on-device access to the same Apple Intelligence language model powering system features, enabling text generation, structured output, and tool-calling entirely on-device without a network connection.
iOS 27 opens the Foundation Models framework to third-party LLM providers via a new public LanguageModel protocol, enabling anyone to integrate custom, server-based, or open-source models using the same Swift API as Apple's on-device system model.
App Schemas let developers describe their app's content and actions using pre-defined domain schemas (like the Calendar domain) so Siri can understand, search, and act on app data without custom NLP. Entities conforming to IndexedEntity are donated to Spotlight's semantic index, enabling natural-language queries over app content.
In-depth guide
iOS 27 On-Device AI & Apple Intelligence →Not every cooperative tensor layout is compatible as a direct matmul input — always call is_compatible_as_left_input / is_compatible_as_right_input before reuse or you must round-trip through threadgroup memory. New 2-bit and FP8 types have stricter buffer alignment requirements. The TensorOps API lives in Metal Shading Language (GPU side), not Swift — Swift/Obj-C is used only for host-side MTLTensor setup.
Neural accelerator optimizations require M5 chip family; quantized FP8/2-bit types require Apple Silicon; alignment requirements differ from standard types — consult Metal documentation
Visual Intelligence brings iOS 17's Visual Look Up capabilities to a new developer-facing API surface in iOS 27, letting apps pipe live camera frames or static images through on-device scene understanding to extract subjects, text, barcodes, and rich semantic labels without any cloud round-trip.