#!/usr/bin/env bash # setup.sh -- materialise and build the pinned GPGPU-Sim upstream checkout. # # This is the Phase-0 entry point of the GreenEye-GPGPU-Sim overlay: # 1. clone upstream GPGPU-Sim at the pinned commit into ./upstream/ (gitignored), # 2. apply ./patches/*.patch in lexical order (empty for now is fine), # 3. build with the CUDA toolkit selected by CUDA_INSTALL_PATH. # # Idempotent: re-running is safe (clone is reused, already-applied patches are # skipped, the build is incremental). Fails loudly on any ambiguity. Never # uses sudo. This is development-only tooling: it never touches GPU hardware, # kernel modules, mdev, a guest, or the product tree. # # Usage: # ./setup.sh [--no-build] [--reclone] [--build-type release|debug] # # Environment: # CUDA_INSTALL_PATH CUDA toolkit to build against (default /usr/local/cuda) # JOBS compile jobs (default 4; host budget cap) # GPGPUSIM_BUILD_TYPE release (default) or debug # GPGPUSIM_CLONE_SOURCE explicit local mirror path or URL (unset by # default; when unset the upstream URL is used) # # Exit codes: 0 success; 1 precondition/build failure; 2 usage error. set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" UPSTREAM="$HERE/upstream" PATCH_DIR="$HERE/patches" BUILD_DIR="$HERE/build" PIN="90ec3399763d7c8512cfe7dc193473086c38ca38" UPSTREAM_URL="https://github.com/gpgpu-sim/gpgpu-sim_distribution.git" BUILD=1 RECLONE=0 BUILD_TYPE="${GPGPUSIM_BUILD_TYPE:-release}" JOBS="${JOBS:-4}" die() { echo "setup.sh: ERROR: $*" >&2; exit 1; } usage() { cat <<'EOF' Usage: setup.sh [--no-build] [--reclone] [--build-type release|debug] --no-build clone/checkout + apply patches only --reclone delete ./upstream and clone fresh --build-type TYPE release (default) or debug Environment: CUDA_INSTALL_PATH CUDA toolkit to build against (default /usr/local/cuda) JOBS compile jobs (default 4; host budget cap) GPGPUSIM_BUILD_TYPE release (default) or debug GPGPUSIM_CLONE_SOURCE explicit local mirror path or URL (unset by default; the upstream URL is always the default source) Idempotent; fails loudly; never uses sudo. EOF } while [ $# -gt 0 ]; do case "$1" in --no-build) BUILD=0 ;; --reclone) RECLONE=1 ;; --build-type) BUILD_TYPE="${2:-}"; shift ;; -h|--help) usage; exit 0 ;; *) usage >&2; exit 2 ;; esac shift done case "$BUILD_TYPE" in release|debug) ;; *) die "unknown build type '$BUILD_TYPE' (use release or debug)" ;; esac if [ "$RECLONE" = 1 ] && [ -e "$UPSTREAM" ]; then echo "== --reclone: removing $UPSTREAM" rm -rf "$UPSTREAM" fi # --------------------------------------------------------------------------- # 1. upstream checkout at the pinned commit # --------------------------------------------------------------------------- if [ -d "$UPSTREAM/.git" ]; then echo "== upstream checkout present: $UPSTREAM" head_commit="$(git -C "$UPSTREAM" rev-parse HEAD)" if [ "$head_commit" != "$PIN" ]; then if [ -n "$(git -C "$UPSTREAM" status --porcelain)" ]; then die "upstream is at $head_commit (expected $PIN) and has local changes; --reclone to reset" fi echo "== checking out pinned commit $PIN" git -C "$UPSTREAM" checkout --quiet --detach "$PIN" \ || die "pinned commit $PIN not present locally; run with --reclone" else echo "== upstream already at pinned commit ($PIN)" fi elif [ -e "$UPSTREAM" ]; then die "$UPSTREAM exists but is not a git checkout; use --reclone" else # Default source is the upstream URL. A local mirror is used only when # GPGPUSIM_CLONE_SOURCE is set explicitly; nothing on this host is guessed. if [ -n "${GPGPUSIM_CLONE_SOURCE:-}" ]; then src="$GPGPUSIM_CLONE_SOURCE" echo "== using explicit clone source from GPGPUSIM_CLONE_SOURCE: $src" else src="$UPSTREAM_URL" echo "== using upstream URL: $UPSTREAM_URL" fi git clone --quiet "$src" "$UPSTREAM" || die "git clone failed from $src" git -C "$UPSTREAM" checkout --quiet --detach "$PIN" \ || die "pinned commit $PIN not found in clone from $src" fi # --------------------------------------------------------------------------- # 2. overlay patches (lexical order; empty directory is tolerated) # --------------------------------------------------------------------------- shopt -s nullglob patches=("$PATCH_DIR"/*.patch) shopt -u nullglob if [ "${#patches[@]}" -eq 0 ]; then echo "== patches/: empty (Phase 0; the CUDA 12 port patch set lands here)" else for p in "${patches[@]}"; do name="$(basename "$p")" if git -C "$UPSTREAM" apply --check "$p" >/dev/null 2>&1; then echo "== applying patch $name" git -C "$UPSTREAM" apply "$p" || die "failed to apply $name" elif git -C "$UPSTREAM" apply --reverse --check "$p" >/dev/null 2>&1; then echo "== patch already applied: $name" else die "patch neither applies cleanly nor is already applied: $name (resolve or --reclone)" fi done fi # --------------------------------------------------------------------------- # 3. build (skipped with --no-build) # --------------------------------------------------------------------------- if [ "$BUILD" = 0 ]; then echo "== --no-build: checkout + patches complete, build skipped" exit 0 fi cuda="${CUDA_INSTALL_PATH:-/usr/local/cuda}" [ -d "$cuda" ] || die "CUDA_INSTALL_PATH=$cuda does not exist (set the env var to a CUDA toolkit)" [ -x "$cuda/bin/nvcc" ] || die "no executable $cuda/bin/nvcc (set CUDA_INSTALL_PATH to a CUDA toolkit)" mkdir -p "$BUILD_DIR" LOG="$BUILD_DIR/build.log" echo "== building GPGPU-Sim ($BUILD_TYPE, -j$JOBS, CUDA_INSTALL_PATH=$cuda)" echo "== build log: $LOG" ( cd "$UPSTREAM" export CUDA_INSTALL_PATH="$cuda" export PATH="$cuda/bin:$PATH" set +u # shellcheck disable=SC1091 source ./setup_environment "$BUILD_TYPE" set -u if [ -z "${GPGPUSIM_CONFIG:-}" ]; then echo "setup.sh: ERROR: setup_environment did not configure a build for CUDA at $cuda." >&2 echo " This host's CUDA may not be ported yet (WP0.1); see UPSTREAM.md." >&2 exit 1 fi make -j"$JOBS" ) 2>&1 | tee "$LOG" echo "== setup complete" echo "== upstream: $UPSTREAM" echo "== runtime libs: $UPSTREAM/lib///$BUILD_TYPE" echo "== next: ./scripts/run_sim.sh [args...]"