Scientific Computing

Fortran contiguous variables

Fortran 2018 contiguous arrays are discussed in pp.139-145 of “Modern Fortran Explained: Incorporating Fortran 2018”. In general, operating on contiguous arrays is faster than non-contiguous arrays.

Contiguous variables happen by default, so unless using pointers or array striding, the variable is likely to be contiguous for simple Fortran code. Check contiguous status of a variable with is_contiguous intrinsic function.

A non-contiguous array actual argument into a contiguous subroutine dummy argument is made contiguous by copy-in, copy-out. This copy-in copy-out as needed is part of the Fortran 2008 and Fortran 2018 standard. GCC ≥ 9, Intel oneAPI, IBM Open XL Fortran, etc. work to Fortran 2008+ standard for contiguous dummy argument copy-in, copy-out for non-contiguous actual argument.

References: Fortran 2008 Contiguity

CMake with clang-tidy

CMake can use clang-tidy as a build option for a CMake project by adding a few parameters to CMakeLists.txt. It’s also possible to use clang-tidy without modifying CMakeLists.txt. Generate the file compile_commands.json used by clang-tidy. You don’t have to build the project as we are interested in checking and possibly fixing the C++ source code.

To install clang-tidy:

  • macOS: brew install llvm, then edit ~/.zshrc, adding the line alias clang-tidy=$(brew --prefix llvm)/bin/clang-tidy or similar
  • Linux: apt install clang-tidy or similar
cmake -Bbuild -DCMAKE_EXPORT_COMPILE_COMMANDS=on

Run clang-tidy. Specify options or use a file .clang-tidy, which is usually in the top directory of the project.

clang-tidy -p build/ <glob or files>

To fix the errors, add clang-tidy option --fix.

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