I just spotted that about a month or so ago, the netcdf-fortran Conda package from Conda Forge got a Windows build (there has been Linux and Mac versions for ages, but Windows had some issues): Netcdf Fortran :: Anaconda.org
This is, potentially, awesome. An easy way to install NetCDF Fortran on Windows!
However, after giving it a quick test, I stumbled across the age old issue of incompatible GFortran versions: cannot read module file netcdf.mod because it was created by a different version of GNU Fortran.
Correct me if Iām wrong, but this basically means that the only way to use this Conda package in the usual use netcdf way is to use the same version of GFortran as the Conda build used. Which from what I can tell is the old m2w64 version 5.3.
Iām always surprised that a standard transportable mod file format is not a higher priority when it comes to new Fortran features. Take it from someone who got stuck with the task of supporting multiple versions of MPI, HDF5, netCDF etc. just because of the mod file incompatability problem a transportable mod file format will solve a lot more problems for Fortran developers than a some of things that will sadly end up in Fortran 2023 and Fortran will be stuck with forever. For example, I refer everyone to @jacobwilliams (excellent) March 27, 2022 post on Degenerate Conic | The New Features of Fortran 202x and his comments about the new āmultiple subscriptā and using an integer array to specify rank and bounds. I am in total agreement with Jacob on these two new āfeaturesā. In 40 plus years of developing and modifying CFD and Finite element codes I have never seen a case where either of these two features would lead to a better code.
The question is whether it is possible for the Fortran Standards Committee to provide some basic standards for Fortranās .mod files to ensure compatibility, C/C++ uses text files as header files, and Fortranās .mod seems to be some kind of binary code, resulting in differences in .mod files in different historical versions of the same compiler, and .mod files between compilers from different vendors are not interoperable.
That program is a nice demo of the difference between sin() and sinpi(). However, I would not say that the first column is āwrongā. I would expect those numbers are the closest number to the exact value of sin(x) for those values of x. If they are, then they are not āwrongā, they are ārightā, and if the first column were all zeros, like the second column, then they would in fact be āwrongā.
Can you elaborate on these statements a little? If one considers 0.0_dp to be the mathematically exact resullt for both columns of numbers, then spacing(0.0_dp) is many orders of magnitude smaller than the values on the left from sin(x). My previous post explains why those values are what they are. Namely, x is a fp value near the mathematical vaue of PI. Whatever that value is (which of course depends on the floating point representation), the exact sin(x) value is nonzero. The slope of sin(x) is about -1 in that neighborhood, so whatever the difference is between the floating point value and the exact value will then result in an exact sin(x) value of that same magnitude. The values in the first column are presumably the correctly rounded values of those differences. There are other issues involved with range reduction, particularly for large values of the arguments, but I donāt think that is a central part of this issue regarding the difference between sin(x) and sinpi(x) and what the āexactā values should be for the two columns.
The other issue you mention is FE_INEXACT. I think that occurs for any floating point multiplication that involves rounding (i.e. where bits are lost in the representation of the result). There are some cases, such as when an operand is a power of 2, that do not involve rounding, but most multiplications do involve rounding. So in a complicated function like sin(x), some or all of the multiplications involved in the evaluation are going to raise that exception.
Could you elaborate how do you compute ULP in there? Iāve seen a couple formulas for it, but perhaps you have a different approach.
I am writing some code for computing non-elementary functions. I am also comparing the computed value with a higher precision one, but then the error checking has merely consisted in plotting the relative error and checking it is below 5e-8 (for floats; or at least, below 1e-7).
This sounds very sensible. Do we know if something like this has been proposed before? I canāt believe it hasnāt been, itās surely not just a handful of us that struggle with this .mod file incompatibility. What are the barriers? Iām guessing back compatibility is the main one.
My answer to a transportable mod file would be to base it on something like a markup language (XML or a derivative maybe). Compiler options could select between native or standard format for
output. Iām willing to allow the compiler vendors native format and a standard format to coexist just as long a there are options to read and write the standard format. You could view the standard format as something like using the COO sparse matrix format as a bridge for converting between other formats. The vendors could write their own translators to their native formats. There is probably a way to have some kind of encryption decryption capabilty for folks selling commercial libraries to protect their IP. As to why this hasnāt been done before, anything I say would be speculation.
The specific reasons may be familiar to some of the old Fortran users, Iām just a beginner, but I think thereās always a way to change, the key is who drives it? We donāt have to get to this point right away, maybe we can look for a unified interface mod file for Fortran for the next decade.
It is clearly fragmented at the moment, and the lack of intercommunication of .mod files is one of the reasons why some well-known libraries like MKL, IMSL, LAPACK, FFTW tend to use F77 style interfaces. HDF5 and NetCDF have compatibility risks because they use F90 module functions.
On Windows, I was able to use MSYS2-gfortran to call mklās F77 dynamic link library, but once mkl was F90-style and used module functionality, the .mod interface would not necessarily be parsed by MSYS2-gfortran.
Most Fortran compilers use .mod as the file suffix for the module files that they generate. Until recently, the Absoft compiler would attempt to read and use .mod files if they existed, rather than regenerate them in the course of compilation. There were times when it would attempt to read .mod files produced by Gfortran (which are plain text) and the ensuing behavior was entertaining. Thus, some provision will be needed to enable each compiler to distinguish between its own module files from other compilerās module files, unless there is complete compatibility of mod files across all compilers.
Maybe Iām missing something but Iām not asking for vendors to read other vendors formats. Iām asking for a standard format that everyone can read (and translate to their native format if so desired). Even then how hard would it be to add a string to a vendors current mod file (Iām guessing they all have a header block of some kind at the start of the file) that says what compiler produced the file.
Perhaps the more solvable problem is how to work with Conda Forge to get them to support more recent compilers? I too have these issues. I canāt use the ancient gfortran compilers because they donāt support the language features I use (or they have show stopping bugs). Also I need to be able to support the intel compiler. In some cases, there will be a conda package (e.g. HDF5) that has built in fortran bindings, but I canāt use it because it was compiled with gfortran. So Iām back to having to compile it myself on multiple platforms.
In a future where all Fortran libraries are FPM compatible, these issues may go away since it could be trivial to just compile everything you need very easily. Right now, itās still very chaotic and tedious (make files, cmake, scons, random build scripts, downloading and manually editing files from some random webpage, poor Windows support, etc.)
Agreed. On a similar note, I noticed when building a Conda package on Windows just now that you get a warning message thatā¦
WARNING:conda_build.windows:Using legacy MSVC compiler setup. This will be removed in conda-build 4.0. If this recipe does not use a compiler, this message is safe to ignore. Otherwise, use {{compiler('<language>')}} jinja2 in requirements/build.
ā¦if you use the MSYS2 GFortran (v5.3). If you do as they suggest and use {{ compiler('fortran') }}, I think you get an even more ancient version of classic Flang.
I hope we have some success getting more modern Fortran compilers onto Conda Forge before they enact that threat!
Even if .mod files were compatible across compilers, wouldnāt there still be a problem with object files? As far as I know there are no standard calling conventions for Fortran, and runtime library calls would also not be compatible.
I have a question about the netcdf-fortran installed by conda in windows. It shows the error of āundefined reference to `__netcdf_MOD_nf90_createāā and other ā_netcdf_MOD_nf90ā errors. I have set the -I"xxxx/include" and -L"xxxx/lib" -lnetcdff -lnetcdf.