Skip to content
Open
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
61604ed
Hardcode build path to enable lints
Silv3S Mar 5, 2026
7d3f8eb
Exclude sycl
Silv3S Mar 5, 2026
026d2d1
Temporary skip known issues
Silv3S Mar 5, 2026
c29ab79
list todos
Silv3S Mar 5, 2026
d5d7f65
readability-duplicate-include
Silv3S Mar 5, 2026
96e7b3e
bugprone-argument-comment
Silv3S Mar 5, 2026
1358822
bugprone-branch-clone
Silv3S Mar 5, 2026
ffaa7dc
modernize-use-bool-literals
Silv3S Mar 5, 2026
a1c75a2
misc-header-include-cycle
Silv3S Mar 5, 2026
ec4779b
readability-container-size-empty
Silv3S Mar 5, 2026
f96c03f
modernize-use-equals-default
Silv3S Mar 5, 2026
8c0900a
Update reducer_xpu.cpp
Silv3S Mar 5, 2026
81f2e28
helper scripts
Silv3S Mar 6, 2026
702dc6c
use-default-member-init
Silv3S Mar 6, 2026
641fa1a
modernize-type-traits
Silv3S Mar 6, 2026
5434b63
modernize-use-transparent-functors
Silv3S Mar 6, 2026
c53d0d9
cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays
Silv3S Mar 6, 2026
1a96ac4
Remove tools for local repro
Silv3S Mar 6, 2026
3c05940
remove todo
Silv3S Mar 6, 2026
109b931
Merge branch 'main' into clangtidy
Silv3S Mar 9, 2026
3a8b317
Fix condition
Silv3S Mar 9, 2026
bfe5ec1
Skip known failures
Silv3S Mar 9, 2026
5aca925
Bump clang-tidy binary and adjust include paths
Silv3S Mar 11, 2026
d088b90
readability-duplicate-include
Silv3S Mar 11, 2026
0058c41
modernize-type-traits
Silv3S Mar 11, 2026
ea3a972
modernize-deprecated-headers
Silv3S Mar 11, 2026
935d151
modernize-type-traits
Silv3S Mar 12, 2026
1e6daa1
Copy upstream config and add CI job
Silv3S Mar 12, 2026
43f160b
temp skip CI for clang-tidy stage enablement
Silv3S Mar 12, 2026
d0b8b0b
remove preci
Silv3S Mar 12, 2026
715a536
move clang-tidy to linux_build stage
Silv3S Mar 12, 2026
f3c92ce
Remove macos/aarch64 from config
Silv3S Mar 12, 2026
5a07c40
Skip clang-diagnostic-error
Silv3S Mar 12, 2026
e5016ab
Hardcode pytorch dir
Silv3S Mar 12, 2026
0595cd8
add hello world action
Silv3S Mar 16, 2026
52a1abc
on push
Silv3S Mar 16, 2026
99190e5
change on pull workflow
Silv3S Mar 16, 2026
b3e4445
Merge remote-tracking branch 'iops/main' into clangtidy_actions
Silv3S Mar 16, 2026
de593cf
Add CLANGTIDY stage with 1 known failure
Silv3S Mar 16, 2026
92fcb68
Fail readability-duplicate-include
Silv3S Mar 16, 2026
93395e9
Remove duplicate includes
Silv3S Mar 16, 2026
db35537
Add asserts for envs
Silv3S Mar 16, 2026
f239e53
Reduce duplications in config
Silv3S Mar 16, 2026
49e9a73
hardcode CMPRL_ROOT
Silv3S Mar 16, 2026
9ca3265
use CMPLR_ROOT
Silv3S Mar 17, 2026
bf0addc
Merge branch 'main' into clangtidy_actions
Silv3S Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 41 additions & 11 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,52 @@
InheritParentConfig: true
Checks: '
bugprone-*,
-bugprone-branch-clone,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file seems different from https://github.com/pytorch/pytorch/blob/main/.clang-tidy. Could you help me understand the difference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. In upstream config there are groups of checks enabled, for example all checks from bugprone- category, but some are failing, so individual checks can be skipped with - prefix. It totally disables the check. Also, one can use in-line comment with NOLINT(check-name) to skip particular occurrence of failed check.

Some checks are debatable and implementing them is not worth it, so explicit skip allows us to ignore one check while enabling all other checks from this category. One example is modernize-concat-nested-namespaces which enforces squashing namespaces, that is purely formatting that depends mostly on personal preferences.

If we used upstream config without modifications, CI would fail on preci-lint-check as we have more issues in codebase than upstream. That's why I extended config with few explicitly skipped checks. Now it will pass CI and guard from further regressions. I plan to create tasks to enable each check one-by-one to not introduce them in one PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your details.

-bugprone-easily-swappable-parameters,
-bugprone-forward-declaration-namespace,
-bugprone-macro-parentheses,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-infinite-loop,
-bugprone-lambda-function-name,
-bugprone-macro-parentheses,
-bugprone-macro-repeated-side-effects,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-return-const-ref-from-parameter,
-bugprone-sizeof-expression,
-bugprone-swapped-arguments,
-bugprone-switch-missing-default-case,
-bugprone-unchecked-optional-access,
-bugprone-unused-local-non-trivial-variable,
clang-analyzer-core.*,
clang-analyzer-cplusplus.*,
clang-analyzer-nullability.*,
clang-analyzer-deadcode.*,
clang-diagnostic-missing-prototypes,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-c-arrays,
-cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-interfaces-global-init,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-macro-to-enum,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-narrowing-conversions,
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-prefer-member-initializer,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-const-cast,
-cppcoreguidelines-pro-type-cstyle-cast,
-cppcoreguidelines-pro-type-member-init,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-static-cast-downcast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-special-member-functions,
-facebook-hte-RelativeInclude,
hicpp-exception-baseclass,
hicpp-avoid-goto,
Expand All @@ -47,35 +64,48 @@ misc-*,
-misc-unused-parameters,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
-misc-redundant-expression,
-misc-unused-using-decls,
-misc-use-internal-linkage,
modernize-*,
-modernize-avoid-c-arrays,
-modernize-concat-nested-namespaces,
-modernize-deprecated-headers,
-modernize-loop-convert,
-modernize-macro-to-enum,
-modernize-return-braced-init-list,
-modernize-type-traits,
-modernize-unary-static-assert,
-modernize-use-auto,
-modernize-use-using,
-modernize-use-trailing-return-type,
-modernize-use-bool-literals,
-modernize-use-equals-default,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
-modernize-use-using,
performance-*,
-performance-enum-size,
-performance-for-range-copy,
-performance-unnecessary-value-param,
readability-container-size-empty,
readability-delete-null-pointer,
readability-duplicate-include,
readability-named-parameter,
readability-misplaced-array-index,
readability-redundant*,
readability-simplify-subscript-expr,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
-readability-named-parameter,
-readability-redundant-access-specifiers,
-readability-redundant-casting,
-readability-redundant-control-flow,
-readability-redundant-declaration,
-readability-redundant-inline-specifier,
-readability-redundant-smartptr-get,
-readability-redundant*,
'
HeaderFilterRegex: '^(src/).*$'
WarningsAsErrors: '*'
LineFilter:
- name: '/usr/include/.*'
WarningsAsErrors: "*"
CheckOptions:
cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor: true
cppcoreguidelines-special-member-functions.AllowImplicitlyDeletedCopyOrMove: true
misc-header-include-cycle.IgnoredFilesList: 'format.h;ivalue.h;custom_class.h;Dict.h;List.h;IListRef.h'
misc-header-include-cycle.IgnoredFilesList: 'library.h'
...
11 changes: 10 additions & 1 deletion .github/workflows/pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,19 @@ jobs:
export ADDITIONAL_LINTRUNNER_ARGS="--skip CLANGTIDY,CLANGFORMAT,MERGE_CONFLICTLESS_CSV --all-files"
cd ./torch-xpu-ops
bash .github/scripts/lintrunner.sh
- name: Checkout PyTorch (for headers)
uses: actions/checkout@v4
with:
repository: pytorch/pytorch
path: pytorch-headers
fetch-depth: 1
submodules: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some code gen files that are handled in

if [[ -e "third_party/torch-xpu-ops/tools/linter/clang_tidy/generate_build_files.py" ]];then
python3 third_party/torch-xpu-ops/tools/linter/clang_tidy/generate_build_files.py

Please ensure these paths are matched.

Copy link
Contributor Author

@Silv3S Silv3S Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would require extracting clang-tidy to separate CI job that builds PyTorch+XPU and pass compile_commands.json to linter. Currently clang-tidy only clones PyTorch (for headers) and torch-xpu-ops to lint. It doesn't build nor generate any files, and both conditions

if [[ "${CLANG}" == "1" ]]; then
    if [[ -e "third_party/torch-xpu-ops/tools/linter/clang_tidy/generate_build_files.py" ]];then

are not met.

This lightweight version lets us quickly fix issues that reproduce without build dependency. It's fast so can guard any regressions in preci-lint-check stage. I agree that it should be extended to cover autogen files, but maybe it could be done in next iteration?

- name: Run lint check with Clang
env:
PYTORCH_ROOT: ${{ github.workspace }}/pytorch-headers
run: |
cd ./torch-xpu-ops
export ADDITIONAL_LINTRUNNER_ARGS="--take CLANGFORMAT --all-files"
export ADDITIONAL_LINTRUNNER_ARGS="--take CLANGFORMAT,CLANGTIDY --all-files"
bash .github/scripts/lintrunner.sh

conditions-filter-win:
Expand Down
1 change: 0 additions & 1 deletion .lintrunner.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ command = [
'python3',
'tools/linter/adapters/clangtidy_linter.py',
'--binary=.lintbin/clang-tidy',
'--build_dir=./build',
'--',
'@{{PATHSFILE}}'
]
Expand Down
1 change: 0 additions & 1 deletion src/ATen/native/sparse/xpu/sycl/SparseSoftmaxKernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
#include <comm/Memory.h>

#include <ATen/native/sparse/xpu/sycl/SparseSoftmaxKernels.h>
#include <ATen/native/xpu/sycl/Loops.h>
#include <comm/SYCLContext.h>
#include <comm/TensorInfo.h>

Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/Activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
#include <ATen/native/DispatchStub.h>
#include <ATen/native/TensorIterator.h>

#include <ATen/native/TensorIterator.h>

#include <ATen/ops/empty.h>
#include <ATen/ops/empty_like.h>
#include <ATen/ops/gelu_backward_native.h>
Expand Down
3 changes: 0 additions & 3 deletions src/ATen/native/xpu/ForeachOpScalarList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
#include <ATen/native/xpu/sycl/ForeachPointwiseOpScalarListKernels.h>
#include <ATen/native/xpu/sycl/ForeachTernaryOpScalarListKernels.h>

#include <ATen/ops/_foreach_add_native.h>
#include <ATen/ops/_foreach_mul_native.h>

namespace at {
namespace native {

Expand Down
1 change: 0 additions & 1 deletion src/ATen/native/xpu/Resize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <comm/xpu_aten.h>
#include <torch/library.h>

#include <ATen/native/Resize.h>
#include <ATen/ops/copy.h>
#include <ATen/ops/resize_native.h>
#include <ATen/ops/set_native.h>
Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/AveragePool2dKernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
#include <comm/SYCLContext.h>
#include <comm/SYCLHelpers.h>

#include <ATen/native/xpu/sycl/AveragePool2dKernels.h>

namespace at::native {
namespace xpu {

Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/DistributionTemplates.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include <comm/DeviceProperties.h>
#include <comm/Runtime.h>

#include <ATen/ops/empty.h>

namespace at {
namespace native {
namespace xpu {
Expand Down
1 change: 0 additions & 1 deletion src/ATen/native/xpu/sycl/LossNLLKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <ATen/native/xpu/sycl/Loops.h>
#include <ATen/native/xpu/sycl/LossNLLKernel.h>

#include <comm/SYCLContext.h>
#include <comm/TensorInfo.h>

namespace at::native::xpu {
Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/MultinomialKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
#include <comm/SYCLContext.h>
#include <comm/SYCLHelpers.h>

#include <ATen/native/xpu/sycl/MultinomialKernel.h>

namespace at::native::xpu {

template <typename scalar_t, typename item_t>
Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/RepeatKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#include <ATen/native/xpu/sycl/RepeatKernel.h>
#include <comm/SYCLContext.h>

#include <ATen/native/xpu/sycl/RepeatKernel.h>

namespace at::native::xpu {
template <typename index_t>
struct RepeatInterleaveKernelFunctor {
Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/UnaryComplexKernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <ATen/native/xpu/sycl/Loops.h>
#include <comm/SYCLContext.h>

#include <ATen/native/xpu/sycl/CopyKernel.h>
#include <ATen/native/xpu/sycl/Loops.h>
#include <ATen/native/xpu/sycl/UnaryComplexKernels.h>

namespace at::native::xpu {
Expand Down
2 changes: 0 additions & 2 deletions src/ATen/native/xpu/sycl/UpSampleNearest1dKernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#include <comm/SYCLContext.h>
#include <comm/SYCLHelpers.h>

#include <ATen/native/xpu/sycl/UpSampleNearest1dKernels.h>

namespace at::native {
namespace xpu {

Expand Down
88 changes: 30 additions & 58 deletions tools/linter/adapters/clangtidy_linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,13 @@
from typing import Any, NamedTuple


# PyTorch directory root
def scm_root() -> str:
path = os.path.abspath(os.getcwd())
while True:
if os.path.exists(os.path.join(path, ".git")):
return path
if os.path.isdir(os.path.join(path, ".hg")):
return path
n = len(path)
path = os.path.dirname(path)
if len(path) == n:
raise RuntimeError("Unable to find SCM root")


PYTORCH_ROOT = scm_root()
PYTORCH_ROOT = os.environ.get("PYTORCH_ROOT")
if PYTORCH_ROOT is None:
raise RuntimeError(
"Environment variable PYTORCH_ROOT is not set. "
"Please set PYTORCH_ROOT to the root directory of the PyTorch source "
"tree so that clang-tidy can locate the appropriate headers."
)
IS_WINDOWS: bool = os.name == "nt"


Expand Down Expand Up @@ -154,22 +146,20 @@ def clang_search_dirs() -> list[str]:

include_args = []
include_dir = [
"/usr/lib/llvm-11/include/openmp",
get_python_include_dir(),
os.path.join(PYTORCH_ROOT, "third_party/pybind11/include"),
os.path.join(PYTORCH_ROOT, "include"),
"/opt/intel/oneapi/compiler/latest/include",
] + clang_search_dirs()
for dir in include_dir:
include_args += ["--extra-arg", f"-I{dir}"]
include_args += ["--extra-arg", f"-isystem{dir}"]


def check_file(
filename: str,
binary: str,
build_dir: Path,
) -> list[LintMessage]:
try:
proc = run_command(
[binary, f"-p={build_dir}", *include_args, filename],
[binary, *include_args, filename],
)
except OSError as err:
return [
Expand All @@ -186,31 +176,25 @@ def check_file(
)
]
lint_messages = []
try:
# Change the current working directory to the build directory, since
# clang-tidy will report files relative to the build directory.
saved_cwd = os.getcwd()
os.chdir(build_dir)

for match in RESULTS_RE.finditer(proc.stdout.decode()):
# Convert the reported path to an absolute path.
abs_path = str(Path(match["file"]).resolve())
message = LintMessage(
path=abs_path,
name=match["code"],
description=match["message"],
line=int(match["line"]),
char=int(match["column"])
if match["column"] is not None and not match["column"].startswith("-")
else None,
code="CLANGTIDY",
severity=severities.get(match["severity"], LintSeverity.ERROR),
original=None,
replacement=None,
)
lint_messages.append(message)
finally:
os.chdir(saved_cwd)
for match in RESULTS_RE.finditer(proc.stdout.decode()):
abs_path = str(Path(match["file"]).resolve())
# clang-diagnostic-error cannot be suppressed via .clang-tidy config.
if match["code"] == "[clang-diagnostic-error]":
continue
message = LintMessage(
path=abs_path,
name=match["code"],
description=match["message"],
line=int(match["line"]),
char=int(match["column"])
if match["column"] is not None and not match["column"].startswith("-")
else None,
code="CLANGTIDY",
severity=severities.get(match["severity"], LintSeverity.ERROR),
original=None,
replacement=None,
)
lint_messages.append(message)

return lint_messages

Expand All @@ -225,15 +209,6 @@ def main() -> None:
required=True,
help="clang-tidy binary path",
)
parser.add_argument(
"--build-dir",
"--build_dir",
required=True,
help=(
"Where the compile_commands.json file is located. "
"Gets passed to clang-tidy -p"
),
)
parser.add_argument(
"--verbose",
action="store_true",
Expand Down Expand Up @@ -274,8 +249,6 @@ def main() -> None:
print(json.dumps(err_msg._asdict()), flush=True)
sys.exit(0)

abs_build_dir = Path(args.build_dir).resolve()

# Get the absolute path to clang-tidy and use this instead of the relative
# path such as .lintbin/clang-tidy. The problem here is that os.chdir is
# per process, and the linter uses it to move between the current directory
Expand All @@ -293,7 +266,6 @@ def main() -> None:
check_file,
filename,
binary_path,
abs_build_dir,
): filename
for filename in args.filenames
}
Expand Down
12 changes: 2 additions & 10 deletions tools/linter/adapters/s3_init_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,9 @@
}
},
"clang-tidy": {
"Darwin-i386": {
"download_url": "https://oss-clang-format.s3.us-east-2.amazonaws.com/macos-i386/15.0.6/clang-tidy",
"hash": "11c9234155dd5b7aec8cf46ea9629401c4432576615b6eff2a5a4c5e3f9e6504"
},
"Darwin-arm": {
"download_url": "https://oss-clang-format.s3.us-east-2.amazonaws.com/macos-arm/15.0.6/clang-tidy",
"hash": "4ed664cf50bb9fddec2d4170b3d7bbe0135dc5648acbd620b61c8d25a5a2fdb7"
},
"Linux": {
"download_url": "https://oss-clang-format.s3.us-east-2.amazonaws.com/linux64/17.0.6/clang-tidy",
"hash": "a93110b0d58b430bb7ce86c8497f2528e1d44eed25d546557e7ec45c44ddfeb7"
"download_url": "https://oss-clang-format.s3.us-east-2.amazonaws.com/linux64/19.1.4/clang-tidy",
"hash": "5637bd0fca665d2797926fedf53ca5ad4655bb9dbed1e1c8654c8e032ce1e7a8"
}
},
"actionlint": {
Expand Down
Loading