Scientific Computing

Homebrew GCC version select

Homebrew can select GCC versions (and versions of other Homebrew formulae) like:

brew install gcc@15

Then create a file like “~/gcc-15.sh” with the following content:

v=15
prefix=$(brew --prefix gcc@$v)/bin

export CC=$prefix/gcc-$v CXX=$prefix/g++-$v FC=$prefix/gfortran-$v

Activate the GCC version in this shell session by running:

source ~/gcc-15.sh

If there is still trouble, try modifying SDKROOT to find a compatible SDK for the selected Homebrew GCC version.

Using an older version of Homebrew-distributed library or program could be useful to workaround bugs, or if one wants to still use their Intel CPU Mac hardware with Homebrew as GCC 16 isn’t supported by Homebrew on Intel CPUs on macOS for example. The Homebrew bottle binaries or source compile scripts must be available for the CPU architecture and OS version of the computer.

Shell scripts should avoid use of aliases

Do not use shell aliases in non-interactive shell scripts to stay shell-agnostic.

In Bash, aliases are not expanded in non-interactive shells unless the script first invokes

shopt -s expand_aliases

In Zsh, aliases are expanded in non-interactive scripts as well. However, while on macOS the default interactive shell is Zsh, non-interactive scripts with the usual #!/bin/sh shebang run Apple’s Bash in POSIX mode instead of Zsh.

List the aliases defined in the current shell (Linux, macOS, BSD) with:

alias

Our practice is to avoid aliases in non-interactive scripts and use explicit paths or functions instead. For example, to pin a user-specified GCC for CMake, pass the compiler paths directly:

#!/bin/sh

prefix="$HOME/.local/bin"
gcc_version=17
CC="$prefix/gcc-$gcc_version"
CXX="$prefix/g++-$gcc_version"
FC="$prefix/gfortran-$gcc_version"

cmake -B build -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_Fortran_COMPILER=$FC

cmake --build build

Windows PowerShell

Although the preceding discussion is for Unix-like systems, Windows PowerShell can also use aliases and has similar considerations for non-interactive scripts.

To list the aliases defined in the current PowerShell session:

Get-Alias

An analogous script for non-interactive PowerShell scripts would be like:

$prefix = "$HOME/.local/bin"
$gcc_version = 17
$CC = "$prefix/gcc-$gcc_version"
$CXX = "$prefix/g++-$gcc_version"
$FC = "$prefix/gfortran-$gcc_version"

cmake -B build -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_Fortran_COMPILER=$FC

cmake --build build

List comments/annotations in PDF

Adobe Reader can export and view a list of comments through the Comment tab on the right side. To do this from a command line program (for example to feed AI analysis / training) consider a Python script using the high performance PyMuPDF (fitz) library:

import fitz
import sys

file = sys.argv[1]

doc = fitz.open(file)

for i, page in enumerate(doc, start=1):
    for a in page.annots() or []:
        info: dict = a.info

        print(
            f"page {i}  {a.type[1]}  "
            f"author={info.get('title')!r}  "
            f"text={info.get('content')!r}"
        )

        # for highlights, get the actual selected words:
        if a.type[1] in ("Highlight", "Underline", "StrikeOut", "Squiggly"):
            print("  quoted:", page.get_textbox(a.rect))

Print PDF from any Linux program

On Linux, the CUPS PDF program saves printed PDFs to the ~/PDF directory from any program.

apt install printer-driver-cups-pdf
# or
dnf install cups-pdf

# then
systemctl restart cups

Verify a PDF printer is visible:

lpstat -p -d

The PDF output directory can be configured by editing the “Out” directory in /etc/cups/cups-pdf.conf

Higher quality PDF might be obtained by using the PDF print options in the specific program, if available.

LibreOffice PDF Conversion

Alternatively, LibreOffice can print compatible documents to PDF directly from the command line in headless mode like:

soffice --headless --convert-to pdf file.docx

Libreoffice can be installed like

apt install libreoffice-common

Related: convert image stack to PDF

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.

LLVM Flang

The LLVM Flang .mod files generated are legal Fortran syntax – they are text files. The .mod format gives the version number, which may be seen like:

head -n1 <moduleName>.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

Examine Gfortran .mod file header like:

gunzip -c <moduleName>.mod | head -n1

The output starts like:

GFORTRAN module version ‘15’ created from …

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 -An -N4 -d <moduleName>.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”.

There is an undocumented “ifx” compiler option -switch:fe_module_dump that outputs the module and submodule data in text format.

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 from LLVMFlang Fortran module files.

The .mod file is a text file, beginning with the version number.

head -n1 <moduleName>.mod

The output is like:

V34 :0x24 dummy

Cray Fortran

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

head -n2 <moduleName>.mod

Related: Fortran submodule file naming

Homebrew EOL Intel CPU support

At WWDC25 on June 9 2025, Apple announced that macOS 27 would no longer support Intel CPUs.

In August 2025, Homebrew announced under Future macOS Support that by the end of summer 2026, Intel CPU Macs would no longer receive binary “bottles” and would be deprioritized to Tier 3 in general. Homebrew Tier 3 status implications includes:

  • Homebrew may work, but with a poor and unstable experience
  • Migration to a Tier 1 or 2 configuration or to a non-Homebrew tool is strongly recommended

Homebrew is not distributing binary “bottles” for Intel CPU Mac hardware. This means that commands “brew upgrade” or “brew install” may take a long time (hours) as packages are compiled from source - or may even fail.

To temporarily keep an Intel CPU Mac functional with Homebrew, one can try to use older versions of Homebrew formulae that still support Intel CPUs, or compile packages from source manually. For example, GCC 15 can be used to maintain compatibility with Intel CPU Macs.

Fortran compiler max line length options

The Fortran 202x standard raises the individual Fortran source code line limit to 10000 characters. The new limits also include unlimited continuation lines and a maximum statement length of one million characters. These are stated as “hard limits”. As has historically been the case, many compilers continue to allow going beyond the line limit in a line or beyond even ten million characters in a statement. LLVMFlang is explicitly designed without a particular character limit per line.

Fortran standard source code line length limit
202x 10000
90 132
77 72

Compiler differences in default maximum source code line length can lead to portability issues. For example, Linux workstations or Linux HPC may default to a GCC Gfortran older than version 14 that has a default Fortran source code line length maximum of 132 characters, which is too short for say generated source code containing a data path on a networked HPC drive.

It’s important to be cognizant of the maximum Fortran line length across compilers as developer laptops often default to a recent Flang or Gfortran that both have effectively unlimited line length.

The maximum line length we experienced with no options follows, as determined experimentally with our Fortran maximum line length test program.

Git file mode permissions

In certain situations, there can be nuisance Git dirty repo messages like:

old mode 100755
new mode 100644

The root cause of this false dirty Git status is loss of fidelity of the executable file mode bit. This can occur in situations including:

  • Using WSL Git on a native Windows filesystem or vice versa
  • Linux HPC where files are shared between users

Workaround this ambiguous executable filemode bit for each Git client by executing within the Git repository:

git config core.filemode false

Extracting raw images from PDF

Use Poppler Utils to extract the original high-resolution images from the PDF. Poppler Utils are command line tools and part of the Poppler library.

This method generally yields much better quality images than screenshots of the PDF pages. The “pdfimages” command exports raster images, and “pdftocairo” exports vector graphics.

In these examples, “in.pdf” is the original PDF file.

Export raster PDF images

List all PDF images using pdfimages

pdfimages -list in.pdf

Extract PDF images from all pages, dumping all images in mydoc.pdf to the same directory. Filenames start with out-. There might be a lot of images.

pdfimages -all in.pdf out

Extract PDF images from specific pages: example is for page 3 only:

pdfimages -all -f 3 -l 3 in.pdf out
-f
first page to extract
-l
last page to extract

Export vector PDF images

Export vector PDF page(s) to SVG format using pdftocairo. Here we assume page 3 of the PDF has the vector images of interest.

pdftocairo -svg -f 3 -l 3 in.pdf out.svg

Use an SVG editor like Inkscape to isolate the image from the rest of the pages.

Install Poppler Utils

  • Linux: apt install poppler-utils
  • macOS / Linux (Homebrew): brew install poppler
  • Windows: use WSL poppler

Related: extracting a page(s) from PDF

PDF extract or combine pages

The free Poppler library includes command line tools that can easily extract pages from a PDF file, or combine pages from multiple PDF files into one PDF file. To do so with Adobe Acrobat or FoxIt generally requires a paid license, but Poppler is a free open-source library.

Extracting page(s) from a PDF into a series of separate PDF files is done with pdfseparate. For example, extract pages 2 to 4 from “in.pdf” to files “out-2.pdf”, “out-3.pdf” and “out-4.pdf” using Poppler:

pdfseparate -f 2 -l 4 in.pdf out-%d.pdf

Combining multiple PDF files into one PDF file is done with pdfunite. For example, combine “in1.pdf”, “in2.pdf” and “in3.pdf” into “out.pdf” using Poppler:

pdfunite in-1.pdf in-2.pdf in-3.pdf out.pdf

Poppler is installed by:

  • Linux: apt install poppler-utils
  • macOS: brew install poppler
  • Windows: use WSL poppler

Related: extract raw full-quality images from PDF