Skip to content

Commit

Permalink
Sync GHA setup with CCCL repo
Browse files Browse the repository at this point in the history
  • Loading branch information
sleeepyjack committed Oct 12, 2023
1 parent 72ca959 commit c906a2c
Show file tree
Hide file tree
Showing 9 changed files with 345 additions and 94 deletions.
11 changes: 8 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"shutdownAction": "stopContainer",
"image": "rapidsai/devcontainers:23.08-cpp-gcc12-cuda12.2-ubuntu22.04",
"image": "rapidsai/devcontainers:23.10-cpp-gcc12-cuda12.2-ubuntu22.04",
"hostRequirements": {
"gpu": true
},
Expand All @@ -13,7 +13,11 @@
"SCCACHE_REGION": "us-east-2",
"SCCACHE_BUCKET": "rapids-sccache-devs",
"VAULT_HOST": "https://vault.ops.k8s.rapids.ai",
"HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history"
"HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history",
"DEVCONTAINER_NAME": "cuda12.2-gcc12",
"CUCO_CUDA_VERSION": "12.2",
"CUCO_HOST_COMPILER": "gcc",
"CUCO_HOST_COMPILER_VERSION": "12"
},
"workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent",
Expand All @@ -33,5 +37,6 @@
]
}
}
}
},
"name": "cuda12.2-gcc12"
}
121 changes: 104 additions & 17 deletions .devcontainer/make_devcontainers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,103 @@
# GitHub docs on using multiple devcontainer.json files:
# https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers#devcontainerjson

set -euo pipefail

# Ensure the script is being executed in its containing directory
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";

# The root devcontainer.json file is used as a template for all other devcontainer.json files
# by replacing the `image:` field with the appropriate image name
base_devcontainer_file="./devcontainer.json"
function usage {
echo "Usage: $0 [--clean] [-h/--help] [-v/--verbose]"
echo " --clean Remove stale devcontainer subdirectories"
echo " -h, --help Display this help message"
echo " -v, --verbose Enable verbose mode (set -x)"
exit 1
}

# Function to update the devcontainer.json file with the provided parameters
update_devcontainer() {
local input_file="$1"
local output_file="$2"
local name="$3"
local cuda_version="$4"
local compiler_name="$5"
local compiler_version="$6"
local os="$7"
local devcontainer_version="$8"

# Read matrix.yaml and convert it to json
matrix_json=$(yq -o json ../ci/matrix.yml)
local IMAGE_ROOT="rapidsai/devcontainers:${devcontainer_version}-cpp-"
local image="${IMAGE_ROOT}${compiler_name}${compiler_version}-cuda${cuda_version}-${os}"

jq --arg image "$image" --arg name "$name" \
--arg cuda_version "$cuda_version" --arg compiler_name "$compiler_name" \
--arg compiler_version "$compiler_version" --arg os "$os" \
'.image = $image | .name = $name | .containerEnv.DEVCONTAINER_NAME = $name |
.containerEnv.CUCO_CUDA_VERSION = $cuda_version | .containerEnv.CUCO_HOST_COMPILER = $compiler_name |
.containerEnv.CUCO_HOST_COMPILER_VERSION = $compiler_version' \
"$input_file" > "$output_file"
}

make_name() {
local cuda_version="$1"
local compiler_name="$2"
local compiler_version="$3"

echo "cuda$cuda_version-$compiler_name$compiler_version"
}

CLEAN=false
VERBOSE=false
while [[ $# -gt 0 ]]; do
case "$1" in
--clean)
CLEAN=true
;;
-h|--help)
usage
;;
-v|--verbose)
VERBOSE=true
;;
*)
usage
;;
esac
shift
done

MATRIX_FILE="../ci/matrix.yml"

# Enable verbose mode if requested
if [ "$VERBOSE" = true ]; then
set -x
cat ${MATRIX_FILE}
fi

# Read matrix.yaml and convert it to json
matrix_json=$(yq -o json ${MATRIX_FILE})

# Get the devcontainer image version and define image tag root
DEVCONTAINER_VERSION=$(echo "$matrix_json" | jq -r '.devcontainer_version')
IMAGE_ROOT="rapidsai/devcontainers:${DEVCONTAINER_VERSION}-cpp-"
readonly DEVCONTAINER_VERSION=$(echo "$matrix_json" | jq -r '.devcontainer_version')

# Get unique combinations of cuda version, compiler name/version, and Ubuntu version
combinations=$(echo "$matrix_json" | jq -c '[.pull_request.nvcc[] | {cuda: .cuda, compiler_name: .compiler.name, compiler_version: .compiler.version, os: .os}] | unique | .[]')
readonly combinations=$(echo "$matrix_json" | jq -c '[.pull_request.nvcc[] | {cuda: .cuda, compiler_name: .compiler.name, compiler_version: .compiler.version, os: .os}] | unique | .[]')

# Update the base devcontainer with the default values
# The root devcontainer.json file is used as the default container as well as a template for all
# other devcontainer.json files by replacing the `image:` field with the appropriate image name
readonly base_devcontainer_file="./devcontainer.json"
readonly NEWEST_GCC_CUDA_ENTRY=$(echo "$combinations" | jq -rs '[.[] | select(.compiler_name == "gcc")] | sort_by((.cuda | tonumber), (.compiler_version | tonumber)) | .[-1]')
readonly DEFAULT_CUDA=$(echo "$NEWEST_GCC_CUDA_ENTRY" | jq -r '.cuda')
readonly DEFAULT_COMPILER_NAME=$(echo "$NEWEST_GCC_CUDA_ENTRY" | jq -r '.compiler_name')
readonly DEFAULT_COMPILER_VERSION=$(echo "$NEWEST_GCC_CUDA_ENTRY" | jq -r '.compiler_version')
readonly DEFAULT_OS=$(echo "$NEWEST_GCC_CUDA_ENTRY" | jq -r '.os')
readonly DEFAULT_NAME=$(make_name "$DEFAULT_CUDA" "$DEFAULT_COMPILER_NAME" "$DEFAULT_COMPILER_VERSION")

update_devcontainer ${base_devcontainer_file} "./temp_devcontainer.json" "$DEFAULT_NAME" "$DEFAULT_CUDA" "$DEFAULT_COMPILER_NAME" "$DEFAULT_COMPILER_VERSION" "$DEFAULT_OS" "$DEVCONTAINER_VERSION"
mv "./temp_devcontainer.json" ${base_devcontainer_file}

# Create an array to keep track of valid subdirectory names
valid_subdirs=()

# For each unique combination
for combination in $combinations; do
Expand All @@ -46,15 +125,23 @@ for combination in $combinations; do
compiler_version=$(echo "$combination" | jq -r '.compiler_version')
os=$(echo "$combination" | jq -r '.os')

name="cuda$cuda_version-$compiler_name$compiler_version"
name=$(make_name "$cuda_version" "$compiler_name" "$compiler_version")
mkdir -p "$name"
devcontainer_file="$name/devcontainer.json"
image="$IMAGE_ROOT$compiler_name$compiler_version-cuda$cuda_version-$os"
new_devcontainer_file="$name/devcontainer.json"

update_devcontainer "$base_devcontainer_file" "$new_devcontainer_file" "$name" "$cuda_version" "$compiler_name" "$compiler_version" "$os" "$DEVCONTAINER_VERSION"
echo "Created $new_devcontainer_file"

# Use the base_devcontainer.json as a template, plug in the CUDA, compiler names, versions, and Ubuntu version,
# and write the output to the new devcontainer.json file
#jq --arg image "$image" --arg name "$name" '. + {image: $image, name: $name}' $base_devcontainer_file > "$devcontainer_file"
jq --arg image "$image" --arg name "$name" '.image = $image | .name = $name | .containerEnv.DEVCONTAINER_NAME = $name' $base_devcontainer_file > "$devcontainer_file"
# Add the subdirectory name to the valid_subdirs array
valid_subdirs+=("$name")
done

echo "Created $devcontainer_file"
done
# Clean up stale subdirectories and devcontainer.json files
if [ "$CLEAN" = true ]; then
for subdir in ./*; do
if [ -d "$subdir" ] && [[ ! " ${valid_subdirs[@]} " =~ " ${subdir#./} " ]]; then
echo "Removing stale subdirectory: $subdir"
rm -r "$subdir"
fi
done
fi
82 changes: 82 additions & 0 deletions .devcontainer/verify_devcontainer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash

function usage {
echo "Usage: $0"
echo
echo "This script is intended to be run within one of CUCO's Dev Containers."
echo "It verifies that the expected environment variables and binary versions match what is expected."
}

check_envvars() {
for var_name in "$@"; do
if [[ -z "${!var_name:-}" ]]; then
echo "::error:: ${var_name} variable is not set."
exit 1
else
echo "$var_name=${!var_name}"
fi
done
}

check_host_compiler_version() {
local version_output=$($CXX --version)

if [[ "$CXX" == "g++" ]]; then
local actual_version=$(echo "$version_output" | head -n 1 | cut -d ' ' -f 4 | cut -d '.' -f 1)
local expected_compiler="gcc"
elif [[ "$CXX" == "clang++" ]]; then
if [[ $version_output =~ clang\ version\ ([0-9]+) ]]; then
actual_version=${BASH_REMATCH[1]}
else
echo "::error:: Unable to determine clang version."
exit 1
fi
expected_compiler="llvm"
else
echo "::error:: Unexpected CXX value ($CXX)."
exit 1
fi

if [[ "$expected_compiler" != "${CUCO_HOST_COMPILER}" || "$actual_version" != "$CUCO_HOST_COMPILER_VERSION" ]]; then
echo "::error:: CXX ($CXX) version ($actual_version) does not match the expected compiler (${CUCO_HOST_COMPILER}) and version (${CUCO_HOST_COMPILER_VERSION})."
exit 1
else
echo "Detected host compiler: $CXX version $actual_version"
fi
}

check_cuda_version() {
local cuda_version_output=$(nvcc --version)
if [[ $cuda_version_output =~ release\ ([0-9]+\.[0-9]+) ]]; then
local actual_cuda_version=${BASH_REMATCH[1]}
else
echo "::error:: Unable to determine CUDA version from nvcc."
exit 1
fi

if [[ "$actual_cuda_version" != "$CUCO_CUDA_VERSION" ]]; then
echo "::error:: CUDA version ($actual_cuda_version) does not match the expected CUDA version ($CUCO_CUDA_VERSION)."
exit 1
else
echo "Detected CUDA version: $actual_cuda_version"
fi
}

main() {
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
usage
exit 0
fi

set -euo pipefail

check_envvars DEVCONTAINER_NAME CXX CUCO_HOST_COMPILER CUCO_CUDA_VERSION CUCO_HOST_COMPILER_VERSION

check_host_compiler_version

check_cuda_version

echo "Dev Container successfully verified!"
}

main "$@"
55 changes: 40 additions & 15 deletions .github/actions/compute-matrix/compute-matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,47 @@

set -euo pipefail

# Check for the correct number of arguments
if [ $# -ne 2 ]; then
echo "Usage: $0 MATRIX_FILE MATRIX_QUERY"
echo "MATRIX_FILE: The path to the matrix file."
echo "MATRIX_QUERY: The jq query used to specify the desired matrix. e.g., '.pull-request.nvcc'"
write_output() {
local key="$1"
local value="$2"
echo "$key=$value" | tee --append "${GITHUB_OUTPUT:-/dev/null}"
}

explode_std_versions() {
jq -cr 'map(. as $o | {std: $o.std[]} + del($o.std))'
}

extract_matrix() {
local file="$1"
local type="$2"
local matrix=$(yq -o=json "$file" | jq -cr ".$type")
write_output "DEVCONTAINER_VERSION" "$(yq -o json "$file" | jq -cr '.devcontainer_version')"
local nvcc_full_matrix="$(echo "$matrix" | jq -cr '.nvcc' | explode_std_versions )"
write_output "NVCC_FULL_MATRIX" "$nvcc_full_matrix"
write_output "CUDA_VERSIONS" "$(echo "$nvcc_full_matrix" | jq -cr '[.[] | .cuda] | unique')"
write_output "HOST_COMPILERS" "$(echo "$nvcc_full_matrix" | jq -cr '[.[] | .compiler.name] | unique')"
write_output "PER_CUDA_COMPILER_MATRIX" "$(echo "$nvcc_full_matrix" | jq -cr ' group_by(.cuda + .compiler.name) | map({(.[0].cuda + "-" + .[0].compiler.name): .}) | add')"
}

main() {
if [ "$1" == "-v" ]; then
set -x
shift
fi

if [ $# -ne 2 ] || [ "$2" != "pull_request" ]; then
echo "Usage: $0 [-v] MATRIX_FILE MATRIX_TYPE"
echo " -v : Enable verbose output"
echo " MATRIX_FILE : The path to the matrix file."
echo " MATRIX_TYPE : The desired matrix. Supported values: 'pull_request'"
exit 1
fi
fi

# Get realpath before changing directory
MATRIX_FILE=$(realpath "$1")
MATRIX_QUERY="$2"
echo "Input matrix file:" >&2
cat "$1" >&2
echo "Matrix Type: $2" >&2

# Ensure the script is being executed in its containing directory
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
extract_matrix "$1" "$2"
}

echo "Input matrix file:" >&2
cat "$MATRIX_FILE" >&2
echo "Query: $MATRIX_QUERY" >&2
echo $(yq -o=json "$MATRIX_FILE" | jq -c -r "$MATRIX_QUERY | map(. as \$o | {std: .std[]} + del(\$o.std))")
main "$@"
Loading

0 comments on commit c906a2c

Please sign in to comment.