Add support for mixing Clang and GCC (as NVCC host).#2297
Add support for mixing Clang and GCC (as NVCC host).#2297pcanal merged 3 commits intoceleritas-project:developfrom
Conversation
The Clang compiler and the GCC compiler have made an incompatible choice in regard to the handling of template alias used as template parameter (the standard is silent on the subject and both interpretation are 'valid' although the GCC choice seems more 'natural'). The problem arise if Celeritas is built with Clang but uses an instance of NVCC which GCC has the host compiler. The symptoms is a failing dynamic cast on what is seemingly a compatible/correct type. However it turns out that Clang makes a valid but surprising interpretation of the C++ standard. Namely when a class template is used as a template argument or an alias to that same class template is used, Clang choose to make the result type/instance distinct. Clang failing example: https://godbolt.org/z/xW8T1PcxW gcc is different/works: https://godbolt.org/z/Tj1PfqWeT The problem is further limited in scope by the fact that the Celeritas code is internally consistent (and works fully when compiled with Clang for CPU only) but mixing Clang and NVCC (with gcc underneath) leads to the inconsistency. The solution here consist in moving any code involving directly the class template instance with the class template alias as a template parameter to the `.cc` side. This result in the need to have seeming 'simple' trampoline function template that are explicitly instantiated in the `.cc` file. Related notes: https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1286 https://stackoverflow.com/questions/78778437/gcc-and-clang-disagree-on-using-alias-templates-as-template-template-argument llvm/llvm-project#72377 llvm/llvm-project#33002
Test summary 5 990 files 9 609 suites 19m 28s ⏱️ Results for commit b75c498. ♻️ This comment has been updated with latest results. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2297 +/- ##
===========================================
- Coverage 87.24% 87.24% -0.01%
===========================================
Files 1353 1353
Lines 43142 43148 +6
Branches 13196 13196
===========================================
+ Hits 37638 37643 +5
- Misses 4284 4286 +2
+ Partials 1220 1219 -1
🚀 New features to boost your workflow:
|
sethrj
left a comment
There was a problem hiding this comment.
A suggestion to consider, good if not. Thanks for tracking this down! Did you encounter the compiler mismatch when disabling vecegom? root-project/veccore#28 may help if so.
There is zero conceptual reason why that would help (this is an nvcc/gcc vs Clang issue not a RDC issue). Nonetheless, I verified and as expected it fails also with ORANGE. |
|
@pcanal the compiler detection is influenced by veccore's use of |
In my case, the host detection (from check_language) sort-of fails but turns out to be irrelevant. The NVCC I have uses GCC and fails miserably (crash and burn on invocation of NVCC) if I try to make it use Clang as the 'host' compiler. If I could not make the mix mode works, I would have pursued fixing the host detection (i.e. try the VecCore patch) and have CMake fails in this mix case. But since I could make it work, this is moot for now. |
The Clang compiler and the GCC compiler have made an incompatible choice in regard to the handling of template alias used as template parameter (the standard is silent on the subject and both interpretation are 'valid' although the GCC choice seems more 'natural').
The problem arise if Celeritas is built with Clang but uses an instance of NVCC which GCC has the host compiler.
The symptoms is a failing dynamic cast on what is seemingly a compatible/correct type. However it turns out that Clang makes a valid but surprising interpretation of the C++ standard. Namely when a class template is used as a template argument or an alias to that same class template is used, Clang choose to make the result type/instance distinct.
Clang failing example: https://godbolt.org/z/xW8T1PcxW
gcc is different/works: https://godbolt.org/z/Tj1PfqWeT
The problem is further limited in scope by the fact that the Celeritas code is internally consistent (and works fully when compiled with Clang for CPU only) but mixing Clang and NVCC (with gcc underneath) leads to the inconsistency.
The solution here consist in moving any code involving directly the class template instance with the class template alias as a template parameter to the
.ccside. This result in the need to have seeming 'simple' trampoline function template that are explicitly instantiated in the.ccfile.Related notes:
https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1286 https://stackoverflow.com/questions/78778437/gcc-and-clang-disagree-on-using-alias-templates-as-template-template-argument
llvm/llvm-project#72377
llvm/llvm-project#33002