Compilation bug regarding `extents`
Bug report
Steps to reproduce
Compile the following snippet.
/// main.cpp
#include <experimental/mdspan>
namespace stdex = std::experimental;
int
main( int argc, char** argv )
{
constexpr stdex::extents< stdex::dynamic_extent, stdex::dynamic_extent > ext1( 1ul, 1ul );
constexpr stdex::extents< stdex::dynamic_extent > ext2( std::array< std::size_t, 1 >{1ul} );
return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(bug-report LANGUAGES CUDA CXX)
find_package(mdspan CONFIG REQUIRED)
add_executable(bug-report main.cpp)
target_link_libraries(bug-report PUBLIC std::mdspan)
target_compile_features(bug-report PUBLIC cxx_std_17 cuda_std_17)
set_source_files_properties(main.cpp PROPERTIES LANGUAGE CUDA)
Environment
- mdspan/0.1-0.2
- nvcc/11.4.48
- g++/9.2.0
- cmake/3.21
- cmake options:
CMAKE_CUDA_ARCHITECTURES=70 - need to disable
no_unique_adressfeature to avoid problem mentionned in #97 and #65
Expected result
Successful compilation
Actual result
/gpfs/users/tpadioleau/cmake-3.21.3-linux-x86_64/bin/cmake -S/gpfs/users/tpadioleau/bug-report -B/gpfs/users/tpadioleau/bug-report/build --check-build-system CMakeFiles/Makefile.cmake 0
/gpfs/users/tpadioleau/cmake-3.21.3-linux-x86_64/bin/cmake -E cmake_progress_start /gpfs/users/tpadioleau/bug-report/build/CMakeFiles /gpfs/users/tpadioleau/bug-report/build//CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1] : on entre dans le répertoire « /gpfs/users/tpadioleau/bug-report/build »
make -f CMakeFiles/bug-report.dir/build.make CMakeFiles/bug-report.dir/depend
make[2] : on entre dans le répertoire « /gpfs/users/tpadioleau/bug-report/build »
cd /gpfs/users/tpadioleau/bug-report/build && /gpfs/users/tpadioleau/cmake-3.21.3-linux-x86_64/bin/cmake -E cmake_depends "Unix Makefiles" /gpfs/users/tpadioleau/bug-report /gpfs/users/tpadioleau/bug-report /gpfs/users/tpadioleau/bug-report/build /gpfs/users/tpadioleau/bug-report/build /gpfs/users/tpadioleau/bug-report/build/CMakeFiles/bug-report.dir/DependInfo.cmake --color=
make[2] : on quitte le répertoire « /gpfs/users/tpadioleau/bug-report/build »
make -f CMakeFiles/bug-report.dir/build.make CMakeFiles/bug-report.dir/build
make[2] : on entre dans le répertoire « /gpfs/users/tpadioleau/bug-report/build »
[ 50%] Building CUDA object CMakeFiles/bug-report.dir/main.cpp.o
/gpfs/softs/spack/opt/spack/linux-centos7-cascadelake/gcc-9.2.0/cuda-11.4.0-tqftpmxbgstj4pkv3oeejmc57us33nq2/bin/nvcc -forward-unknown-to-host-compiler -isystem=/gpfs/users/tpadioleau/opt/include --generate-code=arch=compute_70,code=[compute_70,sm_70] -std=c++17 -MD -MT CMakeFiles/bug-report.dir/main.cpp.o -MF CMakeFiles/bug-report.dir/main.cpp.o.d -x cu -c /gpfs/users/tpadioleau/bug-report/main.cpp -o CMakeFiles/bug-report.dir/main.cpp.o
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/default_accessor.hpp(61): warning: __host__ annotation is ignored on a function("default_accessor") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/default_accessor.hpp(61): warning: __device__ annotation is ignored on a function("default_accessor") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/standard_layout_static_array.hpp(542): warning: __host__ annotation is ignored on a function("__partially_static_sizes_tagged") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/standard_layout_static_array.hpp(542): warning: __device__ annotation is ignored on a function("__partially_static_sizes_tagged") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/bug-report/main.cpp(8): warning: variable "ext1" was declared but never referenced
/gpfs/users/tpadioleau/bug-report/main.cpp(10): warning: variable "ext2" was declared but never referenced
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/default_accessor.hpp(61): warning: __host__ annotation is ignored on a function("default_accessor") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/default_accessor.hpp(61): warning: __device__ annotation is ignored on a function("default_accessor") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/standard_layout_static_array.hpp(542): warning: __host__ annotation is ignored on a function("__partially_static_sizes_tagged") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/standard_layout_static_array.hpp(542): warning: __device__ annotation is ignored on a function("__partially_static_sizes_tagged") that is explicitly defaulted on its first declaration
/gpfs/users/tpadioleau/bug-report/main.cpp: In function 'int main(int, char**)':
/gpfs/users/tpadioleau/bug-report/main.cpp:10:117: error: no matching function for call to 'std::experimental::extents<18446744073709551615>::extents(std::array<long unsigned int, 1>)'
10 | constexpr stdex::extents< stdex::dynamic_extent > ext2( std::array< std::size_t, 1 >{1ul} );
| ^
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:273:20: note: candidate: 'constexpr std::experimental::extents<Extents>::extents(const __storage_t&) [with long unsigned int ...Extents = {18446744073709551615}; std::experimental::extents<Extents>::__storage_t = std::experimental::detail::__partially_static_sizes_tagged<std::experimental::detail::__extents_tag, 18446744073709551615>]'
273 | extents(__storage_t const& sto ) noexcept
| ^~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:273:47: note: no known conversion for argument 1 from 'std::array<long unsigned int, 1>' to 'const __storage_t&' {aka 'const std::experimental::detail::__partially_static_sizes_tagged<std::experimental::detail::__extents_tag, 18446744073709551615>&'}
273 | extents(__storage_t const& sto ) noexcept
| ~~~~~~~~~~~~~~~~ ^
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:252:1: note: candidate: 'template<class SizeType, long unsigned int N, typename std::enable_if<(((N == std::experimental::extents<18446744073709551615, 18446744073709551615>::rank()) || (N == std::experimental::extents<18446744073709551615, 18446744073709551615>::rank_dynamic())) && is_convertible_v<SizeType, long unsigned int>), int>::type <anonymous> > constexpr std::experimental::extents<Extents>::extents(const std::array<_U, _N>&)'
252 | extents(std::array<SizeType, N> const& exts) noexcept
| ^ ~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:252:1: note: template argument deduction/substitution failed:
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:242:209: error: no type named 'type' in 'struct std::enable_if<false, int>'
242 | MDSPAN_TEMPLATE_REQUIRES(
| ^
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:224:1: note: candidate: 'template<class ... Integral, typename std::enable_if<((is_convertible_v<Integral, long unsigned int> && ...) && ((sizeof... (Integral) == std::experimental::extents<18446744073709551615, 18446744073709551615>::rank_dynamic()) || (sizeof... (Integral) == std::experimental::extents<18446744073709551615, 18446744073709551615>::rank()))), int>::type <anonymous> > constexpr std::experimental::extents<Extents>::extents(Integral ...)'
224 | explicit constexpr extents(Integral... exts) noexcept
| ^ ~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:224:1: note: template argument deduction/substitution failed:
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:215:248: error: no type named 'type' in 'struct std::enable_if<false, int>'
215 | MDSPAN_TEMPLATE_REQUIRES(
| ^
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:200:1: note: candidate: 'template<long unsigned int ...OtherExtents, typename std::enable_if<decltype (std::experimental::detail::_check_compatible_extents(std::integral_constant<bool, (1 == sizeof... (OtherExtents))>{}, std::integer_sequence<long unsigned int, 18446744073709551615>{}, std::integer_sequence<long unsigned int, _Idx ...>{}))::value, int>::type <anonymous> > constexpr std::experimental::extents<Extents>::extents(const std::experimental::extents<OtherExtents ...>&)'
200 | constexpr extents(const extents<OtherExtents...>& __other)
| ^ ~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:200:1: note: template argument deduction/substitution failed:
/gpfs/users/tpadioleau/bug-report/main.cpp:10:117: note: 'std::array<long unsigned int, 1>' is not derived from 'const std::experimental::extents<ExtentsPack ...>'
10 | constexpr stdex::extents< stdex::dynamic_extent > ext2( std::array< std::size_t, 1 >{1ul} );
| ^
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:182:11: note: candidate: 'constexpr std::experimental::extents<Extents>::extents(std::experimental::extents<Extents>&&) [with long unsigned int ...Extents = {18446744073709551615}]'
182 | MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr extents(extents&&) noexcept = default;
| ^~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:182:19: note: no known conversion for argument 1 from 'std::array<long unsigned int, 1>' to 'std::experimental::extents<18446744073709551615>&&'
182 | MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr extents(extents&&) noexcept = default;
| ^~~~~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:181:11: note: candidate: 'constexpr std::experimental::extents<Extents>::extents(const std::experimental::extents<Extents>&) [with long unsigned int ...Extents = {18446744073709551615}]'
181 | MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr extents(extents const&) noexcept = default;
| ^~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:181:19: note: no known conversion for argument 1 from 'std::array<long unsigned int, 1>' to 'const std::experimental::extents<18446744073709551615>&'
181 | MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr extents(extents const&) noexcept = default;
| ^~~~~~~~~~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:180:11: note: candidate: 'std::experimental::extents<Extents>::extents() [with long unsigned int ...Extents = {18446744073709551615}]'
180 | MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr extents() noexcept = default;
| ^~~~~~~
/gpfs/users/tpadioleau/opt/include/experimental/__p0009_bits/extents.hpp:180:11: note: candidate expects 0 arguments, 1 provided
make[2]: *** [CMakeFiles/bug-report.dir/main.cpp.o] Erreur 1
make[2] : on quitte le répertoire « /gpfs/users/tpadioleau/bug-report/build »
make[1]: *** [CMakeFiles/bug-report.dir/all] Erreur 2
make[1] : on quitte le répertoire « /gpfs/users/tpadioleau/bug-report/build »
make: *** [all] Erreur 2
Comments
-
The compiler fails at finding a suitable constructor. More specifically, for
ext2(of typestd::experimental::extents<18446744073709551615>) the SFINAE fails atN == std::experimental::extents<18446744073709551615, 18446744073709551615>::rank(), for some reason the compiler seems to be mixing the two classes. -
If I manually inline the calls to
rank()andrank_dynamic()it compiles fine. -
Fortunately the compiler succeeds to compile if only one of the two extents (
ext1orext2) is defined. -
It compiles fine using nvcc/11.4.48 and g++/10.3.0.
I am actually working on making nvcc work in CUDA mode that should come forth in the next couple weeks. Your reported bug is something I fixed in that.
Awesome I would be curious to know the origin of this behavior.
This was reported to NVIDIA, its simply a bug in the compiler. My guess would be that it has to do with the host compiler and nvcc treating the attribute differently leading to a different class layout internally, and then some part in the compiler which expects consistency between the host side layout of the class and the device side layout of the class crashes.
If I understand you correctly you seem to be making a link with the [[no_unique_address]] attribute bug ?
It seemed to me it was a different bug as I disabled the [[no_unique_address]] feature to make this bug appear.
I think this is fixed.