Scientific Computing

CMake sleep

CMake doesn’t have a “sleep” command, but sleep in floating point seconds is accomplished by:

execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 0.5)

This uses CMake command tool to sleep in a platform-indpeendent manner.

cmake -E sleep 0.5

The minimum practical time is about 0.1 seconds. Below that, the overhead of starting/stopping CMake starts to dominate elapsed time.

CMake profile configure

CMake can output JSON in google-trace format that can help understand what tasks a CMake project configuration is taking time on.

cmake -B build --profiling-output=perf.json --profiling-format=google-trace

View profiler data: type in web browser (Chrome or Edge) address bar “about:tracing” and Load “perf.json”.

Other google-trace viewers can also be used.

For example, in a minimal C++ project on a Windows computer:

cmake_minimum_required(VERSION 3.18)
project(b LANGUAGES CXX)

Approximate percent of CMake configure time spent:

  • system ID: 1%
  • Generator identify: 2%
  • Compiler identification: 50%
  • Compiler capabilities: 47%

CMake get current time

CMake can retrieve the current time in local (default), UTC, or other timezone via string(TIMESTAMP). Elapsed time can also readily be computed or compared using timestamp format %s

Currently, CMake math command cannot handle floating point numbers, only integers.

string(TIMESTAMP t)
message(STATUS "local time: ${t}")

string(TIMESTAMP t0 "%s")
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.0)
string(TIMESTAMP t1 "%s")

math(EXPR elapsed "${t1} - ${t0}")

message(STATUS "Elapsed time: ${elapsed} seconds")

Git GUI install

Git history browsing can be easier with a GUI, which are available for most platforms. Git installs can come with a GUI by default. However, many package managers make the GUI a separate install to save considerable time and space on cloud servers, virtual machines and similar. Here are a few example commands to install gitk, a basic Git history browser:

  • macOS: brew install git-gui
  • Linux: apt install gitk or dnf install gitk or similar
  • Windows: winget install Git.Git that comes with “gitk”

For those using GitHub, GitHub Desktop is a popular Git GUI.

GitHub Actions with CMake

The GitHub Actions CI runners have a recent release of CMake and update regularly, often within weeks of a new CMake release. There are Actions in the GitHub Marketplace allowing one to pick specific CMake versions for testing the build system if desired. CMake environment variables are handy to set in top level “env” to avoid forgetting to specify them.

Note that Windows compiler tests in general, including CMake, are often done with distinct setups. These are best shown by example using MSYS2 or MSVC.

name: ci

env:
  CTEST_NO_TESTS_ACTION: error
  CTEST_PARALLEL_LEVEL: 0
  CMAKE_BUILD_PARALLEL_LEVEL: 4
  HOMEBREW_NO_INSTALL_CLEANUP: 1

on:
  push:
    paths:
      - "**.c"
      - "**.cpp"
      - "**.h"
      - "**/CMakeLists.txt"
      - "**.cmake"
      - ".github/workflows/ci.yml"

jobs:

  core:

    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        shared: [true, false]

    runs-on: ${{ matrix.os }}

    steps:

   - uses: actions/checkout@v4

    - name: config shared=${{ matrix.shared }}
      run: >-
        cmake
        -Bbuild
        -DBUILD_SHARED_LIBS=${{ matrix.shared }}

    - name: build
      run: cmake --build build

    - name: test
      run: ctest --test-dir build -V

Fortran ieee_arithmetic NaN

The Fortran 2003 standard ieee_arithmetic intrinsic module gives a robust standard way to use NaN and other functions. However, on certain CPU arches such as PPC, GCC does not yet support ieee_arithmetic.

An example of robust NaN is given in nans.f90. A Fortran standard way to make NaN constant is:

use, intrinsic :: ieee_arithmetic, only: ieee_value, ieee_quiet_nan
implicit none

real:: nan

nan = ieee_value(0., ieee_quiet_nan)

Example NaN memory hex value–can be distinct on older/other compilers:

GCC 12.2.0; Intel oneAPI 2021, 2023
      IEEE   value   isnan                         hex
    real 32    NaN      T                          7FC00000
    real 64    NaN      T                  7FF8000000000000
    real128    NaN      T  7FFF8000000000000000000000000000
 complex 64    NaN      T                          7FC00000
 complex128    NaN      T                  7FF8000000000000
 complex256    NaN      T  7FFF8000000000000000000000000000

nvfortran 22.11 is same for real32/64

Detect if macOS app is Rosetta or Native

When using an Apple Silicon CPU, it’s usually desirable to run the native version of the app rather than the Rosetta translated version for efficiency. If the app is live media based such as Zoom, using the native app version reduces CPU usage and helps avoid latency and jittering in the audio and video.

Determine if an app is native, Universal, or other architecture (Rosetta translated) by going to Applications in Finder. Highlight the application name and press โŒ˜ I to see the “kind” of application. If the app is Universal, there will be a check box to force the app to run in Rosetta mode, which can be useful if an app has non-native plugins. Each application and its plugins must all be native or Rosetta.

CMake sanitize alphanumeric string

To ensure created path names are compatible across computing platforms, it is useful to sanitize strings in general so that only alphanumeric characters are used to avoid adverse or accidental use of confusable UTF8 characters. In CMake this is accomplished like:

set(sneaky "โฒฃ๐š๐—…๐‘ฆ paly")
string(MAKE_C_IDENTIFIER ${sneaky} c)

message(NOTICE ${c})
# notice first characters and space are all underscore