nccl_test_launch.sh 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/env bash
  2. # Launch nccl_collective_test.py inside the spark-glm53 image with the SAME
  3. # per-box network derivation entrypoint.sh performs (LAN address for the
  4. # bootstrap, RoCE devices + GID index for the data plane). Run one container
  5. # per box; see README.md for the docker command.
  6. #
  7. # Required env: RANK (0 on node0), WORLD_SIZE=4, MASTER_ADDR=192.0.2.1,
  8. # MASTER_PORT. Optional: CLUSTER_SUBNET (198.51.100.), FABRIC_SUBNETS,
  9. # VLLM_HOST_IP (the LAN address; derived from the default route if unset),
  10. # any NCCL_* override (NCCL_PROTO, NCCL_ALGO, NCCL_IB_DISABLE, ...).
  11. # Remaining arguments go to the python test.
  12. set -euo pipefail
  13. CLUSTER_SUBNET="${CLUSTER_SUBNET:-198.51.100.}"
  14. FABRIC_SUBNETS="${FABRIC_SUBNETS:-$CLUSTER_SUBNET}"
  15. if [[ -z "${VLLM_HOST_IP:-}" ]]; then
  16. VLLM_HOST_IP=$(ip -o -4 route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')
  17. fi
  18. export VLLM_HOST_IP
  19. GLOO_SOCKET_IFNAME="${GLOO_SOCKET_IFNAME:-$(ip -o -4 addr show | awk -v ip="$VLLM_HOST_IP" '$4 ~ "^"ip"/" {print $2; exit}')}"
  20. export GLOO_SOCKET_IFNAME
  21. export NCCL_SOCKET_IFNAME="${NCCL_SOCKET_IFNAME:-$GLOO_SOCKET_IFNAME}"
  22. # Same as entrypoint.sh fabric_port(): "<rdma-device> <gid-index>" for the
  23. # port holding an address in $1.
  24. fabric_port() {
  25. local prefix="$1" found addr ifname dev="" hex i t g d n
  26. found=$(ip -o -4 addr show 2>/dev/null \
  27. | awk -v p="$prefix" '$4 ~ "^"p {split($4,a,"/"); print $2, a[1]; exit}')
  28. [[ -n "$found" ]] || return 1
  29. ifname="${found%% *}"; addr="${found##* }"
  30. for d in /sys/class/infiniband/*; do
  31. for n in "$d"/ports/1/gid_attrs/ndevs/*; do
  32. [[ -f "$n" ]] || continue
  33. [[ "$(cat "$n" 2>/dev/null)" == "$ifname" ]] || continue
  34. dev="$(basename "$d")"; break 2
  35. done
  36. done
  37. [[ -n "$dev" ]] || return 1
  38. hex=$(printf '%s' "$addr" | awk -F. '{printf "%02x%02x:%02x%02x", $1,$2,$3,$4}')
  39. for i in $(seq 0 15); do
  40. t=$(cat "/sys/class/infiniband/$dev/ports/1/gid_attrs/types/$i" 2>/dev/null) || continue
  41. g=$(cat "/sys/class/infiniband/$dev/ports/1/gids/$i" 2>/dev/null) || continue
  42. [[ "$t" == "RoCE v2" && "$g" == *"ffff:$hex" ]] || continue
  43. printf '%s %s\n' "$dev" "$i"; return 0
  44. done
  45. return 1
  46. }
  47. if [[ "${NCCL_IB_DISABLE:-0}" != "1" && ( -z "${NCCL_IB_HCA:-}" || -z "${NCCL_IB_GID_INDEX:-}" ) ]]; then
  48. _hcas=""; _gid=""
  49. for _p in $FABRIC_SUBNETS; do
  50. _r=$(fabric_port "$_p") || continue
  51. _d="${_r%% *}"; _i="${_r##* }"
  52. if [[ -n "$_gid" && "$_i" != "$_gid" ]]; then
  53. echo "FATAL: fabric ports disagree on GID index ($_d at $_i, expected $_gid)" >&2; exit 1
  54. fi
  55. _gid="${_gid:-$_i}"; _hcas="${_hcas:+$_hcas,}$_d"
  56. done
  57. if [[ -z "$_hcas" ]]; then
  58. echo "FATAL: no RoCE v2 GID for any of: $FABRIC_SUBNETS" >&2; ip -br addr show >&2; exit 1
  59. fi
  60. export NCCL_IB_HCA="${NCCL_IB_HCA:-$_hcas}" NCCL_IB_GID_INDEX="${NCCL_IB_GID_INDEX:-$_gid}"
  61. fi
  62. export NCCL_MAX_NCHANNELS="${NCCL_MAX_NCHANNELS:-8}"
  63. export NCCL_DEBUG="${NCCL_DEBUG:-WARN}"
  64. echo "rank=${RANK} host_ip=${VLLM_HOST_IP} ifname=${GLOO_SOCKET_IFNAME} NCCL_IB_HCA=${NCCL_IB_HCA:-} gid=${NCCL_IB_GID_INDEX:-} NCCL_IB_DISABLE=${NCCL_IB_DISABLE:-0} PROTO=${NCCL_PROTO:-} ALGO=${NCCL_ALGO:-}"
  65. cd /
  66. exec python3 "$(dirname "$0")/nccl_collective_test.py" "$@"