Learning Fortran (2024)
Posted by lioeters 2 days ago
Comments
Comment by thatjoeoverthr 2 days ago
(I considered JAX, but the code in question was not amenable to a compute graph. Another option was to thread by fork, and use IPC.)
I liked the language itself more than expected. You have something like "generics" with tensors. Suppose you pass a parameter, N, and you also would like to pass a tensor, and you would like to specify the tensor's shape (N, N). You can do this; the parameter type constraints can reference other parameters.
Tensors and various operations are first-class types, so the compiler can optimise operations easily for the system you're building on. In my case, I got 80% improvement from ifx over gfortran.
Invocation from Python was basically the same as a C library. Both Python and Fortran have facilities for C interop, and Numpy can be asked to lay out tensors in a Fortran compatible way.
Part of what eased the port was that Numpy seems to be a kind of "Fortran wrapper". The ergonomics on tensor addressing, slicing and views is identical.
Comment by prennert 2 days ago
At the time everyone seems to default to using C instead. But Fortran is so much easier! It even has slicing notations for arrays and the code looked so much like Numpy as you say.
Comment by foxglacier 2 days ago
I wouldn't call multi-dimensional arrays tensors though. That's a bit of a bastardization of the term that seemed to be introduced by ML guys.
It wasn't until I started using Fortran that I realized how similar it is to BASIC which must have been a poor-man's Fortran.
Comment by PaulHoule 2 days ago
If you didn't have vectors, Maxwell's equations would spill all over the place. Tensors on the other hand are used in places like continuum mechanics and general relativity where something more than vectors are called for but you're living in the same space(/time) with the same symmetries.
Comment by Joker_vD 1 day ago
What do you mean, "would": they did! :) The original equations had 20 separate equations, although Maxwell himself tried to reformulate them in quaternions. But if you look e.g. at works of Lorentz, or Einstein's famous 1905 paper, you'll see the fully-expanded version of them. The vector form really didn't fully catch until about the middle of the XX century.
Comment by lioeters 1 day ago
And how Fortran has unique properties that make converting math equations into code "more natural". Intriguing, I'll to dig deeper for intellectual curiosity.
Comment by foxglacier 1 day ago
Comment by foxglacier 2 days ago
Comment by pantsforbirds 2 days ago
Comment by sampo 2 days ago
You can do that, and it might be cleaner and less lines of code that way.
But you don't necessarily need to pass the array dimensions as a parameter, as you can call `size` or `shape` to query it inside your function.
program main
implicit none
real :: a(2, 2) = reshape([1., 2., 3., 4.], [2, 2])
call print_array(a)
contains
subroutine print_array(a)
real, intent(in) :: a(:, :)
integer :: n, m, i, j
n = size(a, 1) ; m = size(a, 2)
write(*, '("array dimensions:", 2i3)') [n, m]
do i = 1, n
do j = 1, m
write(*, '(f6.1, 1x)', advance='no') a(i, j)
end do
print *
end do
end subroutine
end programComment by thatjoeoverthr 1 day ago
Comment by 3uruiueijjj 2 days ago
It also helps that Fortran compatibility is a must for pretty much anything that expects to use BLAS.
Comment by thatjoeoverthr 18 hours ago
Comment by drnick1 2 days ago
Comment by thatjoeoverthr 1 day ago
Intel and Nvidia are both offering both C and Fortran compilers, so I was looking at both. I know C well but I decided to not look at it as a presumed default.
When I used C like this in the past, the intrinsics were very low-level, e.g. wrapping specific Altivec or SSE instructions or whatever. I see see it has OpenMP intrinsics, though, which I’m sure I’ll try later.
If I use a library, I’m breaking up the operations and don’t give the optimizing compiler an opportunity to take operations into account together.
With Fortran, I can give the operations directly to the compiler, tell it the exact chip I’m working with and it deals with it.
It would be fun, when I have some time, to go rewrite it in C and see how it compares.
Comment by atrettel 2 days ago
It is also a bit funny that the author complains about older Fortran programs requiring SCREAMING_CASE, when if anything this is an improvement over previous and current practices. Too many Fortran codes have overly terse variable names that often were just single characters or impenetrable abbreviations for obscure terms. I have had to create cheat sheets for each program to figure out what each variable was.
Sun Microsystems had a great quote about this back in the day [1]:
> Consistently separating words by spaces became a general custom about the tenth century A.D., and lasted until about 1957, when FORTRAN 77 abandoned the practice.
[1] https://docs.oracle.com/cd/E19957-01/802-2998/802-2998.pdf
Comment by Luminary099 2 days ago
Comment by adrian_b 1 day ago
The functions of Fortran are what would be called pure functions in C (which can be marked as such with compilers that support C language extensions, like gcc).
The pure functions cannot modify any of their arguments or any global variable, and they must be idempotent, which is important in program optimization.
Comment by pklausler 1 day ago
One can explicitly declare a function (or subroutine) to be PURE in Fortran, but it is not the default and never has been.
Comment by pklausler 2 days ago
Comment by atrettel 2 days ago
Comment by IAmBroom 2 days ago
Comment by adrian_b 1 day ago
This means that Fortran functions are functions in the mathematical sense. In most early programming languages "functions" were functions in the mathematical sense, while other kinds of subprograms were named procedures or subroutines. The use of the term "function" for any kind of procedure has been popularized mainly by the C language, even if there were earlier languages where all procedures could return a value and even where any program statement was an expression, starting with LISP.
Many C/C++ compilers, e.g. gcc, support language extensions allowing functions to be marked as pure. This is always recommended where applicable, for better program optimization.
This difference is much more important than the fact that subroutines do not return a value.
Many of the "functions" of C/C++ must be written as subroutines in Fortran, with an extra argument for the result, but because they modify some arguments or global variables, not because they were written as "void" functions in C/C++.
Comment by semi-extrinsic 2 days ago
Style wise, many prefer to reserve functions for things that resemble mathematical functions (i.e. only intent(in) and pure). In some sense a little bit similar to how people tend to use lambdas in python.
Comment by adrian_b 1 day ago
The programmer must only specify the behavior of the parameters, i.e. if they are input, output or input-output parameters, like in Ada.
The fact that a parameter is the result is just a matter of syntax, not of semantics. Any other output parameters should behave exactly like the result. This means that for any output parameter, like also for the result, the compiler must decide between receiving the output value in a register or passing an extra pointer on input that is the address of a memory area where the function must write the output value.
Comment by semi-extrinsic 9 hours ago
Giving the user low-level control of how memory is used can be very useful for writing fast code. The compiler is not omniscient. Providing the choice is not bad language design.
Comment by atrettel 2 days ago
Comment by adastra22 2 days ago
Comment by adrian_b 1 day ago
Fortran functions correspond to "pure" functions in C/C++ and other languages, i.e. idempotent functions that do not modify arguments or global variables.
If a C/C++ function is converted to Fortran, it must be rewritten as a subroutine, unless it is a pure function.
Not all C/C++ compilers support the language extension of marking functions as pure, and even with such compilers many programmers are lazy, so they forget to mark as pure the functions where this is applicable, even if this is recommended for improving program optimization and verification.
Fortran function were pure functions because this is the mathematical sense of the term "function". The extension of the meaning of the word "function" for any kind of procedure happened decades after the creation of Fortran.
The distinction between a "void" function and other functions has negligible importance. On the other hand the distinction between "functions" in the C language sense and "pure functions" is very important and programmers should better mark as "pure" all the functions for which this is true. This is at least as important for program optimization and for checking program correctness as declaring a variable with the correct type.
Comment by pklausler 1 day ago
This is nonsense. Fortran functions aren't pure. They can have side effects.
HPF/Fortran '95 added the PURE attribute for subprograms, but it's not the default.
Comment by pklausler 2 days ago
Comment by atrettel 1 day ago
Comment by whynotmaybe 2 days ago
Waitaminit, is that why we have "sub" in Visual Basic ?
Comment by dhosek 2 days ago
Comment by thatjoeoverthr 2 days ago
Comment by adzm 2 days ago
Comment by auraham 1 day ago
Comment by jolt42 2 days ago
Comment by jleyank 2 days ago
Comment by Neywiny 2 days ago
Comment by AdieuToLogic 2 days ago
The NUMERICAL RECIPES in Fortran 90 book[0]
The NUMERICAL RECIPES website[1]
0 - https://www.cambridge.org/us/universitypress/subjects/mathem...Comment by vatsachak 2 days ago
Comment by dhosek 2 days ago
Comment by 5555624 2 days ago
Comment by leephillips 2 days ago
Comment by stevenjgarner 2 days ago
Comment by gorfian_robot 2 days ago
Comment by dhosek 2 days ago
Comment by turing_complete 2 days ago
Comment by xhrpost 2 days ago
Comment by 9rx 2 days ago
FLOW-MATIC's claim to fame was beating Fortran at releasing a working implementation (and having syntax that looked like English, but that's not something to be proud of). Plankalkül, however, has not yet been implemented so if we're only counting releases of working software, it isn't a contender.
Comment by Hizonner 2 days ago
Comment by rahen 2 days ago
I recently learned Fortran IV to build a backpropagated neural network for the IBM 1130 (1965) and was amazed to see it compile with no warning on both the punched card compiler from IBM and on a modern Fortran compiler (gfortran).
Some Fortran II conventions, like the arithmetic IF, are now deprecated, but --std=legacy is all it takes to make it work.
Comment by AdieuToLogic 2 days ago
Comment by ginko 2 days ago
Comment by IAmBroom 2 days ago
Edit: and just three paragraphs in, the author admits they didn't even bother using the oldest version of FORTRAN itself.
So, "oldest" means "rather early".
Comment by riskassessment 2 days ago
Comment by klez 2 days ago
* Nothing wrong with that as a reason, of course
Comment by rramadass 2 days ago
Fortran in Modern Scientific Computing: An Unexpected Comeback - https://medium.com/@stack1/fortran-in-modern-scientific-comp...
5 Reasons Why Fortran is Still Used - https://www.matecdev.com/posts/why-fortran-still-used.html
Is Fortran better than Python for teaching the basics of numerical linear algebra? - https://loiseaujc.github.io/posts/blog-title/fortran_vs_pyth...
I take back everything i said about FORTRAN - https://x.com/ThePrimeagen/status/1745542049284423973
Modern Fortran online tutorial - https://wvuhpc.github.io/Modern-Fortran/
Comment by pklausler 2 days ago
The trickiest part of really learning Fortran today is that it is hard to define what the language is, apart from the practical definition imposed by what its seven or so surviving compilers accept and how they interpret it. There are near-universally portable features that are not part of the ISO standard; there are standard features that are not at all portable, or not available at all anywhere. So what one should know as “Fortran” is its reasonably portable intersection of features across multiple compilers, and there isn’t a good practical book that will teach you that.
Comment by conformist 2 days ago
Comment by AdieuToLogic 2 days ago
0 - https://docs.open-mpi.org/en/main/developers/bindings.html#f...
Comment by adastra22 2 days ago
Comment by RyanOD 2 days ago
Comment by fortranfiend 2 days ago
Comment by sdsd 2 days ago
Comment by aj7 2 days ago
Comment by dizzant 2 days ago
Pretty much sums up this one. Can't say that I agree if/select/stop are "modern" features.
Comment by timonoko 1 day ago
Comment by tarjei_huse 2 days ago
Comment by silverfrost 2 days ago
Comment by fortran77 2 days ago
Comment by vzaliva 2 days ago
Comment by drivers99 2 days ago
> Next time, we’ll talk more about...
Alas, there was no next time.
Comment by fithisux 2 days ago
Comment by self_awareness 2 days ago