Scientific Computing

CMake include-what-you-use (IWYU)

Include-what-you-use IWYU is a static analysis tool that helps find missing and unused #include statements in C / C++ source files. Like any tool, IWYU makes mistakes, so make changes incrementally and be ready to rollback edits. CMake has IWYU support that is enabled in project CMakeLists.txt by including this stanza BEFORE any targets are defined:

option(iwyu "Run include-what-you-use")
if(iwyu)
  find_program(IWYU_EXE NAMES include-what-you-use REQUIRED)
  set(CMAKE_C_INCLUDE_WHAT_YOU_USE ${IWYU_EXE})
  set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_EXE})
endif()

Upon building the project, CMake will run IWYU on all source files. IWYU emits messages as each source file is built, if there are any issues. IWYU does not emit messages by default when there are no issues.

Troubleshooting

Ensure that IWYU is working by deliberately including an unused header. For example, on MSYS2 sometimes IWYU never emits messages with CMake.

Matplotlib / Matlab label tick at min / max value

For numerical plots, it can be important to label the ticks of axes extrema (minimum or maximum). For example, to clearly show the edges of simulated data axes. This can be easily done in Python Matplotlib or in Matlab. This assumes the typical case that the axes values are numeric.

In this example, the y-axis ticks show the endpoints of the y-data range: -3.375 and 27.0.

The data are in general non-monotonic, so we sort ticks before resetting them.

Python: Matplotlib does not require sorting the ticks.

from matplotlib.pyplot import figure, show
import numpy as np

# synthetic data
x = np.arange(-1.5, 3.25, 0.25)
y = x**3

fg = figure()
ax = fg.gca()
ax.plot(x, y)

# label min and max ticks
yticks = np.append(ax.get_yticks(), [y.min(), y.max()])
ax.set_yticks(yticks)

show()

Matlab: requires sorting the ticks before resetting them.

% synthetic data
x = -1.5:0.25:3.0;
y = x.^3;

fg = figure;
ax = axes(fg);
plot(ax, x, y)

% label min and max ticks
yticks = sort([ax.YTick, min(y), max(y)]);
ax.YTick = yticks;

Install Qt in RHEL for CMake GUI

Qt GUI can be installed in RHEL-like Linux from the CRB repository.

dnf config-manager --set-enabled crb

dnf install qt6-devel

Qt can be used to build cmake-gui like:

# from CMake source directory
cmake -Bbuild -DBUILD_QtDialog=ON

cmake --build build

This results in “build/bin/cmake-gui” being built.

Matplotlib / Matlab log axis plots

In Python Matplotlib or Matlab, making a plot with log-scaled (instead of default linear-scaled) axes can use the functions like “loglog()”, “semilogx()”, or “semilogy()”. Here we show the more general object-oriented syntax for each of a 2-D line “plot()” and 2-D pseudocolor “pcolor()” and then set the axes scale properties.

We arbitrarily use log abscissa scale and linear ordinate scale, but the same syntax applies to other combinations.

Python

2-D line plot:

import numpy as np
from matplotlib.pyplot import figure, show

x = np.logspace(0, 10, 100)
y = np.log(x)**2

fg = figure()
ax = fg.gca()

ax.plot(x, y)
ax.set_xscale('log')

ax.set_xlabel('x')
ax.set_ylabel('y')

show()

pseudocolor pcolormesh(): observe the stretching of the ticks along the y-axis. In some cases it’s helpful to set the axis limits manually to avoid whitespace past the last data point.

import numpy as np
from matplotlib.pyplot import figure, show

d = np.random.rand(10, 10)
x = np.linspace(1, 10, d.shape[0])
y = np.logspace(0, 1, d.shape[1])

fg = figure()
ax = fg.gca()

ax.pcolormesh(x, y, d)
ax.set_yscale('log')
ax.set_ylim(y[0], y[-1])

ax.set_xlabel('x')
ax.set_ylabel('y')

show()

Matlab

2-D line plot:

x = logspace(0, 10, 100);
y = log(x).^2;

fg = figure();
ax = axes(fg);

plot(ax, x, y);
ax.XScale = 'log';

xlabel(ax, 'x');
ylabel(ax, 'y');

pseudocolor pcolor(): observe the stretching of the ticks along the y-axis. In some cases it’s helpful to set the axis limits manually to avoid whitespace past the last data point.

d = rand(10, 10);
x = linspace(1, 10, size(d, 1));
y = logspace(0, 1, size(d, 2));

fg = figure();
ax = axes(fg);

pcolor(ax, x, y, d);
ax.YScale = 'log';

xlabel(ax, 'x');
ylabel(ax, 'y');

Troubleshooting DNS problems

If one suspects a website has been compromised, don’t use a standard web browser to access the site as there could be zero-day malware on the site. Consider Terminal programs that don’t have JavaScript enabled like curl or lynx if necessary to browse the site, preferably from a VM or other isolated computing resource. These programs are also not immune from security vulnerabilities.

DNSViz helps visualize the DNS chain. Keep in mind DNS and nameserver updates can take minutes to hours to propagate.

macOS:

dscacheutil -q host -a name host.invalid

Linux / macOS / WSL:

dig +trace host.invalid

If the DNS entries seem valid, consider that the web hosting server (that sends the HTML files to browser) may be compromised.

Compile Matlab .m code executable

Matlab Compiler compiles existing .m Matlab script to run as an executable on another PC without Matlab. Matlab Compiler Runtime MCR is used on computers that don’t have Matlab to run the compiled Matlab code.

Caveats:

  • Matlab Compiler does not in general speedup Matlab code execution
  • in general, compiled binaries might be disassembled to reverse-engineer the underlying code
  • MCR version on each computer running the executable must match the Matlab version of the compiling Matlab, and the compiling computer must have the same operating system as the MCR running computers.

Compiling computer: ensure Matlab Compiler is installed:

assert(license('test', 'compiler') == 1)

Example program “mymcc.m”:

function Y = mymcc()

X = 0:0.01:2*3.14;
Y = sin(X);
plot(X,Y)
title('Test of MCR')
xlabel('x')
ylabel('y')
disp('I ran an MCR program!')

end

Compile “.m” file in Matlab:

mcc -m -v mymcc.m

Run compiled Matlab program:

./run_mymcc.sh mymcc

I ran an MCR program!

and show a Matlab plot window showing a sine wave. Close the plot window to end the execution of your program.


Notes:

Reference

GNU Octave does not currently have the ability to compile “.m” files. Octave mkoctfile is to distribute C / C++ code that calls Octave functions–and ABI-compatible Octave must be installed on the user computers

Using Intel oneAPI and MKL with CMake

There can be substantial speed boosts from Intel compilers with Intel CPUs. Intel oneAPI gives advanced debuggers and performance measurements. Intel oneMKL can give a significant speed boost to ABI-compatible compilers for certain math operations.

For Windows, use the oneAPI Command Prompt. Otherwise, specify environment variables CC, CXX, FC to indicate desired compilers via script:

Build with CMake:

cmake -B build

cmake --build build

Example CMakeLists.txt

To see the compiler commands CMake is issuing, use

cmake --build build -v

Refer to Intel Link Advisor for supported compiler / operating system / MKL combinations.


Get runtime confirmation that MKL is being used via MKL_VERBOSE.

  • Linux:

    MKL_VERBOSE=1 ./mytest
  • Windows

    set MKL_VERBOSE=1
    mytest.exe

That gives verbose text output upon use of MKL functions. That runtime option does slow down MKL performance, so normally we don’t use it.

Apple Silicon virtual machines

Native virtualization has a “guest” OS with the same CPU architecture as the “host” physical CPU. Non-native emulation generally runs slower than native virtualization. Non-native virtualization means a host computer (such as Apple Silicon) can emulate any supported CPU architecture. Apple Silicon is ARM64, but with virtualization such as UTM / QEMU the Apple Silicon CPU can emulate ARM32, x86_64, MIPS, RISC-V, PowerPC, and more within the container.

QEMU emulator is available on Homebrew for Apple Silicon and can emulate a different CPU architecture or run native architecture at nearly full performance. UTM is a containerized emulation based off of QEMU for iOS and macOS–like QEMU, the same CPU architecture is virtualized at near full performance, while non-native virtualization is emulated with slower performance. When creating a new virtual machine in UTM, the first questions include whether the VM will be virtualized (native) or emulated (non-native) and the CPU architecture. UTM works with native virtualized Windows 11 for ARM, Linux, and emulates many architectures, even old PowerPC macOS guest images.

VirtualBox is an open-source native virtualization application that generally targets x86_64 CPUs. VirtualBox “Developer Preview” for Apple Silicon is available from the Nightly Builds as “macOS/ARM64 BETA”. The Oracle developer notes that the VirtualBox Apple Silicon beta is not yet ready for production use.


Commercial paid Apple Silicon virtualization: these native virtualization applications are not open-source. They run native virtual machines on Apple Silicon including Windows 11 ARM.

  • Parallels is paid-only software
  • VMWare Fusion is paid software, but has a no-cost personal-use license for home users.

GUI viewers for HDF5 / NetCDF4 data

HDF5 is a popular data container format, a filesystem within a file. Many programs supporting HDF5 like Matlab can read and plot data. It is useful to have a standalone simple data browser like HDFview.

HDFview from the HDF Group can read HDF5, NetCDF4, and FITS. HDFview enables editing (writing) as well as reading HDF5. One can simply download the HDFview binaries, or use package managers:

  • Linux: apt install hdfview
  • macOS: brew install hdfview

ViTables is a Python-based HDF5 GUI.


The Java-based PanoplyJ is available for macOS, Linux and Windows.