mirror of
https://github.com/cactus-compute/needle.git
synced 2026-10-14 04:59:44 +08:00
130 lines
4.4 KiB
Bash
Executable File
130 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
VENV_DIR=".venv"
|
|
|
|
# On Ubuntu/Debian, ensure Python >= 3.11 and venv are available
|
|
if [ -f /etc/os-release ] && grep -qi 'ubuntu\|debian' /etc/os-release; then
|
|
PYTHON_OK=$(python3 -c "import sys; print(int(sys.version_info >= (3, 11)))" 2>/dev/null || echo "0")
|
|
if [ "$PYTHON_OK" = "0" ]; then
|
|
echo "Python >= 3.11 required. Installing..."
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq software-properties-common
|
|
sudo add-apt-repository -y ppa:deadsnakes/ppa
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq python3.11 python3.11-venv python3.11-dev
|
|
PYTHON=python3.11
|
|
else
|
|
PYTHON=python3
|
|
# Ensure venv package is installed
|
|
if ! $PYTHON -m venv --help &>/dev/null; then
|
|
echo "Installing python3-venv..."
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq python3-venv
|
|
fi
|
|
fi
|
|
else
|
|
# On macOS or other systems, find Python >= 3.11
|
|
PYTHON=""
|
|
for candidate in python3.14 python3.13 python3.12 python3.11 python3; do
|
|
if command -v "$candidate" &>/dev/null; then
|
|
PY_OK=$("$candidate" -c "import sys; print(int(sys.version_info >= (3, 11)))" 2>/dev/null || echo "0")
|
|
if [ "$PY_OK" = "1" ]; then
|
|
PYTHON="$candidate"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
if [ -z "$PYTHON" ]; then
|
|
echo "Error: Python >= 3.11 is required. Install it with: brew install python@3.12"
|
|
return 1 2>/dev/null || exit 1
|
|
fi
|
|
fi
|
|
|
|
# Recreate venv if it doesn't exist or was built with the wrong Python
|
|
RECREATE=0
|
|
if [ ! -d "$VENV_DIR" ]; then
|
|
RECREATE=1
|
|
elif [ ! -f "$VENV_DIR/bin/activate" ]; then
|
|
RECREATE=1
|
|
elif [ -f "$VENV_DIR/bin/python3" ]; then
|
|
VENV_PY_OK=$("$VENV_DIR/bin/python3" -c "import sys; print(int(sys.version_info >= (3, 11)))" 2>/dev/null || echo "0")
|
|
if [ "$VENV_PY_OK" = "0" ]; then
|
|
RECREATE=1
|
|
fi
|
|
fi
|
|
|
|
if [ "$RECREATE" = "1" ]; then
|
|
echo "Creating virtual environment with $PYTHON..."
|
|
rm -rf "$VENV_DIR"
|
|
$PYTHON -m venv "$VENV_DIR"
|
|
else
|
|
echo "Virtual environment already exists."
|
|
fi
|
|
|
|
source "$VENV_DIR/bin/activate"
|
|
|
|
echo "Installing dependencies..."
|
|
pip install --upgrade pip -q
|
|
pip install -e . -q
|
|
|
|
# Detect accelerator and install the matching JAX build
|
|
ACCELERATOR="cpu"
|
|
if command -v nvidia-smi &>/dev/null && nvidia-smi &>/dev/null; then
|
|
ACCELERATOR="gpu"
|
|
elif ls /dev/accel* &>/dev/null 2>&1 || [ -n "$TPU_NAME" ] || [ -d /sys/class/accel ]; then
|
|
ACCELERATOR="tpu"
|
|
fi
|
|
|
|
case "$ACCELERATOR" in
|
|
gpu)
|
|
echo "Detected NVIDIA GPU. Installing jax[cuda12]..."
|
|
pip install -U "jax[cuda12]"
|
|
# GPU-friendly defaults: silence XLA autotuner spam, cache compiled
|
|
# kernels across runs, and let JAX claim most of HBM.
|
|
export TF_CPP_MIN_LOG_LEVEL=2
|
|
export JAX_COMPILATION_CACHE_DIR="$HOME/.cache/jax"
|
|
export XLA_PYTHON_CLIENT_MEM_FRACTION=0.95
|
|
mkdir -p "$JAX_COMPILATION_CACHE_DIR"
|
|
;;
|
|
tpu)
|
|
echo "Detected TPU. Installing jax[tpu]..."
|
|
pip install -U "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
|
|
# Load TPU kernel modules if not already loaded
|
|
if ! ls /dev/accel* &>/dev/null 2>&1; then
|
|
echo "Loading TPU kernel modules..."
|
|
for mod in gasket tpu_common tpu_v2 tpu_v3 tpu_v4 tpu_v4_lite; do
|
|
sudo modprobe "$mod" 2>/dev/null || true
|
|
done
|
|
fi
|
|
if ls /dev/accel* &>/dev/null 2>&1; then
|
|
echo "TPU devices: $(ls /dev/accel* 2>/dev/null | wc -w) chip(s)"
|
|
fi
|
|
;;
|
|
*)
|
|
echo "No GPU or TPU detected. Installing CPU-only jax..."
|
|
pip install -U jax
|
|
;;
|
|
esac
|
|
|
|
# Sanity check: report the JAX backend that was actually selected
|
|
python -c "import jax; print('JAX devices:', jax.devices())" 2>/dev/null || \
|
|
echo "Warning: jax import failed; check the install above."
|
|
|
|
if [ -f /sys/kernel/mm/transparent_hugepage/enabled ]; then
|
|
echo "Enabling transparent hugepages..."
|
|
sudo sh -c "echo always > /sys/kernel/mm/transparent_hugepage/enabled" 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -z "$WANDB_API_KEY" ]; then
|
|
echo ""
|
|
echo " Enter your W&B API key (https://wandb.ai/authorize)"
|
|
echo " Press Enter to skip."
|
|
printf " > "
|
|
read WANDB_API_KEY || true
|
|
if [ -n "$WANDB_API_KEY" ]; then
|
|
export WANDB_API_KEY
|
|
fi
|
|
fi
|
|
|
|
needle --help
|