/*******************************************************************************
* Copyright 2023 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License")* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
#include "gpu/intel/include/dispatch.h"
#include "gpu/intel/include/math_utils.h"
#include "gpu/intel/include/types.h"
#include "gpu/intel/include/types_interop.h"
#define VEC_SUM_DEFINE(TYPE) \
__attribute__((overloadable)) float vec_sum(TYPE val) { \
return vec_sum(val.even + val.odd) }
__attribute__((overloadable)) float vec_sum(float val) {
return val}
VEC_SUM_DEFINE(float2)
VEC_SUM_DEFINE(float4)
VEC_SUM_DEFINE(float8)
__attribute__((intel_reqd_sub_group_size(SG_SIZE))) __kernel void
lnorm_reusable_vectorized(__global SRC_DATA_T *src, __global float *mean,
__global float *variance, dim_t reduce_size, __global DST_DATA_T *dst,
__global WEI_DATA_T *scale, __global WEI_DATA_T *shift, float eps,
__global float *src_scale, __global float *dst_scale, int greads,
float rrs, dispatch_gws_rt_params_t gws_params) {
src = (GWS_GET_BUFFER_POS(SRC, gws_params, src)) - get_sub_group_local_id()
FLT_ACC_DATA_T local_variance = 0.f FLT_ACC_DATA_T local_mean = 0.f if (CALCULATE_STATS) {
/// Read global memory and mean and variance
FLT_ACC_DATA_T sum = 0 unroll_for_by(N_UNROLL)(int sg_idx = 0 sg_idx += SG_STRIDE) {
VECT_FLOAT_T val
= CONVERT_VECT_FLOAT_T(AS_VECT_DATA_T(VECT_BLOCK_READ(
(const __global BLOCK_DATA_T *)(&src[sg_idx])))) sum += vec_sum(val) }
if (!SKIP_MEAN) local_mean = sub_group_reduce_add(sum) * rrs FLT_ACC_DATA_T sumsq = 0 unroll_for_by(N_UNROLL)(int i = 0 VECT_FLOAT_T val val = CONVERT_VECT_FLOAT_T(AS_VECT_DATA_T(VECT_BLOCK_READ((
const __global BLOCK_DATA_T *)(&src[i * SG_STRIDE]))))
- local_mean val *= val sumsq += vec_sum(val) }
local_variance = sub_group_reduce_add(sumsq) * rrs } else {
if (!SKIP_MEAN) {
mean = GWS_GET_BUFFER_POS(STAT, gws_params, mean) local_mean = *mean }
variance = GWS_GET_BUFFER_POS(STAT, gws_params, variance) local_variance = *variance }
if (USE_SCALE)
scale = GWS_GET_BUFFER_POS(SS, gws_params, scale)
- get_sub_group_local_id() + ((greads - 1) * SG_STRIDE) if (USE_SHIFT)
shift = GWS_GET_BUFFER_POS(SS, gws_params, shift)
- get_sub_group_local_id() + ((greads - 1) * SG_STRIDE)
/// Normalize layer
FLT_ACC_DATA_T sqrt_variance = rsqrt(local_variance + eps) __global DST_DATA_T *dst_vect = (GWS_GET_BUFFER_POS(DST, gws_params, dst))
- get_sub_group_local_id() + ((greads - 1) * SG_STRIDE)
float src_scale_val = src_scale ? *src_scale : 1.f float dst_scale_val = dst_scale ? native_recip(*dst_scale) : 1.f
unroll_for_by(N_UNROLL)(int i = greads - 1 VECT_FLOAT_T res
= CONVERT_VECT_FLOAT_T(AS_VECT_DATA_T(VECT_BLOCK_READ((
const __global BLOCK_DATA_T *)(&src[i * SG_STRIDE]))))
- local_mean res *= sqrt_variance if (USE_SCALE) res *= LOAD_VECT_WEI(scale) if (USE_SHIFT) res += LOAD_VECT_WEI(shift)
res *= src_scale_val res *= dst_scale_val
VECT_DST_BLOCK_WRITE(dst_vect, CONVERT_VECTOR_DST_DATA_T(res)) dst_vect -= SG_STRIDE if (USE_SCALE) scale -= SG_STRIDE if (USE_SHIFT) shift -= SG_STRIDE }
if (SAVE_STATS && get_sub_group_local_id() == 0) {
if (!SKIP_MEAN) {
mean = GWS_GET_BUFFER_POS(STAT, gws_params, mean) *mean = local_mean }
variance = GWS_GET_BUFFER_POS(STAT, gws_params, variance) *variance = local_variance }
}