# Rewriting Fortran software in Rust

**URL:** <https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208>\
**Category:** Uncategorized\
**Created:** [July 15, 2020, 7:36pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208 "2020-07-15T19:36:05Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [July 15, 2020, 7:36pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/1 "2020-07-15T19:36:05Z")

</div>

> **[Rewriting FORTRAN Software In Rust | mckeogh.tech](https://mckeogh.tech/post/shallow-water/)**
>
> github.com/rse-standrewscs/shallow-water TL;DR: Rewriting isn’t always bad, Amdahl’s Law is important and memory bandwidth is a potential bottleneck when doing many simple double precision math operations
> Introduction As part of an Undergraduate...

Discussion on Hacker News: [https://news.ycombinator.com/item?id=23843434](https://news.ycombinator.com/item?id=23843434)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 15, 2020, 7:59pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/2 "2020-07-15T19:59:07Z")

</div>

Great idea, made it an issue for LFortran: [https://gitlab.com/lfortran/lfortran/-/issues/172](https://gitlab.com/lfortran/lfortran/-/issues/172).

My motivation to have these backends such as C++ is that people can translate Fortran code right away and don’t have to spend months doing it. And my expectation is that they will find that you actually might not gain much, and only get things slower (which might be the case above, where I think he didn’t use the state of the art Fortran compilers to compare performance). But if you do gain something, that would be the motivation for us to fix up Fortran to catch up. And if people spend months rewriting, maybe they don’t want to throw the work out and use the original Fortran. But if the translation can be done automatically and quickly, they might realize that they might as well stay in Fortran, because it’s better.

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [July 15, 2020, 8:08pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/3 "2020-07-15T20:08:04Z")

</div>

Plus, the translated code in target language is likely to be less readable and maintainable because it’s auto-generated.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 15, 2020, 9:19pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/4 "2020-07-15T21:19:54Z")

</div>

Regarding readability, I am hoping it could be readable, but it’s a bit too early to know for sure.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [July 15, 2020, 9:53pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/5 "2020-07-15T21:53:38Z")

</div>

There are some interesting points in the ensuing discussion on Hacker News.

Given that the author uses the capitalized FORTRAN, it seems to be an older code F77 style code. I wonder if some restructuring of the original Fortran code, or interfacing into specialized numerical libraries (MKL, FFTW) could have already provided the speed up needed.

Some profiling before the rewrite in Rust would have been helpful to see where is the bottleneck.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 16, 2020, 5:22am UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/7 "2020-07-16T05:22:12Z")

</div>

Steve, exactly. Many people don’t know that. This is something we would like to fix with fpm to make these options the default in Release mode.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [July 16, 2020, 8:12am UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/9 "2020-07-16T08:12:42Z")

</div>

> [@kargl](#):
>
> If it’s gfortran and you’re trying to get the fastest execution time (without regards to possible numerical accuracy) then one need to use at a minimum -O3 -funroll-loops -ffast-math -march=native -mtune=native

@kargl  
I have read in GCC doc that `-O3` implies `-floop-unroll-and-jam`:

> **[Optimize Options (Using the GNU Compiler Collection (GCC))](https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Optimize-Options.html)**
>
> Optimize Options (Using the GNU Compiler Collection (GCC))

> -floop-unroll-and-jam : Apply unroll and jam transformations on feasible loops. In a loop nest this unrolls the outer loop by some factor and fuses the resulting multiple inner loops. This flag is enabled by default at -O3. It is also enabled by -fprofile-use and -fauto-profile.

Does it imply `-funroll-loops` or is it something different ? And what is a “feasible loop” ?

There is also this option implied by `-O3`:

> `-fpeel-loops`: Peels loops for which there is enough information that they do not roll much (from profile feedback or static analysis). It also turns on complete loop peeling (i.e. complete removal of loops with small constant number of iterations).

---

<div class="post-metadata">

**Author:** ![tiziano.mueller](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/tiziano.mueller/32/12_2.png) [@tiziano.mueller](https://fortran-lang.discourse.group/u/tiziano.mueller)\
**Post date:** [July 16, 2020, 8:22am UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/10 "2020-07-16T08:22:17Z")

</div>

@kargl Something like `-ffast-math` should never be a default, as it can break things in very subtle ways (example: we used to build our toolchain with it, until someone realized that it broke (sca/)lapack). This also holds for some Intel FP optimization flags which seem to be active by default on certain optimization levels (look at the `-fp-model=...` options).  
Furthermore, `-march=native` implies `-mtune=native` afaik.

We had this whole optimization-by-compiler-flag discussion in Gentoo Linux 10+ years ago and it basically boiled down to `-O2 -march=native -pipe` being the only universally save and fast thing to do (for GCC), see also [https://wiki.gentoo.org/wiki/Safe\_CFLAGS](https://wiki.gentoo.org/wiki/Safe_CFLAGS) (unless of course a package was explicitly tested by upstream for more aggressive optimization flags).

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 16, 2020, 5:22pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/13 "2020-07-16T17:22:28Z")

</div>

@tiziano.mueller, What you wrote is true for code that you know nothing else about. But if you control the code you write, such as the authors of an fpm package, you know if your code works with say `-ffast-math` or not, and so if it does not, you could disable it in `fpm.toml`. The Intel Fortran compiler effectively has `-ffast-math` enabled by default also, as you noted.

The issue of good defaults is that most people do not know what options to enable for gfortran to get good performance out of it. I feel if we set the defaults to just `-O2 -march=native -pipe`, then that is what people will use and they will be missing on good performance.

A better approach I feel is to enable the defaults as something like `-O3 -march=native -funroll-loops -ffast-math` and then if your fpm package requires less aggressive optimizations, then you set it in `fpm.toml`. That way you ensure that your package works, and users still get good speed by default for their code.

P.S. I should mention that the `-ffast-math` is tricky — if a library uses it, it actually can mess up the main application even if it doesn’t use it, because the `-ffast-math` enables some hardware things like no denormal numbers. So it might be that if the dependents have `-ffast-math` off, we might need to turn it off for all dependencies. But fpm could do that.

---

<div class="post-metadata">

**Author:** ![tiziano.mueller](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/tiziano.mueller/32/12_2.png) [@tiziano.mueller](https://fortran-lang.discourse.group/u/tiziano.mueller)\
**Post date:** [July 16, 2020, 5:55pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/14 "2020-07-16T17:55:59Z")

</div>

@kargl in principle you can leave `-g` on for production as well since it should not have any performance implications. If you care about binary size, you can strip, split and compress the debug symbols afterwards (which is something the build system could do automatically) to have the best of both worlds.

@certik exactly, and the fpm doesn’t know anything about the codes internals by default. There is a good reason why the GCC devs do not enable it by default and encouraging speed over correctness doesn’t make any sense. The problem with `-ffast-math` is that it is hard to verify whether your code is working correctly (and with which gcc version and system/arch nonetheless). We had thousands of tests on a vast number of architectures and hosts for years with just a number of spurious errors from users and devs until someone was able to introduce a test to reproduce it properly. So, `-ffast-math` does not make a good default.  
`-O2` vs `-O3` as well as `-funroll-loops` are a different story. As the GCC manual still says: `may or may not make your code run faster`.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 16, 2020, 7:10pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/15 "2020-07-16T19:10:02Z")

</div>

@tiziano.mueller what would be a good design for `-ffast-math` and `fpm`? One way would be that each `fpm` package could indicate if it works with `-ffast-math` in `fpm.toml`, otherwise it is assumed that it does not. Then when I am building my application that I know works with `-ffast-math` (all my personal codes work with it) I can tell `fpm` to use it (as well as for dependencies, assuming all “allow” it). But by default `fpm` would not use it.

The issue with this approach is that people then forget to turn it on to speedup their codes (even if they worked with it).

---

<div class="post-metadata">

**Author:** ![tiziano.mueller](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/tiziano.mueller/32/12_2.png) [@tiziano.mueller](https://fortran-lang.discourse.group/u/tiziano.mueller)\
**Post date:** [July 22, 2020, 7:38am UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/16 "2020-07-22T07:38:59Z")

</div>

> [@certik](#):
>
> what would be a good design for `-ffast-math` and `fpm` ?

Human intelligence; either someone knows about the up- and downsides of enabling `-ffast-math` in numerical code and is capable of verifying that their code is working correctly under `-ffast-math` and then they can flag it as such, or they don’t.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 22, 2020, 4:40pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/17 "2020-07-22T16:40:31Z")

</div>

Yes, a human must decide whether a package can use `-ffast-math`.

But what I am asking is if you think the design for `fpm` that I suggested above would work, given everything we discussed.

---

<div class="post-metadata">

**Author:** ![tiziano.mueller](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/tiziano.mueller/32/12_2.png) [@tiziano.mueller](https://fortran-lang.discourse.group/u/tiziano.mueller)\
**Post date:** [July 22, 2020, 5:02pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/18 "2020-07-22T17:02:25Z")

</div>

😂 oh, I completely misread your previous message, I am sorry.

Yes, I think that this proposal should work. Given the high-level design of the FPM maybe call the option `enable_unsafe_optimizations` (or `enable_extra_optimizations` if you think it would be overly cautious) to enable the respective optimization for the used compiler. And then document the option with the hint that a developer of the package should test whether their package works with said options.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 22, 2020, 5:18pm UTC](https://fortran-lang.discourse.group/t/rewriting-fortran-software-in-rust/208/19 "2020-07-22T17:18:40Z")

</div>

No problem. 🙂 Thanks for the reply. Yes, it’s tricky how to call it, or what it even means in general — `-ffast-math` is enabling a bunch of unrelated options, for example arithmetic rearrangement, which is unsafe for certain codes such as the Kahan summation algorithm, but it is perfectly safe for other kinds of codes. One way to think about it could be via the Fortran standard — which allows a little more optimizations than C, but not many more actually (for example the Fortran standard does not allow an optimization that would break the Kahan summation), and so by “safe” we could mean those optimizations as permitted by the standard, and “unsafe” all others.
