blob: efd71d10f9d94ddbd17acb9aa4429a18babb17a4 [file] [log] [blame]
// { dg-do run { target c++26 } }
#include <mdspan>
#include <iostream> // TODO remove
#include "../layout_traits.h"
#include <testsuite_hooks.h>
constexpr size_t dyn = std::dynamic_extent;
constexpr auto all = std::full_extent;
template<typename Mapping, typename... Slices>
constexpr auto
call_submdspan_mapping(const Mapping& m, std::tuple<Slices...> slices)
{
auto impl = [&]<size_t... I>(std::index_sequence<I...>)
{ return submdspan_mapping(m, get<I>(slices)...); };
return impl(std::make_index_sequence<sizeof...(Slices)>());
}
template<typename Layout>
constexpr bool
test_layout_common_return_types()
{
constexpr auto padding_side = DeducePaddingSide::from_typename<Layout>();
using Traits = LayoutTraits<padding_side>;
using layout_unpadded = typename Traits::layout_same;
{
auto m0 = typename Layout::mapping(std::extents());
auto result = submdspan_mapping(m0);
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, Layout>);
}
auto exts = Traits::make_extents(std::dims<5, int>(3, 5, 7, 11, 13));
auto m = typename Layout::mapping(exts);
auto s251 = std::strided_slice{2, 5, std::cw<1>};
{
auto slices = std::tuple{0, 0, 0, 0, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, layout_unpadded>);
}
{
auto s0 = std::strided_slice{1, 1, std::cw<1>};
auto slices = std::tuple{s0, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(is_same_padded<padding_side, layout_type>);
}
{
auto s0 = std::strided_slice{1, 2, std::cw<1>};
auto slices = std::tuple{s0, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(is_same_padded<padding_side, layout_type>);
}
{
auto s0 = std::strided_slice{1, 2, std::cw<1>};
auto slices = std::tuple{s0, 0, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(is_same_padded<padding_side, layout_type>);
}
{
auto s0 = std::strided_slice{1, 2, 1};
auto slices = std::tuple{s0, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
}
{
auto slices = std::tuple{1, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
}
{
auto s3 = std::strided_slice{2, std::cw<7>, std::cw<2>};
auto slices = std::tuple{all, all, all, s3, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
}
return true;
}
template<typename Layout>
constexpr bool
test_layout_unpadded_return_types()
{
constexpr auto padding_side = DeducePaddingSide::from_typename<Layout>();
using Traits = LayoutTraits<padding_side>;
auto exts = Traits::make_extents(std::dims<5, int>(3, 5, 7, 11, 13));
auto m = typename Layout::mapping(exts);
auto s251 = std::strided_slice{2, 5, std::cw<1>};
{
auto slices = std::tuple{all, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, Layout>);
}
return true;
}
template<typename Layout>
constexpr bool
test_layout_padded_return_types()
{
constexpr auto padding_side = DeducePaddingSide::from_typename<Layout>();
using Traits = LayoutTraits<padding_side>;
auto exts = Traits::make_extents(std::dims<5, int>(3, 5, 7, 11, 13));
auto m = typename Layout::mapping(exts);
auto s251 = std::strided_slice{2, 5, std::cw<1>};
{
auto slices = std::tuple{all, all, all, s251, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
using layout_expected = typename Traits::layout_same_padded<dyn>;
static_assert(std::same_as<layout_type, layout_expected>);
}
{
auto slices = std::tuple{all, 0, 0, 0, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
using layout_expected = typename Traits::layout_same;
static_assert(std::same_as<layout_type, layout_expected>);
}
{
auto s121 = std::strided_slice{1, 2, std::cw<1>};
auto slices = std::tuple{s121, 0, 0, 0, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
using layout_expected = typename Traits::layout_same;
static_assert(std::same_as<layout_type, layout_expected>);
}
{
auto s121 = std::strided_slice{1, 2, std::cw<1>};
auto slices = std::tuple{0, s121, 0, 0, 0};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
using layout_type = typename decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
}
return true;
}
template<typename Layout>
constexpr bool
test_layout_unpadded_padding_value()
{
using Traits = LayoutTraits<DeducePaddingSide::from_typename<Layout>()>;
auto s0 = std::strided_slice{size_t(1), size_t(2), std::cw<size_t(1)>};
auto s3 = std::strided_slice{size_t(2), size_t(5), std::cw<size_t(1)>};
auto check = [&](auto exts, size_t expected)
{
auto m = typename Layout::mapping(Traits::make_extents(exts));
auto slices = std::tuple{s0, size_t(0), all, s3, size_t(0)};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
auto padding_value = decltype(result.mapping)::padding_value;
VERIFY(padding_value == expected);
};
check(std::extents(std::cw<3>, std::cw<5>, std::cw<7>, 11, 13), 3*5);
check(std::extents(std::cw<3>, std::cw<5>, 7, 11, 13), 3*5);
check(std::extents(std::cw<3>, 5, 7, 11, 13), dyn);
check(std::extents(3, 5, 7, 11, 13), dyn);
return true;
}
template<typename Layout>
constexpr size_t static_padding_value = 1;
template<size_t PaddingValue>
constexpr size_t static_padding_value<std::layout_left_padded<PaddingValue>> = PaddingValue;
template<size_t PaddingValue>
constexpr size_t static_padding_value<std::layout_right_padded<PaddingValue>> = PaddingValue;
template<typename Layout>
constexpr bool
test_layout_padded_padding_value()
{
using Traits = LayoutTraits<DeducePaddingSide::from_typename<Layout>()>;
auto s0 = std::strided_slice{size_t(1), size_t(2), std::cw<size_t(1)>};
auto s3 = std::strided_slice{size_t(2), size_t(5), std::cw<size_t(1)>};
auto check = [&](auto exts, size_t expected)
{
auto m = typename Layout::mapping(Traits::make_extents(exts));
auto slices = std::tuple{s0, size_t(0), all, s3, size_t(0)};
auto result = call_submdspan_mapping(m, Traits::make_tuple(slices));
auto padding_value = decltype(result.mapping)::padding_value;
VERIFY(padding_value == expected);
};
auto pad = [](int n, int m) -> size_t
{
constexpr auto padding_value = static_padding_value<Layout>;
if constexpr (padding_value != dyn)
{
auto npad = ((n + padding_value - 1) / padding_value) * padding_value;
return npad * m;
}
else
return dyn;
};
check(std::extents(std::cw<3>, std::cw<5>, std::cw<7>, 11, 13), pad(3, 5));
check(std::extents(std::cw<3>, std::cw<5>, 7, 11, 13), pad(3, 5));
check(std::extents(std::cw<3>, std::cw<6>, 7, 11, 13), pad(3, 6));
check(std::extents(std::cw<3>, 5, 7, 11, 13), dyn);
check(std::extents(3, 5, 7, 11, 13), dyn);
return true;
}
constexpr bool
test_layout_stride_return_types()
{
auto exts = std::extents(3, 5);
auto m = std::layout_stride::mapping(exts, std::array{2, 12});
using index_type = decltype(exts)::index_type;
auto s1 = std::strided_slice{index_type(2), index_type(2),
std::cw<index_type(2)>};
auto result = submdspan_mapping(m, index_type(1), s1);
using layout_type = decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
return true;
}
template<typename Layout>
constexpr bool
test_return_types_all()
{
return true;
}
template<typename Layout>
constexpr bool
test_return_types_unpadded_all()
{
test_layout_common_return_types<Layout>();
static_assert(test_layout_common_return_types<Layout>());
test_layout_unpadded_return_types<Layout>();
static_assert(test_layout_unpadded_return_types<Layout>());
test_layout_unpadded_padding_value<Layout>();
static_assert(test_layout_unpadded_padding_value<Layout>());
return true;
}
template<typename Layout>
constexpr bool
test_return_types_padded_all()
{
test_layout_common_return_types<Layout>();
static_assert(test_layout_common_return_types<Layout>());
test_layout_padded_return_types<Layout>();
static_assert(test_layout_padded_return_types<Layout>());
test_layout_padded_padding_value<Layout>();
static_assert(test_layout_padded_padding_value<Layout>());
return true;
}
int
main()
{
test_return_types_unpadded_all<std::layout_left>();
test_return_types_unpadded_all<std::layout_right>();
test_return_types_padded_all<std::layout_left_padded<1>>();
test_return_types_padded_all<std::layout_left_padded<2>>();
test_return_types_padded_all<std::layout_left_padded<dyn>>();
test_return_types_padded_all<std::layout_right_padded<1>>();
test_return_types_padded_all<std::layout_right_padded<2>>();
test_return_types_padded_all<std::layout_right_padded<dyn>>();
test_layout_stride_return_types();
static_assert(test_layout_stride_return_types());
return 0;
}