Compiling ML models to C for fun
bernsteinbear.com
bernsteinbear.com
I did a similar thing a few years back for small linear systems: https://wordsandbuttons.online/outperforming_everything_with... The idea is essentially the same - we both turn the computation process itself into code. I choose LLVM intermediate language instead of C because the whole point of my exercise was to show that you don't need C (or any other compiler) to generate efficient code. In fact, if you already have your computation figured out, C only gets in the way. For this very reason, I avoided calling the code generation process a "compiler".
My thing, however, doesn't have any practical usage. This one does and I think it's beautiful!
Hmmm why do you think so? There's been one (small) breaking change in the last 6 months (and it came with a simple upgrade recommendation).
(If it's not obvious, I contributedl to the python bindings but I would prefer to remain anon).
https://mlir.llvm.org/docs/Bindings/Python/
is it the "not enabled by default" that scares you off? i honestly don't even know what that's supposed to mean since there's no default anything since there's no official binary build of mlir currently being released.
anyway i'm not trying to be confrontational or adversarial - i was more asking in a "how can i help you accomplish what you want" kind of tone.
For ex, you can lift to the 'metal' dialect or 'nvgpu' dialect. There's also an 'affine' dialect, which implements a small set of polyhedral transformations and works on memrefs like most compilers do. However, it seems that the 'affine' dialect is not as actively used these days. Most optimizations are now performed on tensors, but depending on your use case, it may still make sense.
I don't do deep learning, but have been recently thinking about paths to optimize DAG things, user specified functions in a completely different context, and have been wondering if there's enough off the shelf code for me to glue together...
I look forward to possibly standing on your shoulders to build something cool, and giving appropriate credit, should I post a "show HN" in 3mo-years. :)
EDIT: Also see the top-level comment by okaleniuk: https://news.ycombinator.com/item?id=37608605
I see this applied to work (database) in a way I'll not elaborate until I can do it. :)
But in other areas, I've done a lot of signal processing, numerical algorithm development and optimization, lots of MATLAB (for improving the underlying math, but also using approximation theory for performance. Think: "replace exp(x) with a taylor series" except .... more. :)) and C/C++ (for turning those graphs of lists of equations) into machine code.
I've written dataflow style code starting from "paper of equations", to "runs on N nodes" many times.
Perhaps then you see how this looks (to me) like a "missing piece". :) I can now mix between mathematical optimizations (like replacing an expensive function with a pade approximant, using a lattice of symbolic identities, etc) and _compiler_ optimizations. \o/
Not sure that's a job for me, though - maybe someone else has already done it and I just haven't seen it yet?
TCC compile speed to speedup ratio is bonkers BTW.
Re: TCC: I know, right? I think it would be good to see how much we get from a) just not allocating the whole graph every time and b) doing it linearly/bytecode-style, both while still in Python-land.
[1] https://www.tensorflow.org/js/guide/models_and_layers#the_fu...
# define some graph
x = sp.Placeholder()
y = sp.Lazy(sp.square)(x)
# and run the graph later on
x.assign_value(sp.Variable(np.array([1, 2, 3])))
y_val = y.run() # the result, y_val is an sp.Variable
gradients = sp.get_gradients(y_val)
# run same graph with different values
x.assign_value(sp.Variable(np.array([5, 6, 7])))
y_val = y.run()
gradients = sp.get_gradients(y_val)
(There's some more examples of this being used in training loops in the readme.)