hyteg issueshttps://i10git.cs.fau.de/hyteg/hyteg/-/issues2023-09-15T09:52:04+02:00https://i10git.cs.fau.de/hyteg/hyteg/-/issues/228AdiosWriterTest fails with old ICC2023-09-15T09:52:04+02:00Marcus MohrAdiosWriterTest fails with old ICCActivating ADIOS tests in the pipeline, see MR !645 revealed a [problem](https://i10git.cs.fau.de/hyteg/hyteg/-/jobs/1118381) with the `AdiosWriterTest`. It fails for ICC 2022, but only for that one.Activating ADIOS tests in the pipeline, see MR !645 revealed a [problem](https://i10git.cs.fau.de/hyteg/hyteg/-/jobs/1118381) with the `AdiosWriterTest`. It fails for ICC 2022, but only for that one.Implement basic Checkpointing FunctionalityMarcus MohrMarcus Mohrhttps://i10git.cs.fau.de/hyteg/hyteg/-/issues/175BlockOperator, Template Instantiation and Microsoft Compiler2022-02-23T18:13:51+01:00Marcus MohrBlockOperator, Template Instantiation and Microsoft CompilerHi,
as encouraged in our last developer meeting I will try to document the issue we had recently discussed in the chat. There had been a problem report on compiling on Windows with the Microsoft Visual Studio compiler. This resulted in ...Hi,
as encouraged in our last developer meeting I will try to document the issue we had recently discussed in the chat. There had been a problem report on compiling on Windows with the Microsoft Visual Studio compiler. This resulted in template instantiation errors of the following form, here as an example for the *BlockOperatorBasicTest*
```
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/functions/FunctionWrapper.hpp(179,1): error C2660: 'hyteg::BlockFunction<value_t>::enumerate': function does not take 2 arguments [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] value_t=walberla::real_t
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/functions/BlockFunction.hpp(264,9): message : see declaration of 'hyteg::BlockFunction<value_t>::enumerate' [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] value_t=walberla::real_t
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/functions/FunctionWrapper.hpp(179): message : while compiling class template member function 'void hyteg::FunctionWrapper<func_t>::enumerate(walberla::uint_t,double &) const' [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] func_t=thType
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/functions/GenericFunction.hpp(58): message : see reference to class template instantiation 'hyteg::FunctionWrapper<func_t>' being compiled [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] func_t=thType
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/operators/BlockOperator.hpp(158): message : see reference to function template instantiation 'const func_t &hyteg::GenericFunction<value_t>::unwrap<srcBlockFunc_t>(void) const' being compiled [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] func_t=thType,
[build] value_t=double,
[build] srcBlockFunc_t=thType
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/operators/BlockOperator.hpp(158): message : see reference to function template instantiation 'const func_t &hyteg::GenericFunction<value_t>::unwrap<srcBlockFunc_t>(void) const' being compiled [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] func_t=thType,
[build] value_t=double,
[build] srcBlockFunc_t=thType
[build] ]
[build] C:\Users\[removed]\dev\hyteg\src\hyteg/operators/BlockOperator.hpp(156): message : while compiling class template member function 'void hyteg::BlockOperator<thType,thType>::smooth_gs(const hyteg::GenericFunction<value_t> &,const hyteg::GenericFunction<value_t> &,size_t,hyteg::DoFType) const' [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] with
[build] [
[build] value_t=double
[build] ]
[build] C:\Users\[removed]\dev\hyteg\tests\hyteg\operators\BlockOperatorBasicTest.cpp(76): message : see reference to class template instantiation 'hyteg::BlockOperator<thType,thType>' being compiled [C:\Users\[removed]\dev\hyteg\build\tests\hyteg\BlockOperatorBasicTest.vcxproj]
[build] Build finished with exit code 1
```
The compiler is of course correct in the following respect. The `BlockFunction` does not provide a version of `enumerate` that accepts an offset parameter, as the other functions do. However, the `BlockFunction` was also not intended to be wrapped inside a `FunctionWrapper` object. So the interesting question here is: Why does the Microsoft compiler see the need to instantiate `FunctionWrapper< thType >`, where `thType = P2P1TaylorHoodBlockFunction< real_t >` is a child of `BlockFunction<real_t>`, while neither GCC, nor Clang, nor the Intel compiler does?
My current working hypothesis is the following:
- `BlockOperator< srcBlockFunc_t, dstBlockFunc_t>` inherits from `GSSmoothable< GenericFunction< typename srcBlockFunc_t::valueType >`.
- As `GSSmoothable::smooth_gs()` is pure virtual, it needs to be implemented by
`BlockOperator` and must be instantiable for the given template arguments, when one attempts to generate an object of type `BlockOperator`. In the above case `srcBlockFunc_t = thType = P2P1TaylorHoodBlockFunction< real_t >` which is a child of `BlockFunction<real_t>`.
- `BlockOperator::smooth_gs( GenericFunction, ...)` contains the two lines:
```c++
const auto& dst_unwrapped = dst.template unwrap< srcBlockFunc_t >();
const auto& rhs_unwrapped = rhs.template unwrap< dstBlockFunc_t >();
```
which invoke the templated member function `GenericFunction::unwrap()`. This in turn does the following:
```c++
template < typename func_t >
func_t& unwrap()
{
auto realMe = static_cast< FunctionWrapper< func_t >* >( this );
return realMe->unwrap();
};
- It seems that the static cast is the reason why the compiler attempts to instantiate `FunctionWrapper< thType >` and finally looks for the missing `BlockFunction< real_t >::enumerate()` version. However, two questions remain:
1. As no object of type `FunctionWrapper< srcBlockFunc_t >` is requested, but we only have a cast to pointer, why can the template instance not remain abstract? Is that what the other compilers do?
1. The instantiations involved seem implicit and, thus, should be lazy. But there is no direct call to `FunctionWrapper<srcBlockFunc_t>::enumerate()`.
The complexity here is high and I have no direct access to the compiler to experiment, so the analysis might by faulty. However, commenting out the inheritance and the `smooth_gs()` methods in `BlockOperator` fixed the problem for the Microsoft compiler. So at least no falsification.
Cheers
MarcusMarkus WiedemannMarkus Wiedemann