#ifndef GPU_GENERIC_SYCL_RNN_REF_RNN_HPP
#define GPU_GENERIC_SYCL_RNN_REF_RNN_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/generic/sycl/rnn/rnn_kernels.hpp"
#include "gpu/generic/sycl/rnn/rnn_utils.hpp"
#include "gpu/generic/sycl/sycl_gpu_primitive.hpp"
#include "gpu/gpu_rnn_pd.hpp"
#include "gpu/generic/sycl/sycl_gpu_kernel.hpp"
#include "gpu/generic/sycl/sycl_gpu_primitive.hpp"
#include "gpu/generic/sycl/sycl_primitive_conf.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace generic {
namespace sycl {
enum matmul_kind_t {
matmul_iter_fwd,
matmul_layer_fwd,
matmul_iter_bwd,
matmul_layer_bwd,
matmul_diff_wei_iter,
matmul_diff_wei_layer
};
struct cell_ctx_t {
impl::engine_t *engine;
const exec_ctx_t &ctx;
dim_t dir;
dim_t lay;
dim_t iter;
const rnn_utils::user_data_t &user_data;
const rnn_utils::workspace_t &workspace;
const rnn_utils::scratch_t &scratch;
rnn_utils::conf_t rnn;
};
struct grid_ctx_t {
impl::engine_t *engine;
const exec_ctx_t &ctx;
const rnn_utils::user_data_t &user_data;
const rnn_utils::workspace_t &workspace;
const rnn_utils::scratch_t &scratch;
rnn_utils::conf_t rnn;
};
struct cpy_ctx_t {
memory_storage_t *cpy_in_lay;
memory_storage_t *cpy_out_lay;
memory_storage_t *cpy_in_iter;
memory_storage_t *cpy_out_iter;
};
struct ref_rnn_common_base_t : public primitive_t {
using primitive_t::primitive_t;
status_t init(impl::engine_t *engine) override {
CHECK(init_(engine));
return status::success;
}
status_t execute(const exec_ctx_t &ctx) const override {
CHECK(execute_(ctx));
return status::success;
}
protected:
bool create_nested_matmul(impl::engine_t *engine,
const std::shared_ptr<primitive_desc_t> &prim_desc,
std::shared_ptr<impl::primitive_t> &prim);
virtual status_t init_(impl::engine_t *engine) = 0;
void debug_print(const rnn_utils::conf_t &rnn, dim_t slc, dim_t sic,
bool with_bias, bool with_dst_iter) const;
void get_user_data(const exec_ctx_t &ctx, rnn_utils::user_data_t &user_data,
cpy_ctx_t &cpy_ctx, bool is_fwd, const rnn_pd_t *pd) const;
virtual status_t execute_(const exec_ctx_t &ctx) const = 0;
virtual status_t linear_execution(const grid_ctx_t &grid_struct) = 0;
virtual status_t cell_execution(const cell_ctx_t &cell_struct) = 0;
virtual status_t matmul_primitive(impl::engine_t *engine,
const exec_ctx_t &ctx, std::unique_ptr<memory_storage_t> &a,
std::unique_ptr<memory_storage_t> &b,
std::unique_ptr<memory_storage_t> &c,
matmul_kind_t matmul_kind) const
= 0;
status_t launch_copy(bool fwd, const exec_ctx_t &ctx,
const kernel_t &cpy_kernel, const sycl_rnn_copy_conf_t ©_conf,
::sycl::range<3> global_range, ::sycl::range<3> local_range,
const memory_storage_t &input,
const memory_storage_t &output) const;
status_t do_copy(bool fwd, const exec_ctx_t &ctx, size_t batch_range,
size_t lay_iter_range, size_t channel_range,
const sycl_rnn_copy_conf_t ©_conf, const kernel_t &cpy_kernel,
const memory_storage_t &input,
const memory_storage_t &output) const;
virtual status_t copy_init_layer(const exec_ctx_t &ctx, dim_t batch,
dim_t dhc, dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer,
dim_t n_dir, dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const
= 0;
virtual status_t copy_init_iter(const exec_ctx_t &ctx, dim_t batch,
dim_t dhc, dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer,
dim_t n_dir, dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const
= 0;
virtual status_t copy_res_layer(const exec_ctx_t &ctx, dim_t batch,
dim_t dhc, dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer,
dim_t n_dir, dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const
= 0;
virtual status_t copy_res_iter(const exec_ctx_t &ctx, dim_t batch,
dim_t dhc, dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer,
dim_t n_dir, dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const
= 0;
status_t execution_loop(const grid_ctx_t &grid_struct);
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;
std::function<status_t(const cell_ctx_t &)> cell_func;
std::function<status_t(const grid_ctx_t &)> grid_func;
};
struct ref_rnn_fwd_t : ref_rnn_common_base_t {
using ref_rnn_common_base_t::ref_rnn_common_base_t;
using base_pd_t = gpu_rnn_fwd_pd_t;
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("ref:any", ref_rnn_fwd_t);
status_t init(impl::engine_t *engine);
status_t set_default_params();
rnn_utils::conf_t rnn_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;
std::shared_ptr<primitive_desc_t> vanilla_cell_act_pd_;
std::shared_ptr<primitive_desc_t> matmul_iter_fwd_pd_;
std::shared_ptr<primitive_desc_t> matmul_layer_fwd_pd_;
sycl_rnn_copy_conf_t copy_init_layer_conf_;
sycl_rnn_copy_conf_t copy_init_iter_conf_;
sycl_rnn_copy_conf_t copy_res_layer_conf_;
sycl_rnn_copy_conf_t copy_res_iter_conf_;
sycl_rnn_bias_fwd_conf_t sycl_rnn_bias_fwd_conf_t_;
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);
rnn_utils::scratch_t::book_fwd(scratchpad, rnn_conf,
{matmul_iter_fwd_pd_.get(), matmul_layer_fwd_pd_.get()});
}
};
protected:
const pd_t *pd() const { return (const pd_t *)primitive_t::pd().get(); }
status_t init_(impl::engine_t *engine) override;
status_t execute_(const exec_ctx_t &ctx) const override;
status_t linear_execution(const grid_ctx_t &grid_struct) override;
status_t cell_execution(const cell_ctx_t &cell_struct) override;
status_t matmul_primitive(impl::engine_t *engine, const exec_ctx_t &ctx,
std::unique_ptr<memory_storage_t> &a,
std::unique_ptr<memory_storage_t> &b,
std::unique_ptr<memory_storage_t> &c,
matmul_kind_t matmul_kind) const override;
status_t copy_init_layer(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_init_iter(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_res_layer(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_res_iter(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t rnn_bias(const exec_ctx_t &ctx, dim_t batch, dim_t dhc, dim_t iter,
dim_t lay, dim_t dir, const rnn_utils::workspace_t &ws,
const rnn_utils::scratch_t &scratch,
const rnn_utils ::user_data_t &user_data) const;
std::shared_ptr<impl::primitive_t> matmul_layer_fwd_;
std::shared_ptr<impl::primitive_t> matmul_iter_fwd_;
kernel_t copy_fwd_kernel_;
kernel_t bias_fwd_kernel_;
};
struct ref_rnn_bwd_t : ref_rnn_common_base_t {
using ref_rnn_common_base_t::ref_rnn_common_base_t;
using base_pd_t = gpu_rnn_bwd_pd_t;
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("ref:any", ref_rnn_bwd_t);
status_t init(impl::engine_t *engine);
status_t set_default_params();
rnn_utils::conf_t rnn_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;
std::shared_ptr<primitive_desc_t> vanilla_cell_act_pd_;
std::shared_ptr<primitive_desc_t> matmul_iter_bwd_pd_;
std::shared_ptr<primitive_desc_t> matmul_layer_bwd_pd_;
std::shared_ptr<primitive_desc_t> matmul_diff_wei_iter_pd_;
std::shared_ptr<primitive_desc_t> matmul_diff_wei_layer_pd_;
sycl_rnn_copy_conf_t copy_init_layer_conf_;
sycl_rnn_copy_conf_t copy_init_iter_conf_;
sycl_rnn_copy_conf_t copy_res_layer_conf_;
sycl_rnn_copy_conf_t copy_res_iter_conf_;
sycl_rnn_bias_bwd_conf_t sycl_rnn_bias_bwd_conf_t_;
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);
rnn_utils::scratch_t::book_bwd(scratchpad, rnn_conf,
{matmul_iter_bwd_pd_.get(), matmul_layer_bwd_pd_.get(),
matmul_diff_wei_iter_pd_.get(),
matmul_diff_wei_layer_pd_.get()});
}
};
protected:
const pd_t *pd() const { return (const pd_t *)primitive_t::pd().get(); }
status_t init_(impl::engine_t *engine) override;
status_t execute_(const exec_ctx_t &ctx) const override;
status_t linear_execution(const grid_ctx_t &grid_struct) override;
status_t cell_execution(const cell_ctx_t &cell_struct) override;
status_t matmul_primitive(impl::engine_t *engine, const exec_ctx_t &ctx,
std::unique_ptr<memory_storage_t> &a,
std::unique_ptr<memory_storage_t> &b,
std::unique_ptr<memory_storage_t> &c,
matmul_kind_t matmul_kind) const override;
status_t copy_init_layer(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_init_iter(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_res_layer(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t copy_res_iter(const exec_ctx_t &ctx, dim_t batch, dim_t dhc,
dim_t sic, dim_t slc, dim_t n_iter, dim_t n_layer, dim_t n_dir,
dim_t states_ws_ld, const memory_storage_t &input,
const memory_storage_t &output) const override;
status_t rnn_bias(const exec_ctx_t &ctx, dim_t batch, dim_t dhc, dim_t iter,
dim_t lay, dim_t dir, dim_t n_layer,
const std::unique_ptr<dnnl::impl::memory_storage_t>
&diff_states_layer,
const std::unique_ptr<dnnl::impl::memory_storage_t> &diff_cell_iter,
const rnn_utils ::user_data_t &user_data,
const std::unique_ptr<dnnl::impl::memory_storage_t> &scratch_gate,
const std::unique_ptr<dnnl::impl::memory_storage_t> &diff_gates)
const;
std::shared_ptr<impl::primitive_t> matmul_layer_bwd_;
std::shared_ptr<impl::primitive_t> matmul_iter_bwd_;
std::shared_ptr<impl::primitive_t> matmul_diff_wei_layer_;
std::shared_ptr<impl::primitive_t> matmul_diff_wei_iter_;
kernel_t copy_bwd_kernel_;
kernel_t bias_bwd_kernel_;
};
} } } } } #endif