Why physicists still use Fortran
moreisdifferent.com
moreisdifferent.com
Here are some resources I have collected over the years.
"Introduction to Modern Fortran" (Fortran 2003): http://people.ds.cam.ac.uk/nmm1/Fortran/index.html
Fortran Wiki: http://fortranwiki.org/fortran/show/HomePage
List of Fortran tutorials: http://www.fortran.com/the-fortran-company-homepage/fortran-...
Fortran vs. C: http://www-cs-students.stanford.edu/~blynn/c/fortran.html
Fortran's influence on C's "restrict" keyword: http://www.drdobbs.com/the-new-c-it-all-began-with-fortran/1...
(edit: thanks for the upvotes! and discussion!)
I agree that meshing is definitely a difficult situation; I've never seen a solution (for unusual geometry) that I liked much. Things that can pretend to be rectangular? No problem. Very adaptive meshes? Argh.
for (i ...) {
double a0 = a[i];
double a1 = a[i+1];
double b0 = b[i];
double b1 = b[1+1];
c[i] = a0 + b0;
c[1+1] = a1 + b1;
}
The hand-unrolling is predicated on the knowledge that the arrays do not overlap. It is obvious to the compiler that the locals do not alias with the arrays, or with each other.The stores to c[] could alias with a[] or b[], but that hardly matters; we assume that all the array loads and stores take place. We have done ourselves the unrolling that was hindered by the suspicion that the arrays overlap, and could do more of it.
When coding in C for tightness, it helps to pretend that locals (at least basic type scalar ones) are registers and references to arrays and structs are memory loads and stores. Then think like an assembly language programmer, somewhat. It's better to use a few more locals than a few more loads and stores. Try to load once, process with locals, store once.
I have no idea if this applies to smarnach, but it definitely applies to other people.
Primos wasn't much good compared to the commercial Unixes that were appearing. It did have one nice-ish feature late in it's history; the CPL scripting language.
Shame to hear that Prime / Primos is now defunct but that job was back in the 80's!
[1]: http://stackoverflow.com/questions/146159/is-fortran-faster-...
[0] https://en.wikipedia.org/wiki/Row-_and_column-major_order
I tried to talk the Go and Rust people into putting in multidimensional arrays, but the discussion degenerated into bikeshedding, with arguments for fancy but slower representations so you could take arbitrary N-dimensional slices from a multidimensional array.
Right now there is a focus on SIMD in Rust, which is crucial for this domain, so there is progress being made.
A Fortran-like multidimensional library could effectively happen out of tree, but ndarray is closer to Python's numpy.ndarray than to Fortran arrays. And this means that ndarray can not support negative indexing (see here: https://github.com/bluss/rust-ndarray/issues/152). I started a prototype of Fortran like array here: https://github.com/Luthaf/mudi, if anyone want to look at the code or even work on this.
My only problem at the time was that `Index` must always return a reference, and cannot return a new struct. From my understanding, this could be solved with the HKT/ATC work.
> Right now there is a focus on SIMD in Rust, which is crucial for this domain, so there is progress being made.
This is very exciting! And knowing the Rust community, we may even get a cross-platform cross-architecture SIMD library with a nice API!
The main blocker is just that fortran has a wonderful ecosystem of scientific computing packages and you can find almost any operation you need out there. This is not true of even Matlab or Mathematica. I have often had to reimplement random algorithms in Mathematica. Fortunately mathematica gives some pretty good high-level tools, so it's not that bad, but it's still annoying.
Multidimensional arrays was brought up as an issue with C/++. AIUI using macros in C++ makes it tolerable, but not great. I did ask about `arr[(1, 2, 3)]` and folks seemed okay with it. Many have used mathematica where indexing is done with double braces (`arr[[1,2,3]]`) so it isn't too bad.
Implicit bounds checking was something that was frowned upon. Could even be a dealbreaker. While usually bounds checking can get elided by llvm, scientific computing does tons of indexing and the overhead might crop up in the profile. I'm not actually sure of how well this maps to the real world, and never got a chance to profile this, but it's a concern.
Libraries like ndarray could turn it off but it would basically be unsafe :|
-------
I did use Rust for some scientific computing. At the time, IIRC numeric types had to be more explicit, which was annoying, but that was pretty much my only issue with it (I didn't need any existing scientific libraries). I didn't know of any good visualization libraries so I would usually output to json/csv and visualize in Mathematica. But I have done the same for Fortran code; Mathematica is just awesome at visualization and analysis.
I recall having access to a scientific computing cluster where the only up to date thing was ifort. It had an ancient python, and icc (IIRC it was ancient too, but I'm not sure). Had to compile a bunch of compilers myself to get my own code to run. Asked about this and apparently everyone just used fortran. Python is common in post-processing but a lot of the tools they were using were ancient or maintained by people with similarly ancient toolchains so stuff still worked on it.
This is the most frustrating aspect of Rust, to me, as a developer of scientific software. Rust has great potential to challenge Fortran in this domain, but numerics is mostly an afterthought in Rust.
A common problem with Rust: many people from different backgrounds sees it as a godsend (for some good reasons) and they'd like to replace their former language with it, but the language can't evolve fast enough to satisfy everybody at the same time.
It started as a language for desktop softwares (like a web browser, it's first use-case), and currently the focus is to evolve it to be suitable for back-end development (with asynchronous IO). I hope one day scientific software will become a first class citizen too.
It is totally true that there are many areas that can be improved, and it's gonna take time and effort to knock them out. It's tough! My personal pet area is OS dev...
A lot of the people who work on the compiler/library support for this stuff aren't the primary consumers of it. I personally like working on this kind of code when I have time (I've done a bit of work on the rust bignum library), but it helps to know what's actually going to be useful to people.
1.) Multi-dim arrays supporting array math, slicing and flexible indexing, sizeof always known (internally solved through lookup tables).
2.) Fast-by-default rather than safe-by-default. A safe language is useless if it gives 2x or more runtime overhead. Make it safe where it doesn't give you any performance penalty (i.e. compile-time checks), otherwise make the default performant or leave the choice to the programmer. Example: Pass-by-reference as default, no GC.
Essentially, I don't think Fortran will be replaced any time soon - maybe strong AI that can program all of this stuff from pure math specification will be here sooner than a Fortran replacement. To everyone not understanding this, read the article again. There's been a huge amount of effort going into this language the last 20 or so years - almost more than justified by the size of the HPC market, which is visible by all the compilers lagging behind the specs. If you want to help, go and improve gfortran (e.g. with better GPU support so people don't need the lagging PGI or locked down Cray compilers anymore).
[1] http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
If you want to get started, here's my recommendation: Program Kernels only in Modern Fortran, learn about f2py bindings and do the other parts in NumPy. If you use Fortran purely as a number crunching language - no I/O, no setup, no config code etc. - it's pretty sweet actually - IMO there isn't much need for replacing it with something new that has 50 years of compiler work to catch up (which is near impossible anyways).
I chose C++ (writing in a fairly modern style, but not eschewing aliasing-restricted pointers, etc. where beneficial) because it handily beats everything except Fortran for performance and is vastly superior to Fortran in terms of zero-cost abstraction. I'm writing code that's largely portable between CPUs and accelerators (mostly GPUs) and has a lot of interchangeable parts. With C++ I can use templates to achieve compile time polymorphism and genericity, while retaining Fortran level performance on CPUs at the cost of higher code complexity.
The Fortran story on GPUs has also been very disappointing initially, especially for those of us not interested in proprietary compilers, though I understand the situation is improving there. Ultimately, in my experience, while individual strengths of C++ can be reproduced in other languages, there's no other language that does it all. I hope that changes some day (for now, D looks like the most promising alternative to me) as writing C++ is often an exercise in frustration, but that's where we're at.
Ultimately, it seems to me the only way to justify using Fortran for scientific computing nowadays (apart from legacy issues, of course) is if you have no intention of ever using accelerators and absolutely must have optimal CPU performance. NVidia and, to a lesser extent, Intel/AMD could have maintained the language advantages Fortran offers in the accelerator space as well, but chose not to, and now you need solutions like this coupled with proprietary compilers just to approach CUDA C / OpenCL performance. Legacy projects will be around for decades, of course, but for new things I think C++ is/will increasingly be the default choice.
I ran into issues a year ago when trying to organize a library with more than 8000 loc, when the "dump everything into a global namespace" started to be more a hassle and less a nice way to get stuff done. I am waiting for it to stabilize a bit before giving a second try.
I haven't played with Ada arrays much, but I know it supports various different representations (so it can be binary compatible with Fortran column-first arrays and C row-first arrays), it's got nice array slicing semantics, it's got good support for generics which can operate on arbitrary sized arrays.
I don't know whether it has Fortran-like aliasing guarantees, though. You can't take an address of an array element unless the array has been declared to support it, which helps, but I don't know whether you can e.g. pass the same array by mutable reference into a function twice. (It makes sense that this isn't supported, as it's kinda meaningless, but I can't find an actual reference.)
http://www.adaic.org/resources/add_content/docs/craft/html/c...
Also check out ParaSail language designed for easy, safe parallel and concurrent programming. It's an Ada variant from Tucker Taft at AdaCore. Might have something interesting on this topic. Might not.
I'd dabbled in Go and Rust as well but don't see them as serious competition to Julia in this space. As much as I love Go, it is really poorly suited for numerical computing. No operator overloading of any sort among other things. You really want that for vector based math.
Also Rust, seems like more of a language for software developer professionals. I think Rust looks neat, but it is too complicated for scientists I think. They don't want to focus that much on their language.
In this respect I'd actually think Swift has more appeal as it is quite fast, but easier to use. By easy, I mean there are fewer concepts to learn.
But Swift will have the same problems as Go and Rust, in that it is not being designed with the needs of people doing scientific computing in mind.
That is what is nice with Julia. Out of the box it does so many of the things you want. Right out of the box without explicitly importing anything you can start doing advance matrix operations, load large CSV files, groks imaginary numbers. It actually has a number system which distinguishes between rational and irrational numbers e.g.
What facility is Rust lacking that prevents you from coding this as an extension/package rather than needing core coding support?
Native long integer (128-bit) support could be coded as a compiler extension for a long time before it got pulled in.
That sort of thinking is what drives number-crunching people away from a language. You end up with ten different representations for matrices, and can't pass matrices from one package to another.
So, the question still stands: What in Rust prevents an ambitious number cruncher with good design taste from adding the appropriate pieces to the language?
Rust can't enforce "one way to do it" since this would be done as a library. Currently there's only one library offering this (ndarray), so in a sense there's only one way to do it :)
No array slices needed. Plain Fortran 77 notation provides what I need.
"has pretty syntax", was just showing what the syntax would look like in Rust.
LLVM autovectorizes, and does many loop optimizations. I suspect LNO exists, but if it doesn't there's nothing preventing it from being added afaict.
Was mostly explaining what the status of this in Rust is. It's not awesome, but not horrible either.
* lack of type-level integers
* lack of explicit SIMD on stable Rust
And Rust doesn't have ten different ways to do n-dimensional arrays. There's one major library out there (ndarray). I just learned about a second (https://github.com/Luthaf/mudi) which seems to use the same conventions.
There are multiple ways to do matrices, but these are in graphics-oriented libraries.
I mean, maybe I was an outlier, but when I was in academia I wanted to have my models compute as accurately and quickly as possible, and I generally didn't have much time for or interest in the computer coding beyond the necessary implementation details required to conduct my research.
Telling me "implement an extension", then, would have made me roll my eyes and go back to fortran.
https://bluss.github.io/rust-ndarray/master/ndarray/index.ht...
https://java.net/projects/projectfortress/pages/Home
https://blogs.oracle.com/projectfortress/entry/fortress_wrap...
Actually the actual real history is little more complex than that.
JuliaCon 2016 (Keynote) | Fortress Features and Lessons Learned | Guy Steele
https://www.youtube.com/watch?v=EZD3Scuv02g
It would be good if people on HN would separate a bit the Oracle hate with the facts.
However, there is slight change. The new generation of masters often do know other languages, so they sometime tolerate their new apprentices to use other language and still able to teach them. So at this point, by far, not all physicists use FORTRAN.
FORTRAN will die out, just takes time.
One of the sticking point is the library BLAS/LAPACK. It is in FORTRAN. Or more precisely, its interface is in FORTRAN. I don't foresee this will change for a long time. So FORTRAN will be like COBOL, it will persist even when no-one really use it anymore.
First, if one is familiar with a language or invested in a language, he will be biased to choose that language and it makes sense for him. Before you would argue, I admit I can't prove that you are biased, but nor could you prove you are not biased. So let's agree that some anecdotes like your case is not a strong argument.
So let's look at it in another angle. If physicist/people choose FORTRAN not merely due to apprenticeship, it necessarily means that there will be people choose FORTRAN even when his master do not introduce/require him to use FORTRAN. In another word, we need examples of people who choose FORTRAN despite of non-familiarity to FORTRAN. There are plenty of such cases for, e.g. rust. For me at least, I know none such. How about you? For example, how successful have you been influence other people (other than your student) to use FORTRAN? On the other hand, I do know people who choose other language despite of the familiarity of FORTRAN.
The prerequisite for using Fortran is that someone works in a field that relies heavily on large scale, high performance numerical computation. Since Fortran is pervasive in that domain, it's extremely likely the they would be exposed to Fortran through "apprenticeship". Basically, most people who should be using Fortran are using Fortran! I've seen a few instances where people used C/C++ or Matlab in situations where Fortran would have been more appropriate. Matlab has its own drawbacks, but it is also a very domain-specific numerical language, and likewise its users are exposed to it through apprenticeship! C/C++ is still the default language for high performance computing outside of numerics, and thus it's not surprising that people who have not been exposed to Fortran would attempt to use it for numerical purposes as well.
There isn't exactly a lot of choice for numerical programming: Python and Matlab are (partly) designed with numerical purposes in mind, but don't scale to high performance. C/C++ are performant, but not expressive for numerics. There really isn't any other language that would even be in consideration, besides now Julia, but Julia is extremely new, so time will tell.
I don't know anything about Rust, but based on reading its Wikipedia article its not a language designed for numerics, but basically something designed to replace C++ for systems programming. Thus, like C/C++, it will be performant, but not expressive for numerical purposes.
If Fortran is good for computations, and it's fast, and it does what it is designed to do, and does it well, why should it die out?
As a computer scientist and engineer, I do not understand the animosity towards Fortran?
C replaces FORTRAN. That is from merit point of view. In reality, computational physicists mostly goes to C++ plus Python. Truth to be told, physicists are not computer scientists and they are not even into it. They simply picked out of necessity/convenience -- which was the reason FORTRAN was picked then.
PS: That FORTRAN is fast is over stated IMHO. I am familiar with high performance computing. In terms of parallel computing, it all boils down to algorithm design. In terms of vector/linear algebra, it all depends on machine tuned BLAS (which is mostly due to hand crafting rather than the language itself). There is no evidence FORTRAN code runs necessarily faster than C -- comparing first craft non-optimized code. Unlike C, FORTRAN is less capable and more cumbersome to do trendy stuff -- this is the actual merit of FORTRAN over C.
From my point of view, it's understated, and should be given much more credit than it gets. intel has done a lot of work to make their ifort compiler leverage their latest instruction sets like AVX2, resulting in even bigger speedups, and PGI has done absolutely amazing work of writing a compiler which can ingest unmodified Fortran code and compile it to run on NVidia GPU's. It's nothing short of mind blowing to me and gets way too little mention. Modern Fortran is a really nice language and all this bashing of it because it's not trendy is completely unfounded. Just ask intel.
Perhaps, but it doesn't follow from anything you've said.
Unless I missed something, this directly contradicts the quotes benchmark source[1], where C beat Fortran on all tests except one (where they were tied), and usually by a wide margin. Plus I believe gcc usually produces slower code than Intel's compilers (at least for C), so it's not clear that C-gcc and Fortran-Intel is a fair comparison.
But beyond that, I'm always confused as to why there is a significant difference. I would expect two compiled languages with reasonable compilers to perform almost exactly the same when they're doing nothing but arithmetic operations, since those are almost entirely determined by the CPU, not the cleverness or speed of the standard library algorithms. Can anyone enlighten me?
[1] https://benchmarksgame.alioth.debian.org/u64q/fortran.html
This seems to describe me. I am tempted to rewrite those programs more idiomatically. Thank you for pointing this out.
I have cut back: x64 single core & x86 quad core are no longer measured, x86 single core updates are not frequent, and x64 quad core updates are less frequent than they used to be (although more frequent than the chart dates might suggest).
I've kind-of been hoping the hardware would fail -- but someone would probably gift me a new machine :-)
From my perspective "defence of the benchmarks game" is a matter of saying "Keep it in perspective" and "Keep it in context" until we do ;-)
In C, if you write code like this:
void dostufftotwoarrays(int* a, int* b);
Then maybe b is equal to a + 3, so your compiled code has to assume whenever it writes to an element of a, it might have changed an element of b, and so reload b from memory. Alternatively, it can do a bunch of tests at the start of the function, and compile multiple copies of the function for different situations.In FORTRAN, this isn't possible (you don't tend to pass around raw pointers), so it is much easier for the compiler to reason about what objects might be in the same place, and which aren't.
The restrict keyword goes some way to fixing this in C, but is tricky yo use correctly, and also doesn't solve all problems.
This doesn't affect aliasing in Fortran at all. Aliasing is simply prohibited, which leaves the compiler free to generate code that gets the wrong answer, if the programmer screws up and has actual aliasing at run-time.
mypair* restrict position = &object->pair;
float* restrict position_x = &position->x;
Is undefined behaviour, as you can't take a restricted pointer to a child of a restricted pointer in the same scope (the rule isn't quite that simple, but that's part of it). In general, rules about pointers to pointers get complicated, and I've had trouble with them in the past.In general, it's a good idea to try to only use restrict for "leaf" pointers, not intermediate objects, but that does block some optimisations.
There is also the obvious problem of people getting carried away, and marking something 'restrict' where they shouldn't have.
While 'restrict' is very easy to use on simple structures (like just int*), if you look around you'll find very little, if any, material about using it for complicated nested data structures.
As far as I know Fortran, at least in its original form, enforced the latter (that was fairly easy to do, as it didn't have dynamic memory allocation, pointers or recursion (the compiler determined the location in memory of all variables))
You can totally call a subroutine with several arguments being the same thing, as long as you don't do anything bad inside the subroutine.
I'm aware of this because I tried to get the PathScale compiler team to add a warning for incorrect aliasing. That wasn't possible. But I did get a flag which made the compiler obey C aliasing rules for Fortran, and it was part of the "got the wrong answer? run with these flags and if you get the correct answer, your program is not standard-conforming" thingie.
I claim it is only a promise, you claim you can call it with identical arguments. I don't see a contradiction; making a promise isn't the same as keeping it.
Similarly, your argument that it is fine to break that promise as long as you don't do anything bad inside the subroutine, I read as "you sometimes can get away with breaking a promise", but again, that's not the same as not making the promise.
What am I missing?
int chooseone(restrict int* a, restrict int* b, bool c) {
if(c) return *a; else return *b;
}
Here, we can pass the same pointer for a and b, because only one of them is ever accessed in any call to the function."An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer."
So, it hinges on the meaning of 'accesses'; it is a runtime thing, not a compile-time thing.
> I would expect two compiled languages [...] to perform almost exactly the same when they're doing nothing but arithmetic operations [...]
Different languages are going to have different memory models which is going to result is vastly different performance. E.g. a GC vs reference counting vs linear types. If you are doing arithmetic on something that needs to be managed (e.g. an array), you'll see differences.Some language features close the door for optimizations. E.g. the ability to dynamically add or remove methods to an object/class can make method dispatch more or less expensive.
Finally, some languages have undefined behavior (e.g. what happens when there's an overflow or a division by zero) while other languages want specific behavior for the edge cases. This all affects the performance of the resulting code, even for basic arithmetic operations.
In this case though, C doesn't have garbage collection or OO features, and (I believe) has unspecified behavior for arithmetic exceptions. I assume Fortran does the same (since it's comparably fast), so I guess I still don't really see where people expect the difference to come from.
As for what the differences are, try talking to a compiler engineer. The better ones love how Fortran features like the argument aliasing rule for 100% of code makes generating fast code easier. In fact that's one of my tests for compiler engineers in interviews; if they've worked on a C/C++/Fortran compiler and can't say anything good about the challenges and opportunities of Fortran optimization relative to C/C++, then they haven't really drilled down on performance issues!
I know as a long-time C programmer, there are small changes I can make to source that will result in big-time performance gains.
Could hinge on how tight their FORTRAN code is vs their C code...
Could also depend on how much love their respective machine code translations have been getting.
It is very easy for a physical scientist to write Fortran that performs well - the syntax looks very similar to the maths that is being modeled. It is a lot harder for a scientist to write tight C code.
Look and you might see measurements of several different C or C++ or … programs doing the same task with different performance.
https://benchmarksgame.alioth.debian.org/u64q/performance.ph...
Historically, C compilers just couldn't do such a good job at optimising, because C is pretty complex and has loads of undefined behaviour. Also, Fortran compilers have always been optimised for numerical computation.
Recently * , a lot of effort has gone into making C compilers produce very optimised code. In general, this is a good idea because humans are bad at optimising and also remembering every damned Intel vectorisation instruction.
So historically, Fortran was much faster, recently * with compiler advances in e.g. reordering and AMD64, it's possible C compilers beat Fortran compilers.
* edit: adjust your definition of recently to encompass the entire timeframe of Fortran's existance
Auto-vectorization? These implementations vary wildly between GCC and Intel.
2. As a research student your first program is likely to be a F77 program written by your professor or an older colleague.
3. A library from 30 years ago can be easily wrapped into a modern program, compiled and run.
4. Arrays are really the most important thing for this sort of programming and since F90 array level operations have been baked into the language.
5. It is fairly trivial to write fast Fortran.
6. Fortran is much easier to use for numerical stuff than c++
I heard that there was an effort at JPL to convert over to using Python. I'm not sure how that went. Maybe they were just writing Python bindings for their Fortran code? I know that much of SciPy consists of Python bindings for Fortran and C code [1].
The software I used to do "nonlinear programming" (i.e. parameter optimization), called NPOPT, was also written in Fortran.
[1] https://www.scipy.org/scipylib/faq.html#how-can-scipy-be-fas...
Fortran continues to do that well. And as the article mentions scipy doesn't run as fast.
The logical successor to Fortran was APL (Arithmetic Programming Language) but its notation really killed it.
The properties that keep Fortran rolling (easy to start using, effective in translating formulas into computation) persist.
When you compare the current Fortran standards to its '66 version, you'll see how much progress it made.
And I hope that you can actually use it these days. Round the turn of the millennium, it was still quite common for people to use Fortran 77 because that's all that was supported or fit in the general codebase.
A = B
A = 3.24 * B
C = A * B
B = exp(A)
norm = sqrt(sum(A * * 2))
Quoting:
"Similar C/C++ code simply does not exist ... Having to use libraries instead of intrinsic functions means the resulting code is never as neat, as transferable, or as easy to learn."
While this statement is true, I think strongly undersells how well these kinds of libraries can be "baked" into C++ through operator overloading, templating, etc. See for example, the Eigen library [http://eigen.tuxfamily.org/].
a = [1,2,3,4,5,6]
a(1:3) ! gives [1,2,3]
than with std::valarray a = {1,2,3,4,5,6};
a[slice(0,3,0)]; // gives {1,2,3}
And I couldn't even find examples on how to do slicing with multi-dimensional arrays in std::valarray?In Fortran it's just
a(1:3,1:3)My point was not so much that valarray is awesome, but that articles like this one tend to fight a very strawman version of C++, even when just sticking to strictly standard components.
Fortran is not the fastest language around the block, but if you don't want to go into non-portable machine-based hand-tuned optimisations (e.g. loop unrolling) it's hard to beat. Basically, if you optimise for both runtime and programmer time for HPC applications I'd argue that Fortran is top of the crop.
[1] https://eigen.tuxfamily.org/dox/TopicInsideEigenExample.html
What's he talking about? This is wrong!
The amount of existing scientific code in Fortran is huge and there's a chicken and egg situation (new code uses/extends old code so new code will also be in Fortran) that will lead to further increasing it!
Best of luck with Brave!
To quote The Dude: "You're not wrong, you're just an asshole."
Excellent question, glad you asked! Just what do you think all the people who are asking why Fortran is still in use are using?
My money is on the bet that they're not using Fortran. I've worked in the finite element analysis / high performance computing fields for quite a few years and I've never heard anyone who used Fortran complain that they were, or had to use it. Could it be that it's because people like that they get high performance from a language out of the box?
Fortran certainly has a mythical reputation for performance, but it should be challenged every once in a while.
[0] http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
This was 1992.
https://developer.arm.com/-/media/developer/developers/hpc/f...
[0] https://mobile.twitter.com/astrofrog/status/7870072618771660...
size_t m, n;
... set m and n ...
int (*a)[m][n];
a = (int(*)[m][n])malloc(sizeof(*a));
Edit: and you MUST NOT REUSE OR OTHERWISE CHANGE m and n FOR THE ENTIRE LIFETIME of the array, because bad things will happen.And you access it via
(*a)[x][y]
And you free it with free(a);
And if you want to pass it to a function: void do_with_array(void* raw_array, size_t m, size_t n) {
int (*array)[m][n] = (int(*)[m][n])raw_array;
... do whatever ...
}
do_with_array(a);
And I'd rather do it in Fortran, but if you ever need to do it properly in C (i.e. without using array of pointers) - now you know. void do_with_array(size_t m, size_t n, int a[static m][n]) { ... }
int (*a)[n] = calloc(m, sizeof *a);
do_with_array(m, n, a);Practically you are right, but the article is more right than you. I got into some fights with quite a few elite teachers/coders teaching the way of doing 2D arrays exactly as described, and they wouldn't agree the method you describe is less error prone ... because: it is tradition. (And as every person doing research know tradition is not supposed to change and that what science values).
It seems absurd, but so many things are absurd these days I am not even surprised.
template<typename T>
T** make_2d_array(size_t m, size_t n) {
// TODO: add padding for alignment,
// but you're unlikely to need something aligned
// on a larger extent than sizeof(void*)
void *memory = malloc(m * sizeof(void*) + m * n * sizeof(T));
T** array = (T**)memory;
T* data = (T*)((char*)memory + m * sizeof(void*));
for (size_t i = 0; i < m; i++) {
array[i] = data + i * n;
}
return array;
}
And you can then delete the entire array with a single free().(Not that important if you use a pure C compiler, but your code will also fail if you use a C++ compiler.)
Still up to date. https://docs.scipy.org/doc/numpy-1.10.0/user/c-info.python-a...
There is an Openwatcom project that does C and Fortran but I think it is Fortran 77.
I had Fortran and COBOL on my resume but most jobs I took used Visual Basic.
its also unfair to suggest that C/C++ is as fault with not allowing a = b * c with array types. this is a failing of the standard library and easily fixed... operator overloading lets you create exactly this functionality, and std::valarray already does this for a lot of what you get in Fortran...
Actually physical scientists love Python as much as they love Fortran. It a lot of cases, it is the only two languages they know.