-
Notifications
You must be signed in to change notification settings - Fork 28
Add nightly Presto benchmark script for NVL72 Slurm cluster #382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
misiugodfrey
wants to merge
13
commits into
main
Choose a base branch
from
nightlyPresto
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
01efce8
Add nightly Presto benchmark script for NVL72 Slurm cluster
misiugodfrey da8d45c
Remove velox/presto branch/repo args from post_results.py call
misiugodfrey f3a15d3
Add --now flag to skip initial sleep and trigger immediately
misiugodfrey f166a9a
Fix RESULTS_BASE path mangling from VT_WORKSPACE slash-to-dash flatte…
misiugodfrey ff35fd8
Add logs to run, and allow results to be posted with failures
misiugodfrey 555869a
Guard post_results calls and add SIGINT/SIGTERM cleanup trap
misiugodfrey 5a2bb27
Merge origin/main into feature/nightlyPresto
misiugodfrey 771dd0e
Merge remote-tracking branch 'origin/main' into feature/nightlyPresto
misiugodfrey 956865a
Address review comments on nightly benchmark script
misiugodfrey 7af06c7
Address review comments: errexit isolation, log preservation, run_iso…
misiugodfrey 2dfad9b
Merge branch 'main' into nightlyPresto
misiugodfrey c56239b
Merge origin/main; align LOGS_DIR with main (/opt/presto-server/logs)
misiugodfrey f5b6ae0
Merge remote-tracking branch 'origin/nightlyPresto' into feature/nigh…
misiugodfrey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| #!/bin/bash | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # ============================================================================== | ||
| # Nightly Presto Benchmark Runner | ||
| # ============================================================================== | ||
| # Runs in a persistent tmux/screen session, sleeping until 3 AM EST (08:00 UTC) | ||
| # each day, then: | ||
| # 1. Pulls the latest nightly-pinned coordinator and GPU worker images from GHCR | ||
| # into a temporary directory (does not overwrite IMAGE_DIR images). | ||
| # 2. Runs a 1-node / 4-GPU TPC-H sf1000 benchmark. | ||
| # 3. Runs a 2-node / 8-GPU TPC-H sf3000 benchmark. | ||
| # 4. Posts results to the benchmarking DB via post_results.py. | ||
| # 5. Removes the temporary images. | ||
| # | ||
| # Required environment variables (no defaults — set before launching): | ||
| # SKU_NAME Hardware SKU name (--sku-name for post_results.py) | ||
| # STORAGE_CONFIG_1K --storage-configuration-name for the sf1000 run | ||
| # STORAGE_CONFIG_3K --storage-configuration-name for the sf3000 run | ||
| # | ||
| # Note: BENCHMARK_API_URL and BENCHMARK_API_KEY must also be set in the | ||
| # environment so that post_results.py can authenticate with the DB. | ||
| # | ||
| # Optional environment variables: | ||
| # ITERATIONS Number of benchmark iterations per run (default: 5) | ||
| # RUN_HOUR_UTC Hour (UTC) at which to fire each night (default: 8, i.e. 3 AM EST) | ||
| # | ||
| # Usage: | ||
| # export SKU_NAME="..." | ||
| # export STORAGE_CONFIG_1K="..." | ||
| # export STORAGE_CONFIG_3K="..." | ||
| # export BENCHMARK_API_URL="..." | ||
| # export BENCHMARK_API_KEY="..." | ||
| # tmux new -s nightly-presto | ||
| # ./nightly-benchmark.sh | ||
| # | ||
| # To trigger immediately (e.g. for testing), pass --now: | ||
| # ./nightly-benchmark.sh --now | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| RUN_NOW=0 | ||
| for arg in "$@"; do | ||
| case "${arg}" in | ||
| --now) RUN_NOW=1 ;; | ||
| *) echo "Unknown option: ${arg}" >&2; exit 1 ;; | ||
| esac | ||
| done | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| VT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" | ||
| # Set RESULTS_BASE before sourcing defaults.env so that the VT_WORKSPACE | ||
| # slash-to-dash flattening logic doesn't produce a path that doesn't exist. | ||
| : "${RESULTS_BASE:=${VT_ROOT}/results}" | ||
| source "${SCRIPT_DIR}/defaults.env" | ||
| source "${SCRIPT_DIR}/echo_helpers.sh" | ||
| source "${SCRIPT_DIR}/launcher_common.sh" | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Image constants — the -latest tags are only updated by nightly pinned CI runs | ||
| # Override COORD_TAG / WORKER_TAG in the environment to pull a specific image: | ||
| # COORD_TAG=presto-coordinator-pr-338 WORKER_TAG=presto-pr-338-gpu-cuda13.1 \ | ||
| # ./nightly-benchmark.sh --now | ||
| # ------------------------------------------------------------------------------ | ||
| REGISTRY="ghcr.io/rapidsai/velox-testing-images" | ||
| : "${COORD_TAG:=presto-coordinator-latest}" | ||
| : "${WORKER_TAG:=presto-latest-gpu-cuda13.1}" | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Configuration | ||
| # ------------------------------------------------------------------------------ | ||
| : "${ITERATIONS:=5}" | ||
| : "${RUN_HOUR_UTC:=8}" | ||
|
|
||
| NIGHTLY_IMAGE_DIR="${IMAGE_DIR}/nightly-temp" | ||
| COORD_SQSH="${NIGHTLY_IMAGE_DIR}/presto-coordinator-nightly.sqsh" | ||
| WORKER_SQSH="${NIGHTLY_IMAGE_DIR}/presto-gpu-cuda13.1-nightly.sqsh" | ||
|
|
||
| INTER_RUN_SLEEP=90 | ||
|
|
||
| # Validate required env vars before entering the loop | ||
| for req in SKU_NAME STORAGE_CONFIG_1K STORAGE_CONFIG_3K; do | ||
| [[ -n "${!req:-}" ]] || echo_error "Required env var ${req} is not set" | ||
| done | ||
|
|
||
| # Append all output to a persistent log file | ||
| mkdir -p "${RESULTS_BASE}" | ||
| LOG_FILE="${RESULTS_BASE}/nightly-benchmark.log" | ||
| exec > >(tee -a "${LOG_FILE}") 2>&1 | ||
|
|
||
| echo "Nightly benchmark daemon started (logging to ${LOG_FILE})" | ||
| echo " RUN_HOUR_UTC=${RUN_HOUR_UTC} ITERATIONS=${ITERATIONS}" | ||
| echo " COORD_TAG=${COORD_TAG} WORKER_TAG=${WORKER_TAG}" | ||
| echo " (override COORD_TAG / WORKER_TAG in the environment to use a different image)" | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Functions | ||
| # ------------------------------------------------------------------------------ | ||
|
|
||
| sleep_until_next_run() { | ||
| local now next target_time next_str delay | ||
| now=$(date -u +%s) | ||
| target_time=$(printf '%02d:00:00' "${RUN_HOUR_UTC}") | ||
| next=$(date -u -d "$(date -u +%Y-%m-%d) ${target_time}" +%s) | ||
| if [[ ${next} -le ${now} ]]; then | ||
| next=$(( next + 86400 )) | ||
| fi | ||
| delay=$(( next - now )) | ||
| next_str=$(date -u -d "@${next}" '+%Y-%m-%d %H:%M:%S UTC') | ||
| echo "Sleeping ${delay}s until next run at ${next_str}..." | ||
| sleep "${delay}" | ||
| } | ||
|
|
||
| pull_images() { | ||
| echo "Pulling coordinator image (${COORD_TAG})..." | ||
| "${SCRIPT_DIR}/pull_ghcr_image.sh" \ | ||
| "${REGISTRY}:${COORD_TAG}" \ | ||
| --output "${COORD_SQSH}" \ | ||
| --overwrite | ||
| echo "Pulling worker image (${WORKER_TAG})..." | ||
| "${SCRIPT_DIR}/pull_ghcr_image.sh" \ | ||
| "${REGISTRY}:${WORKER_TAG}" \ | ||
| --output "${WORKER_SQSH}" \ | ||
| --overwrite | ||
| } | ||
|
|
||
| run_benchmark() { | ||
| local nodes="$1" gpus_per_node="$2" scale_factor="$3" output_dir="$4" | ||
| rm -rf "${output_dir}" | ||
| "${SCRIPT_DIR}/launch-run.sh" \ | ||
| -n "${nodes}" \ | ||
| -g "${gpus_per_node}" \ | ||
| -s "${scale_factor}" \ | ||
| --gpu \ | ||
| -c "${COORD_SQSH}" \ | ||
| -w "${WORKER_SQSH}" \ | ||
| -o "${output_dir}" \ | ||
| -i "${ITERATIONS}" | ||
| } | ||
|
|
||
| post_results() { | ||
| local output_dir="$1" benchmark_name="$2" storage_config="$3" | ||
| "${VT_ROOT}/scripts/run_py_script.sh" \ | ||
| -p "${VT_ROOT}/benchmark_reporting_tools/post_results.py" \ | ||
|
patdevinwilson marked this conversation as resolved.
|
||
| "${output_dir}" \ | ||
| --sku-name "${SKU_NAME}" \ | ||
| --storage-configuration-name "${storage_config}" \ | ||
| --cache-state "warm" \ | ||
| --benchmark-name "${benchmark_name}" \ | ||
| --label "nightly" | ||
| } | ||
|
|
||
| cleanup_images() { | ||
| # IMAGE_DIR is on compute-node-only scratch storage on some clusters, so | ||
| # run the deletion via srun to match how pull_ghcr_image.sh created the files. | ||
| resolve_cluster_variant cpu | ||
| local slurm_args=() | ||
| [[ -n "${CLUSTER_DEFAULT_PARTITION:-}" ]] && slurm_args+=(--partition="${CLUSTER_DEFAULT_PARTITION}") | ||
| [[ -n "${CLUSTER_DEFAULT_ACCOUNT:-}" ]] && slurm_args+=(--account="${CLUSTER_DEFAULT_ACCOUNT}") | ||
| export COORD_SQSH WORKER_SQSH NIGHTLY_IMAGE_DIR | ||
| srun "${slurm_args[@]}" --nodes=1 --mem=0 --ntasks-per-node=1 \ | ||
| bash -c 'rm -f "${COORD_SQSH}" "${WORKER_SQSH}"; rmdir --ignore-fail-on-non-empty "${NIGHTLY_IMAGE_DIR}" 2>/dev/null || true' | ||
| } | ||
|
|
||
| run_nightly() { | ||
| local date_tag | ||
| date_tag=$(date -u +%Y%m%d) | ||
| local output_1k="${RESULTS_BASE}/nightly-${date_tag}/tpch-1k" | ||
| local output_3k="${RESULTS_BASE}/nightly-${date_tag}/tpch-3k" | ||
|
|
||
| echo_success "=== Nightly benchmark starting: ${date_tag} ===" | ||
| echo " Coordinator image: ${REGISTRY}:${COORD_TAG}" | ||
| echo " Worker image: ${REGISTRY}:${WORKER_TAG}" | ||
| echo " Iterations: ${ITERATIONS}" | ||
|
|
||
| pull_images | ||
|
|
||
| echo "" | ||
| echo "--- Run 1/2: 1-node, 4-GPU, tpch-sf1000 ---" | ||
| run_benchmark 1 4 1000 "${output_1k}" || true | ||
| if [[ -f "${output_1k}/benchmark_result.json" ]]; then | ||
| echo "Posting results for tpch-1k..." | ||
| post_results "${output_1k}" "tpch-rs-1000" "${STORAGE_CONFIG_1K}" \ | ||
| || echo_warning "Failed to post tpch-1k results" | ||
| else | ||
| echo_warning "SF1000 benchmark produced no results — skipping result posting for tpch-1k" | ||
| fi | ||
|
|
||
| echo "" | ||
| echo "Waiting ${INTER_RUN_SLEEP}s for UCX ports to be released before next run..." | ||
| sleep "${INTER_RUN_SLEEP}" | ||
|
|
||
| echo "" | ||
| echo "--- Run 2/2: 2-node, 8-GPU (4/node), tpch-sf3000 ---" | ||
| run_benchmark 2 4 3000 "${output_3k}" || true | ||
| if [[ -f "${output_3k}/benchmark_result.json" ]]; then | ||
| echo "Posting results for tpch-3k..." | ||
| post_results "${output_3k}" "tpch-rs-3000" "${STORAGE_CONFIG_3K}" \ | ||
| || echo_warning "Failed to post tpch-3k results" | ||
| else | ||
| echo_warning "SF3000 benchmark produced no results — skipping result posting for tpch-3k" | ||
| fi | ||
|
|
||
| echo "" | ||
| echo_success "=== Nightly benchmark complete: ${date_tag} ===" | ||
| } | ||
|
|
||
| # run_isolated() isolates a function in a sub-shell with errexit (-e) such that any error | ||
| # in the function causes it to return an error code, but will not cause the parent shell | ||
| # exit immediatly. Instead if the sub-shell errors out, we will run the cleanup function | ||
| # and then optionally run the failure function if an error occured. | ||
| run_isolated() { | ||
| local fn="$1" cleanup_fn="$2" failure_fn="$3" | ||
| local exit_code=0 | ||
| set +e | ||
| (set -euo pipefail; "${fn}") | ||
| exit_code=$? | ||
| "${cleanup_fn}" || true | ||
| [[ ${exit_code} -eq 0 ]] || "${failure_fn}" "${exit_code}" | ||
| set -e | ||
| } | ||
|
|
||
| warn_on_failure() { | ||
| echo_warning "Nightly run FAILED (exit $1) — will retry tomorrow" | ||
| } | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Main loop | ||
| # ------------------------------------------------------------------------------ | ||
| trap 'cleanup_images || true; exit 130' INT TERM | ||
| while true; do | ||
| [[ "${RUN_NOW}" -eq 1 ]] || sleep_until_next_run | ||
| RUN_NOW=0 | ||
| run_isolated run_nightly cleanup_images warn_on_failure | ||
| done | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.