#ifndef GPU_INTEL_RNN_GRID_HPP
#define GPU_INTEL_RNN_GRID_HPP
#include <stdio.h>
#include "common/c_types_map.hpp"
#include "common/primitive.hpp"
#include "common/primitive_desc_iterator.hpp"
#include "common/utils.hpp"
#include "gpu/gpu_resource.hpp"
#include "gpu/intel/primitive.hpp"
#include "gpu/intel/rnn/utils.hpp"
#define WS_NAN_FILLING 0
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
namespace rnn {
enum gemm_kind_t {
gemm_iter_fwd,
gemm_iter_fwd_2,
gemm_layer_fwd,
gemm_layer_fwd_src,
gemm_iter_bwd,
gemm_iter_bwd_2,
gemm_layer_bwd,
gemm_layer_bwd_src,
gemm_diff_wei_iter,
gemm_diff_wei_iter_2,
gemm_diff_wei_layer,
gemm_diff_wei_layer_src
};
template <prop_kind_t aprop>
struct simple_common_t : public primitive_t {
using primitive_t::primitive_t;
using class_name = simple_common_t<aprop>;
using elemwise_f = elemwise_sig((class_name::*));
using elemwise_gru_f = elemwise_sig_gru((class_name::*));
using elemwise_gru_lbr_f = elemwise_sig_gru_lbr((class_name::*));
using cell_execution_f = cell_execution_sig((class_name::*));
using grid_execution_f = grid_execution_sig((class_name::*));
using gemm_t = gemm_sig((class_name::*));
using base_pd_t =
typename impl::utils::conditional<aprop == prop_kind::forward,
fwd_pd_t, bwd_pd_t>::type;
struct pd_t : public base_pd_t {
using base_pd_t::base_pd_t;
pd_t(const pd_t &other) = default;
DECLARE_COMMON_PD_T("ocl:simple:any", class_name);
status_t init(impl::engine_t *engine);
status_t set_default_params();
ocl_conf_t ocl_conf = {};
offsets_t off = {};
conf_t conf = {};
data_type_t acc_data_t = data_type::undef;
data_type_t src_type = data_type::undef;
data_type_t weights_type = data_type::undef;
bool is_xe_hpc = false;
int max_eus_per_wg = 0;
std::shared_ptr<primitive_desc_t> gemm_iter_fwd_pd_;
std::shared_ptr<primitive_desc_t> gemm_iter_fwd_2_pd_;
std::shared_ptr<primitive_desc_t> gemm_layer_fwd_pd_;
std::shared_ptr<primitive_desc_t> gemm_layer_fwd_src_pd_;
std::shared_ptr<primitive_desc_t> gemm_iter_bwd_pd_;
std::shared_ptr<primitive_desc_t> gemm_iter_bwd_2_pd_;
std::shared_ptr<primitive_desc_t> gemm_layer_bwd_pd_;
std::shared_ptr<primitive_desc_t> gemm_layer_bwd_src_pd_;
std::shared_ptr<primitive_desc_t> gemm_diff_wei_layer_pd_;
std::shared_ptr<primitive_desc_t> gemm_diff_wei_layer_src_pd_;
std::shared_ptr<primitive_desc_t> gemm_diff_wei_iter_pd_;
std::shared_ptr<primitive_desc_t> gemm_diff_wei_iter_2_pd_;
private:
void init_scratchpad(dim_t workspace_size) {
using namespace memory_tracking::names;
auto scratchpad = this->scratchpad_registry().registrar();
scratchpad.book(key_rnn_space, workspace_size, 1,
OCL_BUFFER_ALIGNMENT, 4096);
utils::scratch_t::book(scratchpad, conf,
{
gemm_iter_fwd_pd_.get(),
gemm_iter_fwd_2_pd_.get(),
gemm_layer_fwd_pd_.get(),
gemm_layer_fwd_src_pd_.get(),
gemm_iter_bwd_pd_.get(),
gemm_iter_bwd_2_pd_.get(),
gemm_layer_bwd_pd_.get(),
gemm_layer_bwd_src_pd_.get(),
gemm_diff_wei_layer_pd_.get(),
gemm_diff_wei_layer_src_pd_.get(),
gemm_diff_wei_iter_pd_.get(),
gemm_diff_wei_iter_2_pd_.get(),
});
}
};
status_t init(impl::engine_t *engine) override;
status_t execute(const exec_ctx_t &ctx) const override {
return execute_(ctx);
}
protected:
status_t init_res_storage(
impl::engine_t *engine, gpu_resource_t *r) const override;
private:
status_t execute_(const exec_ctx_t &ctx) const;
const pd_t *pd() const { return (const pd_t *)primitive_t::pd().get(); }
compute::nd_range_t get_nd_range(std::vector<dim_t> gws) const {
int subgroup_size = pd()->ocl_conf.subgroup_size;
dim_t lws_max = (dim_t)pd()->max_eus_per_wg * subgroup_size;
std::vector<dim_t> lws;
lws.reserve(gws.size());
for (size_t i = 0; i < gws.size(); i++) {
dim_t l_dim = 2 * gws[i] <= lws_max
? impl::utils::rnd_up_pow2(gws[i])
: lws_max;
if (i == 0 && l_dim < subgroup_size) l_dim = subgroup_size;
lws.emplace_back(l_dim);
gws[i] = impl::utils::rnd_up(gws[i], l_dim);
lws_max = lws_max / l_dim;
}
return compute::nd_range_t(gws, {lws});
}
grid_execution_sig(linear_execution);
cell_execution_sig(cell_execution);
cell_execution_sig(cell_execution_gru);
cell_execution_sig(cell_execution_gru_lbr);
elemwise_sig(rnn_elemwise);
elemwise_sig(lstm_elemwise);
elemwise_sig(lstm_elemwise_u8s8);
elemwise_sig_gru(gru_elemwise);
elemwise_sig_gru_lbr(gru_lbr_elemwise);
gemm_sig(gemm_primitive);
float (*activation_func)(float dd, float s, float alpha, float cliping)
= nullptr;
status_t bias_prepare(const exec_ctx_t &ctx,
intel::stream_t *compute_stream, dim_t n_layer, dim_t n_dir,
dim_t n_bias, dim_t n_gates, dim_t dhc,
const memory_storage_t &ws_bias, const memory_storage_t &scales,
const memory_storage_t &wei_layer, const memory_storage_t &wei_iter,
const memory_storage_t &bias) const;
status_t copy_init_layer(const exec_ctx_t &ctx,
intel::stream_t *compute_stream, bool lr, bool rl, dim_t n_iter,
dim_t batch, dim_t slc, dim_t dhc, dim_t n_layer, dim_t n_dir,
dim_t n_states, dim_t states_ws_ld, dim_t scratch_diff_states_ld,
const memory_storage_t &ws_states,
const memory_storage_t *scratch_diff_states,
const memory_storage_t &input,
const memory_storage_t &diff_dst_layer) const;
status_t copy_init_iter(const exec_ctx_t &ctx,
intel::stream_t *compute_stream, dim_t n_layer, dim_t n_dir,
dim_t batch, dim_t sic, dim_t dhc, dim_t n_iter, dim_t n_states,
dim_t states_ws_ld, dim_t scratch_diff_states_ld,
const utils::workspace_t &ws,
const memory_storage_t *scratch_diff_states,
const memory_storage_t &firstit_states,
const memory_storage_t &firstit_c_states,
const memory_storage_t &diff_dst_iter,
const memory_storage_t &diff_dst_iter_c, const float shift,
const float scale, const bool quantize) const;
status_t copy_res_layer(const exec_ctx_t &ctx,
intel::stream_t *compute_stream, bool lr, bool rl, dim_t n_iter,
dim_t batch, dim_t slc, dim_t dhc, dim_t n_layer, dim_t n_dir,
dim_t n_states, dim_t states_ws_ld, dim_t scratch_diff_states_ld,
const memory_storage_t *scratch_diff_states,
const memory_storage_t &dst_last_layer,
const memory_storage_t &diff_src_layer,
const memory_storage_t &ws_states, const float shift,
const float scale, const bool dequantize) const;
status_t copy_res_iter(const exec_ctx_t &ctx,
intel::stream_t *compute_stream, dim_t n_layer, dim_t n_dir,
dim_t batch, dim_t sic, dim_t dhc, dim_t n_iter, dim_t n_states,
dim_t states_ws_ld, dim_t scratch_diff_states_ld,
const memory_storage_t *scratch_diff_states,
const memory_storage_t &dst_last_iter,
const memory_storage_t &dst_last_iter_c,
const memory_storage_t &diff_src_iter,
const memory_storage_t &diff_src_iter_c,
const utils::workspace_t &ws, const float shift, const float scale,
const bool dequantize) const;
std::vector<compute::kernel_t> kernels_;
std::shared_ptr<impl::primitive_t> gemm_layer_fwd_;
std::shared_ptr<impl::primitive_t> gemm_layer_fwd_src_;
std::shared_ptr<impl::primitive_t> gemm_iter_fwd_;
std::shared_ptr<impl::primitive_t> gemm_iter_fwd_2_;
std::shared_ptr<impl::primitive_t> gemm_layer_bwd_;
std::shared_ptr<impl::primitive_t> gemm_layer_bwd_src_;
std::shared_ptr<impl::primitive_t> gemm_iter_bwd_;
std::shared_ptr<impl::primitive_t> gemm_iter_bwd_2_;
std::shared_ptr<impl::primitive_t> gemm_diff_wei_layer_;
std::shared_ptr<impl::primitive_t> gemm_diff_wei_layer_src_;
std::shared_ptr<impl::primitive_t> gemm_diff_wei_iter_;
std::shared_ptr<impl::primitive_t> gemm_diff_wei_iter_2_;
dim_t ws_gates_offset_ = 0;
dim_t ws_states_offset_ = 0;
dim_t ws_c_states_offset_ = 0;
dim_t ws_grid_comp_offset_ = 0;
dim_t ws_bias_offset_ = 0;
std::vector<dim_t> wei_layer_offsets;
std::vector<dim_t> wei_iter_offsets;
grid_execution_f grid_computation = nullptr;
cell_execution_f cell_func = nullptr;
elemwise_f elemwise_common = nullptr;
elemwise_gru_f elemwise_gru = nullptr;
elemwise_gru_lbr_f elemwise_gru_lbr = nullptr;
enum { SCALES_ = 0, TM_SCALES_ = 1 };
};
using simple_fwd_t = simple_common_t<prop_kind::forward>;
using simple_bwd_t = simple_common_t<prop_kind::backward>;
} } } } } #endif