Scientific Computing

CMake Zstd compression

Zstd is an open file compression standard. Zstd has become widely used and is incorporated in the Linux kernel and GCC. We use Zstd for data archiving particularly for large files where size and speed are a concern. CMake supports Zstd compression throughout, including file(ARCHIVE_CREATE) and file(ARCHIVE_EXTRACT). Zstd is vendored into CMake, so there is no need to worry about system shared libraries for Zstd.

file(ARCHIVE_CREATE ... WORKING_DIRECTORY ...) is necessary to avoid system-specific relative path issues.

set(archive "example.zst")
set(in_dir "data/")

file(ARCHIVE_CREATE
  OUTPUT ${archive}
  PATHS ${in_dir}
  COMPRESSION Zstd
  COMPRESSION_LEVEL 3
  WORKING_DIRECTORY ${in_dir}
  )
COMPRESSION_LEVEL
arbitrary, bigger value is more compressed.
FORMAT
not used for Zstd.

Wouxun KG-S72C antenna

The Wouxun KG-S72C is a modern CB radio with AM and FM capabilities, which are recommended for anyone buying a new CB radio. The KG-S72C has CTCSS and DCS coded squelch, which allows hearing only parties with the same subaudible code. Only a few other models of CB radio have this capability, so most users might only occasionally use coded squelch. An important point to note is that no one sells the KG-S72C factory antenna replacement, so be very careful not to lose or damage the factory antenna. Since the KG-S72C receives an SMA female antenna (the radio has SMA female connector), using long replacement antennas are mechanically fragile and could break the antenna jack.

The sound quality on receive and transmit is good, especially in FM mode as for most AM / FM CB radios.

Cons

The KG-S72C has a few cons, which are tolerable.

  1. Lack of RF gain control, which is a fundamental requirement for any CB radio to make listening tolerable in AM mode. Using the KG-S72C as a mobile radio with an appropriate SMA adapter to the mobile antenna coax is OK, but the lack of RF gain control can be fatiguing and is the second con.
  2. The squelch mode seems to be noise squelch only, which can be frustrating as it closes intermittently on loud AM modulation. It would benefit from a signal strength squelch as traditional CB radios use.

Captive portal public WiFi URLs

Public WiFi often has captive portal login. Portals may coerce users to accept terms and conditions and absolution of liability before accessing the Internet. The portals may be worked around by DNS tunneling, MAC spoofing, etc. Many users just tolerate the portals.

Web browsers may try to trigger captive portals by checking servers, in case the OS hasn’t already triggered the captive portal. Sometimes captive portals aren’t triggered. HSTS blocks HTTP captive portal redirects. Try visiting a deliberately non-HTTPS portal-triggering site like http://neverssl.com

Devices on networks that block the platform’s automatic network checking may indicate like:

Connected, no Internet

If there’s not a captive sign-in webpage, the network connection may still work to non-Google sites.

Check connectivity manually using curl like:

curl -w %{http_code} URL
Platform server HTTPS response code
Firefox detectportal.firefox.com/success.txt 200
Chromium clients3.google.com/generate_204 204
Windows www.msftconnecttest.com/connecttest.txt 200
macOS captive.apple.com/hotspot-detect.html 200
Android connectivitycheck.gstatic.com/generate_204 204
Ubuntu connectivity-check.ubuntu.com 204
Fedora fedoraproject.org/static/hotspot.txt 200

To disable connectivity checking in Ubuntu: Settings → Privacy → “Network Connectivity Checking”

Cobra 19 Ultra 6 CB radio

The Cobra 19 Ultra 6 appears to be a relabeled AnyTone Smart II. While previous Cobra 19 models had significant features missing, the Cobra 19 Ultra 6 has the necessary features to be a good choice in entry-level very compact CB radio.

From practical in-vehicle use, the speaker is adequately loud. Both AM and FM mode work well on transmit and receive. There is no “dual watch” channel capability, but this may not be a requirement for many users.

RF Gain is essential on any CB radio and the RF gain adjustment range of the Cobra 19 Ultra 6 is good. Typically RF gain between 24 and 39 is useful.

The radio appears to use audio compandoring, which helps improve apparent audio SNR. The radio has a traditional signal squelch as well as “auto” noise squelch. The general problem with noise squelch across CB radios is that overmodulated AM signals can close the squelch regardless of how strong the signal is.

Setting the RF Gain and Squelch on an AM CB radio is best done by opening the squelch – static is heard. Then set the RF Gain so that only very faint static is heard. Then set the signal squelch just closed.

Channel Scan

On firmware version 1.1, entering scan mode is different than the manual states. To enter channel scan, press and hold the microphone “up” or “down” button until the radio goes once through all 40 channels, then the radio beeps and release the button. The radio then scans all 40 channels repeatedly. Unfortunately, there does not appear to be a way to skip channels in scan mode. This means the radio will often stop on channels 6, 11, etc. with high power stations that may not be what the user wants to listen to.

Matlab read FITS image stacks

In Matlab, fitsread is used to read specific frame(s) from a FITS file. Read frames one at a time from a large multi-frame FITS file in MATLAB. This avoids overwhelming RAM or taking an excessive time to load just one or a few image frames from a FITS file.

Example: sequentially read and plot each frame of a 4096-frame FITS file, with each frame being 256 x 256 pixels.

for i = 1:4096
  currFrame = fitsread('myFile.fits', PixelRegion={[1 256],[1 256],i});
  imagesc(currFrame)
  pause(0.05)
end

GNU Octave FITS reading is done with the cfitsio package using a similar API.


Related: read FITS image stack in Python

Install AMD AOCC C C++ Fortran compiler

The no-cost AMD AOCC compiler is tuned for AMD CPUs, akin to how Intel oneAPI is tuned for Intel CPUs. For a RHEL-based Linux, install the downloaded “.rpm” file like:

dnf install ./aocc-compiler*.x86_64.rpm

Create a source script “~/aocc.sh” like:

root=/opt/AMD/aocc-compiler-5.0.0/

[[ ! -d ${root} ]] && echo "ERROR: ${root} not found" && exit 1

source ${root}/setenv_AOCC.sh

# setenv_AOCC doesn't set these
export CC=clang CXX=clang++ FC=flang

export CXXFLAGS=
export MPI_ROOT=

flang --version

To use the AOCC compiler:

source ~/aocc.sh

AOCL libraries

The AOCL libraries provide accelerated math functions for AMD CPUs for several popular libraries for use in C, C++, or Fortran. AOCL is compatible with AOCC and other compilers as listed in the AOCL downloads.

CMAKE_TLS_VERIFY global

TLS verification default is ON since CMake 3.31. Users can override this default for all projects with environment variable CMAKE_TLS_VERIFY. or per-project with CMake variable CMAKE_TLS_VERIFY. The default TLS version may be set by CMAKE_TLS_VERSION. If the system TLS certificate location needs to be specified, this can be done by CMAKE_TLS_CAINFO.

Meson build system uses TLS verification by default, warning if verification fails. TLS verification is part of CMake’s internal nightly testing.

The example uses badssl.com, that purposefully has a variety of certificate problem URLs.


Reference: Issues that would have been caught with this default

CMake dependency graph

CMake --graphviz and graphviz configure preset can generate GraphViz dependency graphs for CMake-supported project code languages including C, C++, and Fortran. Fortran executables and modules are shown in the directed dependency graph. Fortran submodule are not shown in the graph.

The “dot” GraphViz program converts the .dot files to PNG, SVG, etc. dot program is available by installing the “graphviz” program via the package manager.

Generating the dependency graph requires CMake configure and generate. Thus, the compiler and generator needed by the CMake project must be working. The project does not need to be compiled before generating the dependency graph. However, the user should select the same CMake configure options as they would for compiling the project.

Example: h5fortran HDF5 object-oriented Fortran dependency graph is below. SVG vector graphics can be zoomed arbitrarily large in a web browser. The “gfx/” directory is to avoid making files in the source directory.

cmake -B build --graphviz=gfx/block.dot

cd gfx

dot -Tpng -o block.png block.dot

dot -Tsvg -o block.svg block.dot

h5fortran dependency graph

The “dependers” files show only the nodes depending on a node.

Scripts and Viewing output

CMakeUtils graph.py converts a directory of CMake dot diagrams to SVG or PNG and collects them in an HTML document for easy viewing:

python cmakeutils/graph.py ~/myprog/gfx

To open a web browser from the Terminal:

python -m webbrowser -t file:///$HOME/myprog/gfx/index.html

Note that “file:///” has three slashes and the file path must be absolute.


Related: Dependency graphs are also easily created in Python and Matlab.

Find executable path in Python

The full path to executables on the system Path (and cwd on Windows) are discovered by Python shutil.which. On Windows, environment variable PATHEXT is used to search filename suffixes if not specified at the input to shutil.which().

Shell aliases are not found by shutil.which() since the shell is not invoked. Instead append the directory of the desired executable to environment variable PATH, or specify it in shutil.which(..., path="/path/to/exe").

import shutil

# None if executable not found
exe = shutil.which('ls')

Since shutil.which() returns None for non-found executable it is convenient for pytest.mark.skipif

For programs not on PATH where the executable path is known:

shutil.which('myexe', path="/path/to/myexe")

Install Gfortran or Flang compiler on macOS Homebrew

Homebrew can install Fortran compilers including GCC and LLVM Flang.

Gfortran

Gfortran comes with GCC Homebrew package:

brew install gcc

As a complete C / C++ / Fortran compiler package, Gfortran doesn’t require additional flags or environment variables.

To use GCC compilers, source a script like:

p=$(brew --prefix gcc)/bin
v=14

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

where v=14 is the major version number of the GCC compiler installed. It may be necessary to set SDKROOT if the compiler fails to find the C++ standard library headers like cstring, cstddef, etc.

LLVM Flang

LLVM Flang is a separate package from the LLVM C/C++ compilers:

brew install flang

To use Flang compiler (works with Clang, AppleClang, GCC C-C++ compilers), source a script like:

export FC=$(brew --prefix flang)/bin/flang-new

To use LLVM Clang with Flang, source a script like:

p=$(brew --prefix llvm)/bin
export CC=$p/clang CXX=$p/clang++

export FC=$(brew --prefix flang)/bin/flang-new

Troubleshooting

When a new compiler version or macOS version or Xcode SDK is released, it may be necessary to adjust the environment variables or flags temporarily until Homebrew updates the package.

Some examples to try if needed:

  • LIBRARY_PATH for libSystem.tbd and libc++.tbd

    export LIBRARY_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
  • LDFLAGS to the C++ standard library

    export LDFLAGS=-lc++

SDKROOT may also be needed.