Peano
Loading...
Searching...
No Matches
SuperMUC

Connecting to SuperMUC using TinyHTTPProxy

In order to have internet access on SuperMUC, we need to create a reverse SSH tunnel.

One way to do this is to use the TinyHTTPProxy script from below:

#!/usr/bin/env python
"""Tiny HTTP Proxy
This module implements GET, HEAD, POST, PUT, DELETE and CONNECT methods
on BaseHTTPServer (or server.http), and behaves as an HTTP proxy.
"""
from __future__ import print_function
__version__ = "1.1.1"
import select, socket, sys
try:
import http.server as hserv
from socketserver import ThreadingMixIn
import urllib.parse as urlparse
print_word = lambda wd: print(wd, end="\t", flush=True)
_ = lambda s: s.encode('utf-8')
except ImportError:
import BaseHTTPServer as hserv
from SocketServer import ThreadingMixIn
import urlparse
print_word = lambda s: (print(s, end="\t"), sys.stdout.flush())
_ = lambda s: s
class ProxyHandler (hserv.BaseHTTPRequestHandler):
__base = hserv.BaseHTTPRequestHandler
__base_handle = __base.handle
server_version = "TinyHTTPProxy/" + __version__
rbufsize = 0 # self.rfile Be unbuffered
def handle(self):
(ip, port) = self.client_address
if hasattr(self, 'allowed_clients') and ip not in self.allowed_clients:
self.raw_requestline = self.rfile.readline()
if self.parse_request(): self.send_error(403)
else:
self.__base_handle()
def _connect_to(self, netloc, soc):
i = netloc.find(':')
if i >= 0:
host_port = netloc[:i], int(netloc[i+1:])
else:
host_port = netloc, 80
print("\t" "connect to %s:%d" % host_port)
try: soc.connect(host_port)
except socket.error as arg:
try:
msg = arg[1]
except:
msg = arg
self.send_error(404, msg)
return False
return True
def do_CONNECT(self):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self._connect_to(self.path, soc):
self.log_request(200)
self.wfile.write(_(self.protocol_version +
" 200 Connection established\r\n"))
self.wfile.write(_("Proxy-agent: %s\r\n" %
self.version_string()))
self.wfile.write(b"\r\n")
self._read_write(soc, 300)
finally:
print_word("bye")
soc.close()
self.connection.close()
def do_GET(self):
(scm, netloc, path, params, query, fragment) = urlparse.urlparse(
self.path, 'http')
if scm != 'http' or fragment or not netloc:
self.send_error(400, "bad url %s" % self.path)
return
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self._connect_to(netloc, soc):
self.log_request()
soc.send(_("%s %s %s\r\n" % (
self.command,
urlparse.urlunparse(('', '', path, params, query,
'')),
self.request_version)))
self.headers['Connection'] = 'close'
del self.headers['Proxy-Connection']
for key_val in self.headers.items():
soc.send(_("%s: %s\r\n" % key_val))
soc.send(b"\r\n")
self._read_write(soc)
finally:
print_word("bye")
soc.close()
self.connection.close()
def _read_write(self, soc, max_idling=20):
iw = [self.connection, soc]
ow = []
count = 0
while True:
count += 1
(ins, _, exs) = select.select(iw, ow, iw, 3)
if exs:
break
if ins:
for i in ins:
if i is soc:
out = self.connection
else:
out = soc
data = i.recv(8192)
if data:
out.send(data)
count = 0
else:
print_word(count)
if count == max_idling:
break
do_HEAD = do_GET
do_POST = do_GET
do_PUT = do_GET
do_DELETE = do_GET
do_OPTIONS = do_GET
class ThreadingHTTPServer (ThreadingMixIn, hserv.HTTPServer):
pass
def main(argv):
if argv[1:] and argv[1] in ('-h', '--help'):
print(argv[0], "[port [allowed_client_name ...]]")
else:
server_address = ('', int(argv[1]) if argv[1:] else 8000)
if argv[2:]:
allowed = []
for name in argv[2:]:
client = socket.gethostbyname(name)
allowed.append(client)
print("Accept: %s (%s)" % (client, name))
ProxyHandler.allowed_clients = allowed
else:
print("Any clients will be served...")
httpd = ThreadingHTTPServer(server_address, ProxyHandler)
(host, port) = httpd.socket.getsockname()
print("Serving", ProxyHandler.protocol_version,
"on", host, "port", port, "...")
httpd.serve_forever()
if __name__ == '__main__':
main(sys.argv)
int main(int argc, char **argv)

and then forward the port

ssh -l <kennung> -R 8000:localhost:8000 skx.supermuc.lrz.de

SuperMUC-NG Phase 2

Software Environment and Modules

module switch stack/24.5.0
module load gcc/14.3.0
module load intel-toolkit
module load python/3.13.7
module load cmake
module load ninja
module load hdf5/1.10.11-intel25-impi
module load netcdf-c/4.9.2-intel25-impi

Building and Running

Find below a contained shell script that builds and runs ExaHyPE on SuperMUC-NG Phase 2:

#!/bin/bash
# ==============================================================================================
# Installation and Batch Script for ExaHyPE on SuperMUC
# ==============================================================================================
set -eu
# ==============================================================================================
# USER PARAMETERS
# ==============================================================================================
REPO_URL="https://gitlab.lrz.de/hpcsoftware/Peano.git"
BRANCH="muc/exahype"
DIR_NAME="Peano"
# Change to the application you want to build and run
EXAHYPE_APPLICATION=""
EXAHYPE_EXECUTABLE_NAME=""
EXAHYPE_DIMENSIONS=2
EXAHYPE_GRID_LEVELS=5
EXAHYPE_SOLUTION_NUM_SNAPSHOTS=100
EXAHYPE_SOLUTION_FOLDER="solutions"
EXAHYPE_SOLUTION_PATCH_FILE=""
SLURM_ACCOUNT=""
SLURM_PARTITION="general"
# Build Configuration
BUILD_TIME="00:20:00"
BUILD_NODES=1
BUILD_RANKS=1
BUILD_THREADS=32
# Run Configuration
USE_INTERACTIVE_SLURM=true
RUN_NUM_NODES=4
RUN_NUM_RANKS=8
RUN_NUM_THREADS=8
RUN_TIME=02:00:00
# ==============================================================================================
echo ">>> Starting ExaHyPE Setup..."
PEANO_ROOT="$(pwd)/$DIR_NAME"
echo ">>> PEANO_ROOT is set to: $PEANO_ROOT"
export http_proxy="http://localhost:8000"
export https_proxy="http://localhost:8000"
export HTTP_PROXY="http://localhost:8000"
export HTTPS_PROXY="http://localhost:8000"
APP_FULL_PATH="$PEANO_ROOT/$EXAHYPE_APPLICATION"
APP_DIR=$(dirname "$APP_FULL_PATH")
APP_EXEC="$APP_DIR/$EXAHYPE_EXECUTABLE_NAME"
MODULE_LOAD_COMMANDS='
module switch stack/24.5.0
module load gcc/14.3.0
module load intel-toolkit
module load python/3.13.7
module load cmake
module load ninja
module load hdf5/1.10.11-intel25-impi
module load netcdf-c/4.9.2-intel25-impi
'
load_modules() {
eval "$MODULE_LOAD_COMMANDS"
}
load_modules
# ==============================================================================================
# PHASE 1: DOWNLOAD & VENV
# ==============================================================================================
echo ">>> Setting up temporary local Git LFS..."
LFS_VERSION="v3.4.0"
LFS_TEMP_DIR="tmp_git_lfs"
rm -rf "$LFS_TEMP_DIR"
mkdir -p "$LFS_TEMP_DIR"
echo " Downloading Git LFS $LFS_VERSION..."
wget -q --show-progress "https://github.com/git-lfs/git-lfs/releases/download/${LFS_VERSION}/git-lfs-linux-amd64-${LFS_VERSION}.tar.gz" -O "$LFS_TEMP_DIR/lfs.tar.gz"
tar -xf "$LFS_TEMP_DIR/lfs.tar.gz" -C "$LFS_TEMP_DIR"
export PATH="$(pwd)/$LFS_TEMP_DIR/git-lfs-${LFS_VERSION#v}:$PATH"
git lfs install
if [ -d "$DIR_NAME" ]; then
echo ">>> Directory '$DIR_NAME' already exists."
echo ">>> Entering directory and pulling latest changes..."
cd "$DIR_NAME"
git checkout "$BRANCH"
git pull
git lfs pull
cd ..
else
echo ">>> Cloning repository branch: $BRANCH..."
GIT_CLONE_PROTECTION_ACTIVE=false git clone "$REPO_URL" -b "$BRANCH"
fi
echo ">>> Removing temporary local Git LFS..."
git lfs uninstall
rm -rf "$LFS_TEMP_DIR"
cd "$DIR_NAME"
echo ">>> Setting up Python virtual environment..."
if [ ! -d "venv" ]; then
echo " >>> Creating new virtual environment..."
python3 -m venv "venv"
echo " >>> Activating environment..."
source "venv/bin/activate"
echo " >>> Upgrading pip and installing dependencies..."
pip install --upgrade pip
pip install .
else
echo " >>> Existing virtual environment detected. Skipping pip install."
echo " >>> Activating environment..."
source "venv/bin/activate"
fi
# ==============================================================================================
# PHASE 2: COMPILATION & GENERATION
# ==============================================================================================
# Check if the ExaHyPE application executable already exists
if [ -x "$APP_EXEC" ]; then
echo "=========================================="
echo ">>> Existing ExaHyPE executable detected."
echo " >>> Location: $APP_EXEC"
echo " >>> Skipping build phase."
echo "=========================================="
else
echo ">>> No existing executable found at $APP_EXEC"
echo " >>> Proceeding with build phase..."
BUILD_SCRIPT="_build_task.sh"
cat << EOF > $BUILD_SCRIPT
#!/bin/bash
set -eu
echo ">>> [BUILD JOB] Loading Modules..."
$MODULE_LOAD_COMMANDS
echo ">>> [BUILD JOB] Activating Venv..."
source "$PEANO_ROOT/venv/bin/activate"
echo ">>> [BUILD JOB] Creating build directory..."
mkdir -p build
cd build
export CC=icx
export CXX=icpx
echo ">>> [BUILD JOB] Running CMake with Ninja..."
cmake .. -GNinja \
-DWITH_MPI=ON \
-DWITH_MULTITHREADING=ON \
-DWITH_HDF5=ON \
-DWITH_NETCDF=ON
echo ">>> [BUILD JOB] Building with Ninja (using \$SLURM_CPUS_PER_TASK threads)..."
ninja -j \$SLURM_CPUS_PER_TASK
APP_FULL_PATH="$APP_FULL_PATH"
APP_DIR="$APP_DIR"
APP_SCRIPT=\$(basename "\$APP_FULL_PATH")
echo ">>> [BUILD JOB] Entering Application directory: \$APP_DIR"
if [ ! -f "\$APP_FULL_PATH" ]; then
echo "Error: Application script not found at \$APP_FULL_PATH"
exit 1
fi
cd "\$APP_DIR"
echo ">>> [BUILD JOB] Running ExaHyPE Python generation script: \$APP_SCRIPT"
python3 "\$APP_SCRIPT" -ns $EXAHYPE_SOLUTION_NUM_SNAPSHOTS -md $EXAHYPE_GRID_LEVELS -d $EXAHYPE_DIMENSIONS
echo ">>> [BUILD JOB] Build phase complete."
EOF
chmod +x $BUILD_SCRIPT
echo "=========================================="
echo ">>> Submitting BUILD JOB to $SLURM_PARTITION..."
echo "=========================================="
salloc --nodes=$BUILD_NODES \
--ntasks=$BUILD_RANKS \
--cpus-per-task=$BUILD_THREADS \
--account=$SLURM_ACCOUNT \
--partition=$SLURM_PARTITION \
--time=$BUILD_TIME \
srun ./$BUILD_SCRIPT
rm -f $BUILD_SCRIPT
fi
# ==============================================================================================
# PHASE 3: EXECUTION & POST-PROCESSING
# ==============================================================================================
cd "$APP_DIR"
if [ ! -f "./$EXAHYPE_EXECUTABLE_NAME" ]; then
echo "Warning: ./$EXAHYPE_EXECUTABLE_NAME not found."
echo "Looking for any executable created recently..."
EXAHYPE_EXECUTABLE_NAME=$(ls -t | grep -v "\." | head -n 1)
echo "Found: $EXAHYPE_EXECUTABLE_NAME"
fi
echo "=========================================="
echo ">>> Application Build Complete!"
echo " >>> Executable location: $(pwd)"
echo "=========================================="
VISUALISATION_COMMANDS="
if [ \"$EXAHYPE_SOLUTION_NUM_SNAPSHOTS\" -gt 0 ]; then
echo \"==========================================\"
echo \">>> [RUN JOB] Converting to VTU...\"
python3 \"$PEANO_ROOT/python/visualisation/convert-to-vtu.py\" \"$EXAHYPE_SOLUTION_FOLDER/$EXAHYPE_SOLUTION_PATCH_FILE\" -j 32
echo \">>> [RUN JOB] Conversion finished.\"
echo \"==========================================\"
echo \">>> [RUN JOB] Creating animation...\"
python3 \"$PEANO_ROOT/python/visualisation/convert-to-png.py\" \"$EXAHYPE_SOLUTION_FOLDER/$EXAHYPE_SOLUTION_PATCH_FILE\" -j 32 --dpi 600
ANIMATION_OUT=\"$HOME/${EXAHYPE_EXECUTABLE_NAME}.mp4\"
echo \">>> [RUN JOB] Saving animation to: \$ANIMATION_OUT\"
python3 \"$PEANO_ROOT/python/visualisation/create-animation-from-png.py\" --input-dir \"$EXAHYPE_SOLUTION_FOLDER\" --output \"\$ANIMATION_OUT\" --fps 24
echo \">>> [RUN JOB] Creation finished.\"
fi
"
if [ "$USE_INTERACTIVE_SLURM" = true ]; then
if [ -z "$SLURM_ACCOUNT" ]; then
echo "ERROR: SLURM_ACCOUNT variable is empty."
exit 1
fi
echo "=========================================="
echo ">>> Submitting RUN JOB to $SLURM_PARTITION..."
echo "=========================================="
RUN_SCRIPT="_run_and_visualise.sh"
cat << EOF > $RUN_SCRIPT
#!/bin/bash
set -eu
echo ">>> [RUN JOB] Loading Modules..."
$MODULE_LOAD_COMMANDS
echo ">>> [RUN JOB] Activating Venv..."
source "$PEANO_ROOT/venv/bin/activate"
export OMP_PLACES=cores
export OMP_PROC_BIND=close
export OMP_NUM_THREADS=$RUN_NUM_THREADS
cd "$PEANO_ROOT/build"
# ctest --verbose
cd "$APP_DIR"
rm -rf solutions
mkdir -p solutions
echo ">>> [RUN JOB] Starting Simulation ($EXAHYPE_EXECUTABLE_NAME)..."
srun --ntasks-per-node=$RUN_NUM_RANKS --cpus-per-task=$RUN_NUM_THREADS ./$EXAHYPE_EXECUTABLE_NAME
$VISUALISATION_COMMANDS
echo ">>> [RUN JOB] complete."
EOF
chmod +x $RUN_SCRIPT
salloc --nodes=$RUN_NUM_NODES \
--account=$SLURM_ACCOUNT \
--partition=$SLURM_PARTITION \
--time=$RUN_TIME \
./$RUN_SCRIPT
rm -f $RUN_SCRIPT
else
if [ -z "$SLURM_ACCOUNT" ]; then
echo "ERROR: SLURM_ACCOUNT variable is empty."
exit 1
fi
BATCH_FILE="_run_and_visualise.slurm"
echo "=========================================="
echo ">>> Generating Batch Script: $BATCH_FILE"
echo "=========================================="
cat << EOF > "$BATCH_FILE"
#!/bin/bash
#SBATCH --job-name=$EXAHYPE_EXECUTABLE_NAME
#SBATCH --output=$HOME/${EXAHYPE_EXECUTABLE_NAME}_%j.out
#SBATCH --error=$HOME/${EXAHYPE_EXECUTABLE_NAME}_%j.err
#SBATCH --nodes=$RUN_NUM_NODES
#SBATCH --ntasks-per-node=$RUN_NUM_RANKS
#SBATCH --cpus-per-task=$RUN_NUM_THREADS
#SBATCH --time=$RUN_TIME
#SBATCH --account=$SLURM_ACCOUNT
#SBATCH --partition=$SLURM_PARTITION
#SBATCH --exclusive
#SBATCH --requeue
set -eu
echo ">>> [BATCH JOB] Job ID: \$SLURM_JOB_ID"
echo ">>> [BATCH JOB] Hostname: \$(hostname)"
echo ">>> [BATCH JOB] Loading Modules..."
$MODULE_LOAD_COMMANDS
echo ">>> [BATCH JOB] Activating Venv..."
source "$PEANO_ROOT/venv/bin/activate"
cd "$APP_DIR"
rm -rf solutions
mkdir -p solutions
export OMP_NUM_THREADS=\$SLURM_CPUS_PER_TASK
export OMP_PLACES=cores
export OMP_PROC_BIND=close
echo ">>> [BATCH JOB] Starting Simulation ($EXAHYPE_EXECUTABLE_NAME)..."
srun ./$EXAHYPE_EXECUTABLE_NAME
$VISUALISATION_COMMANDS
echo ">>> [BATCH JOB] Finished."
EOF
echo "=========================================="
echo ">>> Submitting BATCH JOB to queue..."
echo "=========================================="
sbatch "$BATCH_FILE"
echo ">>> Job submitted. Check status with: squeue --me"
rm "$BATCH_FILE"
fi