Skip to content

Commit a7e76f7

Browse files
authored
Linter script change: from CMake to Python (NVIDIA#1951)
* Linter script change: from CMake to Python Signed-off-by: szalpal <[email protected]>
1 parent f5a8743 commit a7e76f7

File tree

2 files changed

+189
-54
lines changed

2 files changed

+189
-54
lines changed

cmake/lint.cmake

Lines changed: 19 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,21 @@
1-
# Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
2-
# Get the project dir - not set for this target
3-
get_filename_component(PROJECT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
4-
set(LINT_COMMAND python ${PROJECT_SOURCE_DIR}/third_party/cpplint.py)
5-
set(DALI_SRC_DIR "${PROJECT_SOURCE_DIR}/dali")
6-
set(DALI_INC_DIR "${PROJECT_SOURCE_DIR}/include")
7-
file(GLOB_RECURSE LINT_SRC "${DALI_SRC_DIR}/*.cc" "${DALI_SRC_DIR}/*.h" "${DALI_SRC_DIR}/*.cu" "${DALI_SRC_DIR}/*.cuh")
8-
file(GLOB_RECURSE LINT_INC "${DALI_INC_DIR}/*.h" "${DALI_INC_DIR}/*.cuh" "${DALI_INC_DIR}/*.inc" "${DALI_SRC_DIR}/*.inl")
1+
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
914

10-
# Excluded files
11-
12-
# nvdecoder
13-
list(REMOVE_ITEM LINT_SRC
14-
${DALI_SRC_DIR}/core/dynlink_cuda.cc
15-
${DALI_SRC_DIR}/operators/reader/nvdecoder/nvcuvid.h
16-
${DALI_SRC_DIR}/operators/reader/nvdecoder/cuviddec.h
17-
${DALI_SRC_DIR}/operators/reader/nvdecoder/dynlink_nvcuvid.cc
18-
${DALI_SRC_DIR}/operators/reader/nvdecoder/dynlink_nvcuvid.h
19-
)
20-
21-
list(REMOVE_ITEM LINT_INC
22-
${DALI_INC_DIR}/dali/core/dynlink_cuda.h
23-
)
24-
25-
# cuTT
26-
list(REMOVE_ITEM LINT_SRC
27-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cutt.h
28-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cutt.cc
29-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttplan.h
30-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttplan.cc
31-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttkernel.cu
32-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttkernel.h
33-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/calls.h
34-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttGpuModel.h
35-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttGpuModel.cc
36-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttGpuModelKernel.h
37-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttGpuModelKernel.cu
38-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/CudaMemcpy.h
39-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/CudaMemcpy.cu
40-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/CudaUtils.h
41-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/CudaUtils.cu
42-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/cuttTypes.h
43-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/int_vector.h
44-
${DALI_SRC_DIR}/operators/generic/transpose/cutt/LRUCache.h
15+
add_custom_target(
16+
lint
17+
COMMAND
18+
python ${PROJECT_SOURCE_DIR}/tools/lint.py ${PROJECT_SOURCE_DIR} --nproc=5
19+
COMMENT
20+
"Performing linter check"
4521
)
46-
47-
# empty files
48-
list(REMOVE_ITEM LINT_SRC
49-
${DALI_SRC_DIR}/python/dummy.cu
50-
)
51-
52-
set(LINT_TARGET lint)
53-
54-
add_custom_target(${LINT_TARGET})
55-
add_sources_to_lint(${LINT_TARGET} "--quiet;--linelength=100;--root=${PROJECT_SOURCE_DIR}" "${LINT_SRC}")
56-
add_sources_to_lint(${LINT_TARGET} "--quiet;--linelength=100;--root=${PROJECT_SOURCE_DIR}/include" "${LINT_INC}")

tools/lint.py

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import os
18+
import glob
19+
import itertools
20+
import re
21+
import argparse
22+
import sys
23+
import subprocess
24+
25+
# Linter script, that calls cpplint.py, specifically for DALI repo.
26+
# This will be called in `make lint` cmake target
27+
28+
# Q: How to configure git hook for pre-push linter check?
29+
# A: Create a file `.git/hooks/pre-push`:
30+
#
31+
# #!/bin/sh
32+
# DALI_ROOT_DIR=$(git rev-parse --show-toplevel)
33+
# python $DALI_ROOT_DIR/tools/lint.py $DALI_ROOT_DIR --nproc=10
34+
# ret=$?
35+
# if [ $ret -ne 0 ]; then
36+
# exit 1
37+
# fi
38+
# exit 0
39+
40+
41+
# Specifies, which files are to be excluded
42+
# These filters are regexes, not typical unix-like path specification
43+
negative_filters = [
44+
".*core/dynlink_cuda.cc",
45+
".*operators/reader/nvdecoder/nvcuvid.h",
46+
".*operators/reader/nvdecoder/cuviddec.h",
47+
".*operators/reader/nvdecoder/dynlink_nvcuvid.cc",
48+
".*operators/reader/nvdecoder/dynlink_nvcuvid.h",
49+
".*dali/core/dynlink_cuda.h",
50+
".*operators/generic/transpose/cutt/cutt.h",
51+
".*operators/generic/transpose/cutt/cutt.cc",
52+
".*operators/generic/transpose/cutt/cuttplan.h",
53+
".*operators/generic/transpose/cutt/cuttplan.cc",
54+
".*operators/generic/transpose/cutt/cuttkernel.cu",
55+
".*operators/generic/transpose/cutt/cuttkernel.h",
56+
".*operators/generic/transpose/cutt/calls.h",
57+
".*operators/generic/transpose/cutt/cuttGpuModel.h",
58+
".*operators/generic/transpose/cutt/cuttGpuModel.cc",
59+
".*operators/generic/transpose/cutt/cuttGpuModelKernel.h",
60+
".*operators/generic/transpose/cutt/cuttGpuModelKernel.cu",
61+
".*operators/generic/transpose/cutt/CudaMemcpy.h",
62+
".*operators/generic/transpose/cutt/CudaMemcpy.cu",
63+
".*operators/generic/transpose/cutt/CudaUtils.h",
64+
".*operators/generic/transpose/cutt/CudaUtils.cu",
65+
".*operators/generic/transpose/cutt/cuttTypes.h",
66+
".*operators/generic/transpose/cutt/int_vector.h",
67+
".*operators/generic/transpose/cutt/LRUCache.h",
68+
".*python/dummy.cu"
69+
]
70+
71+
72+
def negative_filtering(patterns: list, file_list):
73+
"""
74+
Patterns shall be a list of regex patterns
75+
"""
76+
if len(patterns) == 0:
77+
return file_list
78+
prog = re.compile(patterns.pop())
79+
it = (i for i in file_list if not prog.search(i))
80+
return negative_filtering(patterns, it)
81+
82+
83+
def gather_files(path: str, patterns: list, antipatterns: list):
84+
"""
85+
Gather files, based on `path`, that match `patterns` unix-like specification
86+
and do not match `antipatterns` regexes
87+
"""
88+
curr_path = os.getcwd()
89+
os.chdir(path)
90+
positive_iterators = [glob.iglob(os.path.join('**', pattern), recursive=True) for pattern in
91+
patterns]
92+
linted_files = itertools.chain(*positive_iterators)
93+
linted_files = (os.path.join(path, file) for file in linted_files)
94+
linted_files = negative_filtering(antipatterns.copy(), linted_files)
95+
ret = list(linted_files)
96+
os.chdir(curr_path)
97+
return ret
98+
99+
100+
def gen_cmd(dali_root_dir, file_list, process_includes=False):
101+
"""
102+
Command for calling cpplint.py
103+
"""
104+
cmd = ["python",
105+
os.path.join(dali_root_dir, "third_party", "cpplint.py"),
106+
"--quiet",
107+
"--linelength=100",
108+
"--root=" + os.path.join(dali_root_dir, "include" if process_includes else "")]
109+
cmd.extend(file_list)
110+
return cmd
111+
112+
113+
def lint(dali_root_dir, file_list, process_includes, n_subproc):
114+
"""
115+
n_subprocesses: how many subprocesses to use for linter processing
116+
Returns: 0 if lint passed, 1 otherwise
117+
"""
118+
if len(file_list)==0:
119+
return 0
120+
cmds = []
121+
diff = int(len(file_list) / n_subproc)
122+
for process_idx in range(n_subproc - 1):
123+
cmds.append(gen_cmd(dali_root_dir=dali_root_dir,
124+
file_list=file_list[process_idx * diff: (process_idx + 1) * diff],
125+
process_includes=process_includes))
126+
cmds.append(gen_cmd(dali_root_dir=dali_root_dir,
127+
file_list=file_list[(n_subproc - 1) * diff:],
128+
process_includes=process_includes))
129+
subprocesses = [subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) for cmd in cmds]
130+
success = True
131+
for subproc in subprocesses:
132+
stdout, stderr = subproc.communicate()
133+
success *= not bool(subproc.poll())
134+
if len(stderr) > 0:
135+
print(stderr.decode("utf-8"))
136+
return 0 if success else 1
137+
138+
139+
def main(dali_root_dir, n_subproc=1, file_list=None):
140+
cc_files = gather_files(
141+
os.path.join(dali_root_dir, "dali"),
142+
["*.cc", "*.h", "*.cu", "*.cuh"] if file_list is None else file_list,
143+
negative_filters)
144+
inc_files = gather_files(
145+
os.path.join(dali_root_dir, "include"),
146+
["*.h", "*.cuh", "*.inc", "*.inl"] if file_list is None else file_list,
147+
negative_filters)
148+
149+
cc_code = lint(dali_root_dir=dali_root_dir, file_list=cc_files, process_includes=False,
150+
n_subproc=n_subproc)
151+
inc_code = lint(dali_root_dir=dali_root_dir, file_list=inc_files, process_includes=True,
152+
n_subproc=n_subproc)
153+
154+
if cc_code != 0 or inc_code != 0:
155+
sys.exit(1)
156+
sys.exit(0)
157+
158+
159+
if __name__ == '__main__':
160+
parser = argparse.ArgumentParser(description="Run linter check for DALI files. "
161+
"Gather all code-files (h, cuh, cc, cu, inc, inl) and perform linter check on them.")
162+
parser.add_argument('dali_root_path', type=str,
163+
help='Root path of DALI repository (pointed directory should contain `.git` folder)')
164+
parser.add_argument('--nproc', type=int, default=1,
165+
help='Number of processes to spawn for linter verification')
166+
parser.add_argument('--file-list', nargs='*',
167+
help='List of files. This overrides the default scenario')
168+
args = parser.parse_args()
169+
assert args.nproc > 0
170+
main(str(args.dali_root_path), args.nproc, file_list=args.file_list)

0 commit comments

Comments
 (0)