Files
project_6/cccl_upstream/ci/util/git_bisect.sh
muh-bot 2a7ca101d7 feat(cccl): integrate missing CCCL directories — python/, ci/, .agent/, docs/, test/
Sparse-checkout from NVIDIA/cccl main branch to complete cccl_upstream:

Added:
- python/cuda_cccl/ (226 files) — Python bindings for device-level algorithms
  Critical for muh toolchain: cuda.compute.reduce_into, scan, radix_sort, etc.
  Includes 204 .py files with full test coverage for all 27 algorithms
- ci/ (163 files) — Build/test infrastructure
  build_cub.sh, test_cub.sh, build_and_test_targets.sh, matrix.yaml
  Directly maps to our [INFRA-CI] and [INFRA-BUILD] items
- .agent/skills/ (7 files) — NVIDIA's own agent skills for CCCL
  cccl-style/SKILL.md, cccl-test/SKILL.md, sass-diff/SKILL.md
- docs/ (491 files) — Official CCCL documentation
  CI references, CMake guides, Python compute docs, libcudacxx PTX docs
- test/ (12 files) — Top-level integration tests (cuda_smoke, stdpar)
- Root configs: .clang-format, .clang-tidy, CONTRIBUTING.md, pyproject.toml
- CLAUDE.md symlink → AGENTS.md (NVIDIA's standard)

cccl_upstream now mirrors full NVIDIA/cccl structure:
  Before: 42M (cub + thrust + libcudacxx + cudax + c + examples + benchmarks)
  After:  53M (+python +ci +docs +.agent +test +configs)

This completes the CCCL base needed for:
- [muh-bench] items: ci/util/build_and_test_targets.sh for targeted builds
- [CCCL-verify] items: python/cuda_cccl/tests/ as reference implementations
- [CCCL-test] items: ci/test_cub.sh, ci/test_thrust.sh
- Agent workflow: .agent/skills/ for consistent style and test patterns
2026-08-07 02:34:33 +00:00

324 lines
9.7 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
ci_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ci_dir/.."
usage() {
cat <<USAGE
Usage: $0 [--preset NAME | --configure-override CMD] [options]
Generic Options:
-h, --help Show this help and exit
Bisection Options:
--good-ref STR Good ref/sha/tag/branch. Defaults to latest release tag.
Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'.
--bad-ref STR Bad ref/sha/tag/branch. Defaults to origin/main.
Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'.
--summary-file PATH Markdown summary output path (optional)
No summary file will be generated if this is omitted.
Build / Test Options:
--preset NAME CMake preset
--cmake-options STR Extra options passed to CMake preset configure (optional)
--configure-override CMD Command to run for configuration instead of cmake preset
If set, --preset and --cmake-options will be ignored
--build-targets STR Space separated ninja build targets (optional)
If omitted, no targets will be built -- explicitly specify 'all' if needed.
--ctest-targets STR Space separated CTest -R regex patterns (optional)
If omitted, no tests will be run -- explicitly specify '.' to run all.
--lit-precompile-tests STR Space-separated libcudacxx lit test paths to precompile without execution (optional)
e.g. 'cuda/utility/basic_any.pass.cpp'
--lit-tests STR Space-separated libcudacxx lit test paths to execute (optional)
e.g. 'cuda/utility/basic_any.pass.cpp'
--custom-test-cmd CMD Custom command run after build and tests (optional)
--repeat N Re-run the build/test for passing commits N times (default: 1)
USAGE
}
start_timestamp=${SECONDS}
function elapsed_time {
local duration=$(( SECONDS - start_timestamp ))
local minutes=$(( duration / 60 ))
local seconds=$(( duration % 60 ))
printf "%dm%02ds" "$minutes" "$seconds"
}
GOOD_REF=""
BAD_REF=""
PRESET=""
BUILD_TARGETS=""
CTEST_TARGETS=""
LIT_PRECOMPILE_TESTS=""
LIT_TESTS=""
SUMMARY_FILE=""
CMAKE_OPTIONS=""
CONFIGURE_OVERRIDE=""
CUSTOM_TEST_CMD=""
REPEAT=1
# Basic arg parser (keep simple, no extras)
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
--preset) PRESET="${2:-}"; shift 2 ;;
--good-ref) GOOD_REF="${2:-}"; shift 2 ;;
--bad-ref) BAD_REF="${2:-}"; shift 2 ;;
--build-targets) BUILD_TARGETS="${2:-}"; shift 2 ;;
--ctest-targets) CTEST_TARGETS="${2:-}"; shift 2 ;;
--lit-precompile-tests) LIT_PRECOMPILE_TESTS="${2:-}"; shift 2 ;;
--lit-tests) LIT_TESTS="${2:-}"; shift 2 ;;
--cmake-options) CMAKE_OPTIONS="${2:-}"; shift 2 ;;
--configure-override) CONFIGURE_OVERRIDE="${2:-}"; shift 2 ;;
--summary-file) SUMMARY_FILE="${2:-}"; shift 2 ;;
--custom-test-cmd) CUSTOM_TEST_CMD="${2:-}"; shift 2 ;;
--repeat) REPEAT="${2:-}"; shift 2 ;;
*) echo "Unknown argument: $1" >&2; usage; exit 2 ;;
esac
done
if [[ -z "${PRESET}" && -z "${CONFIGURE_OVERRIDE}" ]]; then
echo "::error:: --preset or --configure-override is required" >&2
usage
exit 2
fi
if [[ -n "${CONFIGURE_OVERRIDE}" ]]; then
if [[ -n "${PRESET}" ]]; then
echo "::warning:: --preset ignored due to --configure-override" >&2
fi
if [[ -n "${CMAKE_OPTIONS}" ]]; then
echo "::warning:: --cmake-options ignored due to --configure-override" >&2
fi
fi
# Ensure the checkout has complete history and tags:
git fetch --unshallow > /dev/null 2>&1 || :
git fetch --tags > /dev/null 2>&1 || :
# Resolve good and bad refs
good_ref="${GOOD_REF}"
bad_ref="${BAD_REF}"
# Helper to resolve '-Nd' (N days ago on origin/main) to a SHA
_resolve_days_ago() {
local spec="$1"
local base_branch="origin/main"
local n="${spec#-}"
n="${n%d}"
if [[ -z "$n" || ! "$n" =~ ^[0-9]+$ ]]; then
return 1
fi
local when
when=$(date -u -d "$n days ago" '+%Y-%m-%d %H:%M:%S %z')
git rev-list -n 1 --before="$when" "$base_branch"
}
# Resolve good_ref
if [[ -z "$good_ref" ]]; then
good_ref=$(git tag --list 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1 || :)
echo "Good ref defaulted to last release: $good_ref"
fi
if [[ "$good_ref" =~ ^-[0-9]+d$ ]]; then
good_sha=$(_resolve_days_ago "$good_ref")
if [[ -z "$good_sha" ]]; then
echo "::error::Unable to resolve good_ref '$good_ref' to a commit on origin/main" >&2
exit 1
fi
echo "Resolved good_ref '$good_ref' to origin/main @ $good_sha"
else
if [[ -z "$good_ref" ]]; then
echo "::error::Unable to determine good ref" >&2
exit 1
fi
good_sha=$(git rev-parse "$good_ref")
fi
# Resolve bad_ref
if [[ -z "$bad_ref" ]]; then
bad_ref="origin/main"
echo "Bad ref defaulted to origin/main: $bad_ref"
fi
if [[ "$bad_ref" =~ ^-[0-9]+d$ ]]; then
bad_sha=$(_resolve_days_ago "$bad_ref")
if [[ -z "$bad_sha" ]]; then
echo "::error::Unable to resolve bad_ref '$bad_ref' to a commit on origin/main" >&2
exit 1
fi
echo "Resolved bad_ref '$bad_ref' to origin/main @ $bad_sha"
else
bad_sha=$(git rev-parse "$bad_ref")
fi
# Copy the build-and-test runner to a temp file so it remains available as HEAD changes:
tmp_runner="$(mktemp /tmp/build-and-test-XXXXXX.sh)"
cp "${ci_dir}/util/build_and_test_targets.sh" "${tmp_runner}"
chmod +x "${tmp_runner}"
# If --repeat > 1, wrap the runner to repeat successful runs to detect flakiness.
bisect_runner="${tmp_runner}"
if [[ "${REPEAT}" =~ ^[0-9]+$ ]] && [[ "${REPEAT}" -gt 1 ]]; then
tmp_repeat="$(mktemp /tmp/build-and-test-repeat-XXXXXX.sh)"
cat > "${tmp_repeat}" <<EOF
#!/usr/bin/env bash
set -euo pipefail
attempts=${REPEAT}
for ((i=1; i<=attempts; ++i)); do
echo "::group::✅ build_and_test attempt \${i}/${REPEAT}"
"${tmp_runner}" "\$@" || {
echo "Attempt \${i} failed; marking commit as bad."
exit 1
}
echo "::endgroup::"
done
exit 0
EOF
chmod +x "${tmp_repeat}"
bisect_runner="${tmp_repeat}"
echo "Repeating successful runs ${REPEAT} times to check for flakiness."
fi
# Writer that always prints to stdout and tees to file if provided
write_summary() {
if [[ -n "${SUMMARY_FILE}" ]]; then
tee -a "${SUMMARY_FILE}"
else
cat
fi
}
echo "Starting bisect with:"
echo " BAD_SHA: $bad_sha"
echo " GOOD_SHA: $good_sha"
echo "::group::⚙️ Starting git bisect"
(set -x; git bisect start "$bad_sha" "$good_sha")
echo "::endgroup::"
bisect_log="$(mktemp /tmp/git-bisect-log-XXXXXX.log)"
bisect_output="$(mktemp /tmp/git-bisect-output-XXXXXX.log)"
(
set -x
git bisect run "${bisect_runner}" \
--preset "${PRESET}" \
--build-targets "${BUILD_TARGETS}" \
--ctest-targets "${CTEST_TARGETS}" \
--lit-precompile-tests "${LIT_PRECOMPILE_TESTS}" \
--lit-tests "${LIT_TESTS}" \
--cmake-options "${CMAKE_OPTIONS}" \
--configure-override "${CONFIGURE_OVERRIDE}" \
--custom-test-cmd "${CUSTOM_TEST_CMD}" \
| tee "${bisect_output}" || :
git bisect log | tee "${bisect_log}" || :
git bisect reset || :
)
if grep -q " is the first bad commit" "${bisect_output}"; then
bad_commit=$(awk '/ is the first bad commit/ {print $1}' "${bisect_output}")
echo -e "\e[1;32mFound bad commit in $(elapsed_time): $bad_commit\e[0m"
found=true
else
echo -e "\e[1;31mNo bad commit found ($(elapsed_time)).\e[0m"
found=false
fi
function print_repro {
echo "### ♻️ Reproduction Steps"
echo
echo '```bash'
if [[ -n "${LAUNCH_ARGS:-}" ]]; then
echo " .devcontainer/launch.sh \\"
echo " ${LAUNCH_ARGS} \\"
echo " -- \\"
fi
echo " ./ci/util/build_and_test_targets.sh \\"
declare -a build_test_vars=(
PRESET
CMAKE_OPTIONS
CONFIGURE_OVERRIDE
BUILD_TARGETS
CTEST_TARGETS
LIT_PRECOMPILE_TESTS
LIT_TESTS
CUSTOM_TEST_CMD
)
# only print the above vars if they're non-empty.
first=true
for var in "${build_test_vars[@]}"; do
if [[ -n "${!var:-}" ]]; then
flag="--${var,,}"
flag=${flag//_/-} # replace _ with -
if ! $first; then
echo " \\" # Trailing "\" to escape newlines
fi
echo -n " ${flag} \"${!var}\""
first=false
fi
done
echo # Final newline for last argument
echo '```'
}
if [[ "${found}" == "true" ]]; then
commit_info=$(git log "$bad_commit" -1 --pretty=format:'%h %s')
pr_ref=$(echo "$commit_info" | grep -oE '#[0-9]+' | head -n1 || :)
(
echo "## 🔎 Bisect Result"
echo
echo "- Culprit Commit: $commit_info"
if [[ -n "$pr_ref" ]]; then
pr_num=${pr_ref#\#}
echo "- Culprit PR: https://github.com/NVIDIA/cccl/pull/$pr_num"
fi
echo "- Commit SHA: $bad_commit"
echo "- Commit URL: https://github.com/NVIDIA/cccl/commit/${bad_commit}"
if [[ -n "${GHA_LOG_URL:-}" ]]; then
echo "- Bisection Logs: [GHA Job](${GHA_LOG_URL})"
fi
if [[ -n "${STEP_SUMMARY_URL:-}" ]]; then
echo "- Bisection Summary: [GHA Report](${STEP_SUMMARY_URL})"
fi
echo
print_repro
echo
echo "### Commit Details"
echo
echo '```'
git show "$bad_commit" --stat
echo '```'
echo
echo "### 🪵 Bisect Log"
echo
echo '```'
cat "${bisect_log}"
echo '```'
) | write_summary
else
(
echo "## ‼️ Bisect Failed"
echo
echo "git bisect did not resolve to a single commit."
echo
if [[ -n "${GHA_LOG_URL:-}" ]]; then
echo "- Bisection Logs: [GHA Job](${GHA_LOG_URL})"
echo "- Bisection Summary: [GHA Report](${STEP_SUMMARY_URL})"
fi
echo
print_repro
echo
echo "### 🪵 Bisect Log"
echo
echo '```'
cat "${bisect_log}"
echo '```'
) | write_summary
exit 1
fi