Skip to content

Conversation

@guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Dec 17, 2025

Use std::experimental::simd for the vectorized TMath and vectorized TFormula backend if available. We assume it's available if ROOT is compiled with C++20 or later on Linux. In reality, it is available for new-enough Clang and GCC compilers (GCC >= 11), but it is not worth it at this point to check the compiler version explicitly, to keep things simple. People who build with C++20 are also expected to use new compilers.

The fact that ROOT C++17 users lose the vectorized TMath and TFormula features is an acceptable collateral damage of this migration, as the features are rarely used and the code/build system simplification is significant. If users really relied on these niche features, they are expected to build with C++20.

Windows and Apple silicon users are unaffected by this migration. The VecCore+Vc combination did not compile on Windows before anyway, and Vc does not support Apple silicon as Vc didn't support vectorization on ARM via Neon (it was [in developement](https://github.com/VcDevel/Vc?tab=readme-ov-file#vc-portable-zero-overhead-c-types-for-explicitly-data parallel-programming) but never finished).

As a result of this migration, the vc, veccore, builtin_vc, and builtin_veccore build options are deprecated.

The migration also fixes this long-standing JIRA issue about failing TFormula vectorization tests, because Vc symbols could not be resolved: https://its.cern.ch/jira/browse/ROOT-10614 This was a fundamental limitation of the statically-linked Vc library, as symbols could not be looked up by the interpreter at runtime. This limitation is gone with the migration to std::experimental::simd.

The unit test that checks if GenVector works with Vc types was changed to use std::experimental::simd types instead.

@guitargeek guitargeek self-assigned this Dec 17, 2025
@guitargeek guitargeek requested a review from dpiparo as a code owner December 17, 2025 09:53
@guitargeek guitargeek added in:Math Libraries in:CI clean build Ask CI to do non-incremental build on PR labels Dec 17, 2025
@guitargeek guitargeek closed this Dec 17, 2025
@guitargeek guitargeek reopened this Dec 17, 2025
@github-actions
Copy link

github-actions bot commented Dec 17, 2025

Test Results

    22 files      22 suites   3d 18h 43m 25s ⏱️
 3 790 tests  3 790 ✅ 0 💤 0 ❌
80 292 runs  80 292 ✅ 0 💤 0 ❌

Results for commit df58f47.

♻️ This comment has been updated with latest results.

@amadio
Copy link
Member

amadio commented Dec 17, 2025

If ROOT is on C++20 and GCC 11 or later in all platforms, you could also consider dropping Vc/VecCore entirely and go straight for std::simd.

@guitargeek
Copy link
Contributor Author

If ROOT is on C++20 and GCC 11 or later in all platforms, you could also consider dropping Vc/VecCore entirely and go straight for std::simd.

Cool! Yes, that's the plan once we don't have to support alma8 anymore. Thanks for blessing it!

@guitargeek guitargeek requested a review from lmoneta as a code owner December 17, 2025 18:16
@guitargeek guitargeek changed the title [ci] Enable vc and veccore on march=native build [Math] Replace Vc with std::simd Dec 18, 2025
@guitargeek guitargeek changed the title [Math] Replace Vc with std::simd [Math] Migrate from Vc to std::simd Dec 18, 2025
@guitargeek
Copy link
Contributor Author

Actually, I don't think we should delay this migration to standard C++ features just because of the default compiler on Alma 8. I think we can automatically disable the veccore features in that case, nicely explaining to our users that we are now only supporting std::simd as a backend for VecCore and dropped Vc support, so ensure that the configuration matrix that we need to test and validate is not too large.

@guitargeek guitargeek changed the title [Math] Migrate from Vc to std::simd [Math] Migrate from Vc to std::experimental::simd Dec 18, 2025
@amadio
Copy link
Member

amadio commented Dec 18, 2025

If you plan to use std::simd directly, without using it via VecCore interfaces, then you don't need VecCore as dependency anymore either, and would be better to drop it in favor of a full migration to standard library feaures. That is, unless you plan to fallback to scalar, because then you'd write things using VecCore instead of std::simd directly.

As for platform support, I don't remember about Windows (although I think it works), but on macOS it works nicely, so I wouldn't disable unless you have specific reasons. It works well to vectorize with ARM Neon.

@guitargeek
Copy link
Contributor Author

Thank you very much for keeping this discussion going!

If you plan to use std::simd directly, without using it via VecCore interfaces, then you don't need VecCore as dependency anymore either, and would be better to drop it in favor of a full migration to standard library feaures. That is, unless you plan to fallback to scalar, because then you'd write things using VecCore instead of std::simd directly.

Yes I have to think about that, and it's a good point with the scalar fallback. I don't think we need it actually, but our users might. It depends how much the ROOT::Double_v type is used in the wild, and if users wrote code that they expect to be also work with scalar fallback.

As for platform support, I don't remember about Windows (although I think it works), but on macOS it works nicely, so I wouldn't disable unless you have specific reasons. It works well to vectorize with ARM Neon.

You mean std::(experimental)::simd? When I did my research, I think I read that both MSVC and Apple Clang don't support it yet. Or I need to define some secret macros to enable it? Indeed, it would be nice to support Neon, which Vc didn't do. But it's not a blocker if we don't support mac and Windows with std::simd (via VecCore or not), because it would not be a regression. The builtin VecCore didn't compile on our Windows CI, and Vc doesn't support Neon, so for these platforms we had no SIMD. So there'd be no regression if we don't enable it for these platforms.

@guitargeek
Copy link
Contributor Author

guitargeek commented Dec 18, 2025

Ok I'm still struggling with the TFormula tests failing on some platforms, because the GCC compiled tests and Cling don't seem to agree what the size of the SIMDNative (std::experimental::native_simd<double>) should be... I'm trying to use now the compatible ABI tag instead, which would be a compromise. So using std::simd across compiled code and the interpreter runtime seems to be a challenge.

edit: using the "compatible" tag seems to have worked! And not that this is not a "scalar fallback", as I checked that on my laptop the widths of std::simd<.., compatible> are still greater than one. I'll organize a bit the commits, but then this will be good from my side.

@guitargeek
Copy link
Contributor Author

@amadio, you have any comments (besides that we can also migrate VecCore, which will happen later)? I would really appreciate your review here!

@amadio
Copy link
Member

amadio commented Dec 19, 2025

The fixed width std::simd performs quite poorly relative to the native version, see https://github.com/root-project/veccore/blob/master/doc/backends.md#c20-simd-backend-using-stdexperimentalsimd

I will review the commits and give more detailed feedback later.

@vgvassilev
Copy link
Member

vgvassilev commented Dec 19, 2025

Getting rid of Vc would be a huge quality of life improvement. It has been pretty hard to maintain and develop the core infrastructure around the current integration that we have. Please get rid of VecCore, too.

@guitargeek guitargeek force-pushed the veccore_vc branch 4 times, most recently from e7c8346 to 6cded2b Compare December 19, 2025 13:58
@guitargeek guitargeek changed the title [Math] Migrate from Vc to std::experimental::simd [Math] Migrate from VecCore and Vc to std::experimental::simd Dec 19, 2025
@guitargeek guitargeek force-pushed the veccore_vc branch 9 times, most recently from 27f02b2 to 698a6d0 Compare December 20, 2025 15:02
@guitargeek
Copy link
Contributor Author

The fixed width std::simd performs quite poorly relative to the native version, see https://github.com/root-project/veccore/blob/master/doc/backends.md#c20-simd-backend-using-stdexperimentalsimd

I found a solution for that. I now use the native SIMD version for any compiled code, and only use the fixed-width SIMD when declaring the code generated by TFormula to the interpreter. This width is takes as the width of the native SIMD type selected by the compiled code, to ensure compatibility between compiled and interpreted code.

This seems to work! The TFormula test failures that I saw on alma10 and alma9 with march=native when using native_simd all the way are gone.

So at this point I'm done with the PR from my side, except for maybe tweaking a bit the commit history and release notes.

What needs to happen next (next year) besides the eventual review by @amadio is to discuss with the ROOT team whether it's fine to do this migration, as it has a price: the vectorized TFormula and TMath features are only available with C++ 20 and with new-enough compilers.

@guitargeek guitargeek force-pushed the veccore_vc branch 4 times, most recently from 1a989d5 to 5ac240a Compare December 25, 2025 17:27
@guitargeek guitargeek force-pushed the veccore_vc branch 4 times, most recently from 20ba415 to a856372 Compare December 31, 2025 07:31
Use `std::experimental::simd` for the vectorized TMath and vectorized
TFormula backend if available. We assume it's available if ROOT is
compiled with C++20 or later on Linux. In reality, it is avialble for
new-enough Clang and GCC compilers (GCC >= 11), but it is not worth it
at this point to check the compiler version explicitly, to keep things
simple. People who build with C++20 are also expected to use new
compilers.

The fact that ROOT C++17 users lose the vectorized TMath and TFormula
features is an acceptable collateral damage of this migration, as the
features are rarely used and the code/build system simplification is
significant. If users really relied on these niche features, they are
expected to build with C++20.

Windows and Apple silicon users are unaffected by this migration. The
VecCore+Vc combination did not compile on Windows before anyway, and Vc
does not support Apple silicon as Vc didn't support vectorization on ARM
via Neon (it was [in developement](https://github.com/VcDevel/Vc?tab=readme-ov-file#vc-portable-zero-overhead-c-types-for-explicitly-data-parallel-programming) but never finished).

As a result of this migration, the `vc`, `veccore`, `builtin_vc`, and
`builtin_veccore` build options are deprecated.

The migration also fixes this long-standing JIRA issue about failing
TFormula vectorization tests, because Vc symbols could not be resolved:
https://its.cern.ch/jira/browse/ROOT-10614
This was a fundamental limitation of the statically-linked Vc library,
as symbols could not be looked up by the interpreter at runtime. This
limitation is gone with the migration to `std::experimental::simd`.

The unit test that checks if GenVector works with Vc types was changed
to use `std::experimental::simd` types instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clean build Ask CI to do non-incremental build on PR in:CI in:Math Libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants