#ifndef GPU_INTEL_LNORM_REUSABLE_VECTORIZED_HPP
#define GPU_INTEL_LNORM_REUSABLE_VECTORIZED_HPP
#include "common/c_types_map.hpp"
#include "common/layer_normalization_pd.hpp"
#include "common/serialization.hpp"
#include "common/utils.hpp"
#include "gpu/gpu_layer_normalization_pd.hpp"
#include "gpu/intel/compute/dispatch_reusable.hpp"
#include "gpu/intel/compute/kernel_ctx.hpp"
#include "gpu/intel/lnorm/config.hpp"
#include "gpu/intel/primitive.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
namespace lnorm {
struct reusable_vectorized_params_t
: trivially_serializable_t<reusable_vectorized_params_t> {
const std::vector<const char *> &get_kernel_names() const {
static const std::vector<const char *> kernel_names
= {"lnorm_reusable_vectorized"};
return kernel_names;
}
status_t create_generator(const intel::engine_t &engine,
compute::kernel_bundle_t &bundle) const {
auto status = engine.create_kernel_bundle(
bundle, get_kernel_names(), get_kernel_ctx());
return status;
}
compute::kernel_ctx_t get_kernel_ctx() const;
compute::dispatch_compile_params_t gws_params;
int sg_size;
int vector_size;
int unroll;
data_type_t input_dt = data_type::undef;
data_type_t output_dt = data_type::undef;
data_type_t ss_dt = data_type::undef;
bool use_scale = false;
bool use_shift = false;
bool skip_mean = false;
bool calculate_stats = false;
bool save_stats = false;
bool require_stateless_addressing = true;
uint8_t padding[2] = {false};
};
struct reusable_vectorized_runtime_params_t {
compute::dispatch_runtime_params_t gws_params;
};
struct reusable_vectorized_fwd_t : public primitive_t {
using primitive_t::primitive_t;
struct pd_t : public fwd_pd_t {
using fwd_pd_t::fwd_pd_t;
DECLARE_COMMON_PD_T(
"ocl:reusable:vectorized", reusable_vectorized_fwd_t);
status_t init(impl::engine_t *engine) {
using namespace data_type;
auto *intel_engine = utils::downcast<intel::engine_t *>(engine);
data_type_t src_dt = src_md()->data_type;
data_type_t dst_dt = dst_md()->data_type;
const bool uses_f16 = utils::one_of(f16, src_dt, dst_dt);
const bool uses_f64 = utils::one_of(f64, src_dt, dst_dt);
if (uses_f64) return status::unimplemented;
const bool f16_ok = IMPLICATION(uses_f16,
intel_engine->mayiuse(compute::device_ext_t::khr_fp16));
const bool f64_ok = IMPLICATION(uses_f64,
intel_engine->mayiuse(compute::device_ext_t::khr_fp64));
VDISPATCH_LNORM(is_fwd(), VERBOSE_BAD_PROPKIND);
VDISPATCH_LNORM(f16_ok, VERBOSE_UNSUPPORTED_DEVICE_FEATURE, "fp16");
VDISPATCH_LNORM(f64_ok, VERBOSE_UNSUPPORTED_DEVICE_FEATURE, "fp64");
VDISPATCH_LNORM(check_scale_shift_data_type({f32, bf16, f16}),
VERBOSE_UNSUPPORTED_DT);
using skip_mask_t = primitive_attr_t::skip_mask_t;
VDISPATCH_LNORM(attr()->has_default_values(skip_mask_t::scales),
VERBOSE_UNSUPPORTED_ATTR);
VDISPATCH_LNORM(
set_default_formats_common(), VERBOSE_UNSUPPORTED_TAG);
CHECK(init_conf(engine));
return status::success;
}
status_t init_conf(impl::engine_t *engine);
reusable_vectorized_params_t conf;
reusable_vectorized_runtime_params_t rt_conf;
};
status_t init(impl::engine_t *engine) override {
if (pd()->has_zero_dim_memory()) return status::success;
return create_kernel(engine, calculate_lnorm_kernel_,
pd()->conf.get_kernel_names()[0], pd()->conf);
}
status_t execute(const exec_ctx_t &ctx) const override {
return execute_forward(ctx);
}
private:
status_t execute_forward(const exec_ctx_t &ctx) const;
const pd_t *pd() const { return (const pd_t *)primitive_t::pd().get(); }
compute::kernel_t calculate_lnorm_kernel_;
};
} } } } }
#endif