Skip to content

HPC / CFD — Final Cheat Sheets

Print this and bring it (mentally) to the exam. One topic per page.


Linux Permissions

r=4  w=2  x=1
755 = rwxr-xr-x  (script)        644 = rw-r--r--  (text)
700 = rwx------  (private)       777 = rwxrwxrwx  (avoid!)
4xxx setuid  (s in user x)       /usr/bin/passwd → 4755
2xxx setgid  (s in group x)      project share → 2775
1xxx sticky  (t in other x)      /tmp → 1777
umask 022 → file 644, dir 755

chmod 755 file · chmod u+x file · chmod -R g+w dir/ · chown alice:students file


Redirection / Pipe

Op Action
> overwrite stdout
>> append stdout
< feed stdin
2> redirect stderr
2>&1 merge stderr → stdout
&> both → file (bash)
\| stdout → next stdin
<<EOF…EOF here-doc

Linux Filesystem

/ /home /etc /var /tmp /usr /sbin /opt /proc /dev /boot /root /lib


SSH

ssh -i ~/.ssh/key user@host
ssh-keygen -t ed25519 -b 4096 -f ~/.ssh/k
ssh-copy-id -i ~/.ssh/k.pub user@host

~/.ssh/config block:

Host hpc
    HostName cluster.example.com
    User myuser
    IdentityFile ~/.ssh/k

Permissions: ~/.ssh 700, keys 600, .pub 644, authorized_keys 600, config 600.

scp -r src host:dst · rsync -avzP --delete src/ host:/dst/ · sshfs h:/d ~/m · ssh -L 8888:host:8888 hpc (local fwd) · ssh -R reverse · ssh -D 1080 SOCKS · nohup ./run > log 2>&1 &; disown · tmux new -s sim · tmux a -t sim.

Encryption: symmetric (AES) one key fast; asymmetric (Ed25519, RSA) pub+priv slow. SSH does ECDH for key exchange + AES for session.


Vim

Mode Enter Exit
Normal (default)
Insert i a o I A O Esc
Visual v V Ctrl-v Esc
Cmd-line : Enter / Esc

Verbs: d c y > gU. Motions: w b e 0 $ gg G %. Text-objects: iw aw i" ip a{. - dd 5dd dw d$ delete - yy y2j p P yank/paste - u Ctrl-r . undo / redo / repeat - /pat n N * search - :%s/old/new/gc global replace - :%s/\<Re\>/Reynolds/g whole-word - qa…q @a 5@a macros; :reg a view - :e :sp :vsp :tabnew gt :ls buffers/windows/tabs - :argdo %s/x/y/ge \| update bulk

Macro from Vim Task 3: qa /[<Enter> v /]<Enter> d 0 /><Enter> p 0 q then @a.

Save: :wq (or ZZ). Discard: :q!.


Regex / Globbing

Glob: * any string · ? one char · [abc] class · [!abc] not · {a,b} brace expansion · ** recursive (globstar).

ls *.txt
ls dir-?/file.h
ls {dir-1,dir-2}/*.{cpp,h,txt}
ls dir-{1,3}/*[0-9].h
ls dir-3/*[A-Z]*.h

Regex (ERE): . any · * 0+ · + 1+ · ? 0/1 · {n,m} range · ^ start · $ end · [abc] class · [^abc] not · [[:alpha:]] POSIX class · \<word\> whole-word · () capture · \1 backref · \| alt (BRE) / | (ERE).

Lecture solutions:

\+[0-9]+ [0-9]{3}-[0-9]{3}-[0-9]{4}                            # phone
^[[:alnum:]_.]+@[[:alpha:]]+\.[[:alpha:]]{2,}$                 # email
^[^:]+:[^:]+:[^:]+:[1-9][0-9]{2,}:[^:]*:[^:]+:.*$              # /etc/passwd GID>=100
^[^:]+:[^:]+:[^:]+:[^:]+:[^:]*:\/home.+:.*$                    # home /home
^[^:]+:[^:]+:[^:]+:[^:]+:[^:]*:[^:]+:\/bin\/bash               # bash users


find / grep / sed / awk / column / diff

find . -type f -name "*.cpp" -size +1k -mtime -7
find . -regex './.*/[Ss]ource.+\.cpp$' -exec chmod +w {} \;

grep -EinrlA 2 -B 1 "pat" file
grep -lriE "TODO" --include='*.cpp' src/

sed -E -i.bak 's/^Re *= *[0-9]+/Re = 5000/' f
sed -n '/^ERROR/p' run.log
sed -E 's/([A-Za-z]+)_([A-Za-z]+)/\2_\1/'

awk -F, 'NR>1 && $4=="Eng" && $6>60000 {print $1,$2,$3}' f
awk 'BEGIN{FS=",";OFS="\t"} /Mark/ {print $1,$2,$3}' f
awk '{s+=$2} END{print s}' f
awk '{a[$1]++} END{for(k in a) print k,a[k]}' f

column -t -s ":" /etc/passwd > pretty.txt
diff -u a b

Bash Scripting

#!/bin/bash
set -euo pipefail

Vars: $1 $# $@ $* $? $$ $!. Always quote: "${VAR}".

Tests: - [ -f f ] [ -d d ] [ -e p ] [ -r/-w/-x f ] [ -s f ] - [[ "$x" =~ pat ]] (Bash regex) - (( a+b )) arithmetic - [ "$a" = "$b" ] string eq, -eq -ne -lt -le -gt -ge numeric

Control:

if [ ... ]; then ... elif [ ... ]; then ... else ... fi
case x in pat1) ...;; pat2) ...;; *) ...;; esac
for x in "${A[@]}"; do ... done
for ((i=0;i<n;++i)); do ... done
while [ ... ]; do ... done
until [ ... ]; do ... done

Arrays: A=(a b c); ${A[0]}; "${A[@]}"; ${#A[@]}; A+=(d).

Functions: fn(){ local x=$1; ...; return 0; }; fn 42; r=$?.

Capture: x=$(cmd).

getopts:

OPTSTRING=":a:b:v"
while getopts "$OPTSTRING" opt; do
    case "$opt" in
        a) ...$OPTARG ;;
        b) ...$OPTARG ;;
        v) VERBOSE=1 ;;
        :) echo "-$OPTARG needs arg"; exit 1 ;;
        ?) echo "invalid -$OPTARG"; exit 1 ;;
    esac
done
shift $((OPTIND-1))

Trap: trap 'rm -f $tmp' EXIT INT TERM.


Gnuplot

plot 'd' using 1:2 with linespoints lt 1 lw 2 pt 7 lc rgb "red" title 'X'
set title "..."; set xlabel "..."; set ylabel "..."
set xrange [0:12]; set yrange [-1:25]
set logscale y
set grid
set key right top box
set xtics 1; set mxtics 2
set style line 1 lt 1 lw 2 pt 7 ps 1.5 lc rgb "red"
set arrow from 4,0 to 4,8 head
set label "x" at 5,10
set datafile separator ","

plot sin(10*x) with lines

f(x)=a*x**2+b*x+c
fit f(x) 'd' using 1:2 via a,b,c
plot 'd' u 1:2 t 'data' w p, f(x) t 'fit' w l

plot 'd' using 1:2:3 with yerrorbars

set multiplot layout 2,2 title "..."
    plot 'a' u 1:2 w lp
    plot 'b' u 1:2 w lp
    plot 'c' u 1:2 w lp
    plot 'd' u 1:2 w lp
unset multiplot

set terminal png; set output 'x.png'; replot

Bash heredoc:

gnuplot <<EOF
set terminal png; set output 'x.png'
plot 'data' u 1:2 w l
EOF


Git

git config --global user.{name,email} ...
git init / clone url
git status
git add file / git add -p / git add .
git commit -m "Imperative msg"
git log --oneline --graph --all
git diff / git diff --staged / git diff HEAD

git switch -c feature/x   # branch + switch
git switch main
git merge feature/x       # combine
git branch -d feature/x   # delete

git remote add origin url
git push -u origin main
git pull --rebase

git restore file          # discard wd changes
git reset --soft HEAD~1   # uncommit, keep staged
git reset --hard HEAD~1   # discard everything
git revert <hash>         # add inverse commit

git stash / git stash pop
git tag -a v1.0 -m "..."
git push --tags
git cherry-pick <hash>

GitLab TU-BS: PAT (api/read/write) for HTTPS or SSH key.


C++ Basics

g++ -O2 -std=c++17 -Wall -fopenmp src.cpp -o exe

Types: int 4B, char 1B, float 4B, double 8B, bool 1B.

Pointer / reference / call-by:

int a=5;
int *p=&a;     // pointer
int& r=a;      // reference
*p=7;          // a=7
r=8;           // a=8

void byVal(int);
void byPtr(int*);
void byRef(int&);

Class:

class C {
private:
    int x;
public:
    C(int v):x(v){}
    int get() const { return x; }
    void set(int v) { x=v; }
};

Complex:

add  (a+bi)+(c+di) = (a+c) + (b+d)i
mul  (a+bi)*(c+di) = (ac-bd) + (ad+bc)i
mod  sqrt(a²+b²)


Build Process

Stages: .cpp →-E→ .i →-S→ .s →-c→ .o →link→ exe.

Header guard:

#ifndef X_H
#define X_H
...
#endif

Static lib: ar rcs libfoo.a *.o. Shared lib: g++ -fPIC -shared -o libfoo.so *.cpp. Link: g++ -L./lib -lfoo main.cpp. Run: LD_LIBRARY_PATH=./lib ./prog.

Make:

target: deps
<TAB>recipe
Auto-vars: $@ $< $^. .PHONY: clean. Variables CXX CXXFLAGS.

CMake:

cmake_minimum_required(VERSION 3.16)
project(P CXX)
set(CMAKE_CXX_STANDARD 17)
add_library(name SHARED src/a.cpp src/b.cpp)
target_include_directories(name PUBLIC include)
add_executable(main src/main.cpp)
target_link_libraries(main PRIVATE name)
Build: cmake -B build && cmake --build build -j.


Debugging

g++ -O0 -g prog.cpp -o prog
gdb ./prog
(gdb) break 8
(gdb) run
(gdb) next        # step over
(gdb) step        # step into
(gdb) print x
(gdb) print *arr@5
(gdb) watch i
(gdb) backtrace
(gdb) continue
(gdb) finish
(gdb) info locals
(gdb) quit
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./prog

Sanitizers: g++ -O1 -g -fsanitize=address,undefined prog.cpp -o prog. Cost ~2× slower.

Common bugs (lecture): - debug01 i<=5 off-by-one - debug03 NULL deref - debug04 infinite loop - debug06 malloc no free - Mapper2D xyToPos = x + sx*y (lecture's (sx-1)*y wrong)


Parallelization

OpenMP:

#include <omp.h>
#pragma omp parallel for reduction(+:sum)
for(int i=0;i<N;++i) sum += a[i];
g++ -fopenmp prog.cpp -o prog; OMP_NUM_THREADS=8 ./prog.

Race fixes: reduction (best) > atomic > critical.

MPI 6 calls:

#include <mpi.h>
int rank,size;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Send(&x,1,MPI_INT,1,0,MPI_COMM_WORLD);
MPI_Recv(&x,1,MPI_INT,0,0,MPI_COMM_WORLD,&status);
MPI_Finalize();
mpic++ -O2 a.cpp -o a; mpirun -n 4 ./a.

Collectives: MPI_Bcast, MPI_Reduce(SUM/MAX/MIN), MPI_Allreduce, MPI_Scatter, MPI_Gather, MPI_Barrier.

Amdahl: \(S(N)=1/(f+(1-f)/N)\), max \(1/f\). 1% serial → 100×.

CFD: domain decomposition + halo cells; ParMETIS; per step: compute → halo exchange.


HPC Cluster

ssh user@cluster
module purge
module avail
module load gcc/12 openmpi/4.1 cmake/3.27
module list
sbatch run.sbatch
squeue -u $USER
scancel 12345
sinfo
srun --pty bash
salloc --nodes=1 --time=01:00:00
sacct -j 12345 --format=JobID,State,Elapsed,MaxRSS

Job script:

#!/bin/bash
#SBATCH --job-name=cfd
#SBATCH --partition=standard
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=16
#SBATCH --cpus-per-task=2
#SBATCH --time=04:00:00
#SBATCH --output=cfd_%j.log

module purge
module load gcc/12 openmpi/4.1
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
cd $SLURM_SUBMIT_DIR
mpirun -n $SLURM_NTASKS ./solver in.dat

Storage: $HOME slow / $WORK fast (purged) / $ARCHIVE tape.

Vars: $SLURM_NTASKS, $SLURM_CPUS_PER_TASK, $SLURM_NODELIST, $SLURM_JOB_ID, $SLURM_SUBMIT_DIR, $SLURM_NTASKS_PER_NODE, $SLURM_NNODES, $SLURM_ARRAY_TASK_ID.

Array job: #SBATCH --array=0-9.


Common Mistakes & Fixes (master list)

Mistake Fix
chmode 777 (typo) chmod 777
[ $a==$b ] no spaces [ "$a" = "$b" ]
cp dir new no -r cp -r dir new
chmod 644 on script add +x
> instead of >> choose carefully
2>&1 order cmd > out 2>&1 (after)
git push w/o git add + commit full chain
ssh-key perm 644 chmod 600
scp -p 22 lowercase p scp -P 22 (uppercase)
rsync src dst no slash rsync src/ dst/
TAB vs space in Makefile TAB only
Forgot header guard #ifndef X #define X #endif
Forgot -fPIC for shared add -fPIC
Forgot -l library add it
printf w/o \n then exit use \n
if(a=5) assignment if(a==5)
OpenMP race on sum add reduction(+:sum)
MPI Recv before Send both ranks MPI_Sendrecv
Forgot MPI_Finalize always close
Forgot module load in sbatch load explicitly inside script
Heavy work on login node submit via sbatch
<optimized out> in gdb rebuild -O0 -g
Forgot chmod +x script add execute
Glob *.cpp no match → literal shopt -s nullglob

End of cheat sheets — viel Erfolg / শুভ কামনা!