Skip to content

Commit 3e59b65

Browse files
authored
CI: Add custom GitHub Actions job to run clang-tidy (#5235)
Follow-up from #4983 ; should be merged after that. - [x] Adjust clang-tidy script to only run CMAKE to generate the compile-commands db and not to actually build. - [x] #5496 Authors: - Simon Adorf (https://github.com/csadorf) - Bradley Dice (https://github.com/bdice) - Dante Gama Dessavre (https://github.com/dantegd) Approvers: - AJ Schmidt (https://github.com/ajschmidt8) - Dante Gama Dessavre (https://github.com/dantegd) URL: #5235
1 parent c3d4dbb commit 3e59b65

File tree

14 files changed

+280
-69
lines changed

14 files changed

+280
-69
lines changed

.github/workflows/pr.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
pr-builder:
1414
needs:
1515
- checks
16+
- clang-tidy
1617
- conda-cpp-build
1718
- conda-cpp-tests
1819
- conda-python-build
@@ -29,6 +30,16 @@ jobs:
2930
uses: rapidsai/shared-action-workflows/.github/workflows/checks.yaml@cuda-120
3031
with:
3132
enable_check_generated_files: false
33+
clang-tidy:
34+
needs: checks
35+
secrets: inherit
36+
uses: rapidsai/shared-action-workflows/.github/workflows/[email protected]
37+
with:
38+
build_type: pull-request
39+
node_type: "cpu8"
40+
arch: "amd64"
41+
container_image: "rapidsai/ci:latest"
42+
run_script: "ci/run_clang_tidy.sh"
3243
conda-cpp-build:
3344
needs: checks
3445
secrets: inherit

CONTRIBUTING.md

+41
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,47 @@ please see the `.pre-commit-config.yaml` file.
115115
of files are up-to-date and in the correct format.
116116
- `codespell`: Checks for spelling mistakes
117117

118+
### Clang-tidy
119+
120+
In order to maintain high-quality code, cuML uses not only pre-commit hooks
121+
featuring various formatters and linters but also the clang-tidy tool.
122+
Clang-tidy is designed to detect potential issues within the C and C++ code. It
123+
is typically run as part of our continuous integration (CI) process.
124+
125+
While it's generally unnecessary for contributors to run clang-tidy locally,
126+
there might be cases where you would want to do so. There are two primary
127+
methods to run clang-tidy on your local machine: using Docker or Conda.
128+
129+
* **Docker**
130+
131+
1. Navigate to the repository root directory.
132+
2. Run the following Docker command:
133+
134+
```bash
135+
docker run --rm --pull always \
136+
--mount type=bind,source="$(pwd)",target=/opt/repo --workdir /opt/repo \
137+
-e SCCACHE_S3_NO_CREDENTIALS=1 \
138+
rapidsai/ci:latest /opt/repo/ci/run_clang_tidy.sh
139+
```
140+
141+
142+
* **Conda**
143+
144+
1. Navigate to the repository root directory.
145+
2. Create and activate the needed conda environment:
146+
```bash
147+
conda env create --force -n cuml-clang-tidy -f conda/environments/clang_tidy_cuda-118_arch-x86_64.yaml
148+
conda activate cuml-clang-tidy
149+
```
150+
3. Generate the compile command database with
151+
```bash
152+
./build.sh --configure-only libcuml
153+
```
154+
3. Run clang-tidy with the following command:
155+
```bash
156+
python cpp/scripts/run-clang-tidy.py --config pyproject.toml
157+
```
158+
118159
### Managing PR labels
119160

120161
Each PR must be labeled according to whether it is a "breaking" or "non-breaking" change (using Github labels). This is used to highlight changes that users should know about when upgrading.

build.sh

+6-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ARGS=$*
1919
REPODIR=$(cd $(dirname $0); pwd)
2020

2121
VALIDTARGETS="clean libcuml cuml cpp-mgtests prims bench prims-bench cppdocs pydocs"
22-
VALIDFLAGS="-v -g -n --allgpuarch --singlegpu --nolibcumltest --nvtx --show_depr_warn --codecov --ccache -h --help "
22+
VALIDFLAGS="-v -g -n --allgpuarch --singlegpu --nolibcumltest --nvtx --show_depr_warn --codecov --ccache --configure-only -h --help "
2323
VALIDARGS="${VALIDTARGETS} ${VALIDFLAGS}"
2424
HELP="$0 [<target> ...] [<flag> ...]
2525
where <target> is:
@@ -46,6 +46,7 @@ HELP="$0 [<target> ...] [<flag> ...]
4646
--codecov - Enable code coverage support by compiling with Cython linetracing
4747
and profiling enabled (WARNING: Impacts performance)
4848
--ccache - Use ccache to cache previous compilations
49+
--configure-only - Invoke CMake without actually building
4950
--nocloneraft - CMake will clone RAFT even if it is in the environment, use this flag to disable that behavior
5051
--static-treelite - Force CMake to use the Treelite static libs, cloning and building them if necessary
5152
@@ -133,6 +134,7 @@ LONG_ARGUMENT_LIST=(
133134
"ccache"
134135
"nolibcumltest"
135136
"nocloneraft"
137+
"configure-only"
136138
)
137139

138140
# Short arguments
@@ -260,7 +262,7 @@ if completeBuild || hasArg libcuml || hasArg prims || hasArg bench || hasArg pri
260262
fi
261263

262264
# If `./build.sh cuml` is called, don't build C/C++ components
263-
if completeBuild || hasArg libcuml || hasArg prims || hasArg bench || hasArg cpp-mgtests; then
265+
if (! hasArg --configure-only) && (completeBuild || hasArg libcuml || hasArg prims || hasArg bench || hasArg cpp-mgtests); then
264266
cd ${LIBCUML_BUILD_DIR}
265267
if [ -n "${INSTALL_TARGET}" ]; then
266268
cmake --build ${LIBCUML_BUILD_DIR} -j${PARALLEL_LEVEL} ${build_args} --target ${INSTALL_TARGET} ${VERBOSE_FLAG}
@@ -269,14 +271,14 @@ if completeBuild || hasArg libcuml || hasArg prims || hasArg bench || hasArg cpp
269271
fi
270272
fi
271273

272-
if hasArg cppdocs; then
274+
if (! hasArg --configure-only) && hasArg cppdocs; then
273275
cd ${LIBCUML_BUILD_DIR}
274276
cmake --build ${LIBCUML_BUILD_DIR} --target docs_cuml
275277
fi
276278

277279

278280
# Build and (optionally) install the cuml Python package
279-
if completeBuild || hasArg cuml || hasArg pydocs; then
281+
if (! hasArg --configure-only) && (completeBuild || hasArg cuml || hasArg pydocs); then
280282
# Append `-DFIND_CUML_CPP=ON` to CUML_EXTRA_CMAKE_ARGS unless a user specified the option.
281283
SKBUILD_EXTRA_CMAKE_ARGS="${CUML_EXTRA_CMAKE_ARGS}"
282284
if [[ "${CUML_EXTRA_CMAKE_ARGS}" != *"DFIND_CUML_CPP"* ]]; then

ci/run_clang_tidy.sh

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
# Copyright (c) 2023, NVIDIA CORPORATION.
3+
4+
set -euo pipefail
5+
6+
rapids-logger "Create clang_tidy conda environment"
7+
. /opt/conda/etc/profile.d/conda.sh
8+
9+
rapids-dependency-file-generator \
10+
--output conda \
11+
--file_key clang_tidy \
12+
--matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" | tee env.yaml
13+
14+
rapids-mamba-retry env create --force -f env.yaml -n clang_tidy
15+
# Temporarily allow unbound variables for conda activation.
16+
set +u && conda activate clang_tidy && set -u
17+
18+
./build.sh --configure-only libcuml
19+
20+
rapids-logger "Run clang-tidy"
21+
22+
python cpp/scripts/run-clang-tidy.py --config pyproject.toml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# This file is generated by `rapids-dependency-file-generator`.
2+
# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`.
3+
channels:
4+
- rapidsai
5+
- rapidsai-nightly
6+
- dask/label/dev
7+
- conda-forge
8+
- nvidia
9+
dependencies:
10+
- c-compiler
11+
- clang-tools==15.0.7
12+
- clang==15.0.7
13+
- cmake>=3.26.4
14+
- cuda-version=11.8
15+
- cudatoolkit
16+
- cxx-compiler
17+
- gcc_linux-64=11.*
18+
- gmock>=1.13.0
19+
- gtest>=1.13.0
20+
- libcublas-dev=11.11.3.6
21+
- libcublas=11.11.3.6
22+
- libcufft-dev=10.9.0.58
23+
- libcufft=10.9.0.58
24+
- libcumlprims==23.8.*
25+
- libcurand-dev=10.3.0.86
26+
- libcurand=10.3.0.86
27+
- libcusolver-dev=11.4.1.48
28+
- libcusolver=11.4.1.48
29+
- libcusparse-dev=11.7.5.86
30+
- libcusparse=11.7.5.86
31+
- libraft-headers==23.8.*
32+
- libraft==23.8.*
33+
- librmm==23.8.*
34+
- ninja
35+
- nvcc_linux-64=11.8
36+
- sysroot_linux-64==2.17
37+
- tomli
38+
name: clang_tidy_cuda-118_arch-x86_64

cpp/include/cuml/experimental/fil/detail/raft_proto/buffer.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ struct buffer {
9494
}
9595
return result;
9696
}()},
97-
data_{[this, input_data, mem_type]() {
97+
data_{[input_data, mem_type]() {
9898
auto result = data_store{};
9999
switch (mem_type) {
100100
case device_type::cpu: result = non_owning_buffer<device_type::cpu, T>{input_data}; break;
@@ -134,7 +134,7 @@ struct buffer {
134134
}
135135
return result;
136136
}()},
137-
data_{[this, &other, mem_type, device, stream]() {
137+
data_{[this, &other, mem_type, stream]() {
138138
auto result = data_store{};
139139
auto result_data = static_cast<T*>(nullptr);
140140
if (mem_type == device_type::cpu) {

0 commit comments

Comments
 (0)