Skip to content

Commit be8e7e5

Browse files
authored
ci: add phase timing markers to ray.sub for diagnosing startup stalls (#3209)
Signed-off-by: Terry Kong <terryk@nvidia.com>
1 parent 6493bd9 commit be8e7e5

1 file changed

Lines changed: 37 additions & 8 deletions

File tree

ray.sub

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ set -eoux pipefail
2727
# Record job-start epoch so Python can measure pre-Python overhead
2828
export NRL_JOB_START_EPOCH=$(date +%s.%N)
2929

30+
# Log a timestamped, seconds-since-job-start marker at each phase boundary.
31+
log_phase() {
32+
echo "[NRL_PHASE][$(date '+%Y-%m-%dT%H:%M:%S%z')][+$(( $(date +%s) - ${NRL_JOB_START_EPOCH%.*} ))s] $*"
33+
}
34+
log_phase "ray.sub started (job=${SLURM_JOB_ID:-?} nodes=${SLURM_JOB_NUM_NODES:-?} partition=${SLURM_JOB_PARTITION:-?} node=$(hostname))"
35+
36+
# Log a final marker on exit; trap TERM/HUP/INT too so a scancel/time-limit kill is still stamped.
37+
_nrl_log_exit() { local rc=$?; trap - EXIT; log_phase "ray.sub exiting (exit_code=$rc)"; exit $rc; }
38+
trap _nrl_log_exit EXIT TERM HUP INT
39+
3040
########################################################
3141
# Function to detect if SLURM cluster uses GRES
3242
########################################################
@@ -186,6 +196,7 @@ mkdir -p $LOG_DIR
186196
# containers check at startup: a node that can't see it isn't on the shared FS, so
187197
# we fail there immediately instead of hanging on signal files that never appear.
188198
echo "$SLURM_JOB_ID" > "$LOG_DIR/.shared_fs_canary"
199+
log_phase "shared-FS log dir ready ($LOG_DIR)"
189200

190201
# Write setup commands to a file so they can be executed inside each container
191202
# without heredoc escaping surprises.
@@ -209,6 +220,7 @@ fi
209220
GPUS_PER_NODE=${GPUS_PER_NODE:-8}
210221

211222
# Detect GRES support and set GRES_ARG
223+
log_phase "detecting GRES support (sinfo)"
212224
GRES_ARG=$(maybe_gres_arg)
213225
if [[ -n "$GRES_ARG" ]]; then
214226
echo "[INFO] GRES support detected. Using: $GRES_ARG"
@@ -233,6 +245,7 @@ COMMON_SRUN_ARGS+=" -A $SLURM_JOB_ACCOUNT"
233245
if [[ -n "${CPUS_PER_WORKER:-}" ]]; then
234246
echo "[INFO] Using user-provided CPUS_PER_WORKER=$CPUS_PER_WORKER."
235247
else
248+
log_phase "auto-detecting CPUs per node (scontrol show node)"
236249
CPUS_PER_WORKER=$(detect_cpus_per_node)
237250
echo "[INFO] Auto-detected CPUS_PER_WORKER=$CPUS_PER_WORKER from SLURM (CPUTot of first allocated node)."
238251
fi
@@ -328,6 +341,7 @@ nodes=$(scontrol show hostnames "$SLURM_JOB_NODELIST")
328341
nodes_array=($nodes)
329342
ip_addresses_array=()
330343

344+
log_phase "resolving ${#nodes_array[@]} node hostname(s) to IPs"
331345
for node in $nodes; do
332346
# Try multiple methods to get IP address - ENHANCED VERSION v2.0
333347
echo "[DEBUG] Resolving hostname: $node using enhanced resolution methods"
@@ -519,6 +533,11 @@ if [[ ! -f "$LOG_DIR/.shared_fs_canary" ]]; then
519533
exit 1
520534
fi
521535
536+
# Phase markers inside the container; reuse the propagated job-start epoch so the
537+
# elapsed counter shares the submit-side timeline.
538+
log_phase() { local t0="\${NRL_JOB_START_EPOCH:-0}"; echo "[NRL_PHASE][\$(date '+%Y-%m-%dT%H:%M:%S%z')][+\$(( \$(date +%s) - \${t0%.*} ))s] \$*"; }
539+
log_phase "head container started on \$(hostname)"
540+
522541
exit-dramatically() {
523542
# Use SIGTERM to forcefully terminate the srun process
524543
pkill -P $$ || true
@@ -599,6 +618,7 @@ source $LOG_DIR/topology_probe.sh
599618
# GCS is listening, so we touch STARTED_RAY_HEAD only after the head is actually up.
600619
# Workers gate on that file, so they only try to connect once the GCS is accepting
601620
# connections.
621+
log_phase "head: starting Ray head"
602622
count=0
603623
while [[ \$count -lt $num_retries ]]; do
604624
# Clean up stale Ray state before every attempt. A timed-out attempt leaves a
@@ -646,6 +666,7 @@ fi
646666
647667
# Signal workers and the submit host that the Ray head GCS is now listening.
648668
touch $LOG_DIR/STARTED_RAY_HEAD
669+
log_phase "head: Ray GCS listening (STARTED_RAY_HEAD written)"
649670
650671
if [[ -n "$DRIVER_COMMAND_FILE" ]]; then
651672
# Non-interactive: wait for all workers to connect and, if a sandbox is
@@ -662,18 +683,18 @@ if [[ -n "$DRIVER_COMMAND_FILE" ]]; then
662683
while true; do
663684
if [[ "\$workers_ready" -eq 0 ]]; then
664685
worker_units=\$(ray status 2>/dev/null | grep "worker_units" | awk -F'[/. ]' '{print \$4}' || echo 0)
665-
echo "[INFO] Number of actors online: \$worker_units/$NUM_ACTORS"
686+
echo "[INFO][\$(date '+%Y-%m-%dT%H:%M:%S%z')] Number of actors online: \$worker_units/$NUM_ACTORS"
666687
if [[ "\$worker_units" -eq "$NUM_ACTORS" ]]; then
667688
workers_ready=1
668-
echo "All workers connected!"
689+
echo "[INFO][\$(date '+%Y-%m-%dT%H:%M:%S%z')] All workers connected!"
669690
fi
670691
fi
671692
if [[ "\$sandbox_ready" -eq 0 ]]; then
672693
ready_count=\$(ls -1 "$SANDBOX_PORTS_DIR"/SANDBOX_READY_* 2>/dev/null | wc -l)
673-
echo "[INFO] Sandbox ready on \$ready_count/$SLURM_JOB_NUM_NODES nodes..."
694+
echo "[INFO][\$(date '+%Y-%m-%dT%H:%M:%S%z')] Sandbox ready on \$ready_count/$SLURM_JOB_NUM_NODES nodes..."
674695
if [[ "\$ready_count" -ge "$SLURM_JOB_NUM_NODES" ]]; then
675696
sandbox_ready=1
676-
echo "[INFO] All $SLURM_JOB_NUM_NODES sandbox instances ready."
697+
echo "[INFO][\$(date '+%Y-%m-%dT%H:%M:%S%z')] All $SLURM_JOB_NUM_NODES sandbox instances ready."
677698
fi
678699
fi
679700
if [[ "\$workers_ready" -eq 1 ]] && [[ "\$sandbox_ready" -eq 1 ]]; then
@@ -696,6 +717,7 @@ if [[ -n "$DRIVER_COMMAND_FILE" ]]; then
696717
# and training process can measure post-ready initialization timing.
697718
export NRL_RAY_READY_EPOCH=\$(date +%s.%N)
698719
720+
log_phase "head: cluster ready, launching driver"
699721
set +e
700722
bash "$DRIVER_COMMAND_FILE" > "$LOG_DIR/ray-driver.log" 2>&1
701723
exit_code=\$?
@@ -725,6 +747,10 @@ if [[ ! -f "$LOG_DIR/.shared_fs_canary" ]]; then
725747
exit 1
726748
fi
727749
750+
# Phase markers inside the container (see head container).
751+
log_phase() { local t0="\${NRL_JOB_START_EPOCH:-0}"; echo "[NRL_PHASE][\$(date '+%Y-%m-%dT%H:%M:%S%z')][+\$(( \$(date +%s) - \${t0%.*} ))s] \$*"; }
752+
log_phase "worker \$SLURM_PROCID container started on \$(hostname)"
753+
728754
exit-dramatically() {
729755
# Use SIGTERM to forcefully terminate the srun process
730756
pkill -P $$ || true
@@ -786,7 +812,7 @@ source $LOG_DIR/topology_probe.sh
786812
echo "[INFO] Worker \$SLURM_PROCID: waiting for Ray head GCS to be ready..."
787813
while true; do
788814
if [[ -f "$LOG_DIR/STARTED_RAY_HEAD" ]]; then
789-
echo "[INFO] Worker \$SLURM_PROCID: Ray head GCS is ready, connecting."
815+
log_phase "worker \$SLURM_PROCID connecting to Ray head"
790816
break
791817
fi
792818
if [[ -f "$LOG_DIR/ENDED" ]]; then
@@ -811,7 +837,7 @@ while [[ \$count -lt $WORKER_NUM_RETRIES ]]; do
811837
echo "[INFO] Running setup command from $SETUP_COMMAND_FILE..."
812838
bash "$SETUP_COMMAND_FILE"
813839
fi
814-
echo "[INFO] Worker \$SLURM_PROCID: starting Ray worker (attempt \$((count+1))/$WORKER_NUM_RETRIES)..."
840+
echo "[INFO][\$(date '+%Y-%m-%dT%H:%M:%S%z')] Worker \$SLURM_PROCID: starting Ray worker (attempt \$((count+1))/$WORKER_NUM_RETRIES)..."
815841
cat <<EOFINNER | bash
816842
ray start --address "$ip_head" \
817843
--disable-usage-stats \
@@ -904,6 +930,7 @@ else
904930
fi
905931

906932
# Start the Ray head.
933+
log_phase "launching Ray head + worker sruns"
907934
srun $COMMON_SRUN_ARGS --container-name=ray-head --nodes=1 --ntasks=1 --cpus-per-task=$CPUS_PER_WORKER -w "$head_node" -o $LOG_DIR/ray-head.log bash -x -c "$head_cmd" &
908935
SRUN_PIDS["ray-head"]=$!
909936

@@ -936,6 +963,7 @@ while check_srun_processes && ! test -f "$LOG_DIR/STARTED_RAY_HEAD"; do
936963
echo "[INFO][$(date)] Waiting for Ray head GCS to be ready..."
937964
sleep 2
938965
done
966+
log_phase "Ray head GCS up (STARTED_RAY_HEAD observed)"
939967

940968
if [[ -n "$COMMAND" ]]; then
941969
# Non-interactive: the head container polls for workers, gates on sandbox
@@ -968,7 +996,7 @@ else
968996
RAY_STATUS_DEADLINE=$((SECONDS + 1800))
969997
while true; do
970998
worker_units=$(cat "$LOG_DIR/ray_worker_units" 2>/dev/null || echo -1)
971-
echo "[INFO] Number of actors online: $worker_units/$NUM_ACTORS"
999+
echo "[INFO][$(date '+%Y-%m-%dT%H:%M:%S%z')] Number of actors online: $worker_units/$NUM_ACTORS"
9721000
if [[ "$worker_units" -eq "$NUM_ACTORS" ]]; then
9731001
break
9741002
fi
@@ -981,8 +1009,9 @@ else
9811009
sleep 5
9821010
done
9831011

984-
echo "All workers connected!"
1012+
echo "[INFO][$(date '+%Y-%m-%dT%H:%M:%S%z')] All workers connected!"
9851013

1014+
log_phase "generating attach helper (scontrol show job)"
9861015
CONTAINER_CWD=$(scontrol show job $SLURM_JOB_ID | grep -oP 'WorkDir=\K[^ ]+' | head -1)
9871016
echo "[INFO]: Ray Cluster is idled, run this on the slurm head node to get a shell to the head node:"
9881017
cat <<EOF >$SLURM_SUBMIT_DIR/${SLURM_JOB_ID}-attach.sh

0 commit comments

Comments
 (0)