From 4d7fdb40390f8f30ece93665366b1e825a0ec55b Mon Sep 17 00:00:00 2001 From: Allison Piper Date: Mon, 22 Apr 2024 21:59:33 +0000 Subject: [PATCH] More iteration. --- .github/workflows/ci-dispatch-job.yml | 2 +- .github/workflows/pr.yml | 144 -------------------------- ci/build_common.sh | 7 +- ci/compute-matrix.py | 31 +++--- ci/infra_cccl.sh | 20 ++++ ci/inspect_changes.sh | 17 ++- ci/matrix.yaml | 84 +++++++-------- 7 files changed, 94 insertions(+), 211 deletions(-) create mode 100755 ci/infra_cccl.sh diff --git a/.github/workflows/ci-dispatch-job.yml b/.github/workflows/ci-dispatch-job.yml index d7ce3f79780..9a61d7cc470 100644 --- a/.github/workflows/ci-dispatch-job.yml +++ b/.github/workflows/ci-dispatch-job.yml @@ -56,7 +56,7 @@ jobs: NVIDIA_VISIBLE_DEVICES: ${{ env.NVIDIA_VISIBLE_DEVICES }} steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v3 with: path: cccl persist-credentials: false diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 9ab6e3ca5b2..a031425712f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -90,150 +90,6 @@ jobs: ${{contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')}} run: exit 1 -# jobs: -# inspect-changes: -# name: "Inspect Changes" -# runs-on: ubuntu-latest -# outputs: -# LIBCUDACXX_DIRTY: ${{ steps.set-outputs.outputs.LIBCUDACXX_DIRTY }} -# CUB_DIRTY: ${{ steps.set-outputs.outputs.CUB_DIRTY }} -# THRUST_DIRTY: ${{ steps.set-outputs.outputs.THRUST_DIRTY }} -# steps: -# - name: Get Base Branch from PR -# id: get-pr-info -# uses: nv-gha-runners/get-pr-info@main -# - name: Checkout repo -# uses: actions/checkout@v3 -# - name: Identify dirty subprojects -# id: set-outputs -# run: | -# ./ci/inspect_changes.sh ${BASE_SHA} ${GITHUB_SHA} -# env: -# BASE_SHA: ${{ fromJSON(steps.get-pr-info.outputs.pr-info).base.sha }} - -# compute-matrix: -# name: Compute matrix -# runs-on: ubuntu-latest -# needs: -# - inspect-changes -# outputs: -# DEVCONTAINER_VERSION: ${{steps.set-outputs.outputs.DEVCONTAINER_VERSION}} -# PER_CUDA_COMPILER_MATRIX: ${{steps.set-outputs.outputs.PER_CUDA_COMPILER_MATRIX}} -# PER_CUDA_COMPILER_KEYS: ${{steps.set-outputs.outputs.PER_CUDA_COMPILER_KEYS}} -# NVRTC_MATRIX: ${{steps.set-outputs.outputs.NVRTC_MATRIX}} -# CLANG_CUDA_MATRIX: ${{steps.set-outputs.outputs.CLANG_CUDA_MATRIX}} -# CCCL_INFRA_MATRIX: ${{steps.set-outputs.outputs.CCCL_INFRA_MATRIX}} -# steps: -# - name: Checkout repo -# uses: actions/checkout@v3 -# - name: Compute matrix outputs -# id: set-outputs -# run: | -# .github/actions/compute-matrix/compute-matrix.sh ci/matrix.yaml pull_request -# env: -# THRUST_DIRTY: ${{ needs.inspect-changes.outputs.THRUST_DIRTY }} -# CUB_DIRTY: ${{ needs.inspect-changes.outputs.CUB_DIRTY }} -# LIBCUDACXX_DIRTY: ${{ needs.inspect-changes.outputs.LIBCUDACXX_DIRTY }} - -# nvrtc: -# name: libcudacxx NVRTC CUDA${{matrix.cuda}} -# permissions: -# id-token: write -# contents: read -# needs: -# - compute-matrix -# - inspect-changes -# if: ${{ !contains(github.event.head_commit.message, 'skip-tests') && needs.inspect-changes.outputs.LIBCUDACXX_DIRTY == 'true' }} -# uses: ./.github/workflows/run-as-coder.yml -# strategy: -# fail-fast: false -# matrix: -# include: ${{ fromJSON(needs.compute-matrix.outputs.NVRTC_MATRIX) }} -# with: -# name: Build and Test libcudacxx CUDA${{matrix.cuda}} C++${{matrix.std}} -# runner: linux-${{matrix.cpu}}-gpu-v100-latest-1 -# image: rapidsai/devcontainers:${{needs.compute-matrix.outputs.DEVCONTAINER_VERSION}}-cpp-gcc12-cuda${{matrix.cuda}}-${{matrix.os}} -# command: | -# ./ci/nvrtc_libcudacxx.sh -cxx g++ -std ${{matrix.std}} - -# thrust: -# name: Thrust CUDA${{ matrix.cuda_host_combination }} -# permissions: -# id-token: write -# contents: read -# needs: -# - compute-matrix -# - inspect-changes -# if: ${{ needs.inspect-changes.outputs.THRUST_DIRTY == 'true' }} -# uses: ./.github/workflows/dispatch-build-and-test.yml -# strategy: -# fail-fast: false -# matrix: -# cuda_host_combination: ${{ fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_KEYS) }} -# with: -# project_name: "thrust" -# per_cuda_compiler_matrix: ${{ toJSON(fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_MATRIX)[ matrix.cuda_host_combination ]) }} -# devcontainer_version: ${{ needs.compute-matrix.outputs.DEVCONTAINER_VERSION }} -# is_windows: ${{ contains(matrix.cuda_host_combination, 'cl') }} - -# cub: -# name: CUB CUDA${{ matrix.cuda_host_combination }} -# permissions: -# id-token: write -# contents: read -# needs: -# - compute-matrix -# - inspect-changes -# if: ${{ needs.inspect-changes.outputs.CUB_DIRTY == 'true' }} -# uses: ./.github/workflows/dispatch-build-and-test.yml -# strategy: -# fail-fast: false -# matrix: -# cuda_host_combination: ${{ fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_KEYS) }} -# with: -# project_name: "cub" -# per_cuda_compiler_matrix: ${{ toJSON(fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_MATRIX)[ matrix.cuda_host_combination ]) }} -# devcontainer_version: ${{ needs.compute-matrix.outputs.DEVCONTAINER_VERSION }} -# is_windows: ${{ contains(matrix.cuda_host_combination, 'cl') }} - -# libcudacxx: -# name: libcudacxx CUDA${{ matrix.cuda_host_combination }} -# permissions: -# id-token: write -# contents: read -# needs: -# - compute-matrix -# - inspect-changes -# if: ${{ needs.inspect-changes.outputs.LIBCUDACXX_DIRTY == 'true' }} -# uses: ./.github/workflows/dispatch-build-and-test.yml -# strategy: -# fail-fast: false -# matrix: -# cuda_host_combination: ${{ fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_KEYS) }} -# with: -# project_name: "libcudacxx" -# per_cuda_compiler_matrix: ${{ toJSON(fromJSON(needs.compute-matrix.outputs.PER_CUDA_COMPILER_MATRIX)[ matrix.cuda_host_combination ]) }} -# devcontainer_version: ${{ needs.compute-matrix.outputs.DEVCONTAINER_VERSION }} -# is_windows: ${{ contains(matrix.cuda_host_combination, 'cl') }} - -# clang-cuda: -# name: ${{matrix.lib}} Clang CUDA -# permissions: -# id-token: write -# contents: read -# needs: compute-matrix -# strategy: -# fail-fast: false -# matrix: -# include: ${{ fromJSON(needs.compute-matrix.outputs.CLANG_CUDA_MATRIX) }} -# uses: ./.github/workflows/run-as-coder.yml -# with: -# name: Build ${{matrix.lib}} ${{matrix.cpu}}/clang-cuda${{matrix.compiler.version}}/C++${{matrix.std}} -# runner: linux-${{matrix.cpu}}-cpu16 -# image: rapidsai/devcontainers:${{needs.compute-matrix.outputs.DEVCONTAINER_VERSION}}-cpp-${{matrix.compiler.name}}${{matrix.compiler.version}}-cuda${{matrix.cuda}}-${{matrix.os}} -# command: | -# ./ci/build_${{matrix.lib}}.sh -cxx "${{matrix.compiler.exe}}" -cuda "${{matrix.compiler.exe}}" -std "${{matrix.std}}" - # cccl-infra: # name: CCCL Infrastructure # permissions: diff --git a/ci/build_common.sh b/ci/build_common.sh index 1ab262c311a..4b46252c69b 100755 --- a/ci/build_common.sh +++ b/ci/build_common.sh @@ -216,10 +216,13 @@ function test_preset() { local BUILD_NAME=$1 local PRESET=$2 - local GROUP_NAME="🚀 Test ${BUILD_NAME}" + local GPU_REQUIRED=${3:-"true"} - fail_if_no_gpu + if [ $GPU_REQUIRED -eq "true" ]; then + fail_if_no_gpu + fi + local GROUP_NAME="🚀 Test ${BUILD_NAME}" ctest_log_dir="${BUILD_DIR}/log/ctest" ctest_log="${ctest_log_dir}/${PRESET}" diff --git a/ci/compute-matrix.py b/ci/compute-matrix.py index 5f11407553a..7db3e92380b 100755 --- a/ci/compute-matrix.py +++ b/ci/compute-matrix.py @@ -109,12 +109,16 @@ def is_windows(matrix_job): def validate_matrix_job(matrix_job): for tag in matrix_yaml['required_tags']: if tag not in matrix_job: - raise Exception(f"Missing required tag {tag} in matrix job {matrix_job}") + raise Exception(f"Missing required tag '{tag}' in matrix job {matrix_job}") + + required_tags = set(matrix_yaml['required_tags']) + defaulted_tags = set(matrix_yaml['defaulted_tags']) + optional_tags = set(matrix_yaml['optional_tags']) + all_tags = required_tags | defaulted_tags | optional_tags - all_tags = set(matrix_job.keys()) | set(matrix_yaml['required_tags']) | set(matrix_yaml['defaulted_tags']) for tag in matrix_job: if tag not in all_tags: - raise Exception(f"Unknown tag {tag} in matrix job {matrix_job}") + raise Exception(f"Unknown tag '{tag}' in matrix job {matrix_job}") def fill_defaults_matrix_job(matrix_job): @@ -171,7 +175,7 @@ def generate_dispatch_group_name(matrix_job): def generate_dispatch_job_name(matrix_job, job_type): - std_ver = matrix_job['std'][0] + std_str = ("C++" + str(matrix_job['std'][0]) + " ") if 'std' in matrix_job else '' cpu_str = matrix_job['cpu'] gpu_str = (', ' + matrix_job['gpu'].upper()) if job_type in matrix_yaml['gpu_required_job_types'] else "" cuda_compile_arch = (" sm{" + matrix_job['cmake_cuda_arch'] + "}") if 'cmake_cuda_arch' in matrix_job else "" @@ -180,22 +184,12 @@ def generate_dispatch_job_name(matrix_job, job_type): host_compiler_name = get_formatted_host_compiler_name(matrix_job['host_compiler']) host_compiler_info = f"{host_compiler_name}{matrix_job['host_compiler']['version']}" - config_tag = f"C++{std_ver} {host_compiler_info}{cuda_compile_arch}" + config_tag = f"{std_str}{host_compiler_info}{cuda_compile_arch}" formatted_job_type = get_formatted_job_type(job_type) return f"[{config_tag}] {formatted_job_type}({cpu_str}{gpu_str})" - return "[{}-{} C++{}] {}({}{}){}".format( - matrix_job['host_compiler']['name'], - matrix_job['host_compiler']['version'], - matrix_job['std'][0], - formatted_job_type, - matrix_job['cpu'], - gpu_str, - extra_args - ) - def generate_dispatch_job_runner(matrix_job, job_type): runner_os = "windows" if is_windows(matrix_job) else "linux" @@ -230,7 +224,8 @@ def generate_dispatch_job_command(matrix_job, job_type): script_project = matrix_job['projects'][0] script_name = f"{script_path}/{script_job_type}_{script_project}{script_ext}" - std = matrix_job['std'][0] + std_str = str(matrix_job['std'][0]) if 'std' in matrix_job else '' + host_compiler_exe = matrix_job['host_compiler']['exe'] device_compiler_name = matrix_job['device_compiler']['name'] device_compiler_exe = matrix_job['device_compiler']['exe'] @@ -238,7 +233,9 @@ def generate_dispatch_job_command(matrix_job, job_type): cuda_compile_arch = matrix_job['cmake_cuda_arch'] if 'cmake_cuda_arch' in matrix_job else '' cmake_options = matrix_job['cmake_options'] if 'cmake_options' in matrix_job else '' - command = f"\"{script_name}\" -std {std}" + command = f"\"{script_name}\"" + if std_str: + command += f" -std \"{std_str}\"" if cuda_compile_arch: command += f" -arch \"{cuda_compile_arch}\"" if device_compiler_name != 'nvcc': diff --git a/ci/infra_cccl.sh b/ci/infra_cccl.sh new file mode 100755 index 00000000000..475799ace26 --- /dev/null +++ b/ci/infra_cccl.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +source "$(dirname "$0")/build_common.sh" + +print_environment_details + +PRESET="cccl-infra" + +CMAKE_OPTIONS="" + +GPU_REQUIRED="false" + +if [ -n "${GITHUB_SHA:-}" ]; then + CMAKE_OPTIONS="$CMAKE_OPTIONS -DCCCL_EXAMPLE_CPM_TAG=${GITHUB_SHA}" +fi + +configure_preset "CCCL Infra" "$PRESET" "$CMAKE_OPTIONS" +test_preset "CCCL Infra" "$PRESET" "$GPU_REQUIRED" + +print_time_summary diff --git a/ci/inspect_changes.sh b/ci/inspect_changes.sh index 7385318f524..357257c495a 100755 --- a/ci/inspect_changes.sh +++ b/ci/inspect_changes.sh @@ -21,6 +21,7 @@ base_sha=$(git merge-base $head_sha $base_sha) # Define a list of subproject directories: subprojects=( + cccl libcudacxx cub thrust @@ -28,6 +29,7 @@ subprojects=( # ...and their dependencies: declare -A dependencies=( + [cccl]="" [libcudacxx]="cccl" [cub]="cccl libcudacxx thrust" [thrust]="cccl libcudacxx cub" @@ -110,16 +112,24 @@ main() { echo "" echo "Modifications in project?" + # Assign the return value of `inspect_cccl` to the variable `CCCL_DIRTY`: inspect_cccl CCCL_DIRTY=$? - echo "$(if [[ ${CCCL_DIRTY} -eq 0 ]]; then echo " "; else echo "X"; fi) - CCCL Infrastructure" + checkmark=$(if [[ ${CCCL_DIRTY} -eq 0 ]]; then echo " "; else echo "X"; fi) + echo "${checkmark} - CCCL Infrastructure" # Check for changes in each subprojects directory: for subproject in "${subprojects[@]}"; do + if [[ ${subproject} == "cccl" ]]; then + # Special case handled above. + continue + fi + inspect_subdir $subproject declare ${subproject^^}_DIRTY=$? - echo "$(if [[ ${subproject^^}_DIRTY -eq 0 ]]; then echo " "; else echo "X"; fi) - ${subproject}" + checkmark=$(if [[ ${subproject^^}_DIRTY -eq 0 ]]; then echo " "; else echo "X"; fi) + echo "${checkmark} - ${subproject}" done echo @@ -127,7 +137,8 @@ main() { for subproject in "${subprojects[@]}"; do add_dependencies ${subproject} declare ${subproject^^}_DIRTY=$? - echo "$(if [[ ${subproject^^}_DIRTY -eq 0 ]]; then echo " "; else echo "X"; fi) - ${subproject}" + checkmark=$(if [[ ${subproject^^}_DIRTY -eq 0 ]]; then echo " "; else echo "X"; fi) + echo "${checkmark} - ${subproject}" done echo diff --git a/ci/matrix.yaml b/ci/matrix.yaml index a72136ee952..e1232e7b2c2 100644 --- a/ci/matrix.yaml +++ b/ci/matrix.yaml @@ -40,6 +40,41 @@ oneapi: &oneapi { name: 'oneapi', version: '2023.2.0', exe: 'icpc' } # Resources for compute_matrix.py: # +# Error if tags are missing: +required_tags: ['job_types'] + +# Tags that will be added if not specified: +defaulted_tags: ['ctk', 'cpu', 'gpu', 'host_compiler', 'device_compiler', 'projects', 'os'] + +# Tags that may be omitted: +optional_tags: ['std', 'cmake_cuda_arch', 'cmake_options'] + + # If these tags are lists, they will be exploded into separate jobs +explodable_tags: ['projects', 'std'] + +# job_types that have an implied prerequisite 'build' job: +build_required_job_types: ['test'] + +# job_types that require a GPU +gpu_required_job_types: + - 'test' + - 'nvrtc' + - 'infra' # cccl infra's example project test launches a kernel + +formatted_job_types: # Default: Capitalize first letter. + 'nvrtc': 'NVRTC' + +formatted_project_names: + 'libcudacxx': 'libcu++' + 'cub': 'CUB' + 'thrust': 'Thrust' + 'cccl': 'CCCL' + +formatted_host_compiler_names: + 'llvm': 'clang' + 'oneapi': 'intel' + 'cl': 'MSVC' + # `default_`: Used when the tag is omitted. default_ctk: *ctk_curr default_device_compiler: 'nvcc' @@ -84,7 +119,7 @@ all_gpus: - 'rtxa6000' # 12x: sm86, 48 GB - 'l4' # 48x: sm89, 24 GB - 'rtx4090' # 10x: sm89, 24 GB - - 'h100' # 16x: sm90, ?? GB + - 'h100' # 16x: sm90, 80 GB testing_pool_gpus: - 't4' - 'rtx2080' @@ -93,44 +128,6 @@ testing_pool_gpus: - 'rtx4090' - 'h100' -all_projects: - - 'libcudacxx' - - 'cub' - - 'thrust' -formatted_project_names: - 'libcudacxx': 'libcu++' - 'cub': 'CUB' - 'thrust': 'Thrust' - -all_job_types: - - 'build' - - 'test' - - 'nvrtc' -formatted_job_types: # Default: Capitalize first letter. - 'nvrtc': 'NVRTC' - -formatted_host_compiler_names: - 'llvm': 'clang' - 'oneapi': 'intel' - 'cl': 'MSVC' - -# Error if tags are missing: -required_tags: &required_tags ['job_types'] - -# Tags that will be added if not specified: -defaulted_tags: &defaulted_tags ['ctk', 'cpu', 'gpu', 'host_compiler', 'device_compiler', 'std', 'projects', 'os'] - -# Tags that may be omitted: -optional_tags: &optional_tags ['cmake_cuda_arch', 'cmake_options'] - -# If these tags are lists, they will be exploded into separate jobs -explodable_tags: ['projects', 'std'] - -# job_types that have an implied prerequisite 'build' job: -build_required_job_types: ['test'] - -# job_types that require a GPU -gpu_required_job_types: ['test', 'nvrtc'] # # Workflow matrices: @@ -170,11 +167,10 @@ pull_request: # clang-cuda: - {job_types: ['build'], device_compiler: *llvm-newest, host_compiler: *llvm-newest, std: [17, 20]} # cccl-infra: - # TODO: - # - {ctk: *ctk_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *gcc-oldest} - # - {ctk: *ctk_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *llvm-oldest} - # - {ctk: *ctk_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *gcc-newest} - # - {ctk: *ctk_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *llvm-newest} + - {projects: ['cccl'], job_types: ['infra'], ctk: *ctk_prev_min, host_compiler: *gcc-oldest} + - {projects: ['cccl'], job_types: ['infra'], ctk: *ctk_prev_min, host_compiler: *llvm-oldest} + - {projects: ['cccl'], job_types: ['infra'], ctk: *ctk_curr, host_compiler: *gcc-newest} + - {projects: ['cccl'], job_types: ['infra'], ctk: *ctk_curr, host_compiler: *llvm-newest} # Run each night: nightly: