/ concept-collection / turing-sphere
Sign in
concept-collection / turing-sphere
127 lines · 4.4 KBBlameHistoryRaw
1#!/usr/bin/env bash
2#
3# Fetch and build upstream SHTNS, then record how to link against it.
4#
5# ./bootstrap.sh # CPU, with OpenMP; adds CUDA if nvcc is on PATH
6# ./bootstrap.sh --no-cuda # CPU only, even if nvcc is there
7# ./bootstrap.sh --rev master # a different revision than the pinned one
8#
9# Writes shtns.mk, which the Makefile includes: the library name, the link
10# flags configure decided on, and whether GPU transforms were compiled in.
11# Re-run it after changing --rev or the CUDA choice; it is idempotent otherwise.
12set -euo pipefail
14cd "$(dirname "$0")"
16# SHTNS 3.7.5, master as of 2026-05-07. Pinned so a change upstream shows up as
17# a deliberate bump here rather than as a benchmark that quietly moved.
18REV=4e69ceb3fc5f19475d55b03ff0fdec210dc3075e
19URL=https://bitbucket.org/nschaeff/shtns.git
20DIR=shtns
21WANT_CUDA=auto
22CUDA_ARCH=
24while [ $# -gt 0 ]; do
25 case "$1" in
26 --no-cuda) WANT_CUDA=no ;;
27 --cuda) WANT_CUDA=yes ;;
28 --cuda=*) WANT_CUDA=yes; CUDA_ARCH="${1#*=}" ;;
29 --rev) shift; REV="$1" ;;
30 --rev=*) REV="${1#*=}" ;;
31 -h|--help)
32 sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'
33 exit 0 ;;
34 *) echo "bootstrap: unknown option '$1'" >&2; exit 2 ;;
35 esac
36 shift
37done
39if [ "$WANT_CUDA" = auto ]; then
40 if command -v nvcc >/dev/null 2>&1; then WANT_CUDA=yes; else WANT_CUDA=no; fi
41fi
43# ---------------------------------------------------------------------- clone
44if [ ! -d "$DIR/.git" ]; then
45 echo "==> cloning $URL"
46 git clone "$URL" "$DIR"
47fi
48echo "==> checking out $REV"
49# --unshallow so an existing shallow clone can still reach a --rev other than the
50# one it was cloned at; it errors on a full clone, hence the fallback.
51git -C "$DIR" fetch --tags --unshallow origin 2>/dev/null || git -C "$DIR" fetch --tags origin
52git -C "$DIR" checkout --detach "$REV"
54# ------------------------------------------------------------------ configure
55CONF=(--enable-openmp)
56if [ "$WANT_CUDA" = yes ]; then
57 if [ -n "$CUDA_ARCH" ]; then
58 CONF+=("--enable-cuda=$CUDA_ARCH")
59 else
60 CONF+=(--enable-cuda)
61 fi
62 # configure looks for these where CUDA_PATH points; say so if it is unset and
63 # nvcc is somewhere obvious, since the error it produces otherwise is opaque.
64 if [ -z "${CUDA_PATH:-}" ]; then
65 nvcc_dir=$(dirname "$(command -v nvcc)")
66 export CUDA_PATH="${nvcc_dir%/bin}"
67 echo "==> CUDA_PATH was unset; using $CUDA_PATH"
68 fi
69fi
71echo "==> configure ${CONF[*]}"
72( cd "$DIR" && ./configure "${CONF[@]}" )
74echo "==> make"
75( cd "$DIR" && make -j"$(getconf _NPROCESSORS_ONLN)" )
77# --------------------------------------------------------------- record how to
78# link. configure has already worked all of this out; read it back rather than
79# guessing, so a machine that needed MKL or a different FFTW still links.
80libname=$(sed -n 's/^libname *= *//p' "$DIR/Makefile" | head -1)
81libs=$(sed -n 's/^LIBS=//p' "$DIR/Makefile" | head -1)
82if [ ! -f "$DIR/$libname" ]; then
83 echo "bootstrap: expected $DIR/$libname but it is not there" >&2
84 exit 1
85fi
87# Whether the GPU entry points are actually in the archive — asked of the
88# library rather than of configure's intentions, since --enable-cuda can succeed
89# at configure time and still leave them out.
90gpu=0
91if nm -g "$DIR/$libname" 2>/dev/null | grep -q ' T cu_spat_to_SH_float'; then
92 gpu=1
93elif sed -n 's/^objs *= *//p' "$DIR/Makefile" | grep -q 'sht_gpu\.o'; then
94 gpu=1 # no nm on this host; trust what configure put in the object list
95fi
97fft=none
98[ "$gpu" = 1 ] && fft=vkfft
99if [ "$gpu" = 1 ] && ! grep -q '^#define VKFFT_BACKEND' "$DIR/sht_config.h"; then
100 # SHTNS falls back to cuFFT when vkfft/vkFFT.h is absent, and its configure
101 # does not add -lcufft (the check is commented out), so we have to.
102 fft=cufft
103 libs="$libs -lcufft"
104fi
106cat > shtns.mk <<EOF
107# Generated by bootstrap.sh — do not edit; re-run it instead.
108SHTNS_DIR = $DIR
109SHTNS_LIB = \$(SHTNS_DIR)/$libname
110SHTNS_LDLIBS = $libs
111SHTNS_HAS_GPU = $gpu
112SHTNS_GPU_FFT = $fft
113EOF
115echo
116echo "==> built $DIR/$libname (GPU transforms: $([ "$gpu" = 1 ] && echo yes || echo no))"
117if [ "$gpu" = 1 ]; then
118 echo " GPU Fourier stage: $fft"
119 if [ "$fft" = cufft ]; then
120 echo " NOTE: SHTNS' cuFFT path handles only the theta-contiguous layout, so"
121 echo " --layout phi will not work. vkfft/vkFFT.h is normally in the SHTNS"
122 echo " tree; if it is missing, that is why."
123 fi
124fi
125echo " link flags: $libs"
126echo
127echo "Now: make"
moveopenescclose