Scientific Computing

Matlab Gfortran stream redirect

Matlab grabs the stdout, stderr, stdin handles of a Gfortran program, even when using Java ProcessBuilder. Disable this capture to allow external languages like Java to capture the output. Just before the external process is started in the Matlab script:

outold = getenv("GFORTRAN_STDOUT_UNIT");
setenv("GFORTRAN_STDOUT_UNIT", "6");

errold = getenv("GFORTRAN_STDERR_UNIT");
setenv("GFORTRAN_STDERR_UNIT", "0");

inold = getenv("GFORTRAN_STDIN_UNIT");
setenv("GFORTRAN_STDIN_UNIT", "5");

After the process is finished, restore the original values:

setenv("GFORTRAN_STDOUT_UNIT", outold);
setenv("GFORTRAN_STDERR_UNIT", errold);
setenv("GFORTRAN_STDIN_UNIT", inold);

Check website redirect header

If given a link that is suspect, or troubleshooting behavior of a website that is having trouble doing a redirect, check the HTTP header for a redirect. Curl does this with the –head option.

curl --head example.invalid

This will return the HTTP header, which will show if there is a redirect, and where it is redirecting to.

HTTP/2 301
...
Location: https://www.example.invalid

Some web servers behave differently to a HEAD request than a GET request. To see the behavior of a GET request, use the –location option to follow redirects.

curl --location --silent --dump-header - -o /dev/null example.invalid
--silent
suppresses the progress bar
--dump-header -
dumps the header to standard out
-o /dev/null
discards the body

Raspberry Pi Pico Linux

The RISC-V based Raspberry Pi Pico microcontroller is commonly used for analog and digital control, optionally with WiFi or Bluetooth wireless connectivity. While the full Raspberry Pi boards have a general purpose ARM CPU with enough storage and RAM capable of being used as a PC, the Pico is not commonly used for general purpose computing.

The multi-core CPU of the Pi Pico is capable of running parallel multi-threaded programs. The Pico Cortex-M or RISC-V Hazard3 CPUs lacks a memory management unit (MMU). Without an MMU, the Pico is not so effective at running a preemptive multitasking OS like a full Linux distribution. However, it is possible to run a minimal Linux kernel and user space. Provided a Pico board with enough memory, it’s possible to run a minimal Linux distribution on the Pico. The analog and digital I/O pins can be used for VGA output from the Pico.

Jetson Nano with newer OS

The Jetson Nano board has gone through several generations. Older Jetson Nano boards may be stuck on an older unsupported OS. If compatible with the specific Nano version hardware, the NVIDIA Jetpack SDK may be used to install a newer OS. Select a Jetson container suitable for the desired task and hardware.

Intel CPU ISA level detection

Operating systems require a certain minimum ISA microarchitecture level to run for each CPU vendor family. The levels are arbitrarily defined by the vendor as a collection of features, for example AVX2 or AVX512.

A C++-based cpuid library can detect across operating systems if the Intel CPU supports a certain ISA level.

Run macOS Terminal command with Rosetta

On macOS, Terminal commands can be specified to run with Rosetta using the arch command. This is useful for running or testing x86_64 software on Apple Silicon Macs. See “man arch” for more details.

arch -x86_64 <command>

For example to run cmake with Rosetta:

arch -x86_64 cmake -B build

The CMake variable CMAKE_SYSTEM_PROCESSOR or simply

arch -x86_64 uname -m

can be used to check the architecture of the current process.

Fortran submodule file naming

A Fortran submodule may be defined in the same file or a different file than the Fortran module that uses the submodule. Meta-build systems such as CMake and Meson are aware that each Fortran compiler has distinct Fortran submodule naming conventions. Fortran module and submodule interface files are like generated header files.

The order of the commands for each compiler is significant and handled by the meta build system. The Fortran module must be built before the Fortran submodule to generate the necessary module interface files BEFORE compiling the submodule. Each compiler creates corresponding basic.o and basic_sub.o object files.

  1. gfortran -c basic.90 creates object and module files: “basic.o” “demo.mod” “demo.smod”
  2. gfortran -c basic_sub.f90 -o basic_sub.o creates object and submodule files: “basic_sub.o” “demo@hi.smod
  3. gfortran basic.o basic_sub.o -o basic creates executable “basic”

“module” are the files generated by step #1, building the file containing the Fortran module. “submodule” are the files generated by step #2, building the containing the Fortran submodule.

Compiler module files submodule files
GCC gfortran demo.mod demo.smod demo@hi.smod
LLVM flang demo.mod demo-hi.mod
Nvidia HPC nvfortran demo.mod demo-hi.mod
Intel ifx demo.mod demo@hi.smod
IBM xlf demo.mod demo_hi.smod
Cray ftn DEMO.mod HI.mod

GCC Gfortran module and submodule naming convention is defined in module.cc by definintions “MODULE_EXTENSION” and “SUBMODULE_EXTENSION”. LLVM Flang module and submodule naming convention is defined in Semantics.

Example program

The table above is derived from the two-file example program:

file basic.f90

module demo
real, parameter :: pi = 4.*atan(1.)
real :: tau

interface
  module subroutine hello(pi,tau)
    real, intent(in) :: pi
    real, intent(out) :: tau
  end subroutine hello
end interface
contains
end module demo

program sm
use demo
call hello(pi, tau)
print *,'pi=',pi, 'tau=', tau
end program

file basic_sub.f90

submodule (demo) hi
contains
module procedure hello
  tau = 2*pi
end procedure hello
end submodule hi

Related:

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