109 lines
4.1 KiB
Bash
Executable File
109 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
# Copyright (C) 2026 David (Corey) Herrera
|
|
#
|
|
# Build Pantheon for a Tenstorrent Blackhole p150a and let this user drive the card,
|
|
# or (--k80) for a Tesla K80.
|
|
#
|
|
# ./install.sh TT: build, then set up card access (asks before using sudo)
|
|
# ./install.sh --yes same, without asking
|
|
# ./install.sh --k80 K80: build pantheon-cuda (no CUDA toolkit needed; the card needs
|
|
# the NVIDIA 470 driver). Then ./k80_qwen36.sh or ./k80_nexn2.sh.
|
|
#
|
|
# Card access needs no vendor kernel module: Foundry's userspace driver maps the card's
|
|
# PCI BARs. The udev rule (foundry/tt/tools/60-foundry-blackhole.rules) opens those to the
|
|
# `tenstorrent` group and sets two PCI config bits that otherwise need root on every run.
|
|
# Then run ./run_ornith.sh.
|
|
set -eu
|
|
cd "$(dirname "$0")"
|
|
|
|
RULES_SRC=foundry/tt/tools/60-foundry-blackhole.rules
|
|
RULES_DST=/etc/udev/rules.d/60-foundry-blackhole.rules
|
|
YES=0
|
|
K80=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--yes) YES=1 ;;
|
|
--k80) K80=1 ;;
|
|
*) echo "install: unknown option $arg (use --yes, --k80)" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
die() { echo "install: $*" >&2; exit 1; }
|
|
|
|
ask() {
|
|
[ "$YES" -eq 1 ] && return 0
|
|
printf '%s [y/N] ' "$1"
|
|
read -r reply
|
|
[ "$reply" = y ] || [ "$reply" = Y ]
|
|
}
|
|
|
|
check_tools() {
|
|
local missing=() tool
|
|
[ "$(uname -s)" = Linux ] || die "the Tenstorrent and K80 backends are Linux only"
|
|
for tool in cc make git curl sha256sum "$@"; do
|
|
command -v "$tool" > /dev/null || missing+=("$tool")
|
|
done
|
|
[ "${#missing[@]}" -eq 0 ] ||
|
|
die "missing: ${missing[*]} (Debian/Ubuntu: sudo apt install build-essential git curl pciutils)"
|
|
}
|
|
|
|
# build_pantheon <make flag> <backend>: e.g. USE_TT=1 tt -> ./pantheon-tt
|
|
build_pantheon() {
|
|
[ -f foundry/tensor/tensor.h ] || git submodule update --init foundry
|
|
echo "install: building pantheon-$2 (a few minutes on a small CPU)"
|
|
make "$1" -j"$(nproc)" "pantheon-$2"
|
|
[ "$(./pantheon-"$2" --backend)" = "$2" ] || die "built binary is not the $2 backend"
|
|
}
|
|
|
|
# Warn (don't fail) when the K80 can't run yet: the build itself needs no driver.
|
|
check_k80_driver() {
|
|
local driver
|
|
if ! command -v nvidia-smi > /dev/null || ! driver=$(nvidia-smi --query-gpu=driver_version \
|
|
--format=csv,noheader 2> /dev/null | head -1) || [ -z "$driver" ]; then
|
|
echo "install: WARNING: no NVIDIA driver found; a K80 needs the 470 driver to run"
|
|
return 0
|
|
fi
|
|
echo "install: NVIDIA driver $driver"
|
|
case "$driver" in 470.*) ;; *) echo "install: WARNING: Kepler (K80) is supported by the 470 driver branch" ;; esac
|
|
nvidia-smi -L | grep -q "K80" || echo "install: WARNING: no Tesla K80 listed by nvidia-smi -L"
|
|
}
|
|
|
|
# Compare rule lines only, so a reworded comment doesn't trigger sudo again.
|
|
card_access_ready() {
|
|
[ -f "$RULES_DST" ] &&
|
|
diff -q <(grep -v '^#' "$RULES_SRC") <(grep -v '^#' "$RULES_DST") > /dev/null &&
|
|
id -nG | tr ' ' '\n' | grep -qx tenstorrent
|
|
}
|
|
|
|
setup_card_access() {
|
|
if card_access_ready; then
|
|
echo "install: card access already set up"
|
|
return 0
|
|
fi
|
|
echo "install: card access needs sudo, once:"
|
|
echo " - create group 'tenstorrent' and add $USER to it"
|
|
echo " - install $RULES_DST, reload udev, re-trigger the card"
|
|
ask "Do it now?" || { echo "install: skipped; see the header of $RULES_SRC"; return 0; }
|
|
sudo groupadd -f tenstorrent
|
|
sudo usermod -aG tenstorrent "$USER"
|
|
sudo cp "$RULES_SRC" "$RULES_DST"
|
|
sudo udevadm control --reload
|
|
sudo udevadm trigger --subsystem-match=pci --attr-match=vendor=0x1e52
|
|
echo "install: done. Log out and back in so the 'tenstorrent' group applies."
|
|
}
|
|
|
|
if [ "$K80" -eq 1 ]; then
|
|
check_tools
|
|
build_pantheon USE_CUDA=1 cuda
|
|
check_k80_driver
|
|
echo "install: next, ./k80_qwen36.sh or ./k80_nexn2.sh"
|
|
else
|
|
check_tools lspci setpci
|
|
lspci -d 1e52:b140 | grep -q . ||
|
|
echo "install: WARNING: no Blackhole p150a (PCI 1e52:b140) found; building anyway"
|
|
build_pantheon USE_TT=1 tt
|
|
setup_card_access
|
|
echo "install: next, ./run_ornith.sh"
|
|
fi
|