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

Arraymancer

A fast, ergonomic and portable tensor library in Nim with a deep learning focus for CPU, GPU and embedded devices via OpenMP, Cuda and OpenCL backends

27Distinct people
54Mentions
0Explicit recommenders
1.4KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A fast, ergonomic and portable tensor library in Nim with a deep learning focus for CPU, GPU and embedded devices via OpenMP, Cuda and OpenCL backends

GitHub

Where it is used

No documented product use was verified in the last source check.

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 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 2:59:53 AM 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 year54 dated mentions

Observed mentions: 2017-12-23 10:17:49 UTC to 2024-03-29 07:59:14 UTC.

051015202017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 9 mentions; 3 submissions, 6 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 19 mentions; 0 submissions, 19 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 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
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC110
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC936
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC909
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC19019
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC514
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC606
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC413

From the project README

An excerpt from the repository, fetched Nov 12, 2026.

Read the project’s introduction
Arraymancer - A n-dimensional tensor (ndarray) library. Arraymancer is a tensor (N-dimensional array) project in Nim. The main focus is providing a fast and ergonomic CPU, Cuda and OpenCL ndarray library on which to build a scientific computing ecosystem. The library is inspired by Numpy and PyTorch and targets the following use-cases: N-dimensional arrays (tensors) for numerical computing machine learning algorithms (as in Scikit-learn: least squares solvers, PCA and dimensionality reduction, classifiers, regressors and clustering algorithms, cross-validation). deep learning The ndarray component can be used without the machine learning and deep learning component. It can also use the OpenMP, Cuda or OpenCL backends. Note: While Nim is compiled and does not offer an interactive REPL yet (like Jupyter), it allows much faster prototyping than C++ due to extremely fast compilation times. Arraymancer compiles in about 5 seconds on my dual-core MacBook. Reminder of supported compilation flags: -d:release: Nim release mode (no stacktraces and debugging information) -d:danger: No runtime checks like array bound checking -d:blas=blaslibname: Customize the BLAS library used by Arraymancer. By default (i.e. if you don't define this setting) Arraymancer will try to automatically find a BLAS library (e.g. blas.so/blas.dll or libopenblas.dll) on your path. You should only set this setting if for some reason you want to use a specific BLAS library. See nimblas for further information -d:lapack=lapacklibname: Customize the LAPACK library used by Arraymancer. By default (i.e. if you don't define this setting) Arraymancer will try to automatically find a LAPACK library (e.g. lapack.so/lapack.dll or libopenblas.dll) on your path. You should only set this setting if for some reason you want to use a specific LAPACK library. See nimlapack for further information -d:openmp: Multithreaded compilation -d:mkl: Deprecated flag which forces the use of MKL. Implies -d:openmp. Use -d:blas=mkl -d:lapack=mkl instead, but only if you want to force Arraymancer to use MKL, instead of looking for the available BLAS / LAPACK libraries -d:openblas: Deprecated flag which forces the use of OpenBLAS. Use -d:blas=openblas -d:lapack=openblas instead, but only if you want to force Arraymancer to use OpenBLAS, instead of looking for the available BLAS / LAPACK libraries -d:cuda: Build with Cuda support -d:cudnn: Build with CuDNN support, implies -d:cuda -d:avx512: Build with AVX512 support by supplying the -mavx512dq flag to gcc / clang. Without this flag the resulting binary does not use AVX512 even on CPUs that support it. Setting this flag, however, makes the binary incompatible with CPUs that do not support AVX512. See the comments in #505 for a discussion (from v0.7.9) You might want to tune library paths in nim.cfg after installation for OpenBLAS, MKL and Cuda compilation. The current defaults should work on Mac and Linux; and on Windows after downloading libopenblas.dll or another BLAS / LAPACK DLL (see the Installation section for more information) and copying it into a folder in your path or into the compilation output folder. Show me some code The Arraymancer tutorial is available here. Here is a preview of Arraymancer syntax. Tensor creation and slicing import math, arraymancer const x = @[1, 2, 3, 4, 5] y = @[1, 2, 3, 4, 5] var vandermonde = newSeq[seq[int]]() row: seq[int] for i, xx in x: row = newSeq[int]() vandermonde.add(row) for j, yy in y: vandermonde[i].add(xx^yy) let foo = vandermonde.toTensor() echo foo # Tensor[system.int] of shape "[5, 5]" on backend "Cpu" # |1 1 1 1 1| # |2 4 8 16 32| # |3 9 27 81 243| # |4 16 64 256 1024| # |5 25 125 625 3125| echo foo[1..2, 3..4] # slice # Tensor[system.int] of shape "[2, 2]" on backend "Cpu" # |16 32| # |81 243| echo foo[_|-1, _] # reverse the order of the rows # Tensor[int] of shape "[5, 5]" on backend "Cpu" # |5 25 125 625 3125| # |4 16 64 256 1024| # |3 9 27 81 243| # |2 4 8 16 32| # |1 1 1 1 1| Reshaping and concatenation import arraymancer, sequtils let a = toSeq(1..4).toTensor.reshape(2,2) let b = toSeq(5..8).toTensor.reshape(2,2) let c = toSeq(11..16).toTensor let c0 = c.reshape(3,2) let c1 = c.reshape(2,3) echo concat(a,b,c0, axis = 0) # Tensor[system.int] of shape "[7, 2]" on backend "Cpu" # |1 2| # |3 4| # |5 6| # |7 8| # |11 12| # |13 14| # |15 16| echo concat(a,b,c1, axis = 1) # Tensor[system.int] of shape "[2, 7]" on backend "Cpu" # |1 2 5 6 11 12 13| # |3 4 7 8 14 15 16| Broadcasting Image from Scipy import arraymancer let j = [0, 10, 20, 30].toTensor.reshape(4,1) let k = [0, 1, 2].toTensor.reshape(1,3) echo j +. k # Tensor[system.int] of shape "[4, 3]" on backend "Cpu" # |0 1 2| # |10 11 12| # |20 21 22| # |30 31 32| A simple two layers neural network From example 3. import arraymancer, strformat discard """ A fully-connected ReLU network with one hidden layer, trained to predict y from x by minimizing squared Euclidean distance. """ # ################################################################## # Environment variables # N is batch size; D_in is input dimension; # H is hidden dimension; D_out is output dimension. let (N, D_in, H, D_out) = (64, 1000, 100, 10) # Create the autograd context that will hold the computational graph let ctx = newContext Tensor[float32] # Create random Tensors to hold inputs and outputs, and wrap them in Variables. let x = ctx.variable(randomTensor[float32](N, D_in, 1'f32)) y = randomTensor[float32](N, D_out, 1'f32) # ################################################################## # Define the model network TwoLayersNet: lay
Read the full README on GitHub

What Hacker News says

9 sources
Yes. You can even use numpy in nim: https://forum.nim-lang.org/t/4102 But why use that when you can use Cuda and OpenCL accelerated vector math: https://github.com/mratsim/Arraymancer If thats too much speed, you can just roll your own for loops. Because Nim is compiled with battle tested GCC, LLVM or VC++ it will try to SSE optimize your code if you pass the right switches. If you know what CPU your computer/server has you can compile with newest brand of high performance instructions like AVX2, or even the newest AVX512VNNI...
In Nim vs. Crystal
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
Haha, well you can get payed for it, but you won't be payed well. It's hard to give an easy answer for that. But let's step back a little: I played around with Julia several years ago. I don't know when exactly, probably in 2015 (?). Back then I thought of it as a faster python for science. Many things I would use python for back then I could have done in Julia too. Others I couldn't though, because the eco system was still too small. And while Julia was somewhat faster for the things I tried, it wasn't amazingly faster. My interest in the language dropped sometime after that. But still, I felt like it was a language targeted specifically to scientists. Many things I wanted from my analysis framework however were outside that bubble I felt. I didn't simply want to write a faster "analysis script". I do realize however, that the language
Read the rest
has evolved a lot and I'm happy it's finding acceptance! Fortran on the other hand, I never really considered. I suppose modern Fortran is a pretty good language though. So why did I choose Nim then? It gave me: - the ability to produce standalone binaries I could just put on any data acquisition pc without a hassle (well ok, be careful about old glibcs) - it's fast, and I felt right at home syntax wise coming from python - the community is amazing. The first time I entered Nim's IRC channel I noticed Araq, the creator of the language, answering random people's questions! In general the community allows for a super quick feedback loop to learn the language - it's a pretty concise language. The whole manual can be read in less than a day - having written some Clojure, I loved the idea of a powerful macro system - after seeing mratsim's arraymancer library [1] I was happy to 1) have a numpy substitute and 2) thought if one person could write such a great library in O(1 year) it must be a pretty awesome language to work with :) - being able to trivially wrap any C code around is super helpful - a pretty strong type system! No more annoying implicit conversions from any type to a bool, error prone implicit int <-> float conversions etc. I probably forgot many points, but well. The truth is of course, many languages could have worked for me, but the time I spent with Nim in the beginning was just super pleasant. [1] https://github.com/mratsim/Arraymancer
In Root: CERN's scientific data analysis framework for C++
Personally, I use Nim to develop domain specific language for VM, JIT, emulators and neural networks. I'm currently writing a compiler for deep learning with both AOT (emitting Nim code) and hopefully later JIT (emitting LLVM IR) capabilities complete with SIMD support. I don't see how I could do that in another language. My biggest successes: - include a quite maintainable JIT for x86_64 (compared to asmjit and xbyak I don't need to parse or codegen the C++ code): https://github.com/numforge/laser/blob/master/laser/photon_j... - a DSL for neural network: https://github.com/mratsim/Arraymancer#sequence-classificati... - a matrix multiplication BLAS written from scratch competitive with OpenBLAS and MKL on select matrix shape (2000x2000) but that can also support int8/int16/int32/int64 and not just float32/float64 thanks to metaprogramming
Read the rest
. Expanding to new SIMD architecture (ARM) is very easy: --> benchmark: https://github.com/numforge/laser/blob/master/benchmarks/gem... --> Metaprogramming AVX512 support: https://github.com/numforge/laser/blob/master/laser/primitiv... The most important thing for me for metaprogramming is being able to operate on the AST directly
In Ask HN: What metaprogrammable language do you/would like to use?

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.