Library / SDK
ARM-software/ComputeLibrary avatar
ARM-software/ComputeLibrary

ARM Compute Library: A Low-Level Kernel Set for Arm CPUs and Mali GPUs

The Compute Library is a set of computer vision and machine learning functions optimised for both Arm CPUs and GPUs using SIMD technologies.

3,192 stars820 forksC++License varies

At a glance

What is it?
The Compute Library (ACL) is Arm's own collection of roughly 100 low-level machine learning and computer vision functions tuned for Neon, SVE2 and Mali GPUs, shipped under MIT. It is a kernel library, not a runtime, and that distinction decides who should adopt it.
Who is it for?
Adopt ACL if you are writing an inference engine, a DSP-style pipeline, or an embedded vision product that targets Arm Cortex-A, Neoverse or Mali hardware and you want MIT-licensed kernels under your own scheduler. Do not adopt it if you want a model file to go in and predictions to come out: ACL has no graph format, no runtime and no operator fusion pass across a whole network.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What ACL actually gives you: kernels, not a runtime

The Compute Library is a collection of low-level machine learning functions. That word, low-level, is doing the work in the README, and it is the single fact that determines whether this project fits your stack. ACL does not read ONNX, TFLite or any other model format. It does not schedule a network. It gives you functions: convolution, pooling, activation, normalisation, and the rest of the roughly 100 machine learning functions the README mentions, each one written for Arm CPUs or Mali GPUs. You supply the tensors, the shapes and the execution order. The library supplies the inner loop.

That places the intended user somewhere specific. If you are building an inference engine, a vision pipeline for an embedded product, or a custom operator that has to run fast on a Cortex-A core or a Mali GPU, ACL is aimed at you. If you want to load a model and call predict, it is not. There is no graph optimiser here, and no memory planner that spans a whole network. Kernel fusion exists as an optimisation technique the README lists, but it is a technique applied inside the library's own primitives, not a pass you point at an arbitrary model.

The scope is also wider than deep learning. The project describes itself as computer vision and machine learning functions, and the topics list includes computer-vision alongside neural-network. That matters for robotics and camera pipelines, where a convolution kernel and an image processing kernel sit in the same loop and you would rather not pull in two libraries with two build systems.

CPU and GPU paths are not the same code with a flag

The CPU side targets Arm Cortex-A, Neoverse, Cortex-X1 and Cortex-R with Armv8-R AArch64, using Neon and, per the README's feature list, immediate support for newer Arm technologies such as SVE2. The GPU side targets the Mali-G and Mali-T families through OpenCL. These are separate implementations of the same conceptual operations, and the README lists them separately under supported architectures rather than as one portable backend.

Two mechanisms in the README are worth reading closely because they are the parts that separate ACL from a naive kernel dump. The first is the OpenCL tuner: device and workload specific tuning, in the README's phrasing, which implies a tuning pass that produces parameters for a given GPU rather than a single hardcoded configuration. The second is the GeMM optimised heuristics, which suggests the library picks among its convolution strategies rather than making you choose.

That choice of strategies is real. The README lists multiple convolution algorithms: GeMM, Winograd, FFT, Direct and indirect-GeMM. Five routes to the same mathematical result, each with a different cost profile depending on filter size, tensor shape and data type. The library exposes the selection; the heuristics and the tuner are what stop you from having to benchmark all five yourself on every device you ship to.

Data type coverage is FP32, FP16, INT8, UINT8 and BFLOAT16. Note that this is a set of kernels, so mixed precision is something you arrange, not something the library infers for you.

Building it: CMake and Bazel are the experimental paths

The README carries a warning that is easy to skim past and should not be: Bazel and CMake builds are experimental CPU only builds. The documented build instructions live in the how-to-build page of the Arm documentation site, not in the repository README, so the authoritative commands are there rather than here.

What the README does establish is that pre-built binaries exist and are downloadable from the releases page, which is the lower-risk route if you are not modifying the library. The release history shows a steady cadence: v53.1.0 in May 2026, v53.2.0 in July 2026, v53.3.0 in September 2026, with the last push timestamp matching the newest release. Version numbers in the 53.x range with a minor bump every month or two is the shape of a project that ships on a schedule.

The README also documents the compiler flags used to generate those pre-built binaries: -Wall, -Wextra, -Wformat=2, -Winit-self, -Wstrict-overflow=2, -Wswitch-default, -Woverloaded-virtual, -Wformat-security, -Wctor-dtor-privacy, -Wsign-promo, -Weffc++, -pedantic, -fstack-protector-strong. That is a warning-heavy set with -Weffc++ and -pedantic in it, which tells you the published binaries were compiled with a strict configuration. It does not tell you anything about runtime behaviour, and the README does not claim it does.

One build detail deserves a pin in your notes. The README states that libarm_compute-static.a will be renamed to libarm_compute.a in distributed pre-built binaries, effective from the first release in or after January 2026. Any build script that hardcodes the old static library name will break on upgrade. This is the kind of change that costs an afternoon if you find it in CI and five minutes if you read the notice first.

The GPU path is Mali-only, and that is a hard boundary

The supported architectures list is explicit: Arm Mali-G and Mali-T processor families for the GPU path. If your device has an Adreno, a PowerVR, an Apple GPU or an integrated Intel GPU, ACL's OpenCL kernels are not documented as targeting it. This is not a soft limitation that a bug report will fix. The library is written by Arm, for Arm, and the GPU tuning is Mali tuning.

The same logic applies on the CPU side in a subtler way. The README lists x86 under supported architectures, and lists macOS, Linux, Android, Bare Metal, Tizen, OpenBSD, QNX and FreeBSD under supported systems. But the optimisation story is Neon, SVE2 and Mali. On x86 you are running the code without the micro-architecture tuning that is the library's reason to exist. If x86 is your production target and Arm is an afterthought, the value proposition inverts.

The other boundary is the experimental systems. OpenBSD, QNX and FreeBSD are marked Experimental in the README. That is a clear signal about where testing effort goes. If you are shipping on QNX, which is common in automotive, treat the ACL path as something you will be debugging yourself rather than something the project exercises on every release.

Finally, there is no runtime or driver abstraction layer. ACL talks to the hardware through Neon intrinsics, SVE2 and OpenCL directly. That is what makes it fast and also what makes it brittle against unusual platform configurations.

Where it sits next to a full inference runtime

The obvious comparison is a complete inference runtime such as ONNX Runtime or Arm's own ExecuTorch-style stacks, and the difference is architectural rather than a matter of degree. A runtime owns the whole path: it parses a model, builds a graph, plans memory, fuses operators, dispatches to backends, and hands you a result. ACL owns one layer of that path, the kernel layer, and exposes it as a C++ API.

That means the two are not competitors so much as different floors of the same building. Runtimes on Arm frequently use ACL or something like it underneath. Choosing ACL directly means you are choosing to write the layer above it yourself. You get control over scheduling, memory layout and operator selection. You pay for that control with engineering time, and you take on the maintenance of a graph representation that the library does not provide.

A second comparison is KleidiAI, which appears in the README's list of bundled third-party code under Apache License 2.0. KleidiAI is a separate Arm project aimed at micro-kernels for AI workloads, and its presence inside ACL's source tree as a dependency is worth noting if you are auditing what ends up in your binary. It is not an alternative to ACL so much as an adjacent piece of Arm's kernel stack, and the README does not describe how the two divide responsibility.

If your problem is genuinely a single operator or a small fixed pipeline on Arm hardware, ACL is the shorter path. If your problem is arbitrary models from arbitrary teams, the runtime is the shorter path and ACL is a component you may never touch directly.

Licence, bundled code and what you are actually shipping

The README states the software is provided under the MIT license, and that contributions are accepted under the same license. MIT is permissive: it allows commercial use, modification and redistribution with the licence notice retained. That is a genuinely low-friction position for a library you embed in a product, and it is a point in ACL's favour against copyleft alternatives in the same space.

There is a complication, and the README is upfront about it. ACL bundles code from other projects, each with its own licence text included in the relevant source files: the OpenCL header library under Apache License 2.0, the half library under MIT, the libnpy library under MIT, the stb image library under MIT or public domain (used here under MIT terms), KleidiAI under Apache License 2.0, and GoogleTest and the Benchmark library used by KleidiAI under BSD-3-Clause and Apache License 2.0 respectively.

All of these are permissive and the README describes the OpenCL header licence as compatible with MIT. In practice that means a standard attribution exercise rather than a legal problem, but it is an exercise you have to actually do. If your product ships a notices file, ACL contributes several entries to it, not one. The GoogleTest and Benchmark libraries are test dependencies pulled in through KleidiAI, so whether they end up in your shipped binary depends on your build configuration, which is worth confirming rather than assuming.

This is a description of what the README says, not legal advice. If your organisation has a licence review process, the bundled-code list is the section to hand to it.

Maintenance cost and the upgrade cadence you are signing up for

The release history shows three releases between May and September 2026, and v53.3.0 lands on the same day as the last push to the repository. This is an actively maintained project on a roughly monthly-to-six-weekly cadence, which cuts both ways. You get current Arm architecture support, including the SVE2 work the README highlights. You also inherit a moving target.

The static library rename is the concrete example of what that costs. A name change from libarm_compute-static.a to libarm_compute.a is trivial in itself, but it lands in pre-built binaries from a specific date, and any packaging, linker flag or vendored-blob check that references the old name has to change in step. Multiply that by every release you skip and the upgrade becomes a small project rather than a version bump.

Contributing back has its own overhead. The project requires a Developer Certificate of Origin sign-off on every commit, with a real name and no pseudonyms, added as a Signed-off-by line in the commit message. Technical discussion runs through a public mailing list, acl-dev@lists.linaro.org, which is open to subscribers inside and outside Arm. If your team is used to GitHub pull request threads, a mailing list is a different working rhythm and worth factoring into any plan to carry local patches.

The pragmatic shape of adoption is therefore: pin a release, vendor the pre-built binary or build it yourself, and treat upgrades as scheduled work with a changelog read each time rather than a continuous pull. The changelog lives in the documentation site the README points to, alongside the reference API, build guide and errata. That errata page existing at all is a useful signal about how the project handles known issues.

Editorial conclusion

Adopt ACL if you are writing an inference engine, a DSP-style pipeline, or an embedded vision product that targets Arm Cortex-A, Neoverse or Mali hardware and you want MIT-licensed kernels under your own scheduler. Do not adopt it if you want a model file to go in and predictions to come out: ACL has no graph format, no runtime and no operator fusion pass across a whole network. Before committing, verify that your target is on the supported list (Cortex-R with Armv8-R AArch64 is listed, but the GPU path is Mali-only), confirm which build system you intend to use given that Bazel and CMake are flagged experimental and CPU only, and check the static library naming in the release you pin, because libarm_compute-static.a becomes libarm_compute.a in pre-built binaries from the first release in or after January 2026.

Official sources

  1. ARM-software/ComputeLibrary on GitHub
  2. Issues
  3. README
  4. Releases
Community notes

Community notes