| #!/usr/bin/env bash |
| |
| |
| set -uo pipefail |
|
|
| cd "$(dirname "$0")/.." |
|
|
| PASS=0 |
| FAIL=0 |
| LOG=$(mktemp) |
|
|
| ok() { PASS=$((PASS+1)); echo "ok $1"; } |
| fail() { FAIL=$((FAIL+1)); echo "FAIL $1"; } |
|
|
| assert_grep() { |
| |
| if grep -q -- "$2" "$3" 2>/dev/null; then ok "$1"; else |
| fail "$1 (pattern not in $3)" |
| echo " --- content of $3 ---" |
| head -20 "$3" | sed 's/^/ /' |
| fi |
| } |
|
|
| assert_not_grep() { |
| |
| if grep -q -- "$2" "$3" 2>/dev/null; then |
| fail "$1 (obsolete pattern found in $3)" |
| else |
| ok "$1" |
| fi |
| } |
|
|
| |
| BINS=(./ds4 ./ds4-server ./ds4-bench ./ds4-agent) |
| NAMES=(ds4 ds4-server ds4-bench ds4-agent) |
|
|
| |
| for i in "${!BINS[@]}"; do |
| name=${NAMES[$i]}; bin=${BINS[$i]} |
| if [ ! -x "$bin" ]; then |
| fail "$name not built — skipping help check" |
| continue |
| fi |
| "$bin" --help > "$LOG" 2>&1 || true |
| assert_grep "$name --help mentions --gpu-vram" "gpu-vram" "$LOG" |
| assert_grep "$name --help mentions --gpu-devices" "gpu-devices" "$LOG" |
| assert_grep "$name --help mentions --cuda-tensor-parallel" "cuda-tensor-parallel" "$LOG" |
| if [ "$name" = "ds4" ]; then |
| "$bin" --help distributed > "$LOG" 2>&1 || true |
| assert_grep "$name --help distributed mentions --tensor-parallel-token-prefill" \ |
| "tensor-parallel-token-prefill" "$LOG" |
| assert_not_grep "$name --help distributed omits old --tp spellings" "--tp-" "$LOG" |
| fi |
| done |
|
|
| |
| |
| |
| |
| for i in "${!BINS[@]}"; do |
| name=${NAMES[$i]}; bin=${BINS[$i]} |
| [ -x "$bin" ] || continue |
| if [ "$name" = "ds4-bench" ]; then |
| "$bin" --gpu-vram abc -m /dev/null --prompt-file /dev/null > "$LOG" 2>&1 |
| else |
| "$bin" --gpu-vram abc -m /dev/null > "$LOG" 2>&1 |
| fi |
| rc=$? |
| if [ $rc -eq 0 ]; then |
| fail "$name --gpu-vram abc should exit non-zero (got 0)" |
| else |
| ok "$name --gpu-vram abc exits non-zero ($rc)" |
| fi |
| |
| |
| if grep -q -- "--gpu-vram: not a number" "$LOG" 2>/dev/null && |
| ! grep -q "unknown option" "$LOG" 2>/dev/null; then |
| ok "$name --gpu-vram abc reaches shared parser" |
| else |
| fail "$name --gpu-vram abc did not reach shared parser" |
| head -10 "$LOG" | sed 's/^/ /' |
| fi |
| done |
|
|
| |
| for i in "${!BINS[@]}"; do |
| name=${NAMES[$i]}; bin=${BINS[$i]} |
| [ -x "$bin" ] || continue |
| if [ "$name" = "ds4-bench" ]; then |
| "$bin" --gpu-vram 40,12 --gpu-devices 0 -m /dev/null \ |
| --prompt-file /dev/null > "$LOG" 2>&1 |
| else |
| "$bin" --gpu-vram 40,12 --gpu-devices 0 -m /dev/null > "$LOG" 2>&1 |
| fi |
| rc=$? |
| if [ $rc -ne 0 ] && |
| grep -q -- "--gpu-devices count (1) does not match --gpu-vram count (2)" "$LOG" && |
| ! grep -q "unknown option" "$LOG"; then |
| ok "$name count-mismatch reaches shared parser ($rc)" |
| else |
| fail "$name count-mismatch did not reach shared parser" |
| head -10 "$LOG" | sed 's/^/ /' |
| fi |
| done |
|
|
| |
| for i in "${!BINS[@]}"; do |
| name=${NAMES[$i]}; bin=${BINS[$i]} |
| [ -x "$bin" ] || continue |
| "$bin" --cuda --help > "$LOG" 2>&1 || true |
| |
| if grep -qE "Usage:|usage:|--help" "$LOG"; then |
| ok "$name --cuda --help still prints help" |
| else |
| fail "$name --cuda --help did not print help text" |
| fi |
| done |
|
|
| |
| |
| if [ -x ./ds4 ]; then |
| ./ds4 --gpu-vram 0 -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if [ $rc -ne 0 ]; then |
| ok "ds4 --gpu-vram 0 exits non-zero (expected: model-load fail)" |
| else |
| fail "ds4 --gpu-vram 0 returned 0 — unexpected" |
| fi |
| |
| if grep -q "GPU config:" "$LOG"; then |
| fail "ds4 --gpu-vram 0 should NOT print GPU layout line" |
| head -10 "$LOG" | sed 's/^/ /' |
| else |
| ok "ds4 --gpu-vram 0 does not print GPU layout (short-circuit reached)" |
| fi |
| fi |
|
|
| |
| |
| if [ -x ./ds4 ]; then |
| ./ds4 --metal --tensor-parallel --role coordinator --listen 127.0.0.1 9911 \ |
| --layers 0:1 -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if [ $rc -ne 0 ] && grep -q "always uses one 50/50 worker" "$LOG"; then |
| ok "tensor parallel rejects explicit layer slices" |
| else |
| fail "tensor parallel accepted --layers or returned the wrong error" |
| fi |
|
|
| ./ds4 --tensor-parallel --role worker -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if [ $rc -ne 0 ] && grep -q "requires --coordinator HOST PORT" "$LOG"; then |
| ok "tensor-parallel worker requires coordinator address" |
| else |
| fail "tensor-parallel worker returned the wrong missing-address error" |
| fi |
|
|
| ./ds4 --metal --tensor-parallel --role coordinator --listen 127.0.0.1 9911 \ |
| --transport tcp --tensor-parallel-token-prefill --debug-hash 2 \ |
| --rdma-device rdma-test --rdma-gid-index 0 \ |
| --inspect -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if [ $rc -ne 0 ] && |
| grep -qE "model file is too small|another ds4 process is already running" "$LOG" && |
| ! grep -q "requires --layers" "$LOG"; then |
| ok "tensor-parallel common options reach model loading" |
| else |
| fail "tensor-parallel common options did not reach model loading" |
| fi |
|
|
| for old_arg in \ |
| "--tp-coordinator 9911" \ |
| "--tp-lead 9911" \ |
| "--tp-coordinator-host 127.0.0.1" \ |
| "--tp-lead-host 127.0.0.1" \ |
| "--tp-worker 127.0.0.1 9911" \ |
| "--tp-transport tcp" \ |
| "--tp-debug-hash 2" \ |
| "--tp-token-prefill" |
| do |
| |
| |
| ./ds4 $old_arg -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if [ $rc -ne 0 ] && grep -q "unknown option" "$LOG"; then |
| ok "obsolete ${old_arg%% *} is rejected" |
| else |
| fail "obsolete ${old_arg%% *} was not rejected" |
| fi |
| done |
| fi |
|
|
| |
| if [ -x ./ds4 ]; then |
| ./ds4 --gpu-vram 40,12 -m /dev/null > "$LOG" 2>&1 |
| rc=$? |
| if grep -q "GPU config: 2 devices \[0,1\] requested, budgets 40,12 GB" "$LOG"; then |
| ok "ds4 --gpu-vram 40,12 prints expected layout line" |
| else |
| fail "ds4 --gpu-vram 40,12 missing or malformed layout line" |
| head -10 "$LOG" | sed 's/^/ /' |
| fi |
| fi |
|
|
| rm -f "$LOG" |
|
|
| echo "" |
| echo "test_gpu_args_cli: PASS=$PASS FAIL=$FAIL" |
| if [ $FAIL -gt 0 ]; then |
| exit 1 |
| fi |
| exit 0 |
|
|