|
|
@@ -30,37 +30,51 @@ MEGDNN_DEVICE __forceinline__ void transpose_int8_4x4_impl( |
|
|
|
} |
|
|
|
|
|
|
|
template <uint32_t interleaved, typename vec_type> |
|
|
|
MEGDNN_DEVICE __forceinline__ void transpose_int8_interleavedx4( |
|
|
|
const int src[interleaved], vec_type (&dst)[4]); |
|
|
|
struct transpose_int8_interleavedx4; |
|
|
|
|
|
|
|
template <> |
|
|
|
MEGDNN_DEVICE __forceinline__ void transpose_int8_interleavedx4<4, int>( |
|
|
|
const int src[4], int (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0], dst[1], |
|
|
|
dst[2], dst[3]); |
|
|
|
} |
|
|
|
struct transpose_int8_interleavedx4<4, int> { |
|
|
|
static constexpr uint32_t interleaved = 4; |
|
|
|
using vec_type = int; |
|
|
|
using Fragment = array_wrapper<int, interleaved>; |
|
|
|
MEGDNN_DEVICE __forceinline__ void operator()(const Fragment src, |
|
|
|
vec_type (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0], dst[1], |
|
|
|
dst[2], dst[3]); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template <> |
|
|
|
MEGDNN_DEVICE __forceinline__ void transpose_int8_interleavedx4<8, int2>( |
|
|
|
const int src[8], int2 (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0].x, dst[1].x, |
|
|
|
dst[2].x, dst[3].x); |
|
|
|
transpose_int8_4x4_impl(src[4], src[5], src[6], src[7], dst[0].y, dst[1].y, |
|
|
|
dst[2].y, dst[3].y); |
|
|
|
} |
|
|
|
struct transpose_int8_interleavedx4<8, int2> { |
|
|
|
static constexpr uint32_t interleaved = 8; |
|
|
|
using vec_type = int2; |
|
|
|
using Fragment = array_wrapper<int, interleaved>; |
|
|
|
MEGDNN_DEVICE __forceinline__ void operator()(const Fragment src, |
|
|
|
vec_type (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0].x, |
|
|
|
dst[1].x, dst[2].x, dst[3].x); |
|
|
|
transpose_int8_4x4_impl(src[4], src[5], src[6], src[7], dst[0].y, |
|
|
|
dst[1].y, dst[2].y, dst[3].y); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template <> |
|
|
|
MEGDNN_DEVICE __forceinline__ void transpose_int8_interleavedx4<16, int4>( |
|
|
|
const int src[16], int4 (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0].x, dst[1].x, |
|
|
|
dst[2].x, dst[3].x); |
|
|
|
transpose_int8_4x4_impl(src[4], src[5], src[6], src[7], dst[0].y, dst[1].y, |
|
|
|
dst[2].y, dst[3].y); |
|
|
|
transpose_int8_4x4_impl(src[8], src[9], src[10], src[11], dst[0].z, |
|
|
|
dst[1].z, dst[2].z, dst[3].z); |
|
|
|
transpose_int8_4x4_impl(src[12], src[13], src[14], src[15], dst[0].w, |
|
|
|
dst[1].w, dst[2].w, dst[3].w); |
|
|
|
} |
|
|
|
struct transpose_int8_interleavedx4<16, int4> { |
|
|
|
static constexpr uint32_t interleaved = 16; |
|
|
|
using vec_type = int4; |
|
|
|
using Fragment = array_wrapper<int, interleaved>; |
|
|
|
MEGDNN_DEVICE __forceinline__ void operator()(const Fragment src, |
|
|
|
vec_type (&dst)[4]) { |
|
|
|
transpose_int8_4x4_impl(src[0], src[1], src[2], src[3], dst[0].x, |
|
|
|
dst[1].x, dst[2].x, dst[3].x); |
|
|
|
transpose_int8_4x4_impl(src[4], src[5], src[6], src[7], dst[0].y, |
|
|
|
dst[1].y, dst[2].y, dst[3].y); |
|
|
|
transpose_int8_4x4_impl(src[8], src[9], src[10], src[11], dst[0].z, |
|
|
|
dst[1].z, dst[2].z, dst[3].z); |
|
|
|
transpose_int8_4x4_impl(src[12], src[13], src[14], src[15], dst[0].w, |
|
|
|
dst[1].w, dst[2].w, dst[3].w); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
} // namespace cuda |
|
|
|
} // namespace megdnn |
|
|
|