| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include "cute/layout.hpp" |
| #include "cute/container/array.hpp" |
| #include "cutlass/conv/convolution.h" |
|
|
| |
|
|
| namespace cutlass { |
|
|
| |
|
|
| |
|
|
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Int<1>> |
| make_cute_packed_stride(cute::Stride<IntT, cute::Int<1>> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<0>(s_copy) = static_cast<IntT>(cute::get<1>(shape_MKL)); |
| return s_copy; |
| } |
|
|
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, IntT> |
| make_cute_packed_stride(cute::Stride<cute::Int<1>, IntT> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = static_cast<IntT>(cute::get<0>(shape_MKL)); |
| return s_copy; |
| } |
|
|
| |
|
|
| |
|
|
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Int<1>, int64_t> |
| make_cute_packed_stride(cute::Stride<IntT, cute::Int<1>, int64_t> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<0>(s_copy) = static_cast<IntT>(cute::get<1>(shape_MKL)); |
| int batch_count = cute::get<2>(shape_MKL); |
| if (batch_count > 1) { |
| cute::get<2>(s_copy) = static_cast<IntT>(cute::get<0>(shape_MKL) * cute::get<1>(shape_MKL)); |
| } |
| else { |
| cute::get<2>(s_copy) = static_cast<IntT>(0); |
| } |
| return s_copy; |
| } |
|
|
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, IntT, int64_t> |
| make_cute_packed_stride(cute::Stride<cute::Int<1>, IntT, int64_t> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = static_cast<IntT>(cute::get<0>(shape_MKL)); |
| int batch_count = cute::get<2>(shape_MKL); |
| if (batch_count > 1) { |
| cute::get<2>(s_copy) = static_cast<IntT>(cute::get<0>(shape_MKL) * cute::get<1>(shape_MKL)); |
| } |
| else { |
| cute::get<2>(s_copy) = static_cast<IntT>(0); |
| } |
| return s_copy; |
| } |
|
|
| |
|
|
| |
|
|
| template <class StrideIntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<StrideIntT, cute::Int<1>, cute::Int<0>> |
| make_cute_packed_stride(cute::Stride<StrideIntT, cute::Int<1>, cute::Int<0>> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<StrideIntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<0>(s_copy) = static_cast<StrideIntT>(cute::get<1>(shape_MKL)); |
| return s_copy; |
| } |
|
|
| template <class StrideIntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, StrideIntT, cute::Int<0>> |
| make_cute_packed_stride(cute::Stride<cute::Int<1>, StrideIntT, cute::Int<0>> s, cute::Shape<int,int,int> shape_MKL) { |
| static_assert(std::is_integral_v<StrideIntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = static_cast<StrideIntT>(cute::get<0>(shape_MKL)); |
| return s_copy; |
| } |
|
|
| |
|
|
| |
|
|
| |
| |
| |
| |
| |
| template <class IntT, size_t RankT_> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Int<1>, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Int<1>, cute::Int<0>> s, |
| cute::array<int32_t, RankT_> shape_output, |
| cute::array<IntT, RankT_> stride_output, |
| cutlass::conv::Operator conv_op) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| static_assert(RankT_ >= 3u); |
| constexpr static int RankT = static_cast<int>(RankT_); |
|
|
| assert(stride_output[RankT-1] == 1); |
| cute::for_each(cute::make_seq<RankT-2>{}, [&](auto i) { |
| assert(stride_output[i] == shape_output[i+1] * stride_output[i+1]); |
| }); |
|
|
| auto s_copy = s; |
| cute::get<0>(s_copy) = (conv_op == cutlass::conv::Operator::kWgrad) ? |
| stride_output[0] : |
| stride_output[RankT-2]; |
| return s_copy; |
| } |
|
|
| |
| |
| |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<IntT, IntT>, cute::Int<1>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<IntT, IntT>, cute::Int<1>> s, |
| cute::array<IntT, 3> stride_nwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| assert(stride_nwc[2] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_nwc[1]; |
| cute::get<0,1>(s_copy) = stride_nwc[0]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<IntT, IntT, IntT>, cute::Int<1>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<IntT, IntT, IntT>, cute::Int<1>> s, |
| cute::array<IntT, 4> stride_nhwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
| assert(stride_nhwc[3] == 1); |
| auto s_copy = s; |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<0,i>(s_copy) = stride_nhwc[2-i]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<IntT, IntT, IntT, IntT>, cute::Int<1>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<IntT, IntT, IntT, IntT>, cute::Int<1>> s, |
| cute::array<IntT, 5> stride_ndhwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ndhwc[4] == 1); |
| auto s_copy = s; |
| cute::for_each(cute::make_seq<4>{}, [&](auto i) { |
| cute::get<0,i>(s_copy) = stride_ndhwc[3-i]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| |
| |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT>> s, |
| cute::array<IntT, 3> stride_ksc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ksc[2] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_ksc[0]; |
| cute::get<1,1>(s_copy) = stride_ksc[1]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT>> s, |
| cute::array<IntT, 4> stride_krsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_krsc[3] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_krsc[0]; |
| cute::for_each(cute::make_seq<2>{}, [&](auto i) { |
| cute::get<1,2-i>(s_copy) = stride_krsc[i+1]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT, IntT>> s, |
| cute::array<IntT, 5> stride_ktrsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ktrsc[4] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_ktrsc[0]; |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<1,3-i>(s_copy) = stride_ktrsc[i+1]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT>> s, |
| cute::array<IntT, 3> stride_nwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_nwc[2] == 1); |
| auto s_copy = s; |
| if (ConvOp == cutlass::conv::Operator::kWgrad) { |
| cute::get<1,0>(s_copy) = stride_nwc[1]; |
| cute::get<1,1>(s_copy) = stride_nwc[0]; |
| } |
| else if (ConvOp == cutlass::conv::Operator::kDgrad) { |
| |
| cute::get<1,0>(s_copy) = stride_nwc[0]; |
| cute::get<1,1>(s_copy) = stride_nwc[1]; |
| } |
| return s_copy; |
| } |
|
|
| |
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT, IntT>> s, |
| cute::array<IntT, 4> stride_nhwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_nhwc[3] == 1); |
| auto s_copy = s; |
| if (ConvOp == cutlass::conv::Operator::kWgrad) { |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<1,i>(s_copy) = stride_nhwc[2-i]; |
| }); |
| } |
| else if (ConvOp == cutlass::conv::Operator::kDgrad) { |
| |
| cute::get<1,0>(s_copy) = stride_nhwc[0]; |
| cute::for_each(cute::make_seq<2>{}, [&](auto i) { |
| cute::get<1,2-i>(s_copy) = stride_nhwc[i+1]; |
| }); |
| } |
| return s_copy; |
| } |
|
|
| |
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT, IntT, IntT>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, cute::Stride<IntT, IntT, IntT, IntT>> s, |
| cute::array<IntT, 5> stride_ndhwc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ndhwc[4] == 1); |
| auto s_copy = s; |
| if (ConvOp == cutlass::conv::Operator::kWgrad) { |
| cute::for_each(cute::make_seq<4>{}, [&](auto i) { |
| cute::get<1,i>(s_copy) = stride_ndhwc[3-i]; |
| }); |
| } |
| else if (ConvOp == cutlass::conv::Operator::kDgrad) { |
| |
| cute::get<1,0>(s_copy) = stride_ndhwc[0]; |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<1,3-i>(s_copy) = stride_ndhwc[i+1]; |
| }); |
| } |
| return s_copy; |
| } |
|
|
| |
| |
| |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, IntT> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, IntT> s, |
| cute::array<IntT, 3> stride_nqk, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_nqk[2] == 1); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = stride_nqk[1]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, IntT> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, IntT> s, |
| cute::array<IntT, 4> stride_npqk, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_npqk[3] == 1); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = stride_npqk[2]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Int<1>, IntT> |
| make_cute_packed_stride( |
| cute::Stride<cute::Int<1>, IntT> s, |
| cute::array<IntT, 5> stride_nzpqk, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_nzpqk[4] == 1); |
| auto s_copy = s; |
| cute::get<1>(s_copy) = stride_nzpqk[3]; |
| return s_copy; |
| } |
|
|
|
|
|
|
| |
| |
| |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT>, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT>, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 3> shape_output, |
| cute::array<IntT, 3> stride_ksc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ksc[2] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_ksc[0]; |
| cute::get<1,1>(s_copy) = stride_ksc[1]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT>, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT>, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 4> shape_output, |
| cute::array<IntT, 4> stride_krsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_krsc[3] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_krsc[0]; |
| cute::for_each(cute::make_seq<2>{}, [&](auto i) { |
| cute::get<1,2-i>(s_copy) = stride_krsc[i+1]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT, IntT>, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<IntT, cute::Stride<cute::Int<1>, IntT, IntT, IntT>, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 5> shape_output, |
| cute::array<IntT, 5> stride_ktrsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ktrsc[4] == 1); |
| auto s_copy = s; |
| cute::get<0,0>(s_copy) = stride_ktrsc[0]; |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<1,3-i>(s_copy) = stride_ktrsc[i+1]; |
| }); |
| return s_copy; |
| } |
|
|
|
|
| |
| |
| |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<cute::Int<1>, IntT>, IntT, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<cute::Int<1>, IntT>, IntT, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 3> shape_output, |
| cute::array<IntT, 3> stride_ksc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ksc[2] == 1); |
| auto s_copy = s; |
| cute::get<1,0>(s_copy) = stride_ksc[0]; |
| cute::get<0,1>(s_copy) = stride_ksc[1]; |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<cute::Int<1>, IntT, IntT>, IntT, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<cute::Int<1>, IntT, IntT>, IntT, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 4> shape_output, |
| cute::array<IntT, 4> stride_krsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_krsc[3] == 1); |
| auto s_copy = s; |
| cute::get<1,0>(s_copy) = stride_krsc[0]; |
| cute::for_each(cute::make_seq<2>{}, [&](auto i) { |
| cute::get<0,2-i>(s_copy) = stride_krsc[i+1]; |
| }); |
| return s_copy; |
| } |
|
|
| |
| template <class IntT> |
| CUTLASS_HOST_DEVICE |
| cute::Stride<cute::Stride<cute::Int<1>, IntT, IntT, IntT>, IntT, cute::Int<0>> |
| make_cute_packed_stride( |
| cute::Stride<cute::Stride<cute::Int<1>, IntT, IntT, IntT>, IntT, cute::Int<0>> s, |
| [[maybe_unused]] cute::array<int32_t, 5> shape_output, |
| cute::array<IntT, 5> stride_ktrsc, |
| conv::Operator ConvOp) { |
| static_assert(std::is_integral_v<IntT>, |
| "Stride must have an integral type so it can be set dynamically. Static strides not supported."); |
|
|
| assert(stride_ktrsc[4] == 1); |
| auto s_copy = s; |
| cute::get<1,0>(s_copy) = stride_ktrsc[0]; |
| cute::for_each(cute::make_seq<3>{}, [&](auto i) { |
| cute::get<0,3-i>(s_copy) = stride_ktrsc[i+1]; |
| }); |
| return s_copy; |
| } |
| |
|
|
| } |
|
|