/*******************************************************************************
* Copyright 2024 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/post_ops.h"
#include "gpu/intel/include/types.h"
#include "gpu/intel/sdpa/utils.h"
__kernel void ref_sdpa(const __global QRY_DATA_T *Q,
const __global KEY_DATA_T *K, const __global VAL_DATA_T *V,
__global DST_DATA_T *dst, const __global SCALE_DATA_T *scale_ptr,
const __global MSK_DATA_T *mask, long nv, long nd) {
long q = get_global_id(0) long b0 = get_global_id(1) long b1 = get_global_id(2)
float s[SIZE_K]
// Multiply (row of Q)*K
for (long k = 0 float acc = 0 for (long h = 0 long qry_off = QRY_OFF(b1 % QRY_D0, b0 % QRY_D1, q, h) long key_off = KEY_OFF(b1 % KEY_D0, b0 % KEY_D1, h, k)
acc += convert_float(Q[qry_off]) * convert_float(K[key_off]) }
s[k] = acc }
// Scale + shift + softmax
float s_sum = 0
#if WITH_ATTN_SCALE
SCALE_DATA_T scale = *scale_ptr#if INVERT_SCALE
scale = 1.f / scale#endif
for (long k = 0 s[k] *= scale#endif
#if WITH_ATTN_MASK
long msk_off = MSK_OFF(b1 % MSK_D0, b0 % MSK_D1, q, k) s[k] += convert_float(mask[msk_off])#endif
s[k] = exp(s[k]) s_sum += s[k] }
for (long k = 0 s[k] /= s_sum
// Multiply (row of S)*V
for (long v = 0 float acc = 0 for (long k = 0 long val_off = VAL_OFF(b1 % VAL_D0, b0 % VAL_D1, k, v) acc += convert_float(V[val_off]) * s[k] }
long dst_off = DST_OFF(b1 % DST_D0, b0 % DST_D1, 0, q, v) dst[dst_off] = TO_DST(acc) }
}