Library / SDK
uxlfoundation/oneMath avatar
uxlfoundation/oneMath

oneMath is a selector layer, and the math library sits underneath it

oneAPI Math Library (oneMath)

779 stars184 forksC++Apache-2.0

At a glance

What is it?
oneMath is the UXL Foundation implementation of the oneMath specification, a C++ interface layer that dispatches BLAS, LAPACK, FFT, sparse and random number calls to whichever vendor library the target device needs.
Who is it for?
oneMath suits a team whose application must run on more than one vendor's accelerator, because it replaces per-vendor code paths with one call and lets the selector choose the backend at run time or at compile time. It is the wrong tool for a project permanently bound to one hardware stack, since linking directly against oneMKL or one vendor library is less code, and the generic SYCL fallback is explicitly marked as unsupported for other SYCL devices.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

The layer in the middle is the product

oneMath is an open-source implementation of the oneMath specification, and it can work with multiple devices using multiple libraries, called backends, underneath. The project was previously referred to as oneMKL Interfaces, which describes the design accurately: the interface is the deliverable, not the arithmetic.

The layering matters when you read the table in the README. The columns run user application, oneMath layer, third-party library, hardware backend. A single oneMath selector sits between the application and everything below it, and below it sit Intel oneMKL for x86 CPU and Intel GPU, the NVIDIA cu family for NVIDIA GPU, NETLIB LAPACK for x86 and aarch64 CPU, Arm Performance Libraries for aarch64 CPU, the AMD roc family for AMD GPU, and two generic SYCL implementations that cover x86 CPU, Intel GPU, NVIDIA GPU and AMD GPU.

So the same source file can call one gemm and have it run on an Intel CPU with oneMKL, on an NVIDIA GPU with cuBLAS, or on an AMD GPU with rocBLAS. That portability is the entire reason the project exists, and the specification it implements is published separately at uxlfoundation.github.io/oneMath/spec.

The trade-off follows directly. You are adding an abstraction layer to your application, and an abstraction layer costs a dispatch decision, an extra link dependency and a compatibility surface. For a codebase that will only ever run on one vendor's hardware, the abstraction buys nothing and the direct call is simpler.

The project sits under the UXL Foundation, and the repository carries the foundation artwork and a link back to it, along with legal_information.md and a third-party-programs directory, which is where the licensing situation for a stack of vendored vendor libraries is documented.

OneMKL, cuBLAS, rocBLAS and the generic SYCL fallback

The backend table is long enough that it is worth reading as a compatibility matrix rather than a list.

The Intel entry, the oneAPI Math Kernel Library, covers x86 CPU and Intel GPU. The NVIDIA entries are separate libraries rather than one: cuBLAS, cuSOLVER, cuRAND, cuFFT and cuSPARSE, each mapped to NVIDIA GPU. The AMD side mirrors that with rocBLAS, rocSOLVER, rocRAND, rocFFT and rocSPARSE for AMD GPU. The CPU side has NETLIB LAPACK for x86 and aarch64, Arm Performance Libraries for aarch64, and Arm OpenRNG for random numbers on x86 and aarch64.

Two entries are different in kind. The generic SYCL BLAS and portFFT are written against SYCL itself rather than against a vendor library, and their hardware column lists x86 CPU, Intel GPU, NVIDIA GPU, AMD GPU and other SYCL devices marked as unsupported. That parenthetical is doing real work: it means the generic path is the fallback when no vendor library matches, and it will not run on a SYCL device from a vendor that is not in the list.

The practical consequence is that the set of supported devices is a property of the backend you land on, not of oneMath itself. A team shipping to four hardware targets has to accept that some of them will be served by vendor libraries and others by the generic implementation, and that the generic one is explicitly not supported everywhere.

The generic SYCL components are not in this repository. The README links to the generic-sycl-components repository for the SYCL BLAS implementation and to portFFT for the transform implementation, so the fallback path is maintained as separate projects.

Run-time dispatching lets the device vendor decide

There are two oneMath selector layer implementations, and the first is run-time dispatching. The application is linked with the oneMath library and the required backend is loaded at run-time based on device vendor, with the caveat that all libraries should be dynamic.

The application code selects a device and creates a queue per device, then calls the same oneMath entry point with the queue:

cpp
#include "oneapi/math.hpp"

...
cpu_dev = sycl::device(sycl::cpu_selector());
gpu_dev = sycl::device(sycl::gpu_selector());

sycl::queue cpu_queue(cpu_dev);
sycl::queue gpu_queue(gpu_dev);

oneapi::math::blas::column_major::gemm(cpu_queue, transA, transB, m, ...);
oneapi::math::blas::column_major::gemm(gpu_queue, transA, transB, m, ...);

The dispatch happens inside the library, driven by the queue's device. That is the appealing property: a single binary can land its work on an Intel CPU, an Intel GPU or an NVIDIA GPU without the application naming any vendor library.

The cost is that the binary has to carry the vendor libraries and load them at run time, so deployment gets heavier and the set of machines the binary runs on depends on what is installed. The README's instruction that all libraries should be dynamic is a direct consequence of that design.

The build for this mode is a SYCL compile and a link against the oneMath library, using the Intel icpx compiler on Linux and icx on Windows, with the include directory and the library directory of the oneMath installation on the compiler and linker paths. The README refers to the Selecting a Compiler page for the choice between the icpx and icx compilers and clang++.

Compile-time dispatching trades flexibility for a smaller binary

The second implementation is compile-time dispatching. The application uses a templated backend selector API where the template parameters specify the required backends and third-party libraries, and the application is linked with the required oneMath backend wrapper libraries, which may be static or dynamic.

The same call site now takes a selector object instead of a queue:

cpp
#include "oneapi/math.hpp"

...
cpu_dev = sycl::device(sycl::cpu_selector());
gpu_dev = sycl::device(sycl::gpu_selector());

sycl::queue cpu_queue(cpu_dev);
sycl::queue gpu_queue(gpu_dev);

oneapi::math::backend_selector<oneapi::math::backend::mklcpu> cpu_selector(cpu_queue);

oneapi::math::blas::column_major::gemm(cpu_selector, transA, transB, m, ...);
oneapi::math::blas::column_major::gemm(oneapi::math::backend_selector<oneapi::math::backend::cublas> {gpu_queue}, transA, transB, m, ...);

The backend is now named in the type. oneapi::math::backend::mklcpu for the Intel CPU path, oneapi::math::backend::cublas for the NVIDIA GPU path. The compiler knows what to link, so the resulting binary contains only the backends you asked for, and the linker command in the README names the specific wrapper libraries, one for the MKL CPU backend and one for cuBLAS.

The trade is direct. Compile-time dispatch gives a smaller, more predictable binary and no run-time library loading, at the cost of one build per target configuration. A team that ships a single artefact to a known hardware fleet usually prefers this; a team that ships one binary to unknown machines prefers run-time dispatch.

Both modes are documented in the same support section of the README, and the code samples sit side by side, which makes it easy to see that the difference is confined to how the backend is named at the call site.

The Device API is the header-based path used inside a kernel

Beyond the host API, the specification defines a Device API that is header-based and backend-independent, and that can be called within a sycl kernel or from host code. The README points to the device RNG usage model example in the oneMath specification for the details of that pattern.

This is the part of the design that matters for a performance-oriented user. A host API call dispatches into a vendor library that runs on the device. A Device API call is a function that the compiler inlines into the kernel, so the operation happens in the thread that is already running, without a separate launch. For a kernel that is already doing arithmetic, that difference is substantial, and it is the reason the specification bothers to define a device-side interface at all.

The header-based and backend-independent part is what makes it portable: the same source works against a vendor library or against the generic SYCL implementation, provided the target is supported.

The repository layout shows the same division in the source tree. The examples directory is broken into blas, dft, lapack, rng and sparse_blas, plus an include directory and its own CMakeLists.txt and README. The domains in that list are the ones to check against your own needs, since the RNG domain is a first-class part of the library and not an afterthought, with a dedicated example directory and its own device usage model in the specification.

The rest of the tree supports a real build: a top-level CMakeLists.txt, a cmake directory, include, src, tests, deps for dependencies, docs, and third-party-programs for the licence records of what is pulled in.

Apache-2.0 code over vendor libraries with their own terms

oneMath itself is Apache-2.0 licensed, with the LICENSE file at the repository root and a legal_information.md file in the tree. The repository also has a third-party-programs directory, which is the practical place to look for what licences apply to the vendor libraries the stack can pull in at run time.

That distinction is the one to keep in mind. Apache-2.0 covers the interface layer you compile against, and it does not relicense oneMKL, cuBLAS, rocBLAS, the Arm libraries or NETLIB LAPACK. Those carry their own terms, and which of them ends up in a shipped binary depends on which backend the dispatch selects, which in turn depends on the hardware the binary runs on. A licence review that only reads the root LICENSE file is looking at the wrong file.

The project sits with the UXL Foundation, which is what makes the governance and the specification independent of any single vendor, and the repository carries MAINTAINERS.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md as the usual governance files. The README also shows an OpenSSF Scorecard badge, which reflects the security posture checks the project publishes.

On activity, the repository is not archived and the last push was on 2026-10-07, so work is landing. The default branch is develop, which is where the specification implementation evolves, and the published versions are v0.7 on 2025-04-07, v0.8 on 2025-07-03 and v0.9 on 2025-11-07. A version below 1.0 with a develop default branch means the interface can still move, so a consumer that cares about stability should consume a tagged release rather than the tip of the branch.

Editorial conclusion

oneMath suits a team whose application must run on more than one vendor's accelerator, because it replaces per-vendor code paths with one call and lets the selector choose the backend at run time or at compile time. It is the wrong tool for a project permanently bound to one hardware stack, since linking directly against oneMKL or one vendor library is less code, and the generic SYCL fallback is explicitly marked as unsupported for other SYCL devices. Before adopting, confirm that the domains you need, BLAS, LAPACK, DFT, sparse BLAS or RNG, have a backend available for your target device, and read legal_information.md and the third-party-programs directory, because the licences of the underlying vendor libraries travel with the deployment.

Frequently asked questions

What is oneMath and how does it differ from linking oneMKL directly?

oneMath is an open-source implementation of the oneMath specification, a C++ interface layer that dispatches to multiple backends underneath, and it was previously referred to as oneMKL Interfaces. Linking oneMKL directly gives you one vendor's implementation; oneMath gives one call site that can land on oneMKL, cuBLAS, rocBLAS, NETLIB LAPACK or a generic SYCL implementation depending on the device.

What is the difference between run-time and compile-time dispatching in oneMath?

With run-time dispatching the application is linked with the oneMath library and the backend is loaded at run-time based on device vendor, so all libraries should be dynamic. With compile-time dispatching a templated backend selector names the backend in the type, and the application is linked with the specific oneMath backend wrapper libraries, which may be static or dynamic.

Which backends does oneMath support?

The README table lists Intel oneMKL for x86 CPU and Intel GPU, the NVIDIA cu libraries (cuBLAS, cuSOLVER, cuRAND, cuFFT, cuSPARSE) for NVIDIA GPU, the AMD roc libraries (rocBLAS, rocSOLVER, rocRAND, rocFFT, rocSPARSE) for AMD GPU, NETLIB LAPACK for x86 and aarch64 CPU, Arm Performance Libraries for aarch64 CPU, Arm OpenRNG for random numbers, and generic SYCL BLAS plus portFFT for x86 CPU, Intel, NVIDIA and AMD GPUs, with other SYCL devices marked as unsupported.

Can oneMath functions be called from inside a SYCL kernel?

Yes. The Device API is header-based and backend-independent, and it can be called within a sycl kernel or work from host code. The specification links a device RNG usage model example for the pattern.

Which domains does oneMath cover in its examples?

The examples directory is organised into blas, dft, lapack, rng and sparse_blas, with a shared include directory, so the library covers dense linear algebra, transforms, LAPACK, random number generation and sparse linear algebra.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. uxlfoundation/oneMath on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/uxlfoundation-onemath.svg)](https://hysenlabs.com/projects/uxlfoundation-onemath)

Was this useful?