From eb5940c64f0ca23170856b450b0f6b4f6e1fd1e4 Mon Sep 17 00:00:00 2001 From: Allison Piper Date: Thu, 4 Apr 2024 21:07:27 +0000 Subject: [PATCH] Add initial CI, presets, and devcontainers. --- .clangd | 1 - .devcontainer/README.md | 198 ++++++++++++++ .devcontainer/cuda11.1-gcc6/devcontainer.json | 46 ++++ .devcontainer/cuda11.1-gcc7/devcontainer.json | 46 ++++ .devcontainer/cuda11.1-gcc8/devcontainer.json | 46 ++++ .devcontainer/cuda11.1-gcc9/devcontainer.json | 46 ++++ .../cuda11.1-llvm9/devcontainer.json | 46 ++++ .../cuda11.8-gcc11/devcontainer.json | 46 ++++ .../cuda12.4-gcc10/devcontainer.json | 46 ++++ .../cuda12.4-gcc11/devcontainer.json | 46 ++++ .../cuda12.4-gcc12/devcontainer.json | 46 ++++ .devcontainer/cuda12.4-gcc7/devcontainer.json | 46 ++++ .devcontainer/cuda12.4-gcc8/devcontainer.json | 46 ++++ .devcontainer/cuda12.4-gcc9/devcontainer.json | 46 ++++ .../cuda12.4-llvm10/devcontainer.json | 46 ++++ .../cuda12.4-llvm11/devcontainer.json | 46 ++++ .../cuda12.4-llvm12/devcontainer.json | 46 ++++ .../cuda12.4-llvm13/devcontainer.json | 46 ++++ .../cuda12.4-llvm14/devcontainer.json | 46 ++++ .../cuda12.4-llvm15/devcontainer.json | 46 ++++ .../cuda12.4-llvm16/devcontainer.json | 46 ++++ .../cuda12.4-llvm9/devcontainer.json | 46 ++++ .../cuda12.4-oneapi2023.2.0/devcontainer.json | 46 ++++ .devcontainer/devcontainer.json | 46 ++++ .devcontainer/img/container_list.png | Bin 0 -> 159943 bytes .devcontainer/img/github_auth.png | Bin 0 -> 54609 bytes .../img/open_in_container_manual.png | Bin 0 -> 58565 bytes .devcontainer/img/reopen_in_container.png | Bin 0 -> 27864 bytes .devcontainer/launch.sh | 130 +++++++++ .devcontainer/make_devcontainers.sh | 141 ++++++++++ .devcontainer/verify_devcontainer.sh | 89 +++++++ .github/actions/compute-matrix/action.yml | 25 ++ .../actions/compute-matrix/compute-matrix.sh | 52 ++++ .../actions/configure_cccl_sccache/action.yml | 19 ++ .github/copy-pr-bot.yaml | 4 + .github/problem-matchers/problem-matcher.json | 14 + .github/workflows/build-and-test-linux.yml | 47 ++++ .github/workflows/build-and-test-windows.yml | 49 ++++ .github/workflows/dispatch-build-and-test.yml | 51 ++++ .github/workflows/pr.yml | 95 +++++++ .github/workflows/run-as-coder.yml | 67 +++++ .github/workflows/verify-devcontainers.yml | 94 +++++++ .gitignore | 3 + CMakePresets.json | 76 ++++++ ci/axis/cpu.yml | 38 --- ci/axis/gpu.yml | 30 --- ci/build_common.sh | 246 ++++++++++++++++++ ci/build_nvbench.sh | 13 + ci/common/build.bash | 231 ---------------- ci/common/determine_build_parallelism.bash | 119 --------- ci/cpu/build.bash | 14 - ci/gpu/build.bash | 14 - ci/local/build.bash | 215 --------------- ci/matrix.yaml | 85 ++++++ ci/pretty_printing.sh | 105 ++++++++ ci/sccache_hit_rate.sh | 41 +++ ci/sccache_stats.sh | 52 ++++ ci/test_nvbench.sh | 18 ++ ci/windows/build_common.psm1 | 205 +++++++++++++++ ci/windows/build_nvbench.ps1 | 26 ++ cmake/PrintCTestRunTimes.cmake | 127 +++++++++ cmake/PrintNinjaBuildTimes.cmake | 101 +++++++ 62 files changed, 3185 insertions(+), 662 deletions(-) create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/cuda11.1-gcc6/devcontainer.json create mode 100644 .devcontainer/cuda11.1-gcc7/devcontainer.json create mode 100644 .devcontainer/cuda11.1-gcc8/devcontainer.json create mode 100644 .devcontainer/cuda11.1-gcc9/devcontainer.json create mode 100644 .devcontainer/cuda11.1-llvm9/devcontainer.json create mode 100644 .devcontainer/cuda11.8-gcc11/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc10/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc11/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc12/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc7/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc8/devcontainer.json create mode 100644 .devcontainer/cuda12.4-gcc9/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm10/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm11/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm12/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm13/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm14/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm15/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm16/devcontainer.json create mode 100644 .devcontainer/cuda12.4-llvm9/devcontainer.json create mode 100644 .devcontainer/cuda12.4-oneapi2023.2.0/devcontainer.json create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/img/container_list.png create mode 100644 .devcontainer/img/github_auth.png create mode 100644 .devcontainer/img/open_in_container_manual.png create mode 100644 .devcontainer/img/reopen_in_container.png create mode 100755 .devcontainer/launch.sh create mode 100755 .devcontainer/make_devcontainers.sh create mode 100755 .devcontainer/verify_devcontainer.sh create mode 100644 .github/actions/compute-matrix/action.yml create mode 100755 .github/actions/compute-matrix/compute-matrix.sh create mode 100644 .github/actions/configure_cccl_sccache/action.yml create mode 100644 .github/copy-pr-bot.yaml create mode 100644 .github/problem-matchers/problem-matcher.json create mode 100644 .github/workflows/build-and-test-linux.yml create mode 100644 .github/workflows/build-and-test-windows.yml create mode 100644 .github/workflows/dispatch-build-and-test.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/run-as-coder.yml create mode 100644 .github/workflows/verify-devcontainers.yml create mode 100644 CMakePresets.json delete mode 100644 ci/axis/cpu.yml delete mode 100644 ci/axis/gpu.yml create mode 100755 ci/build_common.sh create mode 100755 ci/build_nvbench.sh delete mode 100755 ci/common/build.bash delete mode 100755 ci/common/determine_build_parallelism.bash delete mode 100755 ci/cpu/build.bash delete mode 100755 ci/gpu/build.bash delete mode 100755 ci/local/build.bash create mode 100644 ci/matrix.yaml create mode 100644 ci/pretty_printing.sh create mode 100755 ci/sccache_hit_rate.sh create mode 100755 ci/sccache_stats.sh create mode 100755 ci/test_nvbench.sh create mode 100644 ci/windows/build_common.psm1 create mode 100644 ci/windows/build_nvbench.ps1 create mode 100644 cmake/PrintCTestRunTimes.cmake create mode 100644 cmake/PrintNinjaBuildTimes.cmake diff --git a/.clangd b/.clangd index 1649e163..0e4c84bd 100644 --- a/.clangd +++ b/.clangd @@ -32,7 +32,6 @@ CompileFlags: # report all errors - "-ferror-limit=0" - "-ftemplate-backtrace-limit=0" - - "-stdlib=libc++" - "-std=c++17" Remove: # strip CUDA fatbin args diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..e84b5f39 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,198 @@ +> **Note** +> The instructions in this README are specific to Linux development environments. Instructions for Windows are coming soon! + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/NVIDIA/cccl?quickstart=1&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +# CCCL Dev Containers + +CCCL uses [Development Containers](https://containers.dev/) to provide consistent and convenient development environments for both local development and for CI. This guide covers setup in [Visual Studio Code](#quickstart-vscode-recommended) and [Docker](#quickstart-docker-manual-approach). The guide also provides additional instructions in case you want use WSL. + +## Table of Contents +1. [Quickstart: VSCode (Recommended)](#vscode) +2. [Quickstart: Docker (Manual Approach)](#docker) +3. [Quickstart: Using WSL](#wsl) + +## Quickstart: VSCode (Recommended) + +### Prerequisites +- [Visual Studio Code](https://code.visualstudio.com/) +- [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +- [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) +- [Docker](https://docs.docker.com/engine/install/) - This is only for completeness because it should already be implicitly installed by the Dev Containers extension + +### Steps + +1. Clone the Repository + ```bash + git clone https://github.com/nvidia/cccl.git + ``` +2. Open the cloned directory in VSCode + +3. Launch a Dev Container by clicking the prompt suggesting to "Reopen in Container" + + ![Shows "Reopen in Container" prompt when opening the cccl directory in VScode.](./img/reopen_in_container.png) + + - Alternatively, use the Command Palette to start a Dev Container. Press `Ctrl+Shift+P` to open the Command Palette. Type "Remote-Containers: Reopen in Container" and select it. + + ![Shows "Reopen in Container" in command pallete.](./img/open_in_container_manual.png) + +4. Select an environment with the desired CTK and host compiler from the list: + + ![Shows list of available container environments.](./img/container_list.png) + +5. VSCode will initialize the selected Dev Container. This can take a few minutes the first time. + +6. Once initialized, the local `cccl/` directory is mirrored into the container to ensure any changes are persistent. + +7. Done! See the [contributing guide](../CONTRIBUTING.md#building-and-testing) for instructions on how to build and run tests. + +### (Optional) Authenticate with GitHub for `sccache` + +After starting the container, there will be a prompt to authenticate with GitHub. This grants access to a [`sccache`](https://github.com/mozilla/sccache) server shared with CI and greatly accelerates local build times. This is currently limited to NVIDIA employees belonging to the `NVIDIA` or `rapidsai` GitHub organizations. + +Without authentication to the remote server, `sccache` will still accelerate local builds by using a filesystem cache. + +Follow the instructions in the prompt as below and enter the one-time code at https://github.com/login/device + + ![Shows authentication with GitHub to access sccache bucket.](./img/github_auth.png) + +To manually trigger this authentication, execute the `devcontainer-utils-vault-s3-init` script within the container. + +For more information about the sccache configuration and authentication, see the documentation at [`rapidsai/devcontainers`](https://github.com/rapidsai/devcontainers/blob/branch-23.10/USAGE.md#build-caching-with-sccache). + +## Quickstart: Docker (Manual Approach) + +### Prerequisites +- [Docker](https://docs.docker.com/desktop/install/linux-install/) + +### Steps +1. Clone the repository and use the [`launch.sh`](./launch.sh) script to launch the default container environment + ```bash + git clone https://github.com/nvidia/cccl.git + cd cccl + ./.devcontainer/launch.sh --docker + ``` + This script starts an interactive shell as the `coder` user inside the container with the local `cccl/` directory mirrored into `/home/coder/cccl`. + + For specific environments, use the `--cuda` and `--host` options: + ```bassh + ./.devcontainer/launch.sh --docker --cuda 12.2 --host gcc10 + ``` + See `./.devcontainer/launch.sh --help` for more information. + +2. Done. See the [contributing guide](../CONTRIBUTING.md#building-and-testing) for instructions on how to build and run tests. + +## Available Environments + +CCCL provides environments for both the oldest and newest supported CUDA versions with all compatible host compilers. + +Look in the [`.devcontainer/`](.) directory to see the available configurations. The top-level [`devcontainer.json`](./devcontainer.json) serves as the default environment. All `devcontainer.json` files in the `cuda-` sub-directories are variations on this top-level file, with different base images for the different CUDA and host compiler versions. + +## VSCode Customization + +By default, CCCL's Dev Containers come with certain VSCode settings and extensions configured by default, as can be seen in the [`devcontainer.json`](./devcontainer.json) file. This can be further customized by users without needing to modify the `devcontainer.json` file directly. + +For extensions, the [`dev.containers.defaultExtensions` setting](https://code.visualstudio.com/docs/devcontainers/containers#_always-installed-extensions) allows listing extensions that will always be installed. + +For more general customizations, VSCode allows using a dotfile repository. See the [VSCode documentation](https://code.visualstudio.com/docs/devcontainers/containers#_personalizing-with-dotfile-repositories) for more information. + +## GitHub Codespaces + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/NVIDIA/cccl?quickstart=1&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +One of the benefits of Dev Containers is that they integrate natively with [GitHub Codespaces](https://github.com/features/codespaces). Codespaces provide a VSCode development environment right in your browser running on a machine in the cloud. This provides a truly one-click, turnkey development environment where you can develop, build, and test with no other setup required. + +Click the badge above or [click here](https://codespaces.new/NVIDIA/cccl?quickstart=1&devcontainer_path=.devcontainer%2Fdevcontainer.json) to get started with CCCL's Dev Containers on Codespaces. This will start the default Dev Container environment. [Click here](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=296416761&skip_quickstart=true) to start a Codespace with a particular environment and hardware configuration as shown: + + ![Shows configuring a Codespace with a custom environment](../docs/images/codespaces.png) + +## For Maintainers: The `make_devcontainers.sh` Script + +### Overview + +[`make_devcontainers.sh`](./make_devcontainers.sh) generates devcontainer configurations for the unique combinations of CUDA Toolkit (CTK) versions and host compilers in [`ci/matrix.yaml`](../ci/matrix.yaml). + +### How It Works: + +1. Parses the matrix from `ci/matrix.yaml`. +2. Use the top-level [`.devcontainer/devcontainer.json`](./devcontainer.json) as a template. For each unique combination of CTK version and host compiler, generate a corresponding `devcontainer.json` configuration, adjusting only the base Docker image to match the desired environment. +3. Place the generated configurations in the `.devcontainer` directory, organizing them into subdirectories following the naming convention `cuda-`. + +For more information, see the `.devcontainer/make_devcontainers.sh --help` message. + +**Note**: When adding or updating supported environments, modify `matrix.yaml` and then rerun this script to synchronize the `devcontainer` configurations. + +## Quickstart: Using WSL + +> [!NOTE] +> _Make sure you have the Nvidia driver installed on your Windows host before moving further_. Type in `nvidia-smi` for verification. + +### Install WSL on your Windows host + +> [!WARNING] +> Disclaimer: This guide was developed for WSL 2 on Windows 11. + +1. Launch a Windows terminal (_e.g. Powershell_) as an administrator. + +2. Install WSL 2 by running: +```bash +wsl --install +``` +This should probably install Ubuntu distro as a default. + +3. Restart your computer and run `wsl -l -v` on a Windows terminal to verify installation. + +

Install prerequisites and VS Code extensions

+ +4. Launch your WSL/Ubuntu terminal by running `wsl` in Powershell. + +5. Install the [WSL extension](ms-vscode-remote.remote-wsl) on VS Code. + + - `Ctrl + Shift + P` and select `WSL: Connect to WSL` (it will prompt you to install the WSL extension). + + - Make sure you are connected to WSL with VS Code by checking the bottom left corner of the VS Code window (should indicate "WSL: Ubuntu" in our case). + +6. Install the [Dev Containers extension](ms-vscode-remote.remote-containers) on VS Code. + + - In a vanilla system you should be prompted to install `Docker` at this point, accept it. If it hangs you might have to restart VS Code after that. + +7. Install the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). **Make sure you install the WSL 2 version and not the native Linux one**. This builds on top of Docker so make sure you have Docker properly installed (run `docker --version`). + +8. Open `/etc/docker/daemon.json` from within your WSL system (if the file does not exist, create it) and add the following: + +```json +{ + "runtimes": { + "nvidia": { + "path": "nvidia-container-runtime", + "runtimeArgs": [] + } + } +} +``` + +then run `sudo systemctl restart docker.service`. + +--- +### Build CCCL in WSL using Dev Containers + +9. Still on your WSL terminal run `git clone https://github.com/NVIDIA/cccl.git` + + +10. Open the CCCL cloned repo in VS Code ( `Ctrl + Shift + P `, select `File: Open Folder...` and select the path where your CCCL clone is located). + +11. If prompted, choose `Reopen in Container`. + + - If you are not prompted just type `Ctrl + Shift + P` and `Dev Containers: Open Folder in Container ...`. + +12. Verify that Dev Container was configured properly by running `nvidia-smi` in your Dev Container terminal. For a proper configuration it is important for the steps in [Install prerequisites and VS Code extensions](#prereqs) to be followed in a precise order. + +From that point on, the guide aligns with our [existing Dev Containers native Linux guide](https://github.com/NVIDIA/cccl/blob/main/.devcontainer/README.md) with just one minor potential alteration: + +13. If WSL was launched without the X-server enabled, when asked to "authenticate Git with your Github credentials", if you answer **Yes**, the browser might not open automatically, with the following error message. + +> Failed opening a web browser at https://github.com/login/device + exec: "xdg-open,x-www-browser,www-browser,wslview": executable file not found in $PATH + Please try entering the URL in your browser manually + +In that case type in the address manually in your web browser https://github.com/login/device and fill in the one-time code. diff --git a/.devcontainer/cuda11.1-gcc6/devcontainer.json b/.devcontainer/cuda11.1-gcc6/devcontainer.json new file mode 100644 index 00000000..9faa25a6 --- /dev/null +++ b/.devcontainer/cuda11.1-gcc6/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc6-cuda11.1-ubuntu18.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.1-gcc6", + "CCCL_CUDA_VERSION": "11.1", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "6", + "CCCL_BUILD_INFIX": "cuda11.1-gcc6" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.1-gcc6" +} diff --git a/.devcontainer/cuda11.1-gcc7/devcontainer.json b/.devcontainer/cuda11.1-gcc7/devcontainer.json new file mode 100644 index 00000000..3e9e2f70 --- /dev/null +++ b/.devcontainer/cuda11.1-gcc7/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc7-cuda11.1-ubuntu18.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.1-gcc7", + "CCCL_CUDA_VERSION": "11.1", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "7", + "CCCL_BUILD_INFIX": "cuda11.1-gcc7" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.1-gcc7" +} diff --git a/.devcontainer/cuda11.1-gcc8/devcontainer.json b/.devcontainer/cuda11.1-gcc8/devcontainer.json new file mode 100644 index 00000000..3862680f --- /dev/null +++ b/.devcontainer/cuda11.1-gcc8/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc8-cuda11.1-ubuntu18.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.1-gcc8", + "CCCL_CUDA_VERSION": "11.1", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "8", + "CCCL_BUILD_INFIX": "cuda11.1-gcc8" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.1-gcc8" +} diff --git a/.devcontainer/cuda11.1-gcc9/devcontainer.json b/.devcontainer/cuda11.1-gcc9/devcontainer.json new file mode 100644 index 00000000..54f7b888 --- /dev/null +++ b/.devcontainer/cuda11.1-gcc9/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc9-cuda11.1-ubuntu18.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.1-gcc9", + "CCCL_CUDA_VERSION": "11.1", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "9", + "CCCL_BUILD_INFIX": "cuda11.1-gcc9" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.1-gcc9" +} diff --git a/.devcontainer/cuda11.1-llvm9/devcontainer.json b/.devcontainer/cuda11.1-llvm9/devcontainer.json new file mode 100644 index 00000000..d875c9b6 --- /dev/null +++ b/.devcontainer/cuda11.1-llvm9/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm9-cuda11.1-ubuntu18.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.1-llvm9", + "CCCL_CUDA_VERSION": "11.1", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "9", + "CCCL_BUILD_INFIX": "cuda11.1-llvm9" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.1-llvm9" +} diff --git a/.devcontainer/cuda11.8-gcc11/devcontainer.json b/.devcontainer/cuda11.8-gcc11/devcontainer.json new file mode 100644 index 00000000..389d6c7f --- /dev/null +++ b/.devcontainer/cuda11.8-gcc11/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc11-cuda11.8-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda11.8-gcc11", + "CCCL_CUDA_VERSION": "11.8", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "11", + "CCCL_BUILD_INFIX": "cuda11.8-gcc11" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda11.8-gcc11" +} diff --git a/.devcontainer/cuda12.4-gcc10/devcontainer.json b/.devcontainer/cuda12.4-gcc10/devcontainer.json new file mode 100644 index 00000000..9968a849 --- /dev/null +++ b/.devcontainer/cuda12.4-gcc10/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc10-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc10", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "10", + "CCCL_BUILD_INFIX": "cuda12.4-gcc10" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc10" +} diff --git a/.devcontainer/cuda12.4-gcc11/devcontainer.json b/.devcontainer/cuda12.4-gcc11/devcontainer.json new file mode 100644 index 00000000..d2c26622 --- /dev/null +++ b/.devcontainer/cuda12.4-gcc11/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc11-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc11", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "11", + "CCCL_BUILD_INFIX": "cuda12.4-gcc11" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc11" +} diff --git a/.devcontainer/cuda12.4-gcc12/devcontainer.json b/.devcontainer/cuda12.4-gcc12/devcontainer.json new file mode 100644 index 00000000..fa6e0c5e --- /dev/null +++ b/.devcontainer/cuda12.4-gcc12/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc12-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc12", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "12", + "CCCL_BUILD_INFIX": "cuda12.4-gcc12" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc12" +} diff --git a/.devcontainer/cuda12.4-gcc7/devcontainer.json b/.devcontainer/cuda12.4-gcc7/devcontainer.json new file mode 100644 index 00000000..af6fdb10 --- /dev/null +++ b/.devcontainer/cuda12.4-gcc7/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc7-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc7", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "7", + "CCCL_BUILD_INFIX": "cuda12.4-gcc7" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc7" +} diff --git a/.devcontainer/cuda12.4-gcc8/devcontainer.json b/.devcontainer/cuda12.4-gcc8/devcontainer.json new file mode 100644 index 00000000..46670d42 --- /dev/null +++ b/.devcontainer/cuda12.4-gcc8/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc8-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc8", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "8", + "CCCL_BUILD_INFIX": "cuda12.4-gcc8" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc8" +} diff --git a/.devcontainer/cuda12.4-gcc9/devcontainer.json b/.devcontainer/cuda12.4-gcc9/devcontainer.json new file mode 100644 index 00000000..4005e723 --- /dev/null +++ b/.devcontainer/cuda12.4-gcc9/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc9-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc9", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "9", + "CCCL_BUILD_INFIX": "cuda12.4-gcc9" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc9" +} diff --git a/.devcontainer/cuda12.4-llvm10/devcontainer.json b/.devcontainer/cuda12.4-llvm10/devcontainer.json new file mode 100644 index 00000000..6ee57886 --- /dev/null +++ b/.devcontainer/cuda12.4-llvm10/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm10-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm10", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "10", + "CCCL_BUILD_INFIX": "cuda12.4-llvm10" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm10" +} diff --git a/.devcontainer/cuda12.4-llvm11/devcontainer.json b/.devcontainer/cuda12.4-llvm11/devcontainer.json new file mode 100644 index 00000000..66bd26cf --- /dev/null +++ b/.devcontainer/cuda12.4-llvm11/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm11-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm11", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "11", + "CCCL_BUILD_INFIX": "cuda12.4-llvm11" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm11" +} diff --git a/.devcontainer/cuda12.4-llvm12/devcontainer.json b/.devcontainer/cuda12.4-llvm12/devcontainer.json new file mode 100644 index 00000000..8889f147 --- /dev/null +++ b/.devcontainer/cuda12.4-llvm12/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm12-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm12", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "12", + "CCCL_BUILD_INFIX": "cuda12.4-llvm12" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm12" +} diff --git a/.devcontainer/cuda12.4-llvm13/devcontainer.json b/.devcontainer/cuda12.4-llvm13/devcontainer.json new file mode 100644 index 00000000..76faea9e --- /dev/null +++ b/.devcontainer/cuda12.4-llvm13/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm13-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm13", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "13", + "CCCL_BUILD_INFIX": "cuda12.4-llvm13" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm13" +} diff --git a/.devcontainer/cuda12.4-llvm14/devcontainer.json b/.devcontainer/cuda12.4-llvm14/devcontainer.json new file mode 100644 index 00000000..58b00cc3 --- /dev/null +++ b/.devcontainer/cuda12.4-llvm14/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm14-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm14", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "14", + "CCCL_BUILD_INFIX": "cuda12.4-llvm14" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm14" +} diff --git a/.devcontainer/cuda12.4-llvm15/devcontainer.json b/.devcontainer/cuda12.4-llvm15/devcontainer.json new file mode 100644 index 00000000..9c926538 --- /dev/null +++ b/.devcontainer/cuda12.4-llvm15/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm15-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm15", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "15", + "CCCL_BUILD_INFIX": "cuda12.4-llvm15" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm15" +} diff --git a/.devcontainer/cuda12.4-llvm16/devcontainer.json b/.devcontainer/cuda12.4-llvm16/devcontainer.json new file mode 100644 index 00000000..9f6fcadf --- /dev/null +++ b/.devcontainer/cuda12.4-llvm16/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm16-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm16", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "16", + "CCCL_BUILD_INFIX": "cuda12.4-llvm16" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm16" +} diff --git a/.devcontainer/cuda12.4-llvm9/devcontainer.json b/.devcontainer/cuda12.4-llvm9/devcontainer.json new file mode 100644 index 00000000..d9910e20 --- /dev/null +++ b/.devcontainer/cuda12.4-llvm9/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-llvm9-cuda12.4-ubuntu20.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-llvm9", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "llvm", + "CCCL_HOST_COMPILER_VERSION": "9", + "CCCL_BUILD_INFIX": "cuda12.4-llvm9" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-llvm9" +} diff --git a/.devcontainer/cuda12.4-oneapi2023.2.0/devcontainer.json b/.devcontainer/cuda12.4-oneapi2023.2.0/devcontainer.json new file mode 100644 index 00000000..04d71c2b --- /dev/null +++ b/.devcontainer/cuda12.4-oneapi2023.2.0/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-oneapi2023.2.0-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-oneapi2023.2.0", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "oneapi", + "CCCL_HOST_COMPILER_VERSION": "2023.2.0", + "CCCL_BUILD_INFIX": "cuda12.4-oneapi2023.2.0" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-oneapi2023.2.0" +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fa6e0c5e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,46 @@ +{ + "shutdownAction": "stopContainer", + "image": "rapidsai/devcontainers:24.06-cpp-gcc12-cuda12.4-ubuntu22.04", + "hostRequirements": { + "gpu": "optional" + }, + "initializeCommand": [ + "/bin/bash", + "-c", + "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}" + ], + "containerEnv": { + "SCCACHE_REGION": "us-east-2", + "SCCACHE_BUCKET": "rapids-sccache-devs", + "VAULT_HOST": "https://vault.ops.k8s.rapids.ai", + "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history", + "DEVCONTAINER_NAME": "cuda12.4-gcc12", + "CCCL_CUDA_VERSION": "12.4", + "CCCL_HOST_COMPILER": "gcc", + "CCCL_HOST_COMPILER_VERSION": "12", + "CCCL_BUILD_INFIX": "cuda12.4-gcc12" + }, + "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent", + "mounts": [ + "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent", + "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent" + ], + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "xaver.clang-format" + ], + "settings": { + "editor.defaultFormatter": "xaver.clang-format", + "clang-format.executable": "/usr/local/bin/clang-format", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}" + ] + } + } + }, + "name": "cuda12.4-gcc12" +} diff --git a/.devcontainer/img/container_list.png b/.devcontainer/img/container_list.png new file mode 100644 index 0000000000000000000000000000000000000000..09c4510f34de9b8ed44ca5c33c4b714ea07620b7 GIT binary patch literal 159943 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 EZ`ExK#Q*>R literal 0 HcmV?d00001 diff --git a/.devcontainer/img/github_auth.png b/.devcontainer/img/github_auth.png new file mode 100644 index 0000000000000000000000000000000000000000..3f52b3a2335790996bc98cb002a05fb9b36bf1dc GIT binary patch literal 54609 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 literal 0 HcmV?d00001 diff --git a/.devcontainer/img/open_in_container_manual.png b/.devcontainer/img/open_in_container_manual.png new file mode 100644 index 0000000000000000000000000000000000000000..e09435b83ced66073a9fa13e08108764dbf9a40d GIT binary patch literal 58565 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 k1k;)0F(G+4xaYIr??uGt;P(pT<`TTT zH0GD)hl48*dvm7?5B~q8FD5Sy2j@x#2loRC2X_nJ`mqfM=fD65xBCqajw>Dx?%ns~ z2D#7R0D_*Rs1V%a)7S6j+$iu4n!c`#BODy+)4?xraLC{+@Oq3nZ_nZ2ELg>b_!XV! z4i+7pF~#xWj%Tw>6`WLd4@KbT1W@8uzt_PaJ?TA=o@ag?≺Xd~M>uGMmV2Y}7Ez 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 literal 0 HcmV?d00001 diff --git a/.devcontainer/launch.sh b/.devcontainer/launch.sh new file mode 100755 index 00000000..0299e0c1 --- /dev/null +++ b/.devcontainer/launch.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Ensure the script is being executed in the cccl/ root +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.."; + +print_help() { + echo "Usage: $0 [-c|--cuda ] [-H|--host ] [-d|--docker]" + echo "Launch a development container. If no CUDA version or Host compiler are specified," + echo "the top-level devcontainer in .devcontainer/devcontainer.json will be used." + echo "" + echo "Options:" + echo " -c, --cuda Specify the CUDA version. E.g., 12.2" + echo " -H, --host Specify the host compiler. E.g., gcc12" + echo " -d, --docker Launch the development environment in Docker directly without using VSCode." + echo " -h, --help Display this help message and exit." +} + +parse_options() { + local OPTIONS=c:H:dh + local LONG_OPTIONS=cuda:,host:,docker,help + local PARSED_OPTIONS=$(getopt -n "$0" -o "${OPTIONS}" --long "${LONG_OPTIONS}" -- "$@") + + if [[ $? -ne 0 ]]; then + exit 1 + fi + + eval set -- "${PARSED_OPTIONS}" + + while true; do + case "$1" in + -c|--cuda) + cuda_version="$2" + shift 2 + ;; + -H|--host) + host_compiler="$2" + shift 2 + ;; + -d|--docker) + docker_mode=true + shift + ;; + -h|--help) + print_help + exit 0 + ;; + --) + shift + break + ;; + *) + echo "Invalid option: $1" + print_help + exit 1 + ;; + esac + done +} + +launch_docker() { + DOCKER_IMAGE=$(grep "image" "${path}/devcontainer.json" | sed 's/.*: "\(.*\)",/\1/') + echo "Found image: ${DOCKER_IMAGE}" + docker pull ${DOCKER_IMAGE} + docker run \ + -it --rm \ + --user coder \ + --workdir /home/coder/cccl \ + --mount type=bind,src="$(pwd)",dst='/home/coder/cccl' \ + ${DOCKER_IMAGE} \ + /bin/bash +} + +launch_vscode() { + # Since Visual Studio Code allows only one instance per `devcontainer.json`, + # this code prepares a unique temporary directory structure for each launch of a devcontainer. + # By doing so, it ensures that multiple instances of the same environment can be run + # simultaneously. The script replicates the `devcontainer.json` from the desired CUDA + # and compiler environment into this temporary directory, adjusting paths to ensure the + # correct workspace is loaded. A special URL is then generated to instruct VSCode to + # launch the development container using this temporary configuration. + local workspace="$(basename "$(pwd)")" + local tmpdir="$(mktemp -d)/${workspace}" + mkdir -p "${tmpdir}" + mkdir -p "${tmpdir}/.devcontainer" + cp -arL "${path}/devcontainer.json" "${tmpdir}/.devcontainer" + sed -i 's@\\${localWorkspaceFolder}@$(pwd)@g' "${tmpdir}/.devcontainer/devcontainer.json" + local path="${tmpdir}" + local hash="$(echo -n "${path}" | xxd -pu - | tr -d '[:space:]')" + local url="vscode://vscode-remote/dev-container+${hash}/home/coder/cccl" + + local launch="" + if type open >/dev/null 2>&1; then + launch="open" + elif type xdg-open >/dev/null 2>&1; then + launch="xdg-open" + fi + + if [ -n "${launch}" ]; then + echo "Launching VSCode Dev Container URL: ${url}" + code --new-window "${tmpdir}" + exec "${launch}" "${url}" >/dev/null 2>&1 + fi +} + +main() { + parse_options "$@" + + # If no CTK/Host compiler are provided, just use the default environment + if [[ -z ${cuda_version:-} ]] && [[ -z ${host_compiler:-} ]]; then + path=".devcontainer" + else + path=".devcontainer/cuda${cuda_version}-${host_compiler}" + if [[ ! -f "${path}/devcontainer.json" ]]; then + echo "Unknown CUDA [${cuda_version}] compiler [${host_compiler}] combination" + echo "Requested devcontainer ${path}/devcontainer.json does not exist" + exit 1 + fi + fi + + if ${docker_mode:-'false'}; then + launch_docker + else + launch_vscode + fi +} + +main "$@" + diff --git a/.devcontainer/make_devcontainers.sh b/.devcontainer/make_devcontainers.sh new file mode 100755 index 00000000..64b92c08 --- /dev/null +++ b/.devcontainer/make_devcontainers.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# This script parses the CI matrix.yaml file and generates a devcontainer.json file for each unique combination of +# CUDA version, compiler name/version, and Ubuntu version. The devcontainer.json files are written to the +# .devcontainer directory to a subdirectory named after the CUDA version and compiler name/version. +# 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 )"; + + +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_exe="$6" + local compiler_version="$7" + local os="$8" + local devcontainer_version="$9" + + 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_exe "$compiler_exe" --arg compiler_version "$compiler_version" --arg os "$os" \ + '.image = $image | .name = $name | .containerEnv.DEVCONTAINER_NAME = $name | + .containerEnv.CCCL_BUILD_INFIX = $name | + .containerEnv.CCCL_CUDA_VERSION = $cuda_version | .containerEnv.CCCL_HOST_COMPILER = $compiler_name | + .containerEnv.CCCL_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.yaml" + +# 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}) + +# Exclude Windows environments +readonly matrix_json=$(echo "$matrix_json" | jq 'del(.pull_request.nvcc[] | select(.os | contains("windows")))') + +# Get the devcontainer image version and define image tag root +readonly DEVCONTAINER_VERSION=$(echo "$matrix_json" | jq -r '.devcontainer_version') + +# Get unique combinations of cuda version, compiler name/version, and Ubuntu version +readonly combinations=$(echo "$matrix_json" | jq -c '[.pull_request.nvcc[] | {cuda: .cuda, compiler_name: .compiler.name, compiler_exe: .compiler.exe, 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_EXE=$(echo "$NEWEST_GCC_CUDA_ENTRY" | jq -r '.compiler_exe') +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_EXE" "$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 + cuda_version=$(echo "$combination" | jq -r '.cuda') + compiler_name=$(echo "$combination" | jq -r '.compiler_name') + compiler_exe=$(echo "$combination" | jq -r '.compiler_exe') + compiler_version=$(echo "$combination" | jq -r '.compiler_version') + os=$(echo "$combination" | jq -r '.os') + + name=$(make_name "$cuda_version" "$compiler_name" "$compiler_version") + mkdir -p "$name" + new_devcontainer_file="$name/devcontainer.json" + + update_devcontainer "$base_devcontainer_file" "$new_devcontainer_file" "$name" "$cuda_version" "$compiler_name" "$compiler_exe" "$compiler_version" "$os" "$DEVCONTAINER_VERSION" + echo "Created $new_devcontainer_file" + + # Add the subdirectory name to the valid_subdirs array + valid_subdirs+=("$name") +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 diff --git a/.devcontainer/verify_devcontainer.sh b/.devcontainer/verify_devcontainer.sh new file mode 100755 index 00000000..b5934ea2 --- /dev/null +++ b/.devcontainer/verify_devcontainer.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +function usage { + echo "Usage: $0" + echo + echo "This script is intended to be run within one of CCCL'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" + elif [[ "$CXX" == "icpc" ]]; then + local actual_version=$(echo "$version_output" | head -n 1 | cut -d ' ' -f 3 ) + # The icpc compiler version of oneAPI release 2023.2.0 is 2021.10.0 + if [[ "$actual_version" == "2021.10.0" ]]; then + actual_version="2023.2.0" + fi + expected_compiler="oneapi" + else + echo "::error:: Unexpected CXX value ($CXX)." + exit 1 + fi + + if [[ "$expected_compiler" != "${CCCL_HOST_COMPILER}" || "$actual_version" != "$CCCL_HOST_COMPILER_VERSION" ]]; then + echo "::error:: CXX ($CXX) version ($actual_version) does not match the expected compiler (${CCCL_HOST_COMPILER}) and version (${CCCL_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" != "$CCCL_CUDA_VERSION" ]]; then + echo "::error:: CUDA version ($actual_cuda_version) does not match the expected CUDA version ($CCCL_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 CUDAHOSTCXX CCCL_BUILD_INFIX CCCL_HOST_COMPILER CCCL_CUDA_VERSION CCCL_HOST_COMPILER_VERSION + + check_host_compiler_version + + check_cuda_version + + echo "Dev Container successfully verified!" +} + +main "$@" diff --git a/.github/actions/compute-matrix/action.yml b/.github/actions/compute-matrix/action.yml new file mode 100644 index 00000000..b8155e7a --- /dev/null +++ b/.github/actions/compute-matrix/action.yml @@ -0,0 +1,25 @@ + +name: Compute Matrix +description: "Compute the matrix for a given matrix type from the specified matrix file" + +inputs: + matrix_query: + description: "The jq query used to specify the desired matrix. e.g., .pull_request.nvcc" + required: true + matrix_file: + description: 'The file containing the matrix' + required: true +outputs: + matrix: + description: 'The requested matrix' + value: ${{ steps.compute-matrix.outputs.MATRIX }} + +runs: + using: "composite" + steps: + - name: Compute matrix + id: compute-matrix + run: | + MATRIX=$(./.github/actions/compute-matrix/compute-matrix.sh ${{inputs.matrix_file}} ${{inputs.matrix_query}} ) + echo "matrix=$MATRIX" | tee -a $GITHUB_OUTPUT + shell: bash -euxo pipefail {0} diff --git a/.github/actions/compute-matrix/compute-matrix.sh b/.github/actions/compute-matrix/compute-matrix.sh new file mode 100755 index 00000000..8a6d635c --- /dev/null +++ b/.github/actions/compute-matrix/compute-matrix.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -euo pipefail + +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))' +} + +explode_libs() { + jq -cr 'map(. as $o | {lib: $o.lib[]} + del($o.lib))' +} + +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 )" + local per_cuda_compiler_matrix="$(echo "$nvcc_full_matrix" | jq -cr ' group_by(.cuda + .compiler.name) | map({(.[0].cuda + "-" + .[0].compiler.name): .}) | add')" + write_output "PER_CUDA_COMPILER_MATRIX" "$per_cuda_compiler_matrix" + write_output "PER_CUDA_COMPILER_KEYS" "$(echo "$per_cuda_compiler_matrix" | jq -r 'keys | @json')" +} + +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 + + echo "Input matrix file:" >&2 + cat "$1" >&2 + echo "Matrix Type: $2" >&2 + + extract_matrix "$1" "$2" +} + +main "$@" diff --git a/.github/actions/configure_cccl_sccache/action.yml b/.github/actions/configure_cccl_sccache/action.yml new file mode 100644 index 00000000..1b42fc95 --- /dev/null +++ b/.github/actions/configure_cccl_sccache/action.yml @@ -0,0 +1,19 @@ +name: Set up AWS credentials and environment variables for sccache +description: "Set up AWS credentials and environment variables for sccache" +runs: + using: "composite" + steps: + - name: Get AWS credentials for sccache bucket + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: arn:aws:iam::279114543810:role/gha-oidc-NVIDIA + aws-region: us-east-2 + role-duration-seconds: 43200 # 12 hours) + - name: Set environment variables + run: | + echo "SCCACHE_BUCKET=rapids-sccache-devs" >> $GITHUB_ENV + echo "SCCACHE_REGION=us-east-2" >> $GITHUB_ENV + echo "SCCACHE_IDLE_TIMEOUT=32768" >> $GITHUB_ENV + echo "SCCACHE_S3_USE_SSL=true" >> $GITHUB_ENV + echo "SCCACHE_S3_NO_CREDENTIALS=false" >> $GITHUB_ENV + shell: bash diff --git a/.github/copy-pr-bot.yaml b/.github/copy-pr-bot.yaml new file mode 100644 index 00000000..895ba83e --- /dev/null +++ b/.github/copy-pr-bot.yaml @@ -0,0 +1,4 @@ +# Configuration file for `copy-pr-bot` GitHub App +# https://docs.gha-runners.nvidia.com/apps/copy-pr-bot/ + +enabled: true diff --git a/.github/problem-matchers/problem-matcher.json b/.github/problem-matchers/problem-matcher.json new file mode 100644 index 00000000..f196a5c8 --- /dev/null +++ b/.github/problem-matchers/problem-matcher.json @@ -0,0 +1,14 @@ +{ + "problemMatcher": [ + { + "owner": "nvcc", + "pattern": [ + { + "regexp": "^\\/home\\/coder\\/(.+):(\\d+):(\\d+): (\\w+): \"(.+)\"$", + "severity": 4, + "message": 5 + } + ] + } + ] +} diff --git a/.github/workflows/build-and-test-linux.yml b/.github/workflows/build-and-test-linux.yml new file mode 100644 index 00000000..6c5ba400 --- /dev/null +++ b/.github/workflows/build-and-test-linux.yml @@ -0,0 +1,47 @@ +name: build and test + +defaults: + run: + shell: bash -exo pipefail {0} + +on: + workflow_call: + inputs: + cpu: {type: string, required: true} + test_name: {type: string, required: false} + build_script: {type: string, required: false} + test_script: {type: string, required: false} + container_image: {type: string, required: false} + run_tests: {type: boolean, required: false, default: true} + +permissions: + contents: read + +jobs: + build: + name: Build ${{inputs.test_name}} + permissions: + id-token: write + contents: read + uses: ./.github/workflows/run-as-coder.yml + with: + name: Build ${{inputs.test_name}} + runner: linux-${{inputs.cpu}}-cpu16 + image: ${{ inputs.container_image }} + command: | + ${{ inputs.build_script }} + + test: + needs: build + permissions: + id-token: write + contents: read + if: ${{ !cancelled() && ( needs.build.result == 'success' || needs.build.result == 'skipped' ) && inputs.run_tests}} + name: Test ${{inputs.test_name}} + uses: ./.github/workflows/run-as-coder.yml + with: + name: Test ${{inputs.test_name}} + runner: linux-${{inputs.cpu}}-gpu-v100-latest-1 + image: ${{inputs.container_image}} + command: | + ${{ inputs.test_script }} diff --git a/.github/workflows/build-and-test-windows.yml b/.github/workflows/build-and-test-windows.yml new file mode 100644 index 00000000..55b31005 --- /dev/null +++ b/.github/workflows/build-and-test-windows.yml @@ -0,0 +1,49 @@ +name: Build Windows + +on: + workflow_call: + inputs: + test_name: {type: string, required: false} + build_script: {type: string, required: false} + container_image: {type: string, required: false} + +jobs: + prepare: + name: Build ${{inputs.test_name}} + runs-on: windows-amd64-cpu16 + permissions: + id-token: write + contents: read + env: + SCCACHE_BUCKET: rapids-sccache-devs + SCCACHE_REGION: us-east-2 + SCCACHE_IDLE_TIMEOUT: 0 + SCCACHE_S3_USE_SSL: true + SCCACHE_S3_NO_CREDENTIALS: false + steps: + - name: Get AWS credentials for sccache bucket + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: arn:aws:iam::279114543810:role/gha-oidc-NVIDIA + aws-region: us-east-2 + role-duration-seconds: 43200 # 12 hours + - name: Fetch ${{ inputs.container_image }} + shell: powershell + run: docker pull ${{ inputs.container_image }} + - name: Run the tests + shell: powershell + run: >- + docker run ${{ inputs.container_image }} powershell -c "[System.Environment]::SetEnvironmentVariable('AWS_ACCESS_KEY_ID','${{env.AWS_ACCESS_KEY_ID}}') + [System.Environment]::SetEnvironmentVariable('AWS_SECRET_ACCESS_KEY','${{env.AWS_SECRET_ACCESS_KEY}}') + [System.Environment]::SetEnvironmentVariable('AWS_SESSION_TOKEN','${{env.AWS_SESSION_TOKEN }}') + [System.Environment]::SetEnvironmentVariable('SCCACHE_BUCKET','${{env.SCCACHE_BUCKET}}') + [System.Environment]::SetEnvironmentVariable('SCCACHE_REGION','${{env.SCCACHE_REGION}}') + [System.Environment]::SetEnvironmentVariable('SCCACHE_IDLE_TIMEOUT','${{env.SCCACHE_IDLE_TIMEOUT}}') + [System.Environment]::SetEnvironmentVariable('SCCACHE_S3_USE_SSL','${{env.SCCACHE_S3_USE_SSL}}') + [System.Environment]::SetEnvironmentVariable('SCCACHE_S3_NO_CREDENTIALS','${{env.SCCACHE_S3_NO_CREDENTIALS}}') + git clone https://github.com/NVIDIA/cccl.git; + cd cccl; + git fetch --all; + git checkout ${{github.ref_name}}; + ${{inputs.build_script}};" + diff --git a/.github/workflows/dispatch-build-and-test.yml b/.github/workflows/dispatch-build-and-test.yml new file mode 100644 index 00000000..7b5ed4ef --- /dev/null +++ b/.github/workflows/dispatch-build-and-test.yml @@ -0,0 +1,51 @@ +name: Dispatch build and test + +on: + workflow_call: + inputs: + project_name: {type: string, required: true} + per_cuda_compiler_matrix: {type: string, required: true} + devcontainer_version: {type: string, required: true} + is_windows: {type: boolean, required: true} + +permissions: + contents: read + +jobs: + # Using a matrix to dispatch to the build-and-test reusable workflow for each build configuration + # ensures that the build/test steps can overlap across different configurations. For example, + # the build step for CUDA 12.1 + gcc 9.3 can run at the same time as the test step for CUDA 11.0 + clang 11. + build_and_test_linux: + name: build and test linux + permissions: + id-token: write + contents: read + if: ${{ !inputs.is_windows }} + uses: ./.github/workflows/build-and-test-linux.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJSON(inputs.per_cuda_compiler_matrix) }} + with: + cpu: ${{ matrix.cpu }} + test_name: ${{matrix.cpu}}/${{matrix.compiler.name}}${{matrix.compiler.version}}/C++${{matrix.std}} ${{matrix.extra_build_args}} + build_script: './ci/build_${{ inputs.project_name }}.sh -cxx ${{matrix.compiler.exe}} -std ${{matrix.std}} "${{matrix.extra_build_args}}"' + test_script: './ci/test_${{ inputs.project_name }}.sh -cxx ${{matrix.compiler.exe}} -std ${{matrix.std}} "${{matrix.extra_build_args}}"' + container_image: rapidsai/devcontainers:${{inputs.devcontainer_version}}-cpp-${{matrix.compiler.name}}${{matrix.compiler.version}}-cuda${{matrix.cuda}}-${{matrix.os}} + run_tests: ${{ contains(matrix.jobs, 'test') && !contains(github.event.head_commit.message, 'skip-tests') && matrix.os != 'windows-2022' }} + + build_and_test_windows: + name: build and test windows + permissions: + id-token: write + contents: read + if: ${{ inputs.is_windows }} + uses: ./.github/workflows/build-and-test-windows.yml + strategy: + fail-fast: false + matrix: + include: ${{ fromJSON(inputs.per_cuda_compiler_matrix) }} + with: + test_name: ${{matrix.cpu}}/${{matrix.compiler.name}}${{matrix.compiler.version}}/C++${{matrix.std}} + build_script: "./ci/windows/build_${{ inputs.project_name }}.ps1 -std ${{matrix.std}}" + container_image: rapidsai/devcontainers:${{inputs.devcontainer_version}}-cuda${{matrix.cuda}}-${{matrix.compiler.name}}${{matrix.compiler.version}}-${{matrix.os}} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 00000000..6ea22ab8 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is the main workflow that runs on every PR and push to main +name: pr + +defaults: + run: + shell: bash -euo pipefail {0} + +on: + push: + branches: + - "pull-request/[0-9]+" + +# Only runs one instance of this workflow at a time for a given PR and cancels any in-progress runs when a new one starts. +concurrency: + group: ${{ github.workflow }}-on-${{ github.event_name }}-from-${{ github.ref_name }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: read + +jobs: + compute-matrix: + name: Compute matrix + runs-on: ubuntu-latest + 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}} + 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 + + nvbench: + name: NVBench CUDA${{ matrix.cuda_host_combination }} + permissions: + id-token: write + contents: read + needs: compute-matrix + 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: "nvbench" + 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') }} + + verify-devcontainers: + name: Verify Dev Containers + permissions: + id-token: write + contents: read + uses: ./.github/workflows/verify-devcontainers.yml + + # This job is the final job that runs after all other jobs and is used for branch protection status checks. + # See: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks + # https://github.com/orgs/community/discussions/26822#discussioncomment-5122101 + ci: + runs-on: ubuntu-latest + name: CI + if: ${{ always() }} # need to use always() instead of !cancelled() because skipped jobs count as success + needs: + - nvbench + - verify-devcontainers + steps: + - name: Check status of all precursor jobs + if: >- + ${{ + contains(needs.*.result, 'failure') + || contains(needs.*.result, 'cancelled') + || contains(needs.*.result, 'skipped') + }} + run: exit 1 diff --git a/.github/workflows/run-as-coder.yml b/.github/workflows/run-as-coder.yml new file mode 100644 index 00000000..29399b66 --- /dev/null +++ b/.github/workflows/run-as-coder.yml @@ -0,0 +1,67 @@ +name: Run as coder user + +defaults: + run: + shell: bash -exo pipefail {0} + +on: + workflow_call: + inputs: + name: {type: string, required: true} + image: {type: string, required: true} + runner: {type: string, required: true} + command: {type: string, required: true} + env: { type: string, required: false, default: "" } + +permissions: + contents: read + +jobs: + run-as-coder: + name: ${{inputs.name}} + permissions: + id-token: write + contents: read + runs-on: ${{inputs.runner}} + container: + options: -u root + image: ${{inputs.image}} + env: + NVIDIA_VISIBLE_DEVICES: ${{ env.NVIDIA_VISIBLE_DEVICES }} + steps: + - name: Checkout repo + uses: actions/checkout@v3 + with: + path: nvbench + persist-credentials: false + - name: Move files to coder user home directory + run: | + cp -R nvbench /home/coder/nvbench + chown -R coder:coder /home/coder/ + - name: Add NVCC problem matcher + run: | + echo "::add-matcher::nvbench/.github/problem-matchers/problem-matcher.json" + - name: Configure credentials and environment variables for sccache + uses: ./nvbench/.github/actions/configure_cccl_sccache + - name: Run command + shell: su coder {0} + run: | + set -eo pipefail + cd ~/nvbench + echo -e "\e[1;34mRunning as 'coder' user in $(pwd):\e[0m" + echo -e "\e[1;34m${{inputs.command}}\e[0m" + eval "${{inputs.command}}" || exit_code=$? + if [ ! -z "$exit_code" ]; then + echo -e "::group::️❗ \e[1;31mInstructions to Reproduce CI Failure Locally\e[0m" + echo "::error:: To replicate this failure locally, follow the steps below:" + echo "1. Clone the repository, and navigate to the correct branch and commit:" + echo " git clone --branch $GITHUB_REF_NAME --single-branch https://github.com/$GITHUB_REPOSITORY.git && cd $(echo $GITHUB_REPOSITORY | cut -d'/' -f2) && git checkout $GITHUB_SHA" + echo "" + echo "2. Run the failed command inside the same Docker container used by the CI:" + echo " docker run --rm -it --gpus all --pull=always --volume \$PWD:/repo --workdir /repo ${{ inputs.image }} ${{inputs.command}}" + echo "" + echo "For additional information, see:" + echo " - DevContainer Documentation: https://github.com/NVIDIA/cccl/blob/main/.devcontainer/README.md" + echo " - Continuous Integration (CI) Overview: https://github.com/NVIDIA/cccl/blob/main/ci-overview.md" + exit $exit_code + fi diff --git a/.github/workflows/verify-devcontainers.yml b/.github/workflows/verify-devcontainers.yml new file mode 100644 index 00000000..6fea8aeb --- /dev/null +++ b/.github/workflows/verify-devcontainers.yml @@ -0,0 +1,94 @@ +name: Verify devcontainers + +on: + workflow_call: + +defaults: + run: + shell: bash -euo pipefail {0} + +permissions: + contents: read + +jobs: + verify-make-devcontainers: + name: Verify devcontainer files are up-to-date + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup jq and yq + run: | + sudo apt-get update + sudo apt-get install jq -y + sudo wget -O /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.34.2/yq_linux_amd64 + sudo chmod +x /usr/local/bin/yq + - name: Run the script to generate devcontainer files + run: | + ./.devcontainer/make_devcontainers.sh --verbose + - name: Check for changes + run: | + if [[ $(git diff --stat) != '' || $(git status --porcelain | grep '^??') != '' ]]; then + git diff --minimal + git status --porcelain + echo "::error:: Dev Container files are out of date or there are untracked files. Run the .devcontainer/make_devcontainers.sh script and commit the changes." + exit 1 + else + echo "::note::Dev Container files are up-to-date." + fi + + get-devcontainer-list: + needs: verify-make-devcontainers + name: Get list of devcontainer.json files + runs-on: ubuntu-latest + outputs: + devcontainers: ${{ steps.get-list.outputs.devcontainers }} + steps: + - name: Check out the code + uses: actions/checkout@v3 + - name: Get list of devcontainer.json paths and names + id: get-list + run: | + devcontainers=$(find .devcontainer/ -name 'devcontainer.json' | while read -r devcontainer; do + jq --arg path "$devcontainer" '{path: $path, name: .name}' "$devcontainer" + done | jq -s -c .) + echo "devcontainers=${devcontainers}" | tee --append "${GITHUB_OUTPUT}" + + verify-devcontainers: + needs: get-devcontainer-list + name: ${{matrix.devcontainer.name}} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + devcontainer: ${{fromJson(needs.get-devcontainer-list.outputs.devcontainers)}} + permissions: + id-token: write + contents: read + steps: + - name: Check out the code + uses: actions/checkout@v3 + # devcontainer/ci doesn't supported nested devcontainer.json files, so we need to copy the devcontainer.json + # file to the top level .devcontainer/ directory + - name: Copy devcontainer.json to .devcontainer/ + run: | + src="${{ matrix.devcontainer.path }}" + dst=".devcontainer/devcontainer.json" + if [[ "$src" != "$dst" ]]; then + cp "$src" "$dst" + fi + # We don't really need sccache configured, but we need the AWS credentials envvars to be set + # in order to avoid the devcontainer hanging waiting for GitHub authentication + - name: Configure credentials and environment variables for sccache + uses: ./.github/actions/configure_cccl_sccache + - name: Run in devcontainer + uses: devcontainers/ci@v0.3 + with: + push: never + env: | + SCCACHE_REGION=${{ env.SCCACHE_REGION }} + AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID }} + AWS_SESSION_TOKEN=${{ env.AWS_SESSION_TOKEN }} + AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY }} + runCmd: | + .devcontainer/verify_devcontainer.sh diff --git a/.gitignore b/.gitignore index 20d94d8a..d41aa02f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ build*/ +.aws +.vscode .cache +.config .idea cmake-build-* *~ diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..9dc92cd2 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,76 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 1 + }, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/$env{CCCL_BUILD_INFIX}/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_CUDA_ARCHITECTURES": "60;70;80", + "NVBench_ENABLE_CUPTI": true, + "NVBench_ENABLE_DEVICE_TESTING": false, + "NVBench_ENABLE_EXAMPLES": true, + "NVBench_ENABLE_INSTALL_RULES": true, + "NVBench_ENABLE_NVML": true, + "NVBench_ENABLE_TESTING": true, + "NVBench_ENABLE_WERROR": true + } + }, + { + "name": "all-dev", + "inherits": "base", + "cacheVariables": { + "NVBench_ENABLE_DEVICE_TESTING": true + } + }, + { + "name": "nvbench-cpp17", + "displayName": "nvbench_c++17", + "inherits": "base", + "cacheVariables": { + "CMAKE_CXX_STANDARD": "17", + "CMAKE_CUDA_STANDARD": "17" + } + } + ], + "buildPresets": [ + { + "name": "all-dev", + "configurePreset": "all-dev" + }, + { + "name": "nvbench-cpp17", + "configurePreset": "nvbench-cpp17" + } + ], + "testPresets": [ + { + "name": "base", + "hidden": true, + "output": { + "outputOnFailure": true + }, + "execution": { + "noTestsAction": "error", + "stopOnFailure": false + } + }, + { + "name": "all-dev", + "configurePreset": "all-dev", + "inherits": "base" + }, + { + "name": "nvbench-cpp17", + "configurePreset": "nvbench-cpp17", + "inherits": "base" + } + ] +} diff --git a/ci/axis/cpu.yml b/ci/axis/cpu.yml deleted file mode 100644 index 7230b666..00000000 --- a/ci/axis/cpu.yml +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -SDK_TYPE: - - cuda - -SDK_VER: - - 11.5.1-devel - -OS_TYPE: - - ubuntu - -OS_VER: - - 20.04 - -CXX_TYPE: - - clang - - gcc - -CXX_VER: - - 5 - - 6 - - 7 - - 8 - - 9 - - 10 - - 11 - - 12 - -exclude: - - CXX_TYPE: clang - CXX_VER: 5 - - CXX_TYPE: clang - CXX_VER: 6 - - CXX_TYPE: gcc - CXX_VER: 12 diff --git a/ci/axis/gpu.yml b/ci/axis/gpu.yml deleted file mode 100644 index 15310794..00000000 --- a/ci/axis/gpu.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -SDK_TYPE: - - cuda - -SDK_VER: - - 11.5.1-devel - -OS_TYPE: - - ubuntu - -OS_VER: - - 20.04 - -CXX_TYPE: - - clang - - gcc - -CXX_VER: - - 11 - - 12 - -exclude: - - CXX_TYPE: clang - CXX_VER: 11 - - CXX_TYPE: gcc - CXX_VER: 12 diff --git a/ci/build_common.sh b/ci/build_common.sh new file mode 100755 index 00000000..ee95b00f --- /dev/null +++ b/ci/build_common.sh @@ -0,0 +1,246 @@ +#!/bin/bash + +set -eo pipefail + +# Ensure the script is being executed in its containing directory +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; + +# Script defaults +HOST_COMPILER=${CXX:-g++} # $CXX if set, otherwise `g++` +CXX_STANDARD=17 +CUDA_COMPILER=${CUDACXX:-nvcc} # $CUDACXX if set, otherwise `nvcc` +CUDA_ARCHS= # Empty, use presets by default. +GLOBAL_CMAKE_OPTIONS=() +DISABLE_CUB_BENCHMARKS= # Enable to force-disable building CUB benchmarks. + +# Check if the correct number of arguments has been provided +function usage { + echo "Usage: $0 [OPTIONS]" + echo + echo "The PARALLEL_LEVEL environment variable controls the amount of build parallelism. Default is the number of cores." + echo + echo "Options:" + echo " -v/--verbose: enable shell echo for debugging" + echo " -cuda: CUDA compiler (Defaults to \$CUDACXX if set, otherwise nvcc)" + echo " -cxx: Host compiler (Defaults to \$CXX if set, otherwise g++)" + echo " -std: CUDA/C++ standard (Defaults to 17)" + echo " -arch: Target CUDA arches, e.g. \"60-real;70;80-virtual\" (Defaults to value in presets file)" + echo " -cmake-options: Additional options to pass to CMake" + echo + echo "Examples:" + echo " $ PARALLEL_LEVEL=8 $0" + echo " $ PARALLEL_LEVEL=8 $0 -cxx g++-9" + echo " $ $0 -cxx clang++-8" + echo " $ $0 -cxx g++-8 -std 20 -arch 80-real -v -cuda /usr/local/bin/nvcc" + echo " $ $0 -cmake-options \"-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-Wfatal-errors\"" + exit 1 +} + +# Parse options + +# Copy the args into a temporary array, since we will modify them and +# the parent script may still need them. +args=("$@") +while [ "${#args[@]}" -ne 0 ]; do + case "${args[0]}" in + -v | --verbose) VERBOSE=1; args=("${args[@]:1}");; + -cxx) HOST_COMPILER="${args[1]}"; args=("${args[@]:2}");; + -std) CXX_STANDARD="${args[1]}"; args=("${args[@]:2}");; + -cuda) CUDA_COMPILER="${args[1]}"; args=("${args[@]:2}");; + -arch) CUDA_ARCHS="${args[1]}"; args=("${args[@]:2}");; + -disable-benchmarks) DISABLE_CUB_BENCHMARKS=1; args=("${args[@]:1}");; + -cmake-options) + if [ -n "${args[1]}" ]; then + IFS=' ' read -ra split_args <<< "${args[1]}" + GLOBAL_CMAKE_OPTIONS+=("${split_args[@]}") + args=("${args[@]:2}") + else + echo "Error: No arguments provided for -cmake-options" + usage + exit 1 + fi + ;; + -h | -help | --help) usage ;; + *) echo "Unrecognized option: ${args[0]}"; usage ;; + esac +done + +# Convert to full paths: +HOST_COMPILER=$(which ${HOST_COMPILER}) +CUDA_COMPILER=$(which ${CUDA_COMPILER}) + +if [[ -n "${CUDA_ARCHS}" ]]; then + GLOBAL_CMAKE_OPTIONS+=("-DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCHS}") +fi + +if [ $VERBOSE ]; then + set -x +fi + +# Begin processing unsets after option parsing +set -u + +readonly PARALLEL_LEVEL=${PARALLEL_LEVEL:=$(nproc)} + +if [ -z ${CCCL_BUILD_INFIX+x} ]; then + CCCL_BUILD_INFIX="" +fi + +# Presets will be configured in this directory: +BUILD_DIR="../build/${CCCL_BUILD_INFIX}" + +# The most recent build will always be symlinked to cccl/build/latest +mkdir -p $BUILD_DIR +rm -f ../build/latest +ln -sf $BUILD_DIR ../build/latest + +# Now that BUILD_DIR exists, use readlink to canonicalize the path: +BUILD_DIR=$(readlink -f "${BUILD_DIR}") + +# Prepare environment for CMake: +export CMAKE_BUILD_PARALLEL_LEVEL="${PARALLEL_LEVEL}" +export CTEST_PARALLEL_LEVEL="1" +export CXX="${HOST_COMPILER}" +export CUDACXX="${CUDA_COMPILER}" +export CUDAHOSTCXX="${HOST_COMPILER}" +export CXX_STANDARD + +source ./pretty_printing.sh + +print_environment_details() { + begin_group "⚙️ Environment Details" + + echo "pwd=$(pwd)" + + print_var_values \ + BUILD_DIR \ + CXX_STANDARD \ + CXX \ + CUDACXX \ + CUDAHOSTCXX \ + NVCC_VERSION \ + CMAKE_BUILD_PARALLEL_LEVEL \ + CTEST_PARALLEL_LEVEL \ + CCCL_BUILD_INFIX \ + GLOBAL_CMAKE_OPTIONS + + echo "Current commit is:" + git log -1 || echo "Not a repository" + + if command -v nvidia-smi &> /dev/null; then + nvidia-smi + else + echo "nvidia-smi not found" + fi + + end_group "⚙️ Environment Details" +} + +fail_if_no_gpu() { + if ! nvidia-smi &> /dev/null; then + echo "Error: No NVIDIA GPU detected. Please ensure you have an NVIDIA GPU installed and the drivers are properly configured." >&2 + exit 1 + fi +} + +function print_test_time_summary() +{ + ctest_log=${1} + + if [ -f ${ctest_log} ]; then + begin_group "⏱️ Longest Test Steps" + # Only print the full output in CI: + if [ -n "${GITHUB_ACTIONS:-}" ]; then + cmake -DLOGFILE=${ctest_log} -P ../cmake/PrintCTestRunTimes.cmake + else + cmake -DLOGFILE=${ctest_log} -P ../cmake/PrintCTestRunTimes.cmake | head -n 15 + fi + end_group "⏱️ Longest Test Steps" + fi +} + +function configure_preset() +{ + local BUILD_NAME=$1 + local PRESET=$2 + local CMAKE_OPTIONS=$3 + local GROUP_NAME="🛠️ CMake Configure ${BUILD_NAME}" + + pushd .. > /dev/null + run_command "$GROUP_NAME" cmake --preset=$PRESET --log-level=VERBOSE "${GLOBAL_CMAKE_OPTIONS[@]}" $CMAKE_OPTIONS + status=$? + popd > /dev/null + return $status +} + +function build_preset() { + local BUILD_NAME=$1 + local PRESET=$2 + local green="1;32" + local red="1;31" + local GROUP_NAME="🏗️ Build ${BUILD_NAME}" + + source "./sccache_stats.sh" "start" + + pushd .. > /dev/null + run_command "$GROUP_NAME" cmake --build --preset=$PRESET -v + status=$? + popd > /dev/null + + minimal_sccache_stats=$(source "./sccache_stats.sh" "end") + + # Only print detailed stats in actions workflow + if [ -n "${GITHUB_ACTIONS:-}" ]; then + begin_group "💲 sccache stats" + echo "${minimal_sccache_stats}" + sccache -s + end_group + + begin_group "🥷 ninja build times" + echo "The "weighted" time is the elapsed time of each build step divided by the number + of tasks that were running in parallel. This makes it an excellent approximation + of how "important" a slow step was. A link that is entirely or mostly serialized + will have a weighted time that is the same or similar to its elapsed time. A + compile that runs in parallel with 999 other compiles will have a weighted time + that is tiny." + ./ninja_summary.py -C ${BUILD_DIR}/${PRESET} + end_group + else + echo $minimal_sccache_stats + fi + + return $status +} + +function test_preset() +{ + local BUILD_NAME=$1 + local PRESET=$2 + local GROUP_NAME="🚀 Test ${BUILD_NAME}" + + fail_if_no_gpu + + + ctest_log_dir="${BUILD_DIR}/log/ctest" + ctest_log="${ctest_log_dir}/${PRESET}" + mkdir -p "${ctest_log_dir}" + + pushd .. > /dev/null + run_command "$GROUP_NAME" ctest --output-log "${ctest_log}" --preset=$PRESET + status=$? + popd > /dev/null + + print_test_time_summary ${ctest_log} + + return $status +} + +function configure_and_build_preset() +{ + local BUILD_NAME=$1 + local PRESET=$2 + local CMAKE_OPTIONS=$3 + + configure_preset "$BUILD_NAME" "$PRESET" "$CMAKE_OPTIONS" + build_preset "$BUILD_NAME" "$PRESET" +} diff --git a/ci/build_nvbench.sh b/ci/build_nvbench.sh new file mode 100755 index 00000000..ecd06289 --- /dev/null +++ b/ci/build_nvbench.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +source "$(dirname "$0")/build_common.sh" + +print_environment_details + +PRESET="nvbench-cpp$CXX_STANDARD" + +CMAKE_OPTIONS="" + +configure_and_build_preset "NVBench" "$PRESET" "$CMAKE_OPTIONS" + +print_time_summary diff --git a/ci/common/build.bash b/ci/common/build.bash deleted file mode 100755 index 61b3654c..00000000 --- a/ci/common/build.bash +++ /dev/null @@ -1,231 +0,0 @@ -#! /usr/bin/env bash - -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -################################################################################ -# NVBench build script for gpuCI -################################################################################ - -set -e - -# append variable value -# Appends ${value} to ${variable}, adding a space before ${value} if -# ${variable} is not empty. -function append { - tmp="${!1:+${!1} }${2}" - eval "${1}=\${tmp}" -} - -# log args... -# Prints out ${args[*]} with a gpuCI log prefix and a newline before and after. -function log() { - printf "\n>>>> %s\n\n" "${*}" -} - -# print_with_trailing_blank_line args... -# Prints ${args[*]} with one blank line following, preserving newlines within -# ${args[*]} but stripping any preceding ${args[*]}. -function print_with_trailing_blank_line { - printf "%s\n\n" "${*}" -} - -# echo_and_run name args... -# Echo ${args[@]}, then execute ${args[@]} -function echo_and_run { - echo "${1}: ${@:2}" - ${@:2} -} - -# echo_and_run_timed name args... -# Echo ${args[@]}, then execute ${args[@]} and report how long it took, -# including ${name} in the output of the time. -function echo_and_run_timed { - echo "${@:2}" - TIMEFORMAT=$'\n'"${1} Time: %lR" - time ${@:2} -} - -# join_delimit [value [value [...]]] -# Combine all values into a single string, separating each by a single character -# delimiter. Eg: -# foo=(bar baz kramble) -# joined_foo=$(join_delimit "|" "${foo[@]}") -# echo joined_foo # "bar|baz|kramble" -function join_delimit { - local IFS="${1}" - shift - echo "${*}" -} - -################################################################################ -# VARIABLES - Set up bash and environmental variables. -################################################################################ - -# Get the variables the Docker container set up for us: ${CXX}, ${CUDACXX}, etc. -source /etc/cccl.bashrc - -# Set path. -export PATH=/usr/local/cuda/bin:${PATH} - -# Set home to the job's workspace. -export HOME=${WORKSPACE} - -# Switch to the build directory. -cd ${WORKSPACE} -mkdir -p build -cd build - -# Remove any old .ninja_log file so the PrintNinjaBuildTimes step is accurate: -rm -f .ninja_log - -if [[ -z "${CMAKE_BUILD_TYPE}" ]]; then - CMAKE_BUILD_TYPE="Release" -fi - -CMAKE_BUILD_FLAGS="--" - -# The Docker image sets up `${CXX}` and `${CUDACXX}`. -append CMAKE_FLAGS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" -append CMAKE_FLAGS "-DCMAKE_CUDA_COMPILER='${CUDACXX}'" - -if [[ "${CXX_TYPE}" == "nvcxx" ]]; then - echo "nvc++ not supported." - exit 1 -else - if [[ "${CXX_TYPE}" == "icc" ]]; then - echo "icc not supported." - exit 1 - fi - # We're using NVCC so we need to set the host compiler. - append CMAKE_FLAGS "-DCMAKE_CXX_COMPILER='${CXX}'" - append CMAKE_FLAGS "-DCMAKE_CUDA_HOST_COMPILER='${CXX}'" - append CMAKE_FLAGS "-G Ninja" - # Don't stop on build failures. - append CMAKE_BUILD_FLAGS "-k0" -fi - -if [[ -n "${PARALLEL_LEVEL}" ]]; then - DETERMINE_PARALLELISM_FLAGS="-j ${PARALLEL_LEVEL}" -fi - -WSL=0 -if [[ $(grep -i microsoft /proc/version) ]]; then - echo "Windows Subsystem for Linux detected." - WSL=1 -fi -export WSL - -#append CMAKE_FLAGS "-DCMAKE_CUDA_ARCHITECTURES=all" - -append CMAKE_FLAGS "-DNVBench_ENABLE_EXAMPLES=ON" -append CMAKE_FLAGS "-DNVBench_ENABLE_TESTING=ON" -append CMAKE_FLAGS "-DNVBench_ENABLE_CUPTI=ON" -append CMAKE_FLAGS "-DNVBench_ENABLE_WERROR=ON" - -# These consume a lot of time and don't currently have -# any value as regression tests. -append CMAKE_FLAGS "-DNVBench_ENABLE_DEVICE_TESTING=OFF" - -# NVML doesn't work under WSL -if [[ ${WSL} -eq 0 ]]; then - append CMAKE_FLAGS "-DNVBench_ENABLE_NVML=ON" -else - append CMAKE_FLAGS "-DNVBench_ENABLE_NVML=OFF" -fi - -if [[ -n "${@}" ]]; then - append CMAKE_BUILD_FLAGS "${@}" -fi - -append CTEST_FLAGS "--output-on-failure" - -# Export variables so they'll show up in the logs when we report the environment. -export CMAKE_FLAGS -export CMAKE_BUILD_FLAGS -export CTEST_FLAGS - -################################################################################ -# ENVIRONMENT - Configure and print out information about the environment. -################################################################################ - -log "Determine system topology..." - -# Set `${PARALLEL_LEVEL}` if it is unset; otherwise, this just reports the -# system topology. -source ${WORKSPACE}/ci/common/determine_build_parallelism.bash ${DETERMINE_PARALLELISM_FLAGS} - -log "Get environment..." - -env | sort - -log "Check versions..." - -# We use sed and echo below to ensure there is always one and only trailing -# line following the output from each tool. - -${CXX} --version 2>&1 | sed -Ez '$ s/\n*$/\n/' - -echo - -${CUDACXX} --version 2>&1 | sed -Ez '$ s/\n*$/\n/' - -echo - -cmake --version 2>&1 | sed -Ez '$ s/\n*$/\n/' - -echo - -if [[ "${BUILD_TYPE}" == "gpu" ]]; then - nvidia-smi 2>&1 | sed -Ez '$ s/\n*$/\n/' -fi - -################################################################################ -# BUILD -################################################################################ - -log "Configure..." - -echo_and_run_timed "Configure" cmake .. --log-level=VERBOSE ${CMAKE_FLAGS} -configure_status=$? - -log "Build..." - -# ${PARALLEL_LEVEL} needs to be passed after we run -# determine_build_parallelism.bash, so it can't be part of ${CMAKE_BUILD_FLAGS}. -set +e # Don't stop on build failures. -echo_and_run_timed "Build" cmake --build . ${CMAKE_BUILD_FLAGS} -j ${PARALLEL_LEVEL} -build_status=$? -set -e - -################################################################################ -# TEST - Run examples and tests. -################################################################################ - -log "Test..." - -( - # Make sure test_status captures ctest, not tee: - # https://stackoverflow.com/a/999259/11130318 - set -o pipefail - echo_and_run_timed "Test" ctest ${CTEST_FLAGS} -j ${PARALLEL_LEVEL} | tee ctest_log -) - -test_status=$? - -################################################################################ -# SUMMARY - Print status of each step and exit with failure if needed. -################################################################################ - -log "Summary:" -echo "- Configure Error Code: ${configure_status}" -echo "- Build Error Code: ${build_status}" -echo "- Test Error Code: ${test_status}" - -if [[ "${configure_status}" != "0" ]] || \ - [[ "${build_status}" != "0" ]] || \ - [[ "${test_status}" != "0" ]]; then - exit 1 -fi diff --git a/ci/common/determine_build_parallelism.bash b/ci/common/determine_build_parallelism.bash deleted file mode 100755 index 1a1cf4c7..00000000 --- a/ci/common/determine_build_parallelism.bash +++ /dev/null @@ -1,119 +0,0 @@ -#! /usr/bin/env bash - -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -function usage { - echo "Usage: ${0} [flags...]" - echo - echo "Examine the system topology to determine a reasonable amount of build" - echo "parallelism." - echo - echo "Exported variables:" - echo " \${LOGICAL_CPUS} : Logical processors (e.g. threads)." - echo " \${PHYSICAL_CPUS} : Physical processors (e.g. cores)." - echo " \${TOTAL_MEM} : Total system memory [GB]." - echo " \${MAX_THREADS_PER_CORE} : Maximum threads per core allowed." - echo " \${MIN_MEMORY_PER_THREAD} : Minimum memory [GB] per thread allowed." - echo " \${CPU_BOUND_THREADS} : # of build threads constrained by processors." - echo " \${MEM_BOUND_THREADS} : # of build threads constrained by memory [GB]." - echo " \${PARALLEL_LEVEL} : Determined # of build threads." - echo " \${MEM_PER_THREAD} : Memory [GB] per build thread." - echo - echo "-h, -help, --help" - echo " Print this message." - echo - echo "-q, --quiet" - echo " Print nothing and only export variables." - echo - echo "-j , --jobs " - echo " Explicitly set the number of build threads to use." - echo - echo "--max-threads-per-core " - echo " Specify the maximum threads per core allowed (default: ${MAX_THREADS_PER_CORE} [threads/core])." - echo - echo "--min-memory-per-thread " - echo " Specify the minimum memory per thread allowed (default: ${MIN_MEMORY_PER_THREAD} [GBs/thread])." - - exit -3 -} - -QUIET=0 - -export MAX_THREADS_PER_CORE=2 -export MIN_MEMORY_PER_THREAD=1 # [GB] - -while test ${#} != 0 -do - case "${1}" in - -h) ;& - -help) ;& - --help) usage ;; - -q) ;& - --quiet) QUIET=1 ;; - -j) ;& - --jobs) - shift # The next argument is the number of threads. - PARALLEL_LEVEL="${1}" - ;; - --max-threads-per-core) - shift # The next argument is the number of threads per core. - MAX_THREADS_PER_CORE="${1}" - ;; - --min-memory-per-thread) - shift # The next argument is the amount of memory per thread. - MIN_MEMORY_PER_THREAD="${1}" - ;; - esac - shift -done - -# https://stackoverflow.com/a/23378780 -if [ $(uname) == "Darwin" ]; then - export LOGICAL_CPUS=$(sysctl -n hw.logicalcpu_max) - export PHYSICAL_CPUS=$(sysctl -n hw.physicalcpu_max) -else - export LOGICAL_CPUS=$(lscpu -p | egrep -v '^#' | wc -l) - export PHYSICAL_CPUS=$(lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l) -fi - -export TOTAL_MEM=$(awk "BEGIN { printf \"%0.4g\", $(grep MemTotal /proc/meminfo | awk '{ print $2 }') / (1024 * 1024) }") - -export CPU_BOUND_THREADS=$(awk "BEGIN { printf \"%.04g\", int(${PHYSICAL_CPUS} * ${MAX_THREADS_PER_CORE}) }") -export MEM_BOUND_THREADS=$(awk "BEGIN { printf \"%.04g\", int(${TOTAL_MEM} / ${MIN_MEMORY_PER_THREAD}) }") - -if [[ -z "${PARALLEL_LEVEL}" ]]; then - # Pick the smaller of the two as the default. - if [[ "${MEM_BOUND_THREADS}" -lt "${CPU_BOUND_THREADS}" ]]; then - export PARALLEL_LEVEL=${MEM_BOUND_THREADS} - else - export PARALLEL_LEVEL=${CPU_BOUND_THREADS} - fi -else - EXPLICIT_PARALLEL_LEVEL=1 -fi - -# This can be a floating point number. -export MEM_PER_THREAD=$(awk "BEGIN { printf \"%.04g\", ${TOTAL_MEM} / ${PARALLEL_LEVEL} }") - -if [[ "${QUIET}" == 0 ]]; then - echo "Logical CPUs: ${LOGICAL_CPUS} [threads]" - echo "Physical CPUs: ${PHYSICAL_CPUS} [cores]" - echo "Total Mem: ${TOTAL_MEM} [GBs]" - echo "Max Threads Per Core: ${MAX_THREADS_PER_CORE} [threads/core]" - echo "Min Memory Per Threads: ${MIN_MEMORY_PER_THREAD} [GBs/thread]" - echo "CPU Bound Threads: ${CPU_BOUND_THREADS} [threads]" - echo "Mem Bound Threads: ${MEM_BOUND_THREADS} [threads]" - - echo -n "Parallel Level: ${PARALLEL_LEVEL} [threads]" - if [[ -n "${EXPLICIT_PARALLEL_LEVEL}" ]]; then - echo " (explicitly set)" - else - echo - fi - - echo "Mem Per Thread: ${MEM_PER_THREAD} [GBs/thread]" -fi - diff --git a/ci/cpu/build.bash b/ci/cpu/build.bash deleted file mode 100755 index edf1ba31..00000000 --- a/ci/cpu/build.bash +++ /dev/null @@ -1,14 +0,0 @@ -#! /usr/bin/env bash - -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -################################################################################ -# NVBench build script for gpuCI (CPU-only) -################################################################################ - -export PARALLEL_LEVEL=${PARALLEL_LEVEL:-4} - -source ${WORKSPACE}/ci/common/build.bash diff --git a/ci/gpu/build.bash b/ci/gpu/build.bash deleted file mode 100755 index 9f6fc01f..00000000 --- a/ci/gpu/build.bash +++ /dev/null @@ -1,14 +0,0 @@ -#! /usr/bin/env bash - -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -################################################################################ -# NVBench build script for gpuCI (heterogeneous) -################################################################################ - -export PARALLEL_LEVEL=${PARALLEL_LEVEL:-4} - -source ${WORKSPACE}/ci/common/build.bash diff --git a/ci/local/build.bash b/ci/local/build.bash deleted file mode 100755 index 60d22dea..00000000 --- a/ci/local/build.bash +++ /dev/null @@ -1,215 +0,0 @@ -#! /usr/bin/env bash - -# Copyright (c) 2018-2020 NVIDIA Corporation -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Released under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for license information. - -################################################################################ -# NVBench local containerized build script -################################################################################ - -function usage { - echo "Usage: ${0} [flags...] [cmake-targets...]" - echo - echo "Build and test your local repository using a gpuCI Docker image." - echo "If CMake targets are specified, only those targets are built and tested." - echo "Otherwise, everything is built and tested." - echo - echo "-h, -help, --help" - echo " Print this message." - echo - echo "-r , --repository " - echo " Path to the repository (default: ${REPOSITORY_PATH})." - echo - echo "-i , --image " - echo " Docker image to use (default: ${IMAGE})" - echo - echo "-l, --local-image" - echo " Use the local version of the image instead of pulling from Docker hub." - echo - echo "-s, --shell-only" - echo " Skip building and testing and launch an interactive shell instead." - echo - echo "-d, --disable-gpus" - echo " Don't start the container with the NVIDIA runtime and GPUs attached." - echo - echo "-c, --clean" - echo " If the build directory already exists, delete it." - echo - echo "-j , --jobs " - echo " Number of threads to use when building (default: inferred)." - echo - echo "-b , --cmake-build-type " - echo " CMake build type to use, either Release, RelWithDebInfo, or Debug" - echo " (default: ${CMAKE_BUILD_TYPE})." - echo - - exit -3 -} - -SCRIPT_PATH=$(cd $(dirname ${0}); pwd -P) - -REPOSITORY_PATH=$(realpath ${SCRIPT_PATH}/../..) - -################################################################################ -# FLAGS - Process command line flags. -################################################################################ - -IMAGE="gpuci/cccl:cuda11.5.1-devel-ubuntu20.04-gcc9" - -LOCAL_IMAGE=0 - -SHELL_ONLY=0 - -BUILD_TYPE="gpu" - -CLEAN=0 - -PARALLEL_LEVEL="" - -CMAKE_BUILD_TYPE="Release" - -TARGETS="" - -while test ${#} != 0 -do - case "${1}" in - -h) ;& - -help) ;& - --help) usage ;; - -r) ;& - --repository) - shift # The next argument is the path. - REPOSITORY_PATH="${1}" - ;; - -i) ;& - --image) - shift # The next argument is the image. - IMAGE="${1}" - ;; - -l) ;& - --local-image) LOCAL_IMAGE=1 ;; - -s) ;& - --shell-only) SHELL_ONLY=1 ;; - -d) ;& - --disable-gpus) BUILD_TYPE="cpu" ;; - -c) ;& - --clean) CLEAN=1 ;; - -j) ;& - --jobs) - shift # The next argument is the number of threads. - PARALLEL_LEVEL="${1}" - ;; - -b) ;& - --cmake-build-type) - shift # The next argument is the build type. - CMAKE_BUILD_TYPE="${1}" - ;; - *) - TARGETS="${TARGETS:+${TARGETS} }${1}" - ;; - esac - shift -done - -################################################################################ -# PATHS - Setup paths for the container. -################################################################################ - -# ${REPOSITORY_PATH} is the local filesystem path to the Git repository being -# built and tested. It can be set with the --repository flag. -# -# ${BUILD_PATH} is the local filesystem path that will be used for the build. It -# is named after the image name, allowing multiple image builds to coexist on -# the local filesystem. -# -# ${REPOSITORY_PATH_IN_CONTAINER} is the location of ${REPOSITORY_PATH} inside -# the container. -# -# ${BUILD_PATH_IN_CONTAINER} is the location of ${BUILD_PATH} inside the -# container. - -BUILD_PATH=${REPOSITORY_PATH}/build_$(echo "$(basename "${IMAGE}")" | sed -e 's/:/_/g' | sed -e 's/-/_/g') - -if [[ "${CLEAN}" != 0 ]]; then - rm -rf ${BUILD_PATH} -fi - -mkdir -p ${BUILD_PATH} - -BASE_PATH_IN_CONTAINER="/cccl" - -REPOSITORY_PATH_IN_CONTAINER="${BASE_PATH_IN_CONTAINER}/$(basename "${REPOSITORY_PATH}")" - -BUILD_PATH_IN_CONTAINER="${BASE_PATH_IN_CONTAINER}/$(basename "${REPOSITORY_PATH}")/build" - -################################################################################ -# ENVIRONMENT - Setup the thunk build script that will be run by the container. -################################################################################ - -# We have to run `ldconfig` to rebuild `ld.so.cache` to work around this -# failure on Debian: https://github.com/NVIDIA/nvidia-docker/issues/1399 - -COMMAND="sudo ldconfig; sudo ldconfig" -if [[ "${SHELL_ONLY}" != 0 ]]; then - COMMAND="${COMMAND}; bash" -else - COMMAND="${COMMAND}; ${REPOSITORY_PATH_IN_CONTAINER}/ci/common/build.bash ${TARGETS} || bash" -fi - -################################################################################ -# GPU - Setup GPUs. -################################################################################ - -# Note: We always start docker with --gpus, even for cpu builds. Otherwise -# libcuda.so.1 is not present and no NVBench tests are able to run. - -# Limit GPUs available to the container based on ${CUDA_VISIBLE_DEVICES}. -if [[ -z "${CUDA_VISIBLE_DEVICES}" ]]; then - VISIBLE_DEVICES="all" -else - VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES}" -fi - -DOCKER_MAJOR_VER=$(docker -v | sed 's/[^[0-9]*\([0-9]*\).*/\1/') -GPU_OPTS="--gpus device=${VISIBLE_DEVICES}" -if [[ "${DOCKER_MAJOR_VER}" -lt 19 ]] -then - GPU_OPTS="--runtime=nvidia -e NVIDIA_VISIBLE_DEVICES='${VISIBLE_DEVICES}'" -fi - -################################################################################ -# LAUNCH - Pull and launch the container. -################################################################################ - -#NVIDIA_DOCKER_INSTALLED=$(docker info 2>&1 | grep -i runtime | grep -c nvidia) -NVIDIA_DOCKER_INSTALLED=1 # Broken on WSL -if [[ "${NVIDIA_DOCKER_INSTALLED}" == 0 ]]; then - echo "NVIDIA Docker not found, please install it: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#installing-docker-ce" - exit -4 -fi - -if [[ "${LOCAL_IMAGE}" == 0 ]]; then - docker pull "${IMAGE}" -fi - -docker run --rm -it ${GPU_OPTS} \ - --cap-add=SYS_PTRACE \ - --user "$(id -u)":"$(id -g)" \ - -v "${REPOSITORY_PATH}":"${REPOSITORY_PATH_IN_CONTAINER}" \ - -v "${BUILD_PATH}":"${BUILD_PATH_IN_CONTAINER}" \ - -v /etc/passwd:/etc/passwd:ro \ - -v /etc/group:/etc/group:ro \ - -v /etc/subuid:/etc/subuid:ro \ - -v /etc/subgid:/etc/subgid:ro \ - -v /etc/shadow:/etc/shadow:ro \ - -v /etc/gshadow:/etc/gshadow:ro \ - -e "WORKSPACE=${REPOSITORY_PATH_IN_CONTAINER}" \ - -e "BUILD_TYPE=${BUILD_TYPE}" \ - -e "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" \ - -e "COVERAGE_PLAN=${COVERAGE_PLAN}" \ - -e "PARALLEL_LEVEL=${PARALLEL_LEVEL}" \ - -w "${BUILD_PATH_IN_CONTAINER}" \ - "${IMAGE}" bash -c "${COMMAND}" - diff --git a/ci/matrix.yaml b/ci/matrix.yaml new file mode 100644 index 00000000..e6054fd7 --- /dev/null +++ b/ci/matrix.yaml @@ -0,0 +1,85 @@ + +cuda_prev_min: &cuda_prev_min '11.1' +cuda_prev_max: &cuda_prev_max '11.8' +cuda_curr: &cuda_curr '12.4' + +# The GPUs to test on +gpus: + - 'a100' + - 'v100' + +# The version of the devcontainer images to use from https://hub.docker.com/r/rapidsai/devcontainers +devcontainer_version: '24.06' + +# gcc compiler configurations +gcc6: &gcc6 { name: 'gcc', version: '6', exe: 'g++' } +gcc7: &gcc7 { name: 'gcc', version: '7', exe: 'g++' } +gcc8: &gcc8 { name: 'gcc', version: '8', exe: 'g++' } +gcc9: &gcc9 { name: 'gcc', version: '9', exe: 'g++' } +gcc10: &gcc10 { name: 'gcc', version: '10', exe: 'g++' } +gcc11: &gcc11 { name: 'gcc', version: '11', exe: 'g++' } +gcc12: &gcc12 { name: 'gcc', version: '12', exe: 'g++' } +gcc-oldest: &gcc-oldest { name: 'gcc', version: '6', exe: 'g++' } +gcc-newest: &gcc-newest { name: 'gcc', version: '12', exe: 'g++' } + +# LLVM Compiler configurations +llvm9: &llvm9 { name: 'llvm', version: '9', exe: 'clang++' } +llvm10: &llvm10 { name: 'llvm', version: '10', exe: 'clang++' } +llvm11: &llvm11 { name: 'llvm', version: '11', exe: 'clang++' } +llvm12: &llvm12 { name: 'llvm', version: '12', exe: 'clang++' } +llvm13: &llvm13 { name: 'llvm', version: '13', exe: 'clang++' } +llvm14: &llvm14 { name: 'llvm', version: '14', exe: 'clang++' } +llvm15: &llvm15 { name: 'llvm', version: '15', exe: 'clang++' } +llvm16: &llvm16 { name: 'llvm', version: '16', exe: 'clang++' } +llvm-oldest: &llvm-oldest { name: 'llvm', version: '9', exe: 'clang++' } +llvm-newest: &llvm-newest { name: 'llvm', version: '16', exe: 'clang++' } + +# MSVC configs +msvc2017: &msvc2017 { name: 'cl', version: '14.16', exe: 'cl++' } +msvc2019: &msvc2019 { name: 'cl', version: '14.29', exe: 'cl++' } +msvc2022: &msvc2022 { name: 'cl', version: '14.39', exe: 'cl++' } + +# oneAPI configs +oneapi: &oneapi { name: 'oneapi', version: '2023.2.0', exe: 'icpc' } + +# Each environment below will generate a unique build/test job +# See the "compute-matrix" job in the workflow for how this is parsed and used +# cuda: The CUDA Toolkit version +# os: The operating system used +# cpu: The CPU architecture +# compiler: The compiler to use +# name: The compiler name +# version: The compiler version +# exe: The unverionsed compiler binary name +# std: The C++ standards to build for +# This field is unique as it will generate an independent build/test job for each value + +# Configurations that will run for every PR +pull_request: + nvcc: + - {cuda: *cuda_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *gcc7, std: [17], jobs: ['build']} + - {cuda: *cuda_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *gcc8, std: [17], jobs: ['build']} + - {cuda: *cuda_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *gcc9, std: [17], jobs: ['build']} + - {cuda: *cuda_prev_min, os: 'ubuntu18.04', cpu: 'amd64', compiler: *llvm9, std: [17], jobs: ['build']} + - {cuda: *cuda_prev_min, os: 'windows2022', cpu: 'amd64', compiler: *msvc2017, std: [17], jobs: ['build']} + - {cuda: *cuda_prev_max, os: 'ubuntu22.04', cpu: 'amd64', compiler: *gcc11, std: [17], jobs: ['build'], extra_build_args: '-cmake-options -DCMAKE_CUDA_ARCHITECTURES=90'} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *gcc7, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *gcc8, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *gcc9, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *gcc10, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *gcc11, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *gcc12, std: [17], jobs: ['build'], extra_build_args: '-cmake-options -DCMAKE_CUDA_ARCHITECTURES=90a'} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *gcc12, std: [17], jobs: ['build', 'test']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'arm64', compiler: *gcc12, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm9, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm10, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm11, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm12, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm13, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu20.04', cpu: 'amd64', compiler: *llvm14, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *llvm15, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *llvm16, std: [17], jobs: ['build', 'test']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'arm64', compiler: *llvm16, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'windows2022', cpu: 'amd64', compiler: *msvc2019, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'windows2022', cpu: 'amd64', compiler: *msvc2022, std: [17], jobs: ['build']} + - {cuda: *cuda_curr, os: 'ubuntu22.04', cpu: 'amd64', compiler: *oneapi, std: [17], jobs: ['build']} diff --git a/ci/pretty_printing.sh b/ci/pretty_printing.sh new file mode 100644 index 00000000..5bea1af9 --- /dev/null +++ b/ci/pretty_printing.sh @@ -0,0 +1,105 @@ +# Print "ARG=${ARG}" for all args. +function print_var_values() { + # Iterate through the arguments + for var_name in "$@"; do + if [ -z "$var_name" ]; then + echo "Usage: print_var_values ..." + return 1 + fi + + # Dereference the variable and print the result + echo "$var_name=${!var_name:-(undefined)}" + done +} + +# begin_group: Start a named section of log output, possibly with color. +# Usage: begin_group "Group Name" [Color] +# Group Name: A string specifying the name of the group. +# Color (optional): ANSI color code to set text color. Default is blue (1;34). +function begin_group() { + # See options for colors here: https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc87b2124 + local blue="34" + local name="${1:-}" + local color="${2:-$blue}" + + if [ -n "${GITHUB_ACTIONS:-}" ]; then + echo -e "::group::\e[${color}m${name}\e[0m" + else + echo -e "\e[${color}m================== ${name} ======================\e[0m" + fi +} + +# end_group: End a named section of log output and print status based on exit status. +# Usage: end_group "Group Name" [Exit Status] +# Group Name: A string specifying the name of the group. +# Exit Status (optional): The exit status of the command run within the group. Default is 0. +function end_group() { + local name="${1:-}" + local build_status="${2:-0}" + local duration="${3:-}" + local red="31" + local blue="34" + + if [ -n "${GITHUB_ACTIONS:-}" ]; then + echo "::endgroup::" + + if [ "$build_status" -ne 0 ]; then + echo -e "::error::\e[${red}m ${name} - Failed (⬆️ click above for full log ⬆️)\e[0m" + fi + else + if [ "$build_status" -ne 0 ]; then + echo -e "\e[${red}m================== End ${name} - Failed${duration:+ - Duration: ${duration}s} ==================\e[0m" + else + echo -e "\e[${blue}m================== End ${name} - Success${duration:+ - Duration: ${duration}s} ==================\n\e[0m" + fi + fi +} + +declare -A command_durations + +# Runs a command within a named group, handles the exit status, and prints appropriate messages based on the result. +# Usage: run_command "Group Name" command [arguments...] +function run_command() { + local group_name="${1:-}" + shift + local command=("$@") + local status + + begin_group "$group_name" + set +e + local start_time=$(date +%s) + "${command[@]}" + status=$? + local end_time=$(date +%s) + set -e + local duration=$((end_time - start_time)) + end_group "$group_name" $status $duration + command_durations["$group_name"]=$duration + return $status +} + +function string_width() { + local str="$1" + echo "$str" | awk '{print length}' +} + +function print_time_summary() { + local max_length=0 + local group + + # Find the longest group name for formatting + for group in "${!command_durations[@]}"; do + local group_length=$(echo "$group" | awk '{print length}') + if [ "$group_length" -gt "$max_length" ]; then + max_length=$group_length + fi + done + + echo "Time Summary:" + for group in "${!command_durations[@]}"; do + printf "%-${max_length}s : %s seconds\n" "$group" "${command_durations[$group]}" + done + + # Clear the array of timing info + declare -gA command_durations=() +} diff --git a/ci/sccache_hit_rate.sh b/ci/sccache_hit_rate.sh new file mode 100755 index 00000000..de8ae465 --- /dev/null +++ b/ci/sccache_hit_rate.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -euo pipefail + +# Ensure two arguments are provided +if [ $# -ne 2 ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +# Print the contents of the before file +echo "=== Contents of $1 ===" >&2 +cat $1 >&2 +echo "=== End of $1 ===" >&2 + +# Print the contents of the after file +echo "=== Contents of $2 ===" >&2 +cat $2 >&2 +echo "=== End of $2 ===" >&2 + +# Extract compile requests and cache hits from the before and after files +requests_before=$(awk '/^[ \t]*Compile requests[ \t]+[0-9]+/ {print $3}' "$1") +hits_before=$(awk '/^[ \t]*Cache hits[ \t]+[0-9]+/ {print $3}' "$1") +requests_after=$(awk '/^[ \t]*Compile requests[ \t]+[0-9]+/ {print $3}' "$2") +hits_after=$(awk '/^[ \t]*Cache hits[ \t]+[0-9]+/ {print $3}' "$2") + +# Calculate the differences to find out how many new requests and hits +requests_diff=$((requests_after - requests_before)) +hits_diff=$((hits_after - hits_before)) + +echo "New Compile Requests: $requests_diff" >&2 +echo "New Hits: $hits_diff" >&2 + +# Calculate and print the hit rate +if [ $requests_diff -eq 0 ]; then + echo "No new compile requests, hit rate is not applicable" +else + hit_rate=$(awk -v hits=$hits_diff -v requests=$requests_diff 'BEGIN {printf "%.2f", hits/requests * 100}') + echo "sccache hit rate: $hit_rate%" >&2 + echo "$hit_rate" +fi diff --git a/ci/sccache_stats.sh b/ci/sccache_stats.sh new file mode 100755 index 00000000..3a3ebc42 --- /dev/null +++ b/ci/sccache_stats.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# This script prints the sccache hit rate between two calls to sccache --show-stats. +# It should be sourced in your script before and after the operations you want to profile, +# with the 'start' or 'end' argument respectively. + +mode=$1 + +if [[ "$mode" != "start" && "$mode" != "end" ]]; then + echo "Invalid mode: $mode" + echo "Usage: $0 {start|end}" + exit 1 +fi + +# Check if sccache is available +if ! command -v sccache &> /dev/null; then + echo "Notice: sccache is not available. Skipping..." + exit 0 +fi + +case $mode in + start) + export SCCACHE_START_HITS=$(sccache --show-stats | awk '/^[ \t]*Cache hits[ \t]+[0-9]+/ {print $3}') + export SCCACHE_START_MISSES=$(sccache --show-stats | awk '/^[ \t]*Cache misses[ \t]+[0-9]+/ {print $3}') + ;; + end) + if [[ -z ${SCCACHE_START_HITS+x} || -z ${SCCACHE_START_MISSES+x} ]]; then + echo "Error: start stats not collected. Did you call this script with 'start' before your operations?" + exit 1 + fi + + final_hits=$(sccache --show-stats | awk '/^[ \t]*Cache hits[ \t]+[0-9]+/ {print $3}') + final_misses=$(sccache --show-stats | awk '/^[ \t]*Cache misses[ \t]+[0-9]+/ {print $3}') + hits=$((final_hits - SCCACHE_START_HITS)) + misses=$((final_misses - SCCACHE_START_MISSES)) + total=$((hits + misses)) + + prefix="" + if [ ${GITHUB_ACTIONS:-false} = "true" ]; then + prefix="::notice::" + fi + + if (( total > 0 )); then + hit_rate=$(awk -v hits="$hits" -v total="$total" 'BEGIN { printf "%.2f", (hits / total) * 100 }') + echo ${prefix}"sccache hits: $hits | misses: $misses | hit rate: $hit_rate%" + else + echo ${prefix}"sccache stats: N/A No new compilation requests" + fi + unset SCCACHE_START_HITS + unset SCCACHE_START_MISSES + ;; +esac diff --git a/ci/test_nvbench.sh b/ci/test_nvbench.sh new file mode 100755 index 00000000..f89c6fe6 --- /dev/null +++ b/ci/test_nvbench.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +source "$(dirname "$0")/build_common.sh" + +# Run NVBench tests with high parallelism. If any need to be +# serialized, define the `RUN_SERIAL` CMake property on the +# test. +export CTEST_PARALLEL_LEVEL=${PARALLEL_LEVEL} + +print_environment_details + +./build_nvbench.sh "$@" + +PRESET="nvbench-cpp$CXX_STANDARD" + +test_preset "NVBench" ${PRESET} + +print_time_summary diff --git a/ci/windows/build_common.psm1 b/ci/windows/build_common.psm1 new file mode 100644 index 00000000..9d8e9cf5 --- /dev/null +++ b/ci/windows/build_common.psm1 @@ -0,0 +1,205 @@ + +Param( + [Parameter(Mandatory = $true)] + [Alias("std")] + [ValidateNotNullOrEmpty()] + [ValidateSet(17)] + [int]$CXX_STANDARD = 17 +) + +# We need the full path to cl because otherwise cmake will replace CMAKE_CXX_COMPILER with the full path +# and keep CMAKE_CUDA_HOST_COMPILER at "cl" which breaks our cmake script +$script:HOST_COMPILER = (Get-Command "cl").source -replace '\\','/' +$script:PARALLEL_LEVEL = (Get-WmiObject -class Win32_processor).NumberOfLogicalProcessors + +# Extract the CL version for export to build scripts: +$script:CL_VERSION_STRING = & cl.exe /? +if ($script:CL_VERSION_STRING -match "Version (\d+\.\d+)\.\d+") { + $CL_VERSION = [version]$matches[1] + Write-Host "Detected cl.exe version: $CL_VERSION" +} + +if (-not $env:CCCL_BUILD_INFIX) { + $env:CCCL_BUILD_INFIX = "" +} + +# Presets will be configured in this directory: +$BUILD_DIR = "../build/$env:CCCL_BUILD_INFIX" + +If(!(test-path -PathType container "../build")) { + New-Item -ItemType Directory -Path "../build" +} + +# The most recent build will always be symlinked to cccl/build/latest +New-Item -ItemType Directory -Path "$BUILD_DIR" -Force + +# Prepare environment for CMake: +$env:CMAKE_BUILD_PARALLEL_LEVEL = $PARALLEL_LEVEL +$env:CTEST_PARALLEL_LEVEL = 1 +$env:CUDAHOSTCXX = $HOST_COMPILER.FullName +$env:CXX = $HOST_COMPILER.FullName + +Write-Host "========================================" +Write-Host "Begin build" +Write-Host "pwd=$pwd" +Write-Host "BUILD_DIR=$BUILD_DIR" +Write-Host "CXX_STANDARD=$CXX_STANDARD" +Write-Host "CXX=$env:CXX" +Write-Host "CUDACXX=$env:CUDACXX" +Write-Host "CUDAHOSTCXX=$env:CUDAHOSTCXX" +Write-Host "NVCC_VERSION=$NVCC_VERSION" +Write-Host "CMAKE_BUILD_PARALLEL_LEVEL=$env:CMAKE_BUILD_PARALLEL_LEVEL" +Write-Host "CTEST_PARALLEL_LEVEL=$env:CTEST_PARALLEL_LEVEL" +Write-Host "CCCL_BUILD_INFIX=$env:CCCL_BUILD_INFIX" +Write-Host "Current commit is:" +Write-Host "$(git log -1)" +Write-Host "========================================" + +function configure_preset { + Param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$BUILD_NAME, + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$PRESET, + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string]$CMAKE_OPTIONS + ) + + $step = "$BUILD_NAME (configure)" + + # CMake must be invoked in the same directory as the presets file: + pushd ".." + + cmake --preset $PRESET $CMAKE_OPTIONS --log-level VERBOSE + $test_result = $LastExitCode + + If ($test_result -ne 0) { + throw "$step Failed" + } + + popd + Write-Host "$step complete." +} + +function build_preset { + Param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$BUILD_NAME, + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$PRESET + ) + + $step = "$BUILD_NAME (build)" + + # CMake must be invoked in the same directory as the presets file: + pushd ".." + + sccache_stats('Start') + + cmake --build --preset $PRESET -v + $test_result = $LastExitCode + + sccache_stats('Stop') + + echo "$step complete" + + If ($test_result -ne 0) { + throw "$step Failed" + } + + popd +} + +function test_preset { + Param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$BUILD_NAME, + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$PRESET + ) + + $step = "$BUILD_NAME (test)" + + # CTest must be invoked in the same directory as the presets file: + pushd ".." + + sccache_stats('Start') + + ctest --preset $PRESET + $test_result = $LastExitCode + + sccache_stats('Stop') + + echo "$step complete" + + If ($test_result -ne 0) { + throw "$step Failed" + } + + popd +} + +function configure_and_build_preset { + Param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$BUILD_NAME, + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$PRESET, + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string]$CMAKE_OPTIONS + ) + + configure_preset "$BUILD_NAME" "$PRESET" "$CMAKE_OPTIONS" + build_preset "$BUILD_NAME" "$PRESET" +} + +function sccache_stats { + Param ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [ValidateSet('Start','Stop')] + [string]$MODE + ) + + $sccache_stats = sccache -s + If($MODE -eq 'Start') { + [int]$script:sccache_compile_requests = ($sccache_stats[0] -replace '[^\d]+') + [int]$script:sccache_cache_hits_cpp = ($sccache_stats[2] -replace '[^\d]+') + [int]$script:sccache_cache_hits_cuda = ($sccache_stats[3] -replace '[^\d]+') + [int]$script:sccache_cache_miss_cpp = ($sccache_stats[5] -replace '[^\d]+') + [int]$script:sccache_cache_miss_cuda = ($sccache_stats[6] -replace '[^\d]+') + } else { + [int]$final_sccache_compile_requests = ($sccache_stats[0] -replace '[^\d]+') + [int]$final_sccache_cache_hits_cpp = ($sccache_stats[2] -replace '[^\d]+') + [int]$final_sccache_cache_hits_cuda = ($sccache_stats[3] -replace '[^\d]+') + [int]$final_sccache_cache_miss_cpp = ($sccache_stats[5] -replace '[^\d]+') + [int]$final_sccache_cache_miss_cuda = ($sccache_stats[6] -replace '[^\d]+') + + [int]$total_requests = $final_sccache_compile_requests - $script:sccache_compile_requests + [int]$total_hits_cpp = $final_sccache_cache_hits_cpp - $script:sccache_cache_hits_cpp + [int]$total_hits_cuda = $final_sccache_cache_hits_cuda - $script:sccache_cache_hits_cuda + [int]$total_miss_cpp = $final_sccache_cache_miss_cpp - $script:sccache_cache_miss_cpp + [int]$total_miss_cuda = $final_sccache_cache_miss_cuda - $script:sccache_cache_miss_cuda + If ( $total_requests -gt 0 ) { + [int]$hit_rate_cpp = $total_hits_cpp / $total_requests * 100; + [int]$hit_rate_cuda = $total_hits_cuda / $total_requests * 100; + echo "sccache hits cpp: $total_hits_cpp `t| misses: $total_miss_cpp `t| hit rate: $hit_rate_cpp%" + echo "sccache hits cuda: $total_hits_cuda `t| misses: $total_miss_cuda `t| hit rate: $hit_rate_cuda%" + } else { + echo "sccache stats: N/A No new compilation requests" + } + } +} + +Export-ModuleMember -Function configure_preset, build_preset, test_preset, configure_and_build_preset, sccache_stats +Export-ModuleMember -Variable BUILD_DIR, CL_VERSION diff --git a/ci/windows/build_nvbench.ps1 b/ci/windows/build_nvbench.ps1 new file mode 100644 index 00000000..31b4f7c0 --- /dev/null +++ b/ci/windows/build_nvbench.ps1 @@ -0,0 +1,26 @@ + +Param( + [Parameter(Mandatory = $true)] + [Alias("std")] + [ValidateNotNullOrEmpty()] + [ValidateSet(17)] + [int]$CXX_STANDARD = 17 +) + +$CURRENT_PATH = Split-Path $pwd -leaf +If($CURRENT_PATH -ne "ci") { + Write-Host "Moving to ci folder" + pushd "$PSScriptRoot/.." +} + +Remove-Module -Name build_common +Import-Module $PSScriptRoot/build_common.psm1 -ArgumentList $CXX_STANDARD + +$PRESET = "nvbench-cpp$CXX_STANDARD" +$CMAKE_OPTIONS = "" + +configure_and_build_preset "NVBench" "$PRESET" "$CMAKE_OPTIONS" + +If($CURRENT_PATH -ne "ci") { + popd +} diff --git a/cmake/PrintCTestRunTimes.cmake b/cmake/PrintCTestRunTimes.cmake new file mode 100644 index 00000000..f4ac7d90 --- /dev/null +++ b/cmake/PrintCTestRunTimes.cmake @@ -0,0 +1,127 @@ +## This CMake script parses the output of ctest and prints a formatted list +## of individual test runtimes, sorted longest first. +## +## ctest > ctest_log +## cmake -DLOGFILE=ctest_log \ +## -DMINSEC=10 \ +## -P PrintCTestRunTimes.cmake +## +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +# Prepend the string with "0" until the string length equals the specified width +function(pad_string_with_zeros string_var width) + set(local_string "${${string_var}}") + string(LENGTH "${local_string}" size) + while(size LESS width) + string(PREPEND local_string "0") + string(LENGTH "${local_string}" size) + endwhile() + set(${string_var} "${local_string}" PARENT_SCOPE) +endfunction() + +################################################################################ + +if (NOT LOGFILE) + message(FATAL_ERROR "Missing -DLOGFILE= argument.") +endif() + +if (NOT DEFINED MINSEC) + set(MINSEC 10) +endif() + +set(num_below_thresh 0) + +# Check if logfile exists +if (NOT EXISTS "${LOGFILE}") + message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').") +endif() + +string(JOIN "" regex + "[0-9]+/[0-9]+[ ]+Test[ ]+#" + "([0-9]+)" # Test ID + ":[ ]+" + "([^ ]+)" # Test Name + "[ ]*\\.+[ ]*\\**[ ]*" + "([^ ]+)" # Result + "[ ]+" + "([0-9]+)" # Seconds + "\\.[0-9]+[ ]+sec" +) + +message(DEBUG "LOGFILE: ${LOGFILE}") +message(DEBUG "MINSEC: ${MINSEC}") +message(DEBUG "regex: ${regex}") + +# Read the logfile and generate a map / keylist +set(keys) +file(STRINGS "${LOGFILE}" lines) +foreach(line ${lines}) + + # Parse each build time + string(REGEX MATCH "${regex}" _DUMMY "${line}") + + if (CMAKE_MATCH_COUNT EQUAL 4) + set(test_id "${CMAKE_MATCH_1}") + set(test_name "${CMAKE_MATCH_2}") + set(test_result "${CMAKE_MATCH_3}") + set(tmp "${CMAKE_MATCH_4}") # floor(runtime_seconds) + + if (tmp LESS MINSEC) + math(EXPR num_below_thresh "${num_below_thresh} + 1") + continue() + endif() + + # Compute human readable time + math(EXPR days "${tmp} / (60 * 60 * 24)") + math(EXPR tmp "${tmp} - (${days} * 60 * 60 * 24)") + math(EXPR hours "${tmp} / (60 * 60)") + math(EXPR tmp "${tmp} - (${hours} * 60 * 60)") + math(EXPR minutes "${tmp} / (60)") + math(EXPR tmp "${tmp} - (${minutes} * 60)") + math(EXPR seconds "${tmp}") + + # Format time components + pad_string_with_zeros(days 3) + pad_string_with_zeros(hours 2) + pad_string_with_zeros(minutes 2) + pad_string_with_zeros(seconds 2) + + # Construct table entry + # Later values in the file for the same command overwrite earlier entries + string(MAKE_C_IDENTIFIER "${test_id}" key) + string(JOIN " | " ENTRY_${key} + "${days}d ${hours}h ${minutes}m ${seconds}s" + "${test_result}" + "${test_id}: ${test_name}" + ) + + # Record the key: + list(APPEND keys "${key}") + endif() +endforeach() + +list(REMOVE_DUPLICATES keys) + +# Build the entry list: +set(entries) +foreach(key ${keys}) + list(APPEND entries "${ENTRY_${key}}") +endforeach() + +if (NOT entries) + message(STATUS "LOGFILE contained no test times ('${LOGFILE}').") +endif() + +# Sort in descending order: +list(SORT entries ORDER DESCENDING) + +# Dump table: +foreach(entry ${entries}) + message(STATUS ${entry}) +endforeach() + +if (num_below_thresh GREATER 0) + message(STATUS "${num_below_thresh} additional tests took < ${MINSEC}s each.") +endif() diff --git a/cmake/PrintNinjaBuildTimes.cmake b/cmake/PrintNinjaBuildTimes.cmake new file mode 100644 index 00000000..65d243d3 --- /dev/null +++ b/cmake/PrintNinjaBuildTimes.cmake @@ -0,0 +1,101 @@ +## This CMake script parses a .ninja_log file (LOGFILE) and prints a list of +## build/link times, sorted longest first. +## +## cmake -DLOGFILE=<.ninja_log file> \ +## -P PrintNinjaBuildTimes.cmake +## +## If LOGFILE is omitted, the current directory's .ninja_log file is used. +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +# Prepend the string with "0" until the string length equals the specified width +function(pad_string_with_zeros string_var width) + set(local_string "${${string_var}}") + string(LENGTH "${local_string}" size) + while(size LESS width) + string(PREPEND local_string "0") + string(LENGTH "${local_string}" size) + endwhile() + set(${string_var} "${local_string}" PARENT_SCOPE) +endfunction() + +################################################################################ + +if (NOT LOGFILE) + set(LOGFILE ".ninja_log") +endif() + +# Check if logfile exists +if (NOT EXISTS "${LOGFILE}") + message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').") +endif() + +# Read the logfile and generate a map / keylist +set(keys) +file(STRINGS "${LOGFILE}" lines) +foreach(line ${lines}) + + # Parse each build time + string(REGEX MATCH + "^([0-9]+)\t([0-9]+)\t[0-9]+\t([^\t]+)+\t[0-9a-fA-F]+$" _DUMMY "${line}") + + if (CMAKE_MATCH_COUNT EQUAL 3) + set(start_ms ${CMAKE_MATCH_1}) + set(end_ms ${CMAKE_MATCH_2}) + set(command "${CMAKE_MATCH_3}") + math(EXPR runtime_ms "${end_ms} - ${start_ms}") + + # Compute human readable time + math(EXPR days "${runtime_ms} / (1000 * 60 * 60 * 24)") + math(EXPR runtime_ms "${runtime_ms} - (${days} * 1000 * 60 * 60 * 24)") + math(EXPR hours "${runtime_ms} / (1000 * 60 * 60)") + math(EXPR runtime_ms "${runtime_ms} - (${hours} * 1000 * 60 * 60)") + math(EXPR minutes "${runtime_ms} / (1000 * 60)") + math(EXPR runtime_ms "${runtime_ms} - (${minutes} * 1000 * 60)") + math(EXPR seconds "${runtime_ms} / 1000") + math(EXPR milliseconds "${runtime_ms} - (${seconds} * 1000)") + + # Format time components + pad_string_with_zeros(days 3) + pad_string_with_zeros(hours 2) + pad_string_with_zeros(minutes 2) + pad_string_with_zeros(seconds 2) + pad_string_with_zeros(milliseconds 3) + + # Construct table entry + # Later values in the file for the same command overwrite earlier entries + string(MAKE_C_IDENTIFIER "${command}" key) + set(ENTRY_${key} + "${days}d ${hours}h ${minutes}m ${seconds}s ${milliseconds}ms | ${command}" + ) + + # Record the key: + list(APPEND keys "${key}") + endif() +endforeach() + +list(REMOVE_DUPLICATES keys) + +# Build the entry list: +set(entries) +foreach(key ${keys}) + list(APPEND entries "${ENTRY_${key}}") +endforeach() + +if (NOT entries) + message(FATAL_ERROR "LOGFILE contained no build entries ('${LOGFILE}').") +endif() + +# Sort in descending order: +list(SORT entries) +list(REVERSE entries) + +# Dump table: +message(STATUS "-----------------------+----------------------------") +message(STATUS "Time | Command ") +message(STATUS "-----------------------+----------------------------") + +foreach(entry ${entries}) + message(STATUS ${entry}) +endforeach()