Scientific Computing

GitHub Actions per-job compiler

GitHub Actions workflows can use different compilers per job by writing the compiler name or path to environment files in each job. This is useful for programs and libraries that need distinct compiler versions. An example of this is Matlab, where each Matlab release has a range of compatible compilers.

  • Matlab R2021a, R2021b: GCC-8
  • Matlab R2022a and newer: GCC-10

Implement in GitHub Actions:

jobs:

  linux:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        release: [R2021b, R2024a, latest-including-prerelease]

    steps:

    - name: GCC-8 - Matlab < R2022a
      if: ${{ matrix.release < 'R2022a' && matrix.release != 'latest-including-prerelease' }}
      run: |
        echo "CC=gcc-8" >> $GITHUB_ENV
        echo "CXX=g++-8" >> $GITHUB_ENV
        echo "FC=gfortran-8" >> $GITHUB_ENV

    - name: GCC-10 - Matlab >= R2022a
      if: ${{ matrix.release >= 'R2022a' || matrix.release == 'latest-including-prerelease' }}
      run: |
        echo "CC=gcc-10" >> $GITHUB_ENV
        echo "CXX=g++-10" >> $GITHUB_ENV
        echo "FC=gfortran-10" >> $GITHUB_ENV

    - name: Install MATLAB
      uses: matlab-actions/setup-matlab
      with:
        release: ${{ matrix.release }}
        cache: true

Enable Windows battery time on hover

Battery time remaining estimates for computing devices can vary widely in accuracy. The estimates are based on assumptions about future behavior based on prior usage trends, from a mix of current and prior charge usage. Windows updates can disable battery time remaining, and devices may come from the factory with battery time estimates disabled.

Hovering over the battery icon on the Windows taskbar can show the estimated battery time remaining along with the percent battery charge. The estimated battery time remaining is the same shown under System / Power & Battery.

The usual precautions on modifying the Windows Registry apply–do a Windows System Recovery milestone first. These keys are under:

HKLM\SYSTEM\CurrentControlSet\Control\Power

Reboot after making these changes. It may take a minute or two after first reboot for the estaimted battery life to show up.

If these registry keys exist, set their value to 0. If they don’t exist, that’s fine too.

EnergyEstimationDisabled=0
UserBatteryDischargeEstimator=0

Create this DWORD32 value (if not existing) and set to 1

EnergyEstimationEnabled=1

Reference: forum

CMake JSON array iteration

JSON can hold several data types including arrays. This example iterates over a JSON array in CMake.

Suppose file “json.cmake” contains:

cmake_minimum_required(VERSION 3.19)

set(jarr "{
\"c\":[3,4,5]
}")

string(JSON L LENGTH "${jarr} ""c")
math(EXPR L "${L}-1")

string(JSON t TYPE "${jarr}" "c")
message(STATUS "type: ${t}")

foreach(i RANGE ${L})
  string(JSON v GET "${jarr}" "c" ${i})
  string(JSON t TYPE "${jarr}" "c" ${i})
  message(STATUS "c[${i}] = ${v}  ${t}")
endforeach()

This results in:

$ cmake -P json.cmake

-- type: ARRAY
-- c[0] = 3  NUMBER
-- c[1] = 4  NUMBER
-- c[2] = 5  NUMBER

Easy HDF5 / NetCDF4 / HDF4 Matlab interface

Using HDF5 / NetCDF4 / HDF4 from any language can be intimidating if directly using the low-level API. Interfaces have sprung up for popular languages that make HDF5 trivially easy to use, such as Python h5py.

The stdlib for Matlab provides functions making HDF5, NetCDF4, and HDF4 much easier to use in Matlab.

The “h5*” functions are for HDF5, “nc*” functions are for NetCDF4, and “h4*” functions are for HDF4. The functions are polymorphic, typecasting user data.

The h5*, nc*, and h4* functions work very similarly. For simplicity, we only show the h5* functions.

  • h5save() save a variable to a file
  • h5variables() list all the variable in a file
  • h5size() get the size (shape) of a variable in a file
  • h5exists() check if a variable exists in a file

C macro __CLASSIC_C__

The C macro __CLASSIC_C__ is defined when the compiler is in pre-ANSI (K&R) mode. This is a rather uncommon scenario. It might be used in retrocomputing with very old and unmaintained compilers such as the 1990s Bruce Evans’ C compiler (bcc).

#include <stdio.h>

int main() {

#if defined(__CLASSIC_C__)
  printf("K&R C\n");
#elif defined(__STDC__)
  printf("ANSI C\n");
#else
  printf("Unknown C\n");
#endif

return 0;
}

Reference: Compiler Macros wiki

Windows Command Prompt instant error on open

A botched program install, upgrade, or uninstall such as Anaconda Python can make a Windows registry mis-entry that causes many commands to fail. Simply trying to run “cmd.exe” COMSPEC instantly fails with:

& was unexpected at this time

or

Process exited with code 1

If this message occurs when just opening a new Command Prompt window, the problem may be in the Windows Registry. Check Registry Editor values:

HKCU\Software\Microsoft\Command Processor\AutoRun

and

HKLM\Software\Microsoft\Command Processor\AutoRun

Example 1

A system had a bad Autorun value:

if exist

This was corrected by emptying the Autorun value (or deleting the Autorun key).

Example 2

A system had a bad Autorun value:

if exist & if exist "%USERPROFILE%\miniconda3\condabin\conda_hook.bat" "%USERPROFILE%\miniconda3\condabin\conda_hook.bat"

It was fixed by correcting to:

if exist "%USERPROFILE%\miniconda3\condabin\conda_hook.bat" "%USERPROFILE%\miniconda3\condabin\conda_hook.bat"

C++ nodiscard attribute

C++17 and C23 added the [[nodiscard]] attribute to indicate that the result of a function call should not be ignored. Use care not to overspecify [[nodiscard]] on functions that are not intended to be used in a way that requires the result to be used, as this can make nuisance warnings.

Example: annotate function declaration in the header file with [[nodiscard]] attribute.

[[nodiscard]] int one();
int one() { return 1; }

GNU Data Language (GDL) GUI

GNU Data Language (GDL) can use GDLDE Workbench GUI for graphical development.

Download and install GDL.

The Windows installer includes GDLDE Workbench: gdlsetup-Windows-x86_64-standard.exe Simply install and look in Windows Start menu for “GDL Workbench”.

For macOS use gdl-macOS-x86_64-standard.dmg or build GDL from source.

For Ubuntu Linux:

apt install gnudatalanguage

Download and extract GDLDE for Linux.

Install JDK

Install JDK by:

  • Windows: winget install Microsoft.OpenJDK.21 (find exact version by winget search Microsoft.OpenJDK).
  • macOS: brew install openjdk
  • Linux: apt install default-jdk

Restart Terminal, ensure that echo $JAVA_HOME or PowerShell echo $env:JAVA_HOME is not empty.

Eliminate Python __pycache__ directories

Python can put all Python .pyc cache files under one system-wide directory by the PYTHONPYCACHEPREFIX environment variable.

  • Windows: set environment variable PYTHONPYCACHEPREFIX to %TEMP%
  • Linux: in ~/.profile add export PYTHONPYCACHEPREFIX=${TMPDIR}
  • macOS: in ~/.zshrc add export PYTHONPYCACHEPREFIX=${TMPDIR}

Pycache .pyc files can be set to NOT write anywhere with the PYTHONDONTWRITEBYTECODE environment variable.

  • Windows: set environment variable PYTHONDONTWRITEBYTECODE to 1
  • Linux: in ~/.profile add export PYTHONDONTWRITEBYTECODE=1
  • macOS: in ~/.zshrc add export PYTHONDONTWRITEBYTECODE=1