Scientific Computing

Boost install on Windows

The Boost library brings useful features to C++ that are not yet in STL. For example, the C++17 filesystem library was in Boost for several years before becoming part of the C++ standard.

The Boost install requires several hundred megabytes in general. macOS Homebrew and Linux users can install from a package manager.

On Windows, installing Boost from the Boost binary distribution takes a lengthy build procedure. Most developers using GCC or Clang on Windows can instead simply install MSYS2 Boost.

Software executable dry run

Developers covering multiple platforms and archs can benefit from including a self-contained dry run. We define a software dry run as a fast self-contained run of the executable, exercising most or all of the program using actual input files. The concept of dry run is used by popular programs that rely on several components and connections including rsync.

A dry run self-check can be used from Python or any other script calling the executable to ensure the binary is compatible with the current platform environment. The dry run helps mitigate confusing error messages by checking that the executable runs on the platform before making a large program run.

The dry run can catch platform-specific issues like:

  • incompatible executable format (running a executable built for another platform)
  • executable built for incompatible arch (using CPU feature not available on this platform)
  • shared / dynamic library run-time search path issues

The dry run does not output any files besides temporary files. For example, in a simulation, the dry run might run one complete time step. To test file I/O, optionally write temporary file(s) using the same file format. An advanced dry run might read in those temporary files and do a basic sanity check.

A dry run is distinct from an integration test. A dry run of the program just checks that the platform environment is OK to run with this binary. The dry run checks simply that the code executes without crashing. The dry run does not emphasize deep checks of program output as an integration test would. Consider making the dry run return code be 0 for compatibility with CMake and other high level build systems.

Implement a check of the dry run with CMake:

project(Demo LANGUAGES C)
enable_testing()

add_executable(main main.c)

add_test(NAME check COMMAND main -dryrun <other command line flags>)
set_property(TEST check PROPERTY PASS_REGULAR_EXPRESSION "OK: myprogram")

PASS_REGULAR_EXPRESSION to verify the special dry run text you put in the executable code. The dry run test normally returns code zero, but PASS_REGULAR_EXPRESSION ignore the executable return code.

Python f2py install problem workaround

f2py works with legacy Fortran 77 code, but generally does not work with modern Fortran code. Projects should carefully consider alternative approaches to f2py, such as a command-line + file interface with Python.

If experiencing compiler errors when using f2py, a last resort workaround is finding another computer that the install works on, of the same operating system. This can work on Windows or Linux from a computer of the same operating system and compiler ABI.

On the “donor” working computer:

python -m build

This creates mypkg/dist/mypkg-x.y.z-cp3x-cp3xm-win_amd64.whl (similar for other OS). This can only be used on Python 3.x (as per the filename) and the same CPU architecture.

python -m pip install -e .

This creates mypkg/src/mypkgy/fortranmodule.cp3x-win_amd64.pyd

Recipient computer: both of those files are copied from the “donor” computer to the “recipient” computer. The *.pyd file is placed or soft-linked to the Python current working directory. The *.whl file is one-time installed by:

python -m pip install mypkg-x.y.z-cp3x-cp3xm-win_amd64.whl

Access Windows Subsystem for Linux files

It is possible to safely access the WSL filesystem from Windows. For WSL2, the WSL distro need not be running first to access the files within. WSL2 will automatically start the requested filesystem Linux image and the 9P file server in less than a second upon attempting to access the WSL2 image filesystem.

The WSL distro files are available from Windows under:

\\wsl$\

and

\\wsl.localhost\

To keep things simpler, we still keep files that need to be accessed from WSL and Windows under the usual Windows file system, making softlinks in WSL as useful.

For example, code in Windows under $Env:UserProfile/code is accessed from WSL by one-time:

ln -s /mnt/c/users/username/code ~

Related: mount external drives in WSL

N1MM Logger on Linux

N1MM Logger is popular amateur radio contest logging software designed for Windows. It may also be usable on Linux using WINE.

Caveats: This procedure requires some expertise with using WINE and may not work easily. It’s much easier to just run N1MM Logger on Windows, perhaps in a virtual machine.

Given the rapid development of N1MM, this unsupported procedure may break at any time. This N1MM logger on Linux was tested using Ubuntu with WINE 4.0 (WINE 3.x is fine too), winetricks 20181203, winecfg set to Windows 7 32-bit

Install procedure:

Setup a 32-bit Windows 7 WINE environment with .NET 4.0, then install the N1MM logger.

Set WINE to Windows 7 under

WINEPREFIX=~/.wine_n1mm WINEARCH=win32 winecfg

This implicitly creates a new 32-bit Wineprefix.

Install .NET 4.0 in WINE 32-bit. It takes about 3-5 minutes, and at a couple points in the install, the progress bar seems to freeze, but the console text keeps scrolling. Note that .NET newer than 4.0 might not work for N1MM (thanks Harry Bloomberg for noting this).

WINEPREFIX=~/.wine_n1mm winetricks dotnet40

Download and run N1MM Full Install

WINEPREFIX=~/.wine_n1mm wine N1MM*FullInstaller*.exe

Download and run N1MM latest update

WINEPREFIX=~/.wine_n1mm wine N1MM*Update*.exe

Start and configure N1MM Logger as per the directions for your particular contest, the binary is at:

WINEPREFIX=~/.wine_n1mm wine '/home/thin/.wine_n1mm/drive_c/Program Files/N1MM Logger+/N1MMLogger.net.exe'

Create a script ~/n1mm.sh containing:

#!/bin/sh

WINEPREFIX=~/.wine_n1mm wine '/home/thin/.wine_n1mm/drive_c/Program Files/N1MM Logger+/N1MMLogger.net.exe'

then

chmod +x ~/n1mm.sh

Run N1MM Logger by simply typing in Terminal:

~/n1mm.sh

Radio control: N1MM can OPTIONALLY interface with your radio to pull out the frequency/mode for the log. You’ll need to map the WINE serial port and then select that COM port in N1MM Logger.

Look for the USB ↔ serial adapter before/after plugin with:

dmesg -w

Start the WINE registry editor:

WINEPREFIX=~/.wine_n1mm wine regedit

Configure the port. Say your device is seen at /dev/ttyUSB0, and you want it to appear to WINE on COM1. Edit HKEY_LOCAL_MACHINE/Software/Wine/Ports to have a new string entry named COM1 with value /dev/ttyUSB0.

Restart WINE:

wineserver -k

then reopen N1MM logger wit the script you created in the installation:

~/n1mm.sh

Verify this setting (but do not edit) by:

ls ~/.wine_n1mm/dosdevices/com1

there should be: com1 -> /dev/ttyUSB0

Note: Harry Bloomberg notes that you may be able to specify the specific long device name under /dev/serial instead of /dev/ttyUSB0. This may help avoiding the USB device changing port numbers when plugging / unplugging the USB device.


Alternatives: Currently, ReactOS 0.4.10 is not able to install N1MM logger. The N1MM Logger install hangs at:

Downloading RGB9RAST_x86.msi

Advanced use: Phil Erickson of MIT Haystack noted that for certain SDRs that use hamlib, you may be able to rewire the output of N1MM into hamlib via socat.

Check website links with Python

This small Python-based Markdown link-checking script is effective for large (thousands of pages, tens of thousands of links) Markdown-based websites/ It is immensely faster than the legacy HTML LinkChecker program of the next section. Alternatives exist for Go and JavaScript.

If using Netlify, consider a link-checking plugin that checks tens of thousands of links for each “git push” of the website Markdown in about two minutes.

The PyPI releases are out of date so instead of the usual

pip install linkchecker

we recommend using the development Linkchecker code

git clone --depth 1 https://github.com/linkchecker/linkchecker/

cd linkchecker

python -m pip install -e .

Internal/external links are tested recursively. This example is for a Jekyll website running on laptop:

linkchecker --check-extern localhost:4000

The checking process takes several minutes, perhaps even 20-30 minutes, depending on your website size (number of pages & links). Pipe to a file as below if you want to save the result (recommended).


List options for recursion depth, format output and much more:

linkchecker -h

Save the output to a text file:

linkchecker --check-extern localhost:4000 &> check.log

monitor progress with:

tail -f check.log

Raspberry Pi vs. Beaglebone Black

Pi Model CPU RAM features
Zero ARMv6 512 MB LPDDR2 low power consumption, single-core CPU.
4 ARMv8 (A72) 1..8 GB LPDDR4 quad-core CPU, GPU, Bluetooth 5, 802.11ac, gigabit Ethernet, USB 3.0
3+ ARMv8 (A53) 1 GB LPDDR2 quad-core CPU, GPU, Bluetooth 4.2 / 802.11ac, gigabit Ethernet
2 ARMv8 (A53) 1 GB LPDDR2 no onboard wireless.
1 ARMv6 512 MB LPDDR2 high power consumption, single-core CPU.

The benchmarks for Raspberry Pi 2 and Raspberry Pi 3 show far faster performance than the Raspberry Pi 1 / Zero. Using the graphical desktop and 4 GB of RAM, the Raspberry Pi 4 is useful for modest desktop use. The new CPU-direct USB and Ethernet of the Raspberry Pi 4 brings drastically faster IO.

The Raspberry Pi Zero has an ARMv6 single core CPU but much lower idle power for battery-powered applications.

Beaglebone deterministic IO due to the PRU is a key advantage for certain applications. The Beaglebone DDR3L RAM, and ARMv7 CPU is nearly twice as powerful as the Raspberry Pi Zero, native Ethernet, onboard SSD (eMMC), better onboard I/O (for local sensors), etc. However, CPU or GPU demanding tasks should consider the latest Raspberry Pi or Intel NUC, etc. instead.

Fortran 2018 coarray quick start

Fortran coarrays are an abstract, higher-level construct than using MPI directly. Coarrays support multiple parallel processing libraries including MPI. The simpler Coarray syntax can make debugging easier in general. Gfortran, NAG, Intel oneAPI and Cray are among the compilers supporting Fortran 2018 coarray features so useful in high-performance computing.

Coarray Fortran as enabled in Fortran standard is available from multiple compilers. Compilers with built-in coarray support (not needing external libraries) include:

  • Intel ifx
  • NAG nagfor
  • Cray ftn

The OpenCoarrays library is popular for enabling coarray features in GFortran. Install Fortran OpenCoarrays library for Gfortran by:

Ubuntu / Debian / Raspberry Pi (packages names may vary by Linux distro version)

apt install gfortran libcoarrays-dev libcoarrays-openmpi-dev

macOS: using Homebrew

brew install gcc opencoarrays

When manually compiling, add -fcoarray=lib and -lcaf_mpi. For example:

gfortran -fcoarray=lib myfun.f90 -lcaf_mpi

When manually running use cafrun like:

cafrun -np 4 ./myprog

Intel Fortran standard support includes coarrays.

ifx -coarray

enables the coarray features.


OpenCoarrays includes CMake scripts. CMake itself can recognize generic coarray support with FindCoarray.cmake

An example top-level CMakeLists.txt using Fortran coarray contains:

find_package(Coarray REQUIRED)

add_executable(coarray_pi pi.f90)
target_compile_options(coarray_pi PRIVATE ${Coarray_COMPILE_OPTIONS})
target_link_libraries(coarray_pi ${Coarray_LIBRARIES})

add_test(NAME CoarrayPi
COMMAND ${Coarray_EXECUTABLE} ${Coarray_NUMPROC_FLAG} ${Coarray_MAX_NUMPROCS} ./coarray_pi)

Fortran coarray examples includes CMake for Fortran coarrays.


Avoid general use of GCC march native flag

The GCC -march=native flag can cause unexpected and difficult to diagnose error messages on certain CPU arches, including high end Intel Xeon CPUs. The compiler error messages generally don’t give any clues as to what the real problem may be. While there can be a small to significant performance benefit to using the GCC flags enabling special features in a CPU arch, we feel it’s important to provide software that “just works” by default, even if not completely optimized for a given CPU. The end users that care most about performance probably have already learned the appropriate flags for their CPU, and are willing to fiddle with the CPU arch flags to get the program running at optimum.

We generally have no problems using the GCC -mtune=native flag.

GCC CPU flags: GCC will show a neat list of which flags are enabled and disabled like:

gfortran -Q --help=target foo.f90

Or to just show the raw flags being used

gfortran -v foo.f90

Reference: Gentoo safe Cflags and GCC optimization. ARM benchmarks of -mtune and -march.