7/14/2026 at 12:21:46 PM
Author here — I work on Tesseract at Pasteur Labs, and I wrote this up because the "what if this was possible" was bugging me for way too long :)I was surprised by how well this worked, the LFortran + Enzyme stack seems to be a very clean way to get gradients through Fortran code via LLVM IR transformations. Pretty cool to see a 220-line Fortran heat solver turn into ~6,900-line reverse pass automatically if I dare say so.
Would be awesome to see this applied to a real scientific codebase, and I hope that the demo is enough to convince people that it’s worth trying.
by dionhaefner
7/14/2026 at 2:03:54 PM
Very interesting. Does LFortran have the same internal array layout as the standard C runtime ?A shared layout and a shared calling convention would be very nice.
Sorry about my naive question. Haven't touched Fortran directly in three decades I think.
EDIT: thanks for your reply. For some reason it has been flagged dead. So am responding here. You can mail dang hn at ycombinator dot co m about the flagging. He is very nice.
by srean
7/14/2026 at 3:59:16 PM
I would also like to know this. Fortran itself is column-major, so I would guess the internal layout isn't same for multi-dimensional arrays when compared to row-major C? I'm not sure how LFortran represents arrays internally though.by kmaitreys
7/14/2026 at 4:33:21 PM
LFortran internally uses column-major, so interchanging data with C should be done carefully for multi-dimensional arrays. If row-major representation is highly needed feature, We can introduce a flag to do that. I'm not totally sure about that but it's doable under some conditions for sure.by assemmedhat
7/14/2026 at 8:13:28 PM
We can internally do both row-major and column-major arrays. For Fortran we enable the column-major flag by default, but the door is open to have both at the same time.by certik
7/14/2026 at 2:30:13 PM
Lots of scientific code in Fortran has sparse arrays, so a NxN array that only has values on 5 diagonals will store that as 5xN array to save memory allowing you to run a larger problem.by wombatpm
7/14/2026 at 2:34:31 PM
That's a very orthogonal issue.Sparse arrays are supported on C libraries too. I have done my time with CSC and CSR even inside Python that called out to C libraries.
by srean
7/14/2026 at 2:25:21 PM
Not naive! The answer is yes and no.Array layout: yes, for the simple cases this post relies on. In the demo the work arrays are literally calloc'd in a C wrapper and handed straight to the Fortran routine, and it just works. (Column-major vs. C's row-major is still on you to keep straight, of course.) This wouldn't be so easy for fancier Fortran array features — allocatables, assumed-shape (:) dummies, pointer arrays — which in general get a descriptor struct (bounds, strides, etc.) rather than a bare pointer. Flang uses those descriptors much more aggressively, but I don't know how that would manifest at the C-Fortran bridge. Would be interesting to repeat the experiment with Flang (if at all possible) and comparing the pain.
Calling convention: there are well established contracts, much older than the layout story. Fortran passes everything by reference, so a double precision :: x argument is an x* at the ABI level — which is why every argument in the C wrapper is a pointer (&n_, &k0_, ...). Combine that with C-compatible name mangling (a trailing underscore historically, controllable via LFortran/bind(C)) and Bob's your uncle. Nothing here is new, the pipeline is really just leaning on that decades-old interop contract and then letting Enzyme differentiate across the boundary.
by dionhaefner
7/14/2026 at 2:31:32 PM
[dead]by dionhaefner
7/14/2026 at 4:41:04 PM
Very interesting stuff. How would I get GPU offload working? I have a rather complex scientific code I'm working on with JAX. Most of it can be expressed well with JAX's programming model, but the last 10% really sucks. It's still worth it so I don't have to mess around with offload onto whatever XPU flavor of the week. But going to C++ would really make my life easier, as long as I could use e.g. Kokkos.by Gangway0829
7/14/2026 at 7:16:37 PM
You can write the cuda kernels and directly differentiate them using Enzyme. Last time I checked KOKKOS was still WIP: https://github.com/EnzymeAD/Enzyme/issues?q=kokkosby new_user55
7/14/2026 at 4:55:44 PM
No idea lol. I assume it’s possible since both Enzyme and GPU programming are pervasive in Julia. Let us know if you end up trying.by dionhaefner
7/14/2026 at 3:38:45 PM
When you say you 'wrote this up', you mean you had an AI write (at least) chunks of it.by tanderson92
7/14/2026 at 3:46:47 PM
Indeed, just like I let my compiler write (at least) chunks of my AD logic. Not great when the tool becomes a leaky abstraction, but overall net positive don't you think?by dionhaefner
7/14/2026 at 3:48:19 PM
Disagree; it irks me to read AI slop, and writing is meant to be persuasive and engaging to human readers.by tanderson92
7/14/2026 at 3:54:18 PM
Happy to take the blame for the lack of persuasian and engagement then :) Thanks for the feedback, although I’d like to believe there’s a way to have that cake and eat it too.by dionhaefner