I have been trying to find resources for implementing computational calculations with elixir (and possibly Nx), namely something like the Gauss-Seidel method for solving linear equations as well as using elixir for FEM simulations, maybe with a library such as The FEniCSx computing platform.
However, since I couldn’t find anything, I was wondering if elixir is even a good fit for such a use case.
I also found the following clip from the BEAM Channel about When should you not use Erlang/Elixir from Zack where he states that for numeric computations’ elixir would not be a good choice.
Could you guys give me advice about the above-mentioned use case?
Did the Nx library change the use case for elixir?
And if you have any resources, I would greatly appreciate them!
Thank you in advance.
In “normal” BEAM code, both arrays and floating-point values are expensive:
a plain list like
[0.1, 0.2, 0.3, 0.4] is a linked list, so it takes about 2x as long to access the 4th element as it does the second. This makes large lists like in simulations impossibly slow, adding an extra factor of
N to runtimes in general. (good luck with multidimensional data )
updating an element in the middle of a list is expensive, since it requires updating all the linked list cells before the element. This collides badly with a lot of scientific algorithms that assume that updating a value in-place is cheap.
floating-point values themselves are expensive, because they are boxed
The boxing and the linked-list combined end up making a single element of a floating-point list like
[1.0, 2.0, 3.0, 4.0] cost 28 bytes (on a 64-bit machine):
- two pointers for the cons cell
- a 4-byte header + 8-byte value for the float
Nx removes all that overhead, because it stores tensors with fixed datatype (u64, f32, etc) as contiguous blocks of memory. The Nx intro has more.
There’s a ton of other useful features for numerical computing in Nx, but even if all you used it for was to get constant-time access to multidimensonal arrays it’s a huge increase in Elixir’s capabilities.
@al2o3cr Thank you very much for your thorough explanation. Please correct me if I am wrong, but with the introduction of Nx it seems that elixir is now a good or at least decent fit for numerical calculations?
Do you by any chance know of an implementation with numeric equations solvers or FEM simulations?
Thank you very much in advance!
I haven’t seen anything specific along those lines; Nx is new enough that it mostly has the features that somebody needed to get the thing done they wanted to do, so a lot of the focus has been on ML-adjacent problems and things that parallelize well to GPUs.
There’s some basic algorithms in
Nx.LinAlg, but you won’t find optimizations like “store L and U from LU decomposition together in the same array to save space that would otherwise be zeroes” there.
On the positive side, that means there’s plenty of unclaimed library real-estate just waiting for an author to put some code in it!
One other option: since Nx stores values in contiguous blocks, it would be much easier to interface to a Serious Science numeric library with Rustler (versus trying to convert to and from linked-lists).
Scholar can also provide some examples/ideas: Scholar — Scholar v0.1.0
@al2o3cr Thank you so much for your reply, especially the hint about
Nx.LinAlg. And yes, lots of uncharted territory
I was also thinking about using Rustler, but wanted to see if I can stay purely in elixir.
If the route I take is worth mentioning, I will make an update
@josevalim Thank you for this tip, will definitely look into Scholar