Scientific Computing

Fortran module file format

The Fortran standard does not define a specific Fortran module file format. Each compiler vendor has a unique incompatible Fortran module file format. Fortran module files are not portable between different compilers or even different versions of the same compiler.

The per-compiler examples below assume Fortran source file “example.f90”:

module dummy

real, parameter :: pi = 4*atan(1.0)

contains

real function tau()
  tau = 2*pi
end function tau

end module dummy

Flang-new (LLVM)

The flang-f18 or flang-new LLVM Fortran .mod files generated are legal Fortran syntax – they are text files. The .mod format gives the version number.

Build:

gfortran -c example.f90

This generates Fortran module file “dummy.mod” and object file “example.o”.

Get the .mod file header:

head -n1 dummy.mod

The output starts like:

!mod$ v1

GNU Fortran (GFortran)

The GFortran header version is defined in module.cc as variable “MOD_VERSION”. GNU Fortran “gfortran” .mod files are GZIP and is not documented

GCC version module file version
15.x 16
8.x - 14.x 15
5.1.0 14
4.9.2 12
4.8.1 10
4.7.1 9

Build a Fortran module source file like:

gfortran -c example.f90

This generates Fortran module file “dummy.mod” and object file “example.o”.

Extract the .mod file header like:

gunzip -c dummy.mod | head -n1

The output starts like:

GFORTRAN module version ‘15’ created from …

If you get:

gzip: not in gzip format

the .mod file is probably from another compiler vendor e.g. Intel oneAPI.

Intel oneAPI (ifx)

Intel oneAPI .mod files are a proprietary binary format. It is possible to determine the version of the .mod file by using od to look at the first 2 bytes of the .mod file.

od -N4 -d dummy.mod

The first number is like “13” and is the module format version. This version may change over time as oneAPI internals change. The second number is the update version, which is fixed at “1”.

NVHPC and AOCC

NVIDIA HPC SDK (NVHPC) and AOCC compilers generate .mod files that are text files. The format for legacy Flang module files is distinct than flang-new Fortran module files.

Create the .mod file like:

nvfortran -c example.f90

# or

flang -c example.f90

generates a text file, beginning with the version number.

head -n1 dummy.mod

the output is like:

V34 :0x24 dummy

Cray Fortran

By default, Cray Fortran stores uppercase DUMMY.mod filenames. This can be made lowercase witht the ftn -ef flag. The Cray Fortran .mod format is proprietary, but the version number might be seen like:

ftn -c example.f90

head -n2 DUMMY.mod

Related: Fortran submodule file naming

Matlab Name=Value function arguments

Matlab function arguments since R2021a can use name-value pairs. GNU Octave already supported this syntax. This is a convenient way to pass optional parameters to functions. The syntax is:

myfun(Name1=Value1, Name2=Value2, ...)

where Name1, Name2, … are the names of the parameters and Value1, Value2, … are the corresponding values.

The previous syntax for optional parameters is still supported:

myfun("Name1", Value1, "Name2", Value2, ...)

Pacman check space disable

The Pacman package manager by default says “checking available disk space” before installing or upgrading packages. This can take an excessively long time (especially on Windows with MSYS2) when a large number of packages are being installed or upgraded. To disable this behavior, edit the /etc/pacman.conf file and find and comment out:

#CheckSpace

CTCSS / DCS coded squelch selection

In general for narrowband FM two-way PTT radio systems including amateur radio, FRS, GMRS, MURS and CB radio, using CTCSS / DCS is a means to allow a group or subgroup to communicate while not bothering others on a different squelch code. Coded squelch has the side effects of slightly reducing communication range and adding a slight delay to unmuting audio at the beginning of a transmission while the receivers decode the squelch code.

Coded squelch does NOT make communications private, as anyone without coded squelch can hear the audio–the subaudible tone is added to the voice audio, but does not scramble the audio.

Unless there is a specific need, users should generally use CTCSS to avoid unmuting delays and range loss that are noticeably worse with DCS. DCS is for crowded areas where range loss isn’t important, and where the user wants to avoid CTCSS interference from other users. By default use CTCSS unless you are really having a problem with not enough tones to pick from. DCS is a last resort.

Historically, lower frequency CTCSS tones had a longer unmute delay, but modern radios minimize this impact. Avoid tones that are near harmonics of the AC mains frequency in the area (50 Hz or 60 Hz typically).

In particular, CB Radio use among family groups and convoys is dramatically improved by using CTCSS to avoid interference from other users and “skip” on the 27 MHz band from users hundreds or thousands of miles away. CTCSS also avoids nuisance opening of squelch from power lines, computers, etc.

Particular to CB radio, the receiver may have an RF gain control that can be used to reduce the sensitivity of the receiver to avoid interference from strong signals. With CTCSS, one might leave the RF Gain on “auto” or maximum (“off” on Anytone family of radios) and use auto noise squelch “ASQ” to maximum communication range while protected from noise by coded squelch.

Sub-$100 CB radios that have CTCSS include the Radioddity CB-500 and the Radioddity CS-27. Anyone buying CB radio for family, group, or convoy use should strongly consider a CB radio with CTCSS.

Reference: very detailed history of subaudible squelch by Repeater Builder.

Matlab buildfile MEX

Matlab buildtool has become a capable build system for tasks including MEX targets and tests with incremental progress, which avoids the need rerun already completed tasks. A standalone buildtool example illustrates the basic use of Matlab buildtool.

Run the build and test tasks:

buildtool mex

buildtool test

See several additional examples of more advanced Mex and Matlab Engine tasks. Matlab-stdlib is another substantial example of buildfile.m usage.

Quote CMake JSON arguments

The CMake string(JSON) subcommands should have the “json-string” input variable quoted to avoid CMake interpreting any semicolon in the JSON string as a list separator. This avoids CMake string(JSON ...) failures when the JSON string contains semicolons.

string sub-command JSON failed parsing json string:
  Syntax error: value, object or array expected.

Example

Suppose a JSON string contains one or more values with semicolons in any value. In that case, the JSON string should be quoted to avoid the CMake string(JSON ...) failure.

set(json_string "{ \"key1\": 432, \"key2\": \"I like to write; my blog is about tech. \" }")

# Fails with a syntax error
string(JSON a GET ${json_string} key1)

# works as expeccted
string(JSON a GET "${json_string}" key1)

Related: CMake JSON array iteration

GitHub API with CMake

CMake can use the GitHub REST API to fetch the latest release download URL from GitHub in the form of JSON data. The API is useful to download the latest release of a GitHub project using CMake. The API used in this example specifically ignore pre-releases and draft releases. The example CMake code shows how to parse the JSON data to get the download URL.

CMake file(DOWNLOAD …) has HTTPHEADER option that can be repeated to add multiple headers to the HTTP request. In GitHubRelease.cmake linked above, a specific version of the GitHub API and format is used to get the latest release download URL. Authentication parameters can also be passed if API limits are exceeded. Don’t save/commit API credentials to a public repository!

file(DOWNLOAD ...
HTTPHEADER "Accept: application/vnd.github+json"
HTTPHEADER "X-GitHub-Api-Version: 2022-11-28"
)

MATLAB GCC version compatibility fix

Matlab requires compatible compilers to run compiled code and even to run itself. Trying to use Matlab on a non-supported just-released OS version can sometimes encounter difficulty. libc, libstdc++, or libgfortran incompatible with Matlab and cause failure to run MEX code. The workaround below assumes Linux.

Example error messages:

MATLAB/R*/sys/os/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found (myfun.mexa64)

Workaround by having the system libraries take priority by using environment variable LD_PRELOAD.

Find the system libstdc++:

find /usr -name libstdc++.so.6

Suppose “/usr/lib64/libstdc++.so.6”.

LD_PRELOAD=/usr/lib64/libstdc++.so.6 matlab

C / C++ include inline code file

In certain cases, such as defining multiple classes or templates in a single header or source file in C or C++, it may be useful to include inline source code files to reduce code duplication. This can be achieved by using the #include directive with a file containing the inline code. This technique is distinct from the use of header files, which are typically used to declare functions, classes, and other entities that are defined in a separate source file. This technique is also distinct from the use of the inline specifier on functions.

A traditional file suffix for include code files is .inc or .inl, but any suffix can be used. Build systems detect changes to these included inline code files and rebuild the source file if necessary. For example, CMake detects include dependencies (header, inline code) based on its own source parser, or some modern compilers manage dependencies themselves.

Makefiles with CMake uses the compiler itself or depend.make in each target build directory to track dependencies.

Ninja (with CMake or other build system such as Meson) specifies include dependencies via depfiles per source file, which may be observed for debugging with option ninja -d keepdepfile

Example

Here we assume a CMake project with source file main.cpp and inline source file myconst.inl.

main.cpp:

#include <iostream>
#include "myconst.inl"

int main() {
    std::cout << "The value of MY_CONST is: " << MY_CONST << std::endl;
    return 0;
}

myconst.inl:

constexpr int MY_CONST 42
cmake_minimum_required(VERSION 3.20)

project(InlineDemo LANGUAGES C CXX)

add_executable(demo main.cpp)

Observe that CMake will rebuild main.cpp if myconst.inl changes.

cmake -Bbuild
cmake --build build

touch myconst.inl

cmake --build build