@@ -915,6 +915,51 @@ __ESIMD_API void lsc_block_store(T *p, __ESIMD_NS::simd<T, NElts> vals) {
915
915
vals.data ());
916
916
}
917
917
918
+ namespace detail {
919
+ // Compile-time checks for lsc_load2d/store2d restrictions.
920
+ template <typename T, int BlockWidth, int BlockHeight, int NBlocks,
921
+ bool Transposed, bool Transformed, bool IsStore = false >
922
+ constexpr void check_lsc_block_2d_restrictions () {
923
+ constexpr int GRFByteSize = BlockWidth * BlockHeight * NBlocks * sizeof (T);
924
+ static_assert (!IsStore || GRFByteSize <= 512 ,
925
+ " 2D store supports 512 bytes max" );
926
+ static_assert (IsStore || GRFByteSize <= 2048 ,
927
+ " 2D load supports 2048 bytes max" );
928
+ static_assert (!Transposed || !Transformed,
929
+ " Transposed and transformed is not supported" );
930
+ if constexpr (Transposed) {
931
+ static_assert (NBlocks == 1 , " Transposed expected to be 1 block only" );
932
+ static_assert (sizeof (T) == 4 || sizeof (T) == 8 ,
933
+ " Transposed load is supported only for data size u32 or u64" );
934
+ static_assert (sizeof (T) == 64 ? BlockHeight == 8
935
+ : BlockHeight >= 1 && BlockHeight <= 32 ,
936
+ " Unsupported block height" );
937
+ static_assert (sizeof (T) == 64 ? __ESIMD_DNS::isPowerOf2 (BlockWidth, 4 )
938
+ : BlockWidth >= 1 && BlockWidth <= 8 ,
939
+ " Unsupported block width" );
940
+ } else if constexpr (Transformed) {
941
+ static_assert (sizeof (T) == 1 || sizeof (T) == 2 ,
942
+ " VNNI transform is supported only for data size u8 or u16" );
943
+ static_assert (__ESIMD_DNS::isPowerOf2 (NBlocks, 4 ),
944
+ " Unsupported number of blocks" );
945
+ static_assert (BlockHeight * sizeof (T) >= 4 && BlockHeight <= 32 ,
946
+ " Unsupported block height" );
947
+ static_assert (BlockWidth * sizeof (T) >= 4 &&
948
+ BlockWidth * NBlocks * sizeof (T) <= 64 ,
949
+ " Unsupported block width" );
950
+ } else {
951
+ static_assert (
952
+ __ESIMD_DNS::isPowerOf2 (NBlocks, sizeof (T) == 1 ? 4 : 8 / sizeof (T)),
953
+ " Unsupported number of blocks" );
954
+ static_assert (BlockHeight >= 1 && BlockHeight <= 32 ,
955
+ " Unsupported block height" );
956
+ static_assert (BlockWidth * sizeof (T) >= 4 &&
957
+ BlockWidth * NBlocks * sizeof (T) <= 64 ,
958
+ " Unsupported block width" );
959
+ }
960
+ }
961
+ } // namespace detail
962
+
918
963
// / 2D USM pointer block load.
919
964
// / Supported platforms: PVC
920
965
// / VISA instruction: lsc_load_block2d.ugm
@@ -953,11 +998,9 @@ template <typename T, int BlockWidth, int BlockHeight = 1, int NBlocks = 1,
953
998
__ESIMD_API __ESIMD_NS::simd<T, N>
954
999
lsc_load2d (const T *Ptr, unsigned SurfaceWidth, unsigned SurfaceHeight,
955
1000
unsigned SurfacePitch, int X, int Y) {
956
- static_assert (!Transposed || !Transformed,
957
- " Transposed and transformed is not supported" );
958
- static_assert (!Transposed || (Transposed && NBlocks == 1 ),
959
- " Transposed expected to be 1 block only" );
960
1001
detail::check_lsc_cache_hint<detail::lsc_action::load, L1H, L3H>();
1002
+ detail::check_lsc_block_2d_restrictions<T, BlockWidth, BlockHeight, NBlocks,
1003
+ Transposed, Transformed>();
961
1004
constexpr int ElemsPerDword = 4 / sizeof (T);
962
1005
constexpr int GRFRowSize = Transposed ? BlockHeight : BlockWidth;
963
1006
constexpr int GRFRowPitch = __ESIMD_DNS::getNextPowerOf2<GRFRowSize>();
@@ -971,12 +1014,6 @@ lsc_load2d(const T *Ptr, unsigned SurfaceWidth, unsigned SurfaceHeight,
971
1014
" These parameters require unpadding. It is not implemented yet" );
972
1015
constexpr lsc_data_size DS =
973
1016
detail::finalize_data_size<T, lsc_data_size::default_size>();
974
- static_assert (!Transformed ||
975
- (DS == lsc_data_size::u8 || DS == lsc_data_size::u16 ),
976
- " VNNI transform is supported only for data size U8 or U16" );
977
- static_assert (!Transposed ||
978
- (DS == lsc_data_size::u32 || DS == lsc_data_size::u64 ),
979
- " Transposed load is supported only for data size u32 or u64" );
980
1017
__ESIMD_NS::simd_mask<N> pred = 1 ;
981
1018
uintptr_t surf_addr = reinterpret_cast <uintptr_t >(Ptr);
982
1019
constexpr detail::lsc_data_order _Transposed =
@@ -1017,6 +1054,8 @@ __ESIMD_API void lsc_prefetch2d(const T *Ptr, unsigned SurfaceWidth,
1017
1054
unsigned SurfaceHeight, unsigned SurfacePitch,
1018
1055
int X, int Y) {
1019
1056
detail::check_lsc_cache_hint<detail::lsc_action::prefetch, L1H, L3H>();
1057
+ detail::check_lsc_block_2d_restrictions<T, BlockWidth, BlockHeight, NBlocks,
1058
+ false , false >();
1020
1059
constexpr lsc_data_size DS =
1021
1060
detail::finalize_data_size<T, lsc_data_size::default_size>();
1022
1061
__ESIMD_NS::simd_mask<N> pred = 1 ;
@@ -1060,6 +1099,8 @@ __ESIMD_API void lsc_store2d(T *Ptr, unsigned SurfaceWidth,
1060
1099
unsigned SurfaceHeight, unsigned SurfacePitch,
1061
1100
int X, int Y, __ESIMD_NS::simd<T, N> Vals) {
1062
1101
detail::check_lsc_cache_hint<detail::lsc_action::store, L1H, L3H>();
1102
+ detail::check_lsc_block_2d_restrictions<T, BlockWidth, BlockHeight, 1 , false ,
1103
+ false , true /* IsStore*/ >();
1063
1104
constexpr lsc_data_size DS =
1064
1105
detail::finalize_data_size<T, lsc_data_size::default_size>();
1065
1106
__ESIMD_NS::simd_mask<N> pred = 1 ;
0 commit comments