Scientific Computing

USB-serial adapters on Windows / WSL

Windows natively or with Windows Subsystem for Linux supports USB-serial devices. The device must be recognized in Windows Device Manager.

Plug the USB-serial adapter into the Windows PC. Look in Windows Device Manager under Ports to see the COM port number. See troubleshooting notes below if it doesn’t show there.

The device must show in Windows Device Manager → USB Devices → Ports.

The serial device baud rate must be consistent between device and PC. If the baud rate is incorrect, either no text or garbled text will be seen.

Connect to serial devices using PuTTY or use WSL.

Windows Subsystem for Linux USB-serial

Command line screen or PuTTY can be used in WSL.

Configure USB-serial adapters in WSL by adding the WSL username to “dialout” group:

adduser $(whoami) dialout

If so, try in WSL terminal, (assuming device is on COM 5 for this example):

chmod 666 /dev/ttyS5

The usbipd program can help debug and connect devices in Windows and WSL.

Troubleshooting

The COM port number can change upon plugging in the same device, especially if replugging into a different physical USB port on the PC. If plugging in a different unit of the same type of device, it may likely also get a new COM port number. Distinct devices of the same model, even if sequentially plugged into the same USB port may get different COM port numbers.

If the device doesn’t show up in Device Manager → Ports, see if it was mistakenly enabled as a Mouse or Human Interface Device. If so, unplug and replug your device.

If it still fails to show up as a Port, instead showing up as mouse or HID, try right-clicking and Disabling the device and unplug/plug it once more.

If it still fails, maybe the Windows device driver is missing. Try the device in a native Linux PC and see if the device works there.

USB-serial with PuTTY

PuTTY is a terminal emulator that also works well for serial port connections.

PuTTY is available on Linux like:

apt install putty

macOS PuTTY install

On macOS, PuTTY is obtained by:

brew install putty

If PuTTY doesn’t link on macOS due to “pterm” name conflict, create an alias by finding the putty binary using macOS Homebrew findutils that makes the command “gfind” in place of “find”.

gfind $(brew --prefix) -name putty -type f

Create a shell alias based on gfind results like:

alias putty="/opt/homebrew/Cellar/putty/<version>>/bin/putty"

Windows PuTTY install

On Windows, putty can be installed with winget:

winget install PuTTY.PuTTY

PuTTY connection

Start PuTTY in Terminal command line or from the Windows Start Menu.

putty

which opens the PuTTY GUI.

Select the serial line (say /dev/ttyUSB0 for Linux, COM5 for Windows) and baud rate (say 115200).

PuTTY serial config

PuTTY main load screen

USB-serial screen program

The screen terminal multiplexer program is useful for connecting to serial port devices.

On Linux, including WSL:

apt install screen

configure USB-serial adapters in Linux or WSL by adding the username to “dialout” group:

adduser $(whoami) dialout

On Homebrew:

brew install screen

A serial port connection is established at 115200 baud like:

screen /dev/ttyUSB0 115200

Matlab Gfortran stream redirect

Matlab redirects the I/O streams of binaries compiled with GFortran by setting runtime environment variables for stdout, stderr, and stdin. This can lead to unexpected behavior of programs run from Matlab with built-in functions like system() as well as external language interfaces run from Matlab scripts like Java ProcessBuilder, Python subprocess, etc.

Disable I/O stream capture before the external process is started in the Matlab script:

outold = getenv("GFORTRAN_STDOUT_UNIT");
setenv("GFORTRAN_STDOUT_UNIT", "6");

errold = getenv("GFORTRAN_STDERR_UNIT");
setenv("GFORTRAN_STDERR_UNIT", "0");

inold = getenv("GFORTRAN_STDIN_UNIT");
setenv("GFORTRAN_STDIN_UNIT", "5");

After the process is finished, restore the original values:

setenv("GFORTRAN_STDOUT_UNIT", outold);
setenv("GFORTRAN_STDERR_UNIT", errold);
setenv("GFORTRAN_STDIN_UNIT", inold);

Runtime environment variables affect GCC programs including C and C++ programs.

Check website redirect header

If given a link that is suspect, or troubleshooting behavior of a website that is having trouble doing a redirect, check the HTTP header for a redirect. Curl does this with the –head option.

curl --head example.invalid

This will return the HTTP header, which will show if there is a redirect, and where it is redirecting to.

HTTP/2 301
...
Location: https://www.example.invalid

Some web servers behave differently to a HEAD request than a GET request. To see the behavior of a GET request, use the –location option to follow redirects.

curl --location --silent --dump-header - -o /dev/null example.invalid
--silent
suppresses the progress bar
--dump-header -
dumps the header to standard out
-o /dev/null
discards the body

Raspberry Pi Pico Linux

The RISC-V based Raspberry Pi Pico microcontroller is commonly used for analog and digital control, optionally with WiFi or Bluetooth wireless connectivity. While the full Raspberry Pi boards have a general purpose ARM CPU with enough storage and RAM capable of being used as a PC, the Pico is not commonly used for general purpose computing.

The multi-core CPU of the Pi Pico is capable of running parallel multi-threaded programs. The Pico Cortex-M or RISC-V Hazard3 CPUs lacks a memory management unit (MMU). Without an MMU, the Pico is not so effective at running a preemptive multitasking OS like a full Linux distribution. However, it is possible to run a minimal Linux kernel and user space. Provided a Pico board with enough memory, it’s possible to run a minimal Linux distribution on the Pico. The analog and digital I/O pins can be used for VGA output from the Pico.

Jetson Nano with newer OS

The Jetson Nano board has gone through several generations. Older Jetson Nano boards may be stuck on an older unsupported OS. If compatible with the specific Nano version hardware, the NVIDIA Jetpack SDK may be used to install a newer OS. Select a Jetson container suitable for the desired task and hardware.

Intel CPU ISA level detection

Operating systems require a certain minimum ISA microarchitecture level to run for each CPU vendor family. The levels are arbitrarily defined by the vendor as a collection of features, for example AVX2 or AVX512.

A C++-based cpuid library can detect across operating systems if the Intel CPU supports a certain ISA level.

Run macOS Terminal command with Rosetta

On macOS, Terminal commands can be specified to run with Rosetta using the arch command. This is useful for running or testing x86_64 software on Apple Silicon Macs. See “man arch” for more details.

arch -x86_64 <command>

For example to run cmake with Rosetta:

arch -x86_64 cmake -B build

The CMake variable CMAKE_SYSTEM_PROCESSOR or simply

arch -x86_64 uname -m

can be used to check the architecture of the current process.

Fortran submodule file naming

A Fortran submodule may be defined in the same file or a different file than the Fortran module that uses the submodule. Meta-build systems such as CMake and Meson are aware that each Fortran compiler has distinct Fortran submodule naming conventions. Fortran module and submodule interface files are like generated header files.

The order of the commands for each compiler is significant and handled by the meta build system. The Fortran module must be built before the Fortran submodule to generate the necessary module interface files BEFORE compiling the submodule. Each compiler creates corresponding basic.o and basic_sub.o object files.

  1. gfortran -c basic.90 creates object and module files: basic.o demo.mod demo.smod
  2. gfortran -c basic_sub.f90 -o basic_sub.o creates object and submodule files: basic_sub.o demo@hi.smod
  3. gfortran basic.o basic_sub.o -o basic creates executable basic

“module” are the files generated by step #1, building the file containing the Fortran module. “submodule” are the files generated by step #2, building the containing the Fortran submodule.

Compiler module files submodule files
GCC gfortran demo.mod demo.smod demo@hi.smod
LLVM flang demo.mod demo-hi.mod
Nvidia HPC nvfortran demo.mod demo-hi.mod
Intel ifx demo.mod demo@hi.smod
IBM xlf demo.mod demo_hi.smod
Cray ftn < 19.0 DEMO.mod HI.mod
Cray ftn ≥ 19.0 DEMO.mod DEMO.HI.mod

GCC Gfortran module and submodule naming convention is defined in module.cc by definintions “MODULE_EXTENSION” and “SUBMODULE_EXTENSION”. LLVM Flang module and submodule naming convention is defined in Semantics.

Example program

The table above is derived from the two-file example program:

file basic.f90

module demo
real, parameter :: pi = 4.*atan(1.)
real :: tau

interface
  module subroutine hello(pi,tau)
    real, intent(in) :: pi
    real, intent(out) :: tau
  end subroutine hello
end interface
contains
end module demo

program sm
use demo
call hello(pi, tau)
print *,'pi=',pi, 'tau=', tau
end program

file basic_sub.f90

submodule (demo) hi
contains
module procedure hello
  tau = 2*pi
end procedure hello
end submodule hi

Related: