AMReX C++20 in VS2026
According to a non-descript bug report in WarpX, AMReX might not yet compile with the latest VS 2026 (MSVC) for Windows. VS 2026 uses C++20 by default, so I suspect it is somehow related to C++20 in MSVC.
We should update our CI runners to add a C++20 build in those and fix issues that we see.
Problem is WarpX specific: https://github.com/BLAST-WarpX/warpx/issues/6406#issuecomment-3555607062
Ah, but the errors are in AMReX LinearSolvers MLMG: https://github.com/BLAST-WarpX/warpx/pull/6448
...
2025-12-09T18:27:19.9118795Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(24,30): error C2039: 'fab_type': is not a member of 'std::array<amrex::MultiFab,3>' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9120581Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
2025-12-09T18:27:19.9121683Z C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\array(402,7):
2025-12-09T18:27:19.9122634Z see declaration of 'std::array<amrex::MultiFab,3>'
2025-12-09T18:27:19.9123488Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(24,30):
2025-12-09T18:27:19.9124438Z the template instantiation context (the oldest one first) is
2025-12-09T18:27:19.9125373Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCurlCurl.H(25,14):
2025-12-09T18:27:19.9126555Z see reference to class template instantiation 'amrex::MLLinOpT<std::array<amrex::MultiFab,3>>' being compiled
2025-12-09T18:27:19.9127771Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(522,1):
2025-12-09T18:27:19.9129199Z while compiling class template member function 'void amrex::MLLinOpT<std::array<amrex::MultiFab,3>>::setLevelBC(int,const MF *,const MF *,const MF *,const MF *)'
2025-12-09T18:27:19.9131962Z with
2025-12-09T18:27:19.9132345Z [
2025-12-09T18:27:19.9132740Z MF=std::array<amrex::MultiFab,3>
2025-12-09T18:27:19.9133257Z ]
2025-12-09T18:27:19.9133918Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(520,19):
2025-12-09T18:27:19.9135017Z see reference to class template instantiation 'amrex::MLCellLinOpT<MF>' being compiled
2025-12-09T18:27:19.9136320Z with
2025-12-09T18:27:19.9136702Z [
2025-12-09T18:27:19.9137138Z MF=std::array<amrex::MultiFab,3>
2025-12-09T18:27:19.9137589Z ]
2025-12-09T18:27:19.9137932Z
2025-12-09T18:27:19.9139009Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(24,30): error C2061: syntax error: identifier 'fab_type' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9140550Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
2025-12-09T18:27:19.9141255Z
2025-12-09T18:27:19.9425450Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(107,16): error C2555: 'amrex::MLCellLinOpT<MF>::getSolvabilityOffset': overriding virtual function return type differs and is not covariant from 'amrex::MLLinOpT<std::array<amrex::MultiFab,3>>::getSolvabilityOffset' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9427089Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(107,16): error C2555: with [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9428020Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(107,16): error C2555: [ [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9428990Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(107,16): error C2555: MF=std::array<amrex::MultiFab,3> [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9430053Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(107,16): error C2555: ] [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T18:27:19.9430840Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
...
Could be a missing include of #include <AMReX_MultiFab.H> in Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H?
I think MSVC is confused by setLevelBC, which has a virtual function version and a template version.
If you have a test set up, we can try
diff --git a/Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H b/Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H
index c63921ced1..a45d8ea198 100644
--- a/Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H
+++ b/Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H
@@ -21,8 +21,8 @@ class MLCellLinOpT // NOLINT(cppcoreguidelines-virtual-class-destructor)
{
public:
- using FAB = typename MF::fab_type;
- using RT = typename MF::value_type;
+ using FAB = typename FabDataType<MF>::fab_type;
+ using RT = typename FabDataType<MF>::value_type;
using BCType = LinOpBCType;
using BCMode = typename MLLinOpT<MF>::BCMode;
Good idea, trying in https://github.com/BLAST-WarpX/warpx/pull/6448
Branch: https://github.com/ax3l/amrex/tree/fix-linop-mlmg
That changes the error somewhat, now:
...
2025-12-09T19:24:28.8177040Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(533,14): error C2039: 'define': is not a member of 'std::array<amrex::MultiFab,3>' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T19:24:28.8178335Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
2025-12-09T19:24:28.8179762Z C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\array(402,7):
2025-12-09T19:24:28.8180765Z see declaration of 'std::array<amrex::MultiFab,3>'
2025-12-09T19:24:28.8181610Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(533,14):
2025-12-09T19:24:28.8182674Z the template instantiation context (the oldest one first) is
2025-12-09T19:24:28.8183605Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCurlCurl.H(25,14):
2025-12-09T19:24:28.8184845Z see reference to class template instantiation 'amrex::MLLinOpT<std::array<amrex::MultiFab,3>>' being compiled
2025-12-09T19:24:28.8187644Z D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(522,1):
2025-12-09T19:24:28.8189106Z while compiling class template member function 'void amrex::MLLinOpT<std::array<amrex::MultiFab,3>>::setLevelBC(int,const MF *,const MF *,const MF *,const MF *)'
2025-12-09T19:24:28.8190273Z with
2025-12-09T19:24:28.8190634Z [
2025-12-09T19:24:28.8191003Z MF=std::array<amrex::MultiFab,3>
2025-12-09T19:24:28.8191469Z ]
2025-12-09T19:24:28.8191777Z
2025-12-09T19:24:28.8193009Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(534,14): error C2039: 'setVal': is not a member of 'std::array<amrex::MultiFab,3>' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T19:24:28.8195059Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
2025-12-09T19:24:28.8196192Z C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\array(402,7):
2025-12-09T19:24:28.8197140Z see declaration of 'std::array<amrex::MultiFab,3>'
2025-12-09T19:24:28.8197625Z
2025-12-09T19:24:28.8198875Z 10>D:\a\warpx\warpx\build\_deps\fetchedamrex-src\Src\LinearSolvers\MLMG\AMReX_MLCellLinOp.H(536,9): error C2039: 'nGrowVect': is not a member of 'std::array<amrex::MultiFab,3>' [D:\a\warpx\warpx\build\lib_3d.vcxproj]
2025-12-09T19:24:28.8200535Z (compiling source file '../Source/Initialization/DivCleaner/ProjectionDivCleaner.cpp')
2025-12-09T19:24:28.8201679Z C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\array(402,7):
2025-12-09T19:24:28.8202616Z see declaration of 'std::array<amrex::MultiFab,3>'
...
I am not surprised that that is not the only issue. We have MLCurlCurl<T> and MLCellLinOp<T> both derived from MLLinOp<T>. MLCurlCurl has no relationship with MLCellLinOp at all other than they both derive from MLLinOp. But somehow for MSVC, MLCurlCurl<std::array<MultiFab,3>> makes it try to instantiate MLCellLinOp<std::array<MultiFab,3>>. It makes no sense.