Skip to content

Conversation

@guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Dec 17, 2025

This PR suggests to always use std::experimental::simd as the backend for VecCore if the platform supports it. Otherwise, we drop support for the TMath and TFormula vectorization features that VecCore enables. The GenVector classes are also changed to be able to accept std::experimental::simd types as template parameters, while dropping compatibility with Vc types to keep the overall support burden low.

In the future, we can also fully replace the VecCore abstraction with std::experimental::simd.

Motivation / what speaks for this PR:

  • it finally fixes the vectorized TFormula tests. These couldn't pass before when building with march=native, as many math functions require symbols from Vc, which the interpreter can't look up (Vc is always built statically). This was a fundamental problem with the design. See ROOT-10614.
  • Users get the vectorization features that veccore=ON enables without also building vc (or getting it via builtin_vc=ON)
  • We move from an unmaintained dependency (Vc) to something that comes with GCC and Clang (std::experimental::simd)
  • Now that the TFormula tests pass again, we can enable veccore vectorization features also in the CI and and get test coverage

Neutral:

  • No effective change for Windows users concerning the vectorized TMath and TFormula, as ROOT with veccore=ON didn't compile on Windows anyway (I checked that with the CI)
  • No effective change for Apple silicon users, as Vc didn't support vectorization of ARM via Neon (it was in developement but never finished)

What you might argue against this PR:

  • The vectorized TMath and the vectorized TFormula backend (in cases where is worked...) is not available anymore to Linux users who compile ROOT with GCC < 11 (our only supported platform where this applies is AlmaLinux 8 with GCC 8.5 as the default compiler)
  • It's also not available anymore to users of Apple hardware with Intel CPUs (std::simd is not yet available with Apple Clang)
  • People that instantiated GenVector classes with Vc SIMD types must migrate to std::simd, as this PR suggests to update GenVector to match std::simd and compatibility is broken. However, if people actually used GenVector with Vc, we can easily fix this for them with some constexpr branching in the templated GenVector classes. It's just not worth to do this at this point, as I'm not aware of anyone who used GenVector with Vc.

This other PR shows what would happen if veccore=ON is set for all platforms:

Closes the following Jira ticket: https://its.cern.ch/jira/browse/ROOT-10614

@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

3 754 tests   3 754 ✅  2h 36m 35s ⏱️
    1 suites      0 💤
    1 files        0 ❌

Results for commit e293465.

♻️ 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!

@guitargeek guitargeek requested a review from amadio December 18, 2025 20:52
… type

The GenVector classes are also to be able to accept
`std::experimental::simd types` as template parameters, while dropping
compatibility with Vc types to keep the overall support burden low.

However, if people actually used GenVector with Vc, we can easily fix
this for them with some `constexpr` branching in the templated GenVector
classes. It's just not worth to do this at this point, as I'm not aware
of anyone who used GenVector with Vc.
Always use `std::experimental::simd` as the backend for VecCore if the
platform supports it. Otherwise, we drop support for the TMath and
TFormula vectorization features that VecCore enables.
We have no test coverage on Linux for these options right now.

We don't want to necessarily enable them in the release at this point,
but enabling them on the `march=native` build is the perfect opportunity
to test the TFormula and TMath features that VecCore enables, in
particular with the `std::simd` backend.
Some of the shortcuts represent the same `cmath` functions that are used
to implement TMath anyway.
@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.

Now that we always use the `std::simd` backend of VecCore, we don't need
to use `vecCore::math` anymore, because all the functions from `cmath`
that VecCore wraps are also implemented for `std::simd`.
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.

3 participants