#ifndef GPU_INTEL_SDPA_REF_HPP
#define GPU_INTEL_SDPA_REF_HPP
#include "gpu/intel/primitive.hpp"
#include "gpu/intel/primitive_conf.hpp"
#include "gpu/intel/sdpa/config.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
namespace sdpa {
struct ref_fwd_t : public primitive_t {
using primitive_t::primitive_t;
struct pd_t : public sdpa_fwd_pd_t {
using sdpa_fwd_pd_t::sdpa_fwd_pd_t;
DECLARE_COMMON_PD_T("ocl:ref:any", ref_fwd_t);
status_t init(impl::engine_t *engine) {
using namespace data_type;
using smask_t = primitive_attr_t::skip_mask_t;
bool enable_ref = gpu_utils::dev_getenv("enable_ref_sdpa", false);
VDISPATCH_SDPA(enable_ref, VERBOSE_SKIP_PRIMITIVE_IMPL);
VDISPATCH_SDPA(attr()->has_default_values(smask_t::scales),
VERBOSE_UNSUPPORTED_ATTR);
VDISPATCH_SDPA(utils::everyone_is(4, desc()->qry_md()->ndims,
desc()->key_md()->ndims,
desc()->val_md()->ndims, dst_md()->ndims),
VERBOSE_UNSUPPORTED_TAG);
if (with_attn_mask()) {
VDISPATCH_SDPA(desc()->attn_mask_md()->ndims == 4,
VERBOSE_UNSUPPORTED_TAG);
}
VDISPATCH_SDPA(set_default_formats(), VERBOSE_UNSUPPORTED_TAG);
return status::success;
}
};
status_t init(impl::engine_t *engine) override {
compute::kernel_ctx_t kernel_ctx;
kernel_ctx.set_data_type(pd()->dst_md()->data_type);
kernel_ctx.require_stateless_addressing(pd()->has_large_buffers());
int ndims = 4;
const memory_desc_wrapper qry_mdw(pd()->desc()->qry_md());
const memory_desc_wrapper key_mdw(pd()->desc()->key_md());
const memory_desc_wrapper val_mdw(pd()->desc()->val_md());
const memory_desc_wrapper dst_mdw(pd()->dst_md());
const memory_desc_wrapper msk_mdw(pd()->desc()->attn_mask_md());
using offset_t = decltype(offsets_t().src_off);
offset_t qry_off, key_off, val_off, dst_off, msk_off;
set_offsets(qry_mdw, qry_off);
set_offsets(key_mdw, key_off);
set_offsets(val_mdw, val_off);
set_offsets(dst_mdw, dst_off);
set_offsets(msk_mdw, msk_off);
def_offsets(qry_off, kernel_ctx, "QRY", ndims);
def_offsets(key_off, kernel_ctx, "KEY", ndims);
def_offsets(val_off, kernel_ctx, "VAL", ndims);
def_offsets(dst_off, kernel_ctx, "DST", ndims);
def_offsets(msk_off, kernel_ctx, "MSK", ndims);
kernel_ctx.define_int("NDIMS", ndims);
kernel_ctx.define_int("SIZE_K", pd()->desc()->keys());
kernel_ctx.define_int("INVERT_SCALE", pd()->desc()->invert_scale);
kernel_ctx.define_int("WITH_ATTN_SCALE", pd()->with_attn_scale());
kernel_ctx.define_int("WITH_ATTN_MASK", pd()->with_attn_mask());
def_data_type(kernel_ctx, pd()->desc()->qry_md()->data_type, "QRY");
def_data_type(kernel_ctx, pd()->desc()->key_md()->data_type, "KEY");
def_data_type(kernel_ctx, pd()->desc()->val_md()->data_type, "VAL");
def_data_type(kernel_ctx, pd()->dst_md()->data_type, "DST");
def_data_type(
kernel_ctx, pd()->desc()->attn_mask_md()->data_type, "MSK");
def_data_type(kernel_ctx, pd()->desc()->scale_md()->data_type, "SCALE");
CHECK(create_kernel(engine, &kernel_, "ref_sdpa", kernel_ctx));
if (!kernel_) return status::runtime_error;
return status::success;
}
status_t execute(const exec_ctx_t &ctx) const override {
return execute_ref(ctx);
}
private:
const pd_t *pd() const { return (const pd_t *)primitive_t::pd().get(); }
status_t execute_ref(const exec_ctx_t &ctx) const;
compute::kernel_t kernel_;
};
} } } } }
#endif