Oh, array striding.
This is a classic bikeshedding issue. When Go and Rust were first being designed, I brought up support for multidimensional arrays. For both cases, that became lost in discussions over what features arrays should have. Subarrays, like slices but multidimensional? That's the main use case for striding. Flattening in more than one dimension? And some people want sparse arrays. Stuff like that. So the problem gets pushed off onto collection classes, there's no standard, and everybody using such arrays spends time doing format conversion. This is why FORTRAN and Matlab still have strong positions in number-crunching.
From everything I'm seeing, it follows that Matlab & Fortran have been decimated by Python and C/C++ around 1990s and 2010s, respectively. Of course I could be wrong; any evidence of their still strong position will be greatly appreciated, doubly so evidence that this position is due to stride issues.
(Of course Python provides wrappers to Fortran code, eg FITPACK, but this code specifically was mostly written in the 80s, with small updates in this century, and is probably used more thru the numpy wrappers, stride conversion issues and all, than thru its native Fortran interface)
I think pretty much all linear algebra libraries are still Fortran and are unlikely to ever be C because Fortran is legitimately faster than C for this stuff. I don't know if it has anything to do with strong opinions about how values are represented, I think it has more to do with lower overhead of function calling, but that is just repeating what someone told me about Fortran vs C in general, not necessarily applicable to BLAS libraries.
Fortran at least used to be very common in heavy scientific computing, but I would bet that relies on GPUs or other accelerators these days.
The question is how much new numeric code is written in Fortran vs C/C++. My guess is way below 10%, certainly if we measure by usage as opposed to LOC and I would guess by LOC as well.
Is Fortran legitimately faster than C with the restrict keyword? Regardless of the function call cost diffs between the two - meaning, even if we assume Fortran is somehow faster here - there's no way numeric production code does enough function calls for this to matter. If Fortran was faster than C at any point in time I can only imagine pointer aliasing issues to have been the culprit and I can't imagine it still being relevant, but I am of course ready to stand corrected.
I don't think fortran is faster by language virtue, but it's certainly easier to scrap together high performance numeric fortran code. And ifort/aocc are amazing at making code that runs well on clusters, which is not a priority for any other domain. Fortran is absolutely still on top for modern numerics research code that involves clusters, talk to anyone who works in simulations at a national lab. If your code is mostly matrix math, modern fortran is very nice to work with.
Emphasis on modern because maintaining 70s-80s numeric mathematician cowboy code is a ninth circle of hell. It has a bad rep for that reason.
When you speak about code from the 1970s in particular, you need to appreciate the extremely limited language features that were available.
They did not even have while-loops in the language until Fortran 77. While-loop functionality used to be implemented using DO-loops mixed with GOTOs. You can't fault the people of that era for using the only tools that were available to them.
Restrict probably helps. I can't say much about fortran but C still has warts that can significantly impact its math library. For example almost every math function may set errno, that is a sideeffect that isn't easy to eliminate by the compiler and might bloat the code significantly. For example with gcc a single instruction sqrt turns into a sqrt instruction, followed by several checks to see if it succeeded, followed by a function call to the sqrt library function just to set errno correctly. I just started to disable math-errno completely once I realized that C allows several alternative ways to handle math errors, which basically makes any code relying on it non portable.
At the core, Fortran uses multidimensional numerical arrays, with the shapes being defined being defined in the code. So the compiler knows much more about the data that’s being operated on, which in theory allows better optimization.
I thought blas/lapack is still written in Fortran, so most numerical code would still be built on top of Fortran.
That is more of an urban legend than reality in 2024. Fact is, although the original BLAS implementation was fortran, it has been at least a decade since every Linux distribution ships either OpenBLAS or ATLAS or the MKL, which are both written in a mix of C and assembly. All modern processor support is only available in these implementations.
LAPACK itself is still often built from the Fortran code base, but it's just glue over BLAS, and it gets performance solely from its underlying BLAS. Fortran doesn't bring any value to LAPACK, it's just that rewriting millions of algebraic tricks and heuristics for no performance gain is not enticing.
Nit: this failed to be respective; the years are the other way around
Interesting... maybe the respective comparison was Matlab to Python and Fortran to C/C++? This sentence actually had three parallel clauses.
But that was a great nit to find.
yes that's what I originally meant. Matlab to Python was 2010's and Fortran to C/C++ was 1990s. (Probably not the exact time frame, but that's close)
Fortran still dominates certain areas of scientific computing / HPC, primarily computational chemistry and CFD. - https://fortran-lang.org/packages/scientific - you don't hear about most of them because they're generally run on HPC centers by scientists in niche fields. But you do get their benefit if you buy things that have the chemical sector in their supply chain.
The common thread is generally historical codes with a lot of matrix math. Fortran has some pretty great syntax for arrays and their operations. And the for-loop parallelization syntax in parallel compilers (like openmp) is also easy to use. The language can even enforce function purity for you, which removes some of the foot guns from parallel code that you get in other languages.
The kinds of problems those packages solve tend to bottleneck at matrix math, so it's not surprising a language that is very ergonomic for vector math found use there.
Same for Matlab, it's mostly used by niche fields and engineers who work on physical objects (chemical, mechanical, etc). Their marketing strategy is to give discounts to universities to encourage classes that use them. Like Fortran, it has good syntax for matrix operations. Plus it has a legitimately strong standard library. Great for students who aren't programmers and who don't want to be programmers. They then only know this language and ask their future employer for a license. If you don't interact with a lot of engineers at many companies, you aren't going to see Matlab.
While it's not as ubiquitous as it used to be, Matlab is still very heavily used within shops that do a lot of traditional engineering (ME, EE, Aero, etc.).
This surprises people who just write software, but consider:
- The documentation and support is superb. This alone can justify the cost for many orgs.
- Did I mention the support? MathWorks has teams of application support engineers to help you use the tool. The ability to pay to get someone on the phone can also justify the price.
- The toolkits tend to do what specific fields want, and they tend to have a decent api. In contrast, you might end up hacking together something out of scipy and 3-4 weirdly incompatible data science packages. That's fine for me, but your average ME/EE would rather just have a tool that does what they need.
- It also has SIMULINK, which can help engineers get from spec to simulation very quickly, and seems deeply embedded in certain areas (eg: it's pretty common for a job ad with control systems work to want SIMULINK experience).
Is Python gradually displacing it? Probably.
(Honestly, I wish it would happen faster. I've written one large program in Matlab, and I have absolutely no desire to write another.)
I work for the National Solar Observatory, creating Level 2 data for the DKIST Telescope’s observations of the sun. (For example, an image of the Temperature that lines up with the observation)
Just the other day, the solar physicist I work with said “yeah, that code that runs on the supercomputer needs to be rewritten in Fortran” (from C, I think.
He’s nearing retirement, but it’s not that he’s behind the times. He knows his stuff, and has a lot of software experience in addition to physics
Matlab has the issue of not being open source (similarly IDL), but I still see it popping up (though naturally, if I've got any choice it the matter, it's going to be ported to Python). I've also seen new Fortran codebases as well, mainly where the (conceptual, not computational) overhead of using helper libraries isn't worth it.
I'd suggest Python (via the various memoryview related PEPs, plus numpy) does provide most of the required information (vs. e.g. Go or Rust or Ruby), so I'm not sure that proving much other than if the value of using a library to handle multidimensional arrays is enough such that the combined value of a more general language plus library beats Matlab or Fortran (likely due to other ecosystem or licensing effects), people will switch.
we still get new Matlab codebases at my work, also R. In my case it comes from academics in the power systems and renewables fields who move into industry and keep using the tools they used there. We try to gently ease them into python and version control and sensible collaboration but we get new hires all the time
Julia has gained a lot of mindshare in array-heavy coding, with a lot of hard work put into making it possible to get comparable speeds to C++ and Fortran. The manual[0] offers a good introduction to what's possible: this includes sparse and strided arrays, as well as the sort of zero-copy reinterpretation you accomplish with pointer wizardry in the Fine Article.
[0]: https://docs.julialang.org/en/v1/manual/interfaces/#man-inte...
If everyone is just using the Fortran libraries instead of reimplementing it in a modern language, then that's evidence that it's still being used for that purpose.
But format conversion is inevitable because C and FORTRAN has a different axis ordering anyway, isn't it?
Not really, you can always change the indexing to account for it. For example, the GEMM matrix multiplication subroutines from BLAS can transpose their arguments [1]. So if you have A (m x n) and B (n x p) stored row-major, but you want to use a column-major BLAS to compute A*B, you can instead tell BLAS that A is n x m, B is p x n, and you want to compute A' * B'.
As the article mentions, NumPy can handle both and do all the bookkeeping. So can Eigen in C++.
[1] https://www.math.utah.edu/software/lapack/lapack-blas/dgemm....
That's conceptually still a format conversion, though the actual conversion might not happen. Users have to track which format is being used for which matrix and I believe that was what the GP was originally complaining for.
Agreed, realistically you're going to either convert the data or give up on using the function rather than reimplementing it to support another data layout efficiently; while converting the code instead of the data, so to speak, is more efficient from the machine resource use POV, it can be very rough on human resources.
(The article is basically about not having to give up in some cases where you can tweak the input parameters and make things work without rewriting the function; but it's not always possible)
Talking about rough on human resources, I take it you've never written iterative Krylov methods where matrices are in compressed sparse row (CSR) format?
Because that's the kind of mental model capacity scientific programmers needed to have back in the days. People still do similarly brain-twisting things today. In this context, converting your logic between C and Fortran to avoid shuffling data is trivial.
What kind of support would you have hoped for?
A way to reinterpret a slice of size N as a multidimensional array with strides that are a factorization of N, including optional reverse order strides. Basically, do the stride bookkeeping internally so I can write an algorithm only considering the logic and optimize the striding order independently.
That's where you end up after heavy bikeshedding. Lots of features, terrible performance, as the OP points out.
I agree with you on sparse arrays and multidimensional slices, but this is basically the same as what you'd do manually. Saying that "track strides for me" is "lots of features" is a bit uncharitable.