HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
mratsim
laser
Nim2018–2024
mratsim / laser

laser

The HPC toolbox: fused matrix multiplication, convolution, data-parallel strided tensor primitives, OpenMP facilities, SIMD, JIT Assembler, CPU detection, state-of-the-art vectorized BLAS for floats and integers

4Distinct people
21Mentions
0Explicit recommenders
295GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

The HPC toolbox: fused matrix multiplication, convolution, data-parallel strided tensor primitives, OpenMP facilities, SIMD, JIT Assembler, CPU detection, state-of-the-art vectorized BLAS for floats and integers

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year21 dated mentions

Observed mentions: 2018-12-19 17:48:10 UTC to 2024-07-20 19:28:21 UTC.

024682018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20182019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 8 mentions; 0 submissions, 8 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2024

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC707
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC808
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC000
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC000
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC505

What Hacker News says

21 sources
Ah, It was from an older implementation that wasn't compatible with Nim v2. I've commented it out. If you pull again it should work. > Anyway the reason for your competitive performance is likely that you are benchmarking with very small matrices. OpenBLAS spends some time preprocessing the tiles which doesn't really pay off until they become really huge. I don't get why you think it's impossible to reach BLAS speed. The matrix sizes are configured here: https://github.com/mratsim/laser/blob/master/benchmarks/gemm... It defaults to 1920x1920 * 1920x1920. Note, if you activate the benchmarks versus PyTorch Glow, in the past it didn't support non-multiple of 16 or something, not sure today. Packing is done here: https://github.com/mratsim/laser/blob/master/laser/primitive... And it also support pre-packing which is useful to reimplement bat
Read the rest
ch_matmul like what CuBLAS provides and is quite useful for convolution via matmul.
In Benchmarking 20 programming languages on N-queens and matrix multiplication
First we can use Laser, which was my initial BLAS experiment in 2019. At the time in particular, OpenBLAS didn't properly use the AVX512 VPUs. (See thread in BLIS https://github.com/flame/blis/issues/352 ), It has made progress since then, still, on my current laptop perf is in the same range Reproduction: - Assuming x86 and preferably Linux. - Install Nim - Install a C compiler with OpenMP support (not the default MacOS Clang) - Install git The repo submodules MKLDNN (now Intel oneDNN) to bench vs Intel JIT Compiler ``` git clone https://github.com/mratsim/laser cd laser git submodule update --init --recursive nim cpp -r --outdir:build -d:danger -d:openmp benchmarks/gemm/gemm_bench_float32.nim ``` This should output something like this ``` Laser production implementation Collected 10 samples in 0.230 seconds Average time: 22.684 ms Stdde
Read the rest
v time: 0.596 ms Min time: 21.769 ms Max time: 23.603 ms Perf: 624.037 GFLOP/s OpenBLAS benchmark Collected 10 samples in 0.216 seconds Average time: 21.340 ms Stddev time: 3.334 ms Min time: 19.346 ms Max time: 27.502 ms Perf: 663.359 GFLOP/s MKL-DNN JIT AVX512 benchmark Collected 10 samples in 0.201 seconds Average time: 19.775 ms Stddev time: 8.262 ms Min time: 15.625 ms Max time: 43.237 ms Perf: 715.855 GFLOP/s ``` Note: the Theoretical peak limit is hardcoded and used my previous machine i9-9980XE. It maybe that your BLAS library is not named libopenblas.so, you can change that here: https://github.com/mratsim/laser/blob/master/benchmarks/thir... Implementation is in this folder: https://github.com/mratsim/laser/tree/master/laser/primitive... in particular, tiling, cache and register optimization: https://github.com/mratsim/laser/blob/master/laser/primitive... AVX512 code generator: https://github.com/mratsim/laser/blob/master/laser/primitive... And generic Scalar/SSE/AVX/AVX2/AVX512 microkernel generator (this is Nim macros to generate code at compile-time): https://github.com/mratsim/laser/blob/master/laser/primitive... I'll come back later with details on how to use my custom HPC threadpool Weave instead of OpenMP (https://github.com/mratsim/weave/tree/master/benchmarks/matm...). As a side bonus it also has parallel nqueens implemented.
In Benchmarking 20 programming languages on N-queens and matrix multiplication
> FFI: Can nim use a C++ class and vtables? D does it all the time, nearly every language proclaims to have the best C++ interop but only D seems to be actually able to do it. Templates, classes, structs, and more all work. Well, it depends on how you define "best". Beyond an ABI, FFI is obviously a function of the implementation rather than the language per-se. The main Nim implementation can use C++ as a backend language, and when it does, it can use any C++ construct very easily by way of the .emit and .importcpp directives. For sure, classes, structs, exceptions all work, and IIRC templates do too (although you might need to instantiate a header yourself for each concrete type or something .... haven't done that myself). This implementation also means that it can use any C++17 or C++20 construct, including lambdas and friends. Does D'
Read the rest
s C++ interop support C++17? C++20? Can you guarantee it will support C++27? Nim's implementation already does, on every single platform you'll be able to use C++27 on (as long as C++27 can compile modern C++ code; there had been backward incompatible changes along the C++ history). You can't just #include a C or C++ header and call it a day; You need to have a Nim compatible definition for any symbol (variable, macro, function, class, ...). There are tools that help you and make it almost as easy as #include, such as nimterop[0] and and nimline[1], and "c2nim" which is included with the Nim compiler is enough to generate the Nim definitions from the .h definitions (though it can't do crazy metaprogramming; if D can do that, then D essentially includes a C++ compiler. Which is a fine way to get perfect C++ compatibility - Nim does that) But Nim can also do the same for JS when treating JS as a backend. And it can basically do the same for Python, with nimpy[2] and nimporter, generating a single executable that works with your installed Python DLL (2.7, 3.5, 3.6, 3.7) - which is something not even Python itself can do. There was a similar Lua bridge, but I think that one is no longer maintained. > We also have Mir, which I haven't benchmarked for a while but was faster than OpenBLAS and Eugene There's quite a bit of scientific stack built natively with Nim. It is far from self-sufficient, but the ease with which you can use a C library makes up for it. I haven't used it, but Laser[3] is on par with or exceeds OpenBLAS speedwise, and generalizes to e.g. int32 and int64 matrix multiplication; Arraymancer[4] does not heve all of numpy's functionality but does have quite a few nice bits from scikit-learn, supports CUDA and OpenCL, and you can use numpy through nimpy if all else fails. Also notable is NimTorch[5]. laser and arraymancer are mostly developed by mratsim, who occasionally hangs out here on HN. D is a fine language, I used it a little in the D1 days, and it was indeed a "better C++" but did not deliver enough value to be worth it for me, so I stopped. I know D2 is much better, but I've already found my better C++ (and better Python at the same time!) in Nim, so I haven't looked at it seriously. [0] https://github.com/nimterop/nimterop [1] https://github.com/sinkingsugar/nimline [2] https://github.com/yglukhov/nimpy [3] https://github.com/numforge/laser [4] https://github.com/mratsim/Arraymancer [5] https://github.com/sinkingsugar/nimtorch
In Java is better than C++ for high speed trading systems
> Syntax wise Nim it is a step back. It's hard to read and understand while any C/C++ dev will have next to no effort reading through D code. And of course while D is C ABI compliant it interoperates with C++ well too. On the other hand, people coming from Python, Ruby, Pascal, Ada will appreciate the minimal amount of sigils. > I seriously doubt that Nim or any other language in this regard has better metaprogramming than D. Can you write an Embedded DSL + compiler running at compile-time in D - https://github.com/numforge/laser/tree/master/laser/lux_comp... Can you write a cryptographic library with hex conversion to big integer and modular arithmetic running at compile-time in D? - https://github.com/mratsim/constantine/blob/master/constanti... Can you generate a state machine that lowers down to optimized computed gotos with no dynami
Read the rest
c allocation suitable for multithreading runtimes and embedded devices and able to display the actual graph at compiletime? - https://github.com/mratsim/Synthesis Can you describe x86 opcodes in a declarative way for a JIT assembler and do all the rex/modrm/sib computation at compile-time? - https://github.com/mratsim/photon-jit/blob/master/photon_jit... And the same thing for an emulator? - https://github.com/mratsim/glyph/blob/master/glyph/snes/opco... Can you implement async as a library? Can you emulate classes with ADTs to solve the expression problem, avoid cache misses and multithreading problem due to OOP and the double indirection due to the visitor pattern? - https://github.com/mratsim/trace-of-radiance/blob/master/tra... > Nim might have a speed overhead in certain tasks but that depends on a benchmark. Besides, does Nim have anything similar to NumPy which is actually faster? D does. It does: - https://github.com/mratsim/Arraymancer With CPU, OpenCL and Cuda backends (in differing state of maturity) and it's being used for data analysis for example ancestry prediction: - http://home.chpc.utah.edu/~u6000771/somalier-ancestry.html You can even run a neural network and see its training live: - https://github.com/Vindaar/NeuralNetworkLiveDemo AFAIK D doesn't have any plotting library while Nim has plot.ly integration and a ggplot2 port in pure Nim: - https://github.com/brentp/nim-plotly - https://github.com/Vindaar/ggplotnim And lastly nim can easily call Python: - https://github.com/yglukhov/nimpy or be called from Python: - https://github.com/Pebaz/nimporter
In Ray Tracing in Nim
Sure, you might be interested in the research in loop nest scheduling I gathered here: https://github.com/numforge/laser/blob/master/research/autom... The most promising here being the Halide and Tiramisu compiler. Halide uses machine learning to discover scheduling and Tiramisu uses a polyhedral approach. Also I didn't add them yet but Stanford Legion https://legion.stanford.edu/ and ETH Zurich DaCe http://spcl.inf.ethz.ch/Research/DAPP/ are more focused on memory locality and are obtaining excellent results as well.
In PyTorch 1.5
It might be Internet and the issue of communicating emotions across but you sound quite taken by this issue. Anyway, I stand by what I say and I'm backed by my high performance code: - Writing matrix multiplication that is as fast as Assembly, complete with analysis and control on register allocations, L1 and L2 cache tiling and avoiding TLB cache miss: - https://github.com/numforge/laser/blob/master/laser/primitiv... - Code, including caveat about hyperthreading: https://github.com/numforge/laser/blob/master/laser/primitiv... - The code is all pure Nim and is as fast/faster than OpenBLAS when multithreaded, caveat, the single-threaded kernel are slightly slower but it scales better on multiple cores. - I've also written my own multithreading runtime. It's scale better and has lower overhead than Intel TBB. There is no constexpr, you need
Read the rest
type-erasure to handle everything people can use a multithreading runtime for, same comparison on GEMM: https://github.com/mratsim/weave/tree/v0.4.0/benchmarks/matm... - More resources on the importance of memory bandwidth: optimization convolutions https://github.com/numforge/laser/wiki/Convolution-optimisat... - Optimizing matrix multiplication on GPUs: https://github.com/NervanaSystems/maxas/wiki/SGEMM, again it's all about memory and caches optimization - Let's switch to another domain with critical perf need, cryptography. Even when knowing the bounds of iterating on a bigint at compile-time, compiler are very bad at producing optimized code, see GCC vs Clang https://gcc.godbolt.org/z/2h768y - And crypto is the one thing where integer templates are very useful since you know the bounds. - Another domain? VM interpretation. The slowness there is due to function call overhead and/or switch dispatching and not properly using hardware prefetchers. Same thing, C++ constexpr doesn't help it's lower-level, see resources: https://github.com/status-im/nimbus/wiki/Interpreter-optimiz... Also all the polyhedral research, and deep learning compiler research including the Halide compiler, Taichi, Tiramisu, Legion, DaCE confirm that memory is the big bottleneck. Now since you want to stop on the theory and you mentioned HPC, pick your algorithm, it could be matrix multiplication, QR decomposition, Cholesky, ... Any fast C++ code (or C, or Fortran or Assembly) that you find will be fast because of careful memory layout and all level of caches, not constexpr. If you have your own library in one of those domains I would be also very happy to have a look. As a simple example, let's pick an out-of-place transposition kernel to transpose a matrix. Show me how you use constexpr and template metaprogramming to speed it up. Here is a detailed analysis on the impact of 1D-tiling and 2D tiling: https://github.com/numforge/laser/blob/master/benchmarks/tra..., throughput can be increased 4x with proper usage of memory caches.
In A possible new back end for Rust
Author here: Actually it's 7 [1] But in my future backend revamp I plan to make the default 6 [2] Note that the line can easily be updated to const MAXRANK* {.intdefine.} = 6 as in the planned revamp and then you would be able to change the MAXRANK with a compile parameter nim c -d:MAXRANK=16 path/to/my/app [1]: https://github.com/mratsim/Arraymancer/blob/6fddfa9a734ac01c... [2]: https://github.com/numforge/laser/blob/d1e6ae6106564bfb350d4...
In Nim Community Survey 2019 Results
Entirely reasonable doubt, you can find well-commented benchmark output of the Laser High-Performance Computing lib and Arraymancer lib in their source: https://github.com/numforge/laser/blob/d1e6ae6106564bfb350d4... https://github.com/mratsim/Arraymancer/blob/6fddfa9a734ac01c... To qualify the statement, it would be more accurate to say that Nim can smoke C by several orders of magnitude unless you devote significant engineering efforts into replicating the equivalent Nim (as Nim targets C/C++ regardless, so this is just heavy lifting and optimizations)
In Nim Community Survey 2019 Results
I keep looking for a good excuse to learn it, but it does not fit my domain or my language-style preferences very well. I primarily develop web services, and it is really difficult to beat Typescript due to the fact I can write my front-end, backend, and mobile apps in it (via NativeScript or React Native). I use uWebsockets.js, which has both an HTTP API that is nearly-identical to Express, and a Websocket API that is identical to Socket.io, but performance ~x10 faster than Express and ~x2 faster than the top-performing Go/Rust/C web libraries due to being a C++ library exposed as Node V8 bindings. If I really need performance outside the context of handling web requests, I will write small functions or services in Go/Rust and compile to WASM and invoke it through Node, or just throw it up on OpenFaaS. I like a lot of what Nim does, but
Read the rest
I have had a difficult time since finding it two years ago ever coming up with an adequate reason for using it. Edit: I want to make one clarification. I think that Nim may actually have a bright future in ML, primarily due to the work of Mamy Ratsimbazafy. He has some libraries for HPC, Laser [0] and Arraymancer [1] that can smoke C by several orders of magnitude. Combined with Weave [2], the multi-threaded runtime he built for Nim, that opens the doors for ridiculously performant ML. I think the only the other language that would give Nim a run for its money here is Julia, I really dig the work that has been going on there for ML as well. [0] https://github.com/numforge/laser [1] https://github.com/mratsim/Arraymancer [2] https://github.com/mratsim/weave
In Nim Community Survey 2019 Results
The follow-up paper should include the deep learning and linear algebra compilers: - Halide - Tiramisu - Ngraph - Weld - PyTorch JIT & PyTorch Glow and Tensor Comprehensions - TVM - Futhark - A toy MLIR language build on the linalg dialect. I'm sure Google would love to help them. to name the main ones. Everyone is moving towards a compiler approach. I'm actively researching the domain and I think Halide is the most promising: by separating the algorithm from the schedule you can leave the algorithm side to the researchers and optimization is done by HPC devs or automated methods without having to rewrite in C/Fortran. Much more attempts in the past: - https://github.com/mratsim/Arraymancer/issues/347#issuecomme... - My own domain specific language and compiler: https://github.com/numforge/laser/tree/master/laser/lux_comp... there are a
Read the rest
low_level_design_considerations.md and challenges.md that should be interesting as well. Unfortunately I didn't go beyond the proof of concept as I need to revamp the Nim multithreading runtime to improve composition of parallel linear algebra kernels. One thing for sure is that OpenMP is today something that needs to be workaround due to it's lack of composability and GCC implementation is a contention point due to using a single queue protected by a lock. While traditional linear algebra algorithms can deal with static distribution and no load balancing, some algorithms would hugely benefits from a more flexible task system, for example Beam Search.
In The Linear Algebra Mapping Problem
Yes exactly. Usually you can extract 2x to 4x instruction level parallelism on simple add instructions [1] vs [2] For fused-multiply-add even though the latency is higher the instruction is also slower so its the same. BLIS, OpenBLAS and my code extract 2x parallelism (2 accumulators) at the lowest level because we are restricted by the number of registers and the fact that x86 can only issue 2 FMAs per cycle [3]. Details, we divided the work until we have a small micro matrix C or size MR x NR (input matrix of size MxK and KxN so output of MxN), and then here is are the constraints you have to deal with: Registers constraints and micro-kernel tuning - To issue 2xFMAs in parallel we need to use 2x SIMD registers - We want to hold C of size MR * NR completely in SIMD registers as well as each value is reused k times during accumula
Read the rest
tion C[i, j] += A[i, k] * B[k, j] - We should have enough SIMD registers left to hold the corresponding sections of A and B (at least 4, 2xA and 2xB for FMAs) On x86-64 X SIMD registers that can issue 2xFMAs per cycle: - NbVecs is 2 minimum - RegsPerVec = 2 * NbVecs => 4 minimum (for A and for B) - NR = NbVecs * NbScalarsPerSIMD - C: MR*NR and uses MR*NbVecs SIMD registers - MR*NbVecs + RegsPerVec <= X -> MR*NbVecs + 2 * NbVecs <= X -> (MR+2) * NbVecs <= X Some solutions: - AVX with 16 registers: - MR = 6, NbVecs = 2 FP32: 8xFP32 per SIMD --> NR = 2x8 ukernel = 6x16 FP64, ukernel = 6x8 - MR = 2, NbVecs = 4 FP32: 8xFP32 per SIMD --> NR = 4x8 ukernel = 2x32 FP64, ukernel = 2x16 - AVX512 with 32 registers - MR = 6, NbVecs = 4 FP32 ukernel = 6x64 FP64 ukernel = 6x32 - MR = 2, NbVecs = 8 FP32 ukernel = 2x128 FP64 ukernel = 2x64 - MR = 14, NbVecs = 2 FP32 ukernel = 14x32 FP64 ukernel = 14x16 And in-depth overview of the lowest level details is available in the paper Automating the last mile for High Performance Dense Linear Algebra[5]. In short, the compiler is completely unable to deal with this, and a high performance computing compiler should give an escape hatch to allow hand optimization like Halide[6] or Tiramisu do[7]. [1]: https://github.com/numforge/laser/blob/e660eeeb723426e80a7b1... [2]: https://github.com/numforge/laser/blob/e660eeeb723426e80a7b1... [3]: https://github.com/numforge/laser/blob/e660eeeb723426e80a7b1... [4]: https://github.com/numforge/laser/blob/e660eeeb723426e80a7b1... [5]: https://arxiv.org/pdf/1611.08035.pdf [6]: https://halide-lang.org/ [7]: http://tiramisu-compiler.org/
In Comparing Parallel Rust and C++

Showing the 15 most recent of 21 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.