#ifndef GPU_INTEL_JIT_IR_SLM_REDUCE_BUILDER_HPP
#define GPU_INTEL_JIT_IR_SLM_REDUCE_BUILDER_HPP
#include "gpu/intel/jit/ir/hw.hpp"
#include "gpu/intel/jit/ir/legacy.hpp"
#include "gpu/intel/jit/ir/tensor.hpp"
#include "gpu/intel/jit/pass/alloc.hpp"
#include "ngen.hpp"
#include <vector>
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
namespace jit {
class slm_reduce_builder_t {
public:
slm_reduce_builder_t() = default;
slm_reduce_builder_t(ir_context_t &ir_ctx, const grid_info_t &tg_grid,
const expr_t ®_buf, const layout_t ®_layout,
const tile_coord_t &thr_tile_coord, dim_idx_t dim = 2);
bool is_empty() const { return reg_buf_.is_empty(); }
const layout_t ®_layout() const { return reg_layout_; }
const tile_coord_t &thr_tile_coord() const { return thr_tile_coord_; }
const stmt_t &store_stmt() const { return store_stmt_; }
const stmt_t &load_stmt() const { return load_stmt_; }
const std::vector<stmt_t> &allocs() const { return allocs_; }
const expr_t &reduce_cond() const { return reduce_cond_; }
stmt_t stmt() const {
stmt_t ret;
ret = ret.append(funcs::barrier());
ret = ret.append(store_stmt_);
ret = ret.append(funcs::barrier());
ret = ret.append(load_stmt_);
ret = inject_alloc_stmts(ret, allocs_);
return ret;
}
private:
void build();
uint32_t reduction_mask() const {
uint32_t mask = 0xFFFFFFFF;
for (dim_idx_t i = 0; i < tg_ndims_; i++) {
auto k_dim_idx = reg_layout_.ndims() + i;
mask &= ~(1u << k_dim_idx);
}
return mask;
}
ir_context_t *ir_ctx_ = nullptr;
grid_info_t tg_grid_;
expr_t reg_buf_;
layout_t reg_layout_;
tile_coord_t thr_tile_coord_;
dim_idx_t dim_ = -1;
expr_t tmp_reg_buf_;
int tmp_reg_buf_size_ = 0;
expr_t slm_buf_;
int slm_buf_size_ = 0;
dim_idx_t tg_ndims_ = 0;
stmt_t store_stmt_;
stmt_t load_stmt_;
expr_t reduce_cond_;
std::vector<stmt_t> allocs_;
};
} } } } }
#endif