# Fool's errand - building the fastest numerical computation library

**URL:** <https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832>\
**Category:** Brainstorming\
**Tags:** performance, optimization\
**Created:** [October 4, 2026, 4:32pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832 "2026-10-04T16:32:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sfn](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/c6cbf5/32.png) [@sfn](https://ziggit.dev/u/sfn)\
**Post date:** [October 4, 2026, 4:32pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832/1 "2026-10-04T16:32:05Z")

</div>

I may or may not end up figuring out how to write my own domain-specific high-performance physics simulators in the near future, but the possibility got me thinking about how to do the underlying calculations in the fastest possible way for any given hardware, from my old ThinkPad to Multi-Processor Multi-GPU racks.

Now, I may be a fool but I’m not an idiot, each hardware vendor writes their own set of libraries for these sorts of workloads and I don’t think to outperform them. The idea would be to write a wrapper library that presents a simple, unified interface to each of these vendor implementations, choosing which one to use when multiple are available (for example, on a box with an intel CPU and Nvidia GPU, choosing what problems to execute where and how).

Here are the libraries I’ve found so far for the sort of computations one might need, not sure if I’ve missed anything important:

| Calculation type | x86 CPU | arm CPU | Apple M-series | Intel GPU | NVIDIA GPU | AMD GPU |
| --- | --- | --- | --- | --- | --- | --- |
| BLAS/(Sca)LAPACK | oneMKL (ex intel) | APL | A. Accelerate\* | oneMKL (SYCL flavour) | cuSOLVERMp | rocSOLVER |
| FFT | oneMKL | APL | A. Accelerate | oneMKL | cuFFTMp | rocFFT |
| (P)RNG | oneMKL(?) | openRNG (part of APL) | openRNG(?) | oneMKL | cuRAND | rocRAND |
| Sparse | oneMKL | APL | A. Accelerate | oneMKL | cuSPARSE/cuSPARSELt | rocSPARSE/rocSPARSELt |

An eventual simulator also needs a good non-linear solver and a DAE solver. If these ever come to light, I think they should be separate libraries implemented on top of this computational core.

Acronyms:

- A. = Apple
- APL = arm performance libraries
- MPS = (apple) metal performance shaders

Other notes

- This project intends to adhere to Zig praxis and philosophy: follow the style guide, accept external alloc/io where possible, no AI for writing code, ecc.
- If we can get this library to provide compatible C/Fortran interfaces for each component (e.g. use this library as a drop-in replacement for existing software) that would be great, but performance comes first
- RISC-V cpu’s are excluded from lack of hardware and knowledge, but I see no reason to add them once software/hardware comes out
- I’m aware of the OpenMathLib, they might be a good generic fallback option but they seem to be slightly outperformed by vendor implementations across the board. Also, no device (GPU) capability.
- On Apple M-series chips, matrix multiplication of certain large matrices might be further sped up with shared memory and MPS, see [Apple vs. Oranges: Evaluating the Apple Silicon M-Series SoCs for HPC Performance and Efficiency](https://arxiv.org/html/2502.05317v2)
- Different sparse implementations (for example cuSPARSE vs cuSPARSELt) need to be selected depending on the sparsity ratio of the matrix. Sparse routines might therefore want to take a sparseness value to aid in deciding how to dispatch them, which can either be estimated by the user in advance or calculated.
- FFTW would not, in fact, appear to be the fastest Fourier transform, but I’m not entirely convinced yet: [Benchmark source 1](https://hal.science/hal-04684180/) [Benchmark source 2](https://hal.science/hal-04684180/)
- Need better benchmarks for openRNG vs oneMKL on x86 CPU’s and alternatives to openRNG for Apple hardware
- Given the focus on performance, we need a consistent, scalable benchmark for each component in general
- A suggested approach is to dynamically load the vendor libraries that are installed on the running system, and fall back to open-source generic alternatives (I.e. OpenBLAS, OpenRNG) when we can’t find anything better
- Something similar is kind-of provided by [GitHub - uxlfoundation/oneMath: oneAPI Math Library (oneMath) · GitHub](https://github.com/uxlfoundation/onemath), but a) it’s C++ b) no dedicated Apple support and c) requires the user to handle dispatching (choosing which device to use for what).

Feedback appreciated as to the best way to go about doing this (i.e. tell me why this is stupid and I’m wasting my time 😉)!

---

<div class="post-metadata">

**Author:** ![smj-edison](https://ziggit.dev/user_avatar/ziggit.dev/smj-edison/32/6629_2.png) [@smj-edison](https://ziggit.dev/u/smj-edison)\
**Post date:** [October 4, 2026, 4:56pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832/2 "2026-10-04T16:56:18Z")

</div>

I’ll admit I’m not super familiar with this space, but HPC is definitely on my radar to learn. One promising piece prior work is the Eigen library in C++ if you’re not already aware of it.

---

<div class="post-metadata">

**Author:** ![pzittlau](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/ecae2f/32.png) [@pzittlau](https://ziggit.dev/u/pzittlau)\
**Post date:** [October 4, 2026, 5:10pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832/3 "2026-10-04T17:10:06Z")

</div>

First of I like the spirit but I don’t quite know if Zig is a real advantage here because most of them are written half in assembly anyway while the other half being macros. The only ones I know of that are trying to be readable are [BLIS](https://github.com/flame/blis) and [ulmBlas](https://www.mathematik.uni-ulm.de/~lehn/apfel/ulmBLAS/) which is more trying to be educational.

If you want for it to also abstract over accelerators and maybe even distribution and cluster configuration you could also take a look at [sycl](https://www.khronos.org/sycl/).

A nice thing that I would like if it is reasonably readable.

---

<div class="post-metadata">

**Author:** ![sfn](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/c6cbf5/32.png) [@sfn](https://ziggit.dev/u/sfn)\
**Post date:** [October 4, 2026, 5:33pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832/4 "2026-10-04T17:33:12Z")

</div>

Zig isn’t so much an advantage as an alternative to C/C++ (these libraries provide C interfaces), mostly personal preference (although I suspect the I/O interface over io\_uring might come in handy should I ever need to write a task scheduler).

I’ve worked with SYCL in the past (check out the amazing [https://adaptivecpp.github.io/](https://adaptivecpp.github.io/) project), but I don’t think the abstraction is work the overhead for this use-case - vendor libraries already handle that for us, and still provide the tools we need for memory management.

What do you mean by readable? Good quality code? An interface that calls functions triangularMatrixMultiply instead of trmm? I must admit, a lot of the older libraries for this sort of workload seem to have been written to a character limit.

---

<div class="post-metadata">

**Author:** ![pzittlau](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/ecae2f/32.png) [@pzittlau](https://ziggit.dev/u/pzittlau)\
**Post date:** [October 4, 2026, 5:53pm UTC](https://ziggit.dev/t/fools-errand-building-the-fastest-numerical-computation-library/17832/5 "2026-10-04T17:53:01Z")

</div>

> [@sfn](#):
>
> What do you mean by readable? Good quality code? An interface that calls functions triangularMatrixMultiply instead of trmm? I must admit, a lot of the older libraries for this sort of workload seem to have been written to a character limit.

I don’t think that stuff like `trmm`, `gemm`, or `axpy` are really problematic. I would just think that generics likely aren’t done via prefixes. Having a `triangularMatrixMultiply` that just defers to `trmm` would likely make it a bit more usable for people that haven’t really worked with blas but isn’t that necessary I think.

For readability I was more talking about the implementation. If I look into something like openBLAS I see a lot of different ifdefs enabling or disabling single lines which is quite common in old C and on it’s own okay, but in addition to all the macros it get’s hard to reason about, at least for me.  
Of course, I also wouldn’t really like to have _a lot_ less speed just to make it readable but I think we now know better then to have a soup of conditional compilation.
