Why Rust fails hard at scientific computing

by Mamy Ratsimbazafy | April 1, 2017 2:23 pm

1.5 years ago I started a computer go bot in Rust based on Monte Carlo Tree Search[1] (MCTS).

MCTS is at the heart of all strong go programs, and many AI for various games and real world competitions like RoboCup Soccer. Yes, even Google AlphaGo’s neural networks are just “suggesting” moves to the MCTS, it has the last words.

After weeks of fighting the borrow checker like many beginners I managed to program my way out, and produce this[2] and brain dump material probably worth a PhD or two (check the README[3]):

6 months ago, I found the time to dive into Data Science and Deep Learning, and 1 week ago I got the urge to write my own neural network library. Rust didn’t even enter my mind at the time, it had to be Nim[4].

4 Nim bugs later … After breaking a (Guiness ?) record of 5 bugs in 12 hours to a core language tracker.

… and a discussion with a fellow data scientist, I still think it’s the best language that fits my needs. Those bugs are only flesh wounds.

 

 

Let’s go back to Rust

Rust appealed to me due to speed, type safety and functional programming facilities. Why ? well, my first real programming language after bash, SQL and Excel VBA was Haskell, yep before even Javascript and Python.

So why did it fails for me, and why is it still failing for scientific computing:

 

1. Too much symbols & <> :: {} (Your mileage may vary, C++ programmers will feel right at home)

I’m not even talking about Rc, RefCell and Box which seems like security through obscurity. (Though it can’t reach Haskell monadic level)

 

2. Arrays in Rust are a second-class citizens, actually I think they don’t even have their visas. I hear them laughing at me when I try to use them. You can’t even clone them:

Actually I misrepresented, you can, only if the array size is 32 or less.

Consequences ? You can’t use Rust arrays to represent a matrix bigger than 4×8, how useful is that?

Actually you can’t even represent a 8×8 chessboard without coding every properties from scratch (copy, clone, print, indexing with [] …). I’m in luck, go has 9×9, 13×13 and 19×19 board sizes …

You can work around it by using a Vec (arbitrary sized sequence/list) but then your matrix is allocated on the heap not the stack, meaning slower operations. Plus that means you cannot use Rust wonderful type system to check that you multiply matrices with compatible dimensions, say a 2×2 matrix with a 2×1 matrix, without jumping through hoops.

That brings me to the third point.

 

3. Rust is still “discussing” integer as generic type parameter (since 2015), meaning a matrix type Matrix[M, N, float] will not exist before a long long time. The following github discussions are quite the read:

That’s it folks, hope you enjoyed the read.

PS: Would “3 reasons why Rust fails hard at scientific computing” be too much baitclick ?


Also published on Medium[8].

Endnotes:
  1. Monte Carlo Tree Search: https://en.wikipedia.org/wiki/Monte_Carlo_tree_search
  2. this: https://github.com/mratsim/rustygo
  3. README: https://github.com/mratsim/rustygo/blob/master/README.md
  4. Nim: https://nim-lang.org/
  5. Allow types to be parameterized by integer (and bool) constant values.: https://github.com/rust-lang/rfcs/pull/884
  6. Parameterize types over numerics / type level integers: https://github.com/rust-lang/rfcs/issues/1038
  7. RFC: Constant generics (restricted Π types) for Rust, core RFC (v2): https://github.com/rust-lang/rfcs/pull/1931
  8. Medium: https://medium.com/@MARatsimbazafy/why-rust-fails-hard-at-scientific-computing-9dcb140c8d81

Source URL: https://andre-ratsimbazafy.com/why-rust-fails-hard-at-scientific-computing/