Support building ONNX runtime with clang on Windows for Windows ML#29741
Draft
adrastogi wants to merge 4 commits into
Draft
Support building ONNX runtime with clang on Windows for Windows ML#29741adrastogi wants to merge 4 commits into
adrastogi wants to merge 4 commits into
Conversation
Add a --use_clang_cl build.py option that selects the Visual Studio 'ClangCL' toolset (-T ClangCL,host=x64), plus the source/cmake fixes required for the core onnxruntime.dll to compile with clang-cl: - build_args.py: new --use_clang_cl arg + validation (VS generator only, not for arm/arm64/arm64ec). - build.py: prepend 'ClangCL,' to the x64 VS toolset; guard /Qspectre (unsupported by clang-cl) in the binskim-compliant flag set. - spin_pause.cc: isolate the _tpause (waitpkg) intrinsic in a target-attributed helper so clang-cl will emit it (MSVC unaffected). - onnxruntime_mlas.cmake: clang-cl feature-gates x86 intrinsics (unlike MSVC cl.exe), so give the per-ISA x64 kernels that carry no /arch: flag the equivalent -m<feature> flags (mirroring the non-MSVC branch), incl. -msse4.1 for qgemm_kernel_sse41.cpp and -mamx-tile -mamx-int8 for qgemm_kernel_amx.cpp. Relates to #29465, #1025. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b55a1989-57d8-45eb-88fb-8619f855611c
Three portability fixes let the DirectML execution provider build under clang-cl (conforming two-phase name lookup / stricter template rules), while remaining valid for MSVC cl.exe: - AbstractOperatorDesc.h: OperatorField and AbstractOperatorDesc are mutually recursive, so OperatorField is incomplete where the struct is defined. Move the special member functions and the GetTensors template out of line, defined after OperatorField is completed (via a bottom-of-header include of GeneratedSchemaTypes.h). cl.exe defers these instantiations; clang-cl performs them at definition time and otherwise fails with 'incomplete type OperatorField'. - MLOperatorAuthorImpl.cpp: drop the spurious token paste in 'initializer.##Z()' (CASE_PROTO). '.##Z' never forms a valid token; clang-cl errors with -Winvalid-token-paste. 'initializer.Z()' is the intended member call on both compilers. - DmlDFT.h / DmlGridSample.h: the Dispatch() non-type template parameter is deduced from std::array's size_type, so it must be size_t, not uint32_t; clang requires an exact type match for the deduced argument. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b55a1989-57d8-45eb-88fb-8619f855611c
Enable onnxruntime_test_all, onnxruntime_provider_test, and onnxruntime_perf_test to build under clang-cl (lld-link). All fixes are standard-conformant and behavior-preserving on MSVC cl.exe. - float16.h: MLFloat16 defines operator==/!= on the derived type instead of inheriting the CRTP base version via using. Under C++20 (which clang-cl applies), comparing two MLFloat16 through the inherited base operator synthesizes a reversed candidate that is ambiguous with the non-reversed one. Defining a homogeneous derived-type operator== (mirroring BFloat16) resolves it. The delegating call Base::operator==(rhs) is qualified, so no reversed candidate is synthesized. Inline, ABI-neutral. - element_wise_ops_test.cc: MATH_NO_EXCEPT now also expands to empty for clang targeting MSVC (defined(__clang__) && defined(_MSC_VER)). clang-cl sees the global-namespace UCRT math functions (::sinf, ::cosf, ...) as non-noexcept, so the reference template parameter float (op)(float) noexcept failed to bind. cl.exe and clang+Linux are unaffected. - onnxruntime_unittests.cmake: stop compiling core/platform/path_lib.cc directly into onnxruntime_perf_test. onnxruntime_common (linked in both the shared and non-shared configurations) already provides GetDirNameFromFilePath; the direct compile is a duplicate definition that link.exe tolerates but lld-link rejects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b55a1989-57d8-45eb-88fb-8619f855611c
ONNX 1.22.0's onnx/common/scoped_resource.h defines
`using ScopedHandle = ScopedResource<INVALID_HANDLE_VALUE, close_handle>`.
INVALID_HANDLE_VALUE expands to ((HANDLE)(LONG_PTR)-1), a reinterpret_cast
that is not a constant expression and therefore cannot be used as a non-type
template argument. MSVC accepts this as an extension; clang-cl rejects it as a
hard error ("non-type template argument is not a constant expression"), which
blocks clang-cl builds of ONNX Runtime against the pinned ONNX.
Extend cmake/patches/onnx/onnx.patch to replace the templated ScopedHandle
alias with an equivalent non-template ScopedHandle class (same get()/release()
API) that only references INVALID_HANDLE_VALUE at runtime. ScopedFd is left
untouched since -1 is a valid constant expression.
Validated on an RTX 5060 Ti GPU box: clang-cl and MSVC builds both compile the
patched ONNX cleanly, and onnxruntime_test_all (1824 passed / 0 failed) and
onnxruntime_provider_test (5440 tests / 0 failed) run identically under both
compilers with the DirectML EP on real hardware.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 716cc750-9984-4096-b8bb-e0f9e548ab80
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Enable ONNX Runtime to build with clang-cl on Windows for the Windows ML distribution flag set (--use_dml --enable_wcos --client_package_build --enable_msvc_static_runtime ). Adds a --use_clang_cl build flag that selects the ClangCL VS platform toolset (x64 + Visual Studio generator only; ARM and non-VS generators are rejected), and fixes the source-level incompatibilities clang-cl surfaces that MSVC cl.exe silently tolerates:
• MLAS ( onnxruntime_mlas.cmake ): clang-cl feature-gates intrinsics, so per-ISA kernels get explicit -m flags (mirroring the non-MSVC branch); assembly-backed kernels like qgemm_kernel_avx2.cpp need none. Runtime CPUID dispatch is unchanged.
• spin_pause.cc: isolate the _tpause ( waitpkg ) intrinsic into a helper carrying attribute((target("waitpkg"))) ; the HasTPAUSE() runtime guard is preserved
• float16.h: give MLFloat16 derived-typed operator== / != to resolve C++20 reversed-candidate ambiguity (behavior-preserving; mirrors BFloat16 ).
• DML EP: out-of-line AbstractOperatorDesc special members for two-phase name lookup; uint32_t → size_t template params to match std::array deduction; drop an invalid ## token-paste.
• Build/link: skip MSVC-only /Qspectre under clang-cl; remove a duplicate path_lib.cc translation unit (lld-link enforces ODR); test-only noexcept macro adjustment.
• ONNX 1.22.0 patch: replace a reinterpret_cast -based non-type template argument (INVALID_HANDLE_VALUE) in scoped_resource.h with an equivalent non-template ScopedHandle class.
No ABI changes; no change to MSVC build behavior (all clang-cl paths are compiler-gated).
Validation: Built and tested under both clang-cl and MSVC on a DirectML GPU (RTX 5060 Ti): onnxruntime_test_all 1824/0 and onnxruntime_provider_test 5435/0 with identical pass sets and clean DML inference.
Motivation and Context
Building ORT with clang on Windows unblocks security-testing workflows (ASAN / libFuzzer / WebNN fuzzing) that depend on Clang-only tooling.