#ifndef GRAPH_BACKEND_DNNL_KERNELS_MQA_HPP
#define GRAPH_BACKEND_DNNL_KERNELS_MQA_HPP
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "graph/backend/dnnl/kernels/kernel_base.hpp"
#include "graph/backend/dnnl/kernels/mqa_decomp.hpp"
#include "graph/backend/dnnl/dnnl_partition_impl.hpp"
namespace dnnl {
namespace impl {
namespace graph {
namespace dnnl_impl {
template <bool quantized = false, memory::data_type dt = memory::data_type::f32>
struct mqa_base_t : public kernel_base_t {
private:
std::shared_ptr<kernel_base_t> kernel;
public:
status_t compile_impl(const dnnl_partition_impl_t *part,
const engine_t *g_engine,
const std::vector<logical_tensor_t> &inputs,
const std::vector<logical_tensor_t> &outputs) override {
const engine_kind_t ekind = g_engine->kind();
const bool enable_decomp
= ekind == engine_kind::cpu && enable_decomp_kernel();
status_t mqa_decomp_status = status::success;
if (enable_decomp) {
kernel = std::make_shared<mqa_decomp_kernel_t<quantized, dt>>();
mqa_decomp_status
= kernel->compile_impl(part, g_engine, inputs, outputs);
}
if (!enable_decomp || mqa_decomp_status != status::success) {
kernel = std::make_shared<larger_partition_kernel_t>();
return kernel->compile_impl(part, g_engine, inputs, outputs);
}
return mqa_decomp_status;
}
bool enable_decomp_kernel() {
#if DNNL_CPU_RUNTIME == DNNL_RUNTIME_OMP \
|| DNNL_CPU_RUNTIME == DNNL_RUNTIME_THREADPOOL
const int force_prim = graph::utils::getenv_int_internal(
"GRAPH_SDPA_FORCE_PRIMITIVE", 0);
return force_prim == 0;
#else
return false;
#endif
}
status_t execute_impl(const stream_t *g_stream,
const std::vector<tensor_t> &inputs,
const std::vector<tensor_t> &outputs) override {
return kernel->execute_impl(g_stream, inputs, outputs);
}
#ifdef DNNL_WITH_SYCL
status_t sycl_execute_impl(const stream_t *g_stream,
const std::vector<tensor_t> &inputs,
const std::vector<tensor_t> &outputs,
const std::vector<::sycl::event> &sycl_deps,
::sycl::event *sycl_event) override {
return kernel->sycl_execute_impl(
g_stream, inputs, outputs, sycl_deps, sycl_event);
}
#endif
#if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL
status_t ocl_execute_impl(const stream_t *g_stream,
const std::vector<tensor_t> &inputs,
const std::vector<tensor_t> &outputs,
const std::vector<cl_event> &deps, cl_event *event) override {
return kernel->ocl_execute_impl(g_stream, inputs, outputs, deps, event);
}
#endif
std::string str() const override { return kernel->str(); }
};
} } } }
#endif