#ifndef GPU_INTEL_COMPUTE_DISPATCH_HPP
#define GPU_INTEL_COMPUTE_DISPATCH_HPP
#include <cassert>
#include <string>
#include "common/c_types_map.hpp"
#include "common/utils.hpp"
#include "gpu/intel/compute/device_info.hpp"
#include "gpu/intel/compute/kernel_ctx.hpp"
#include "gpu/intel/compute/utils.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
class engine_t;
namespace compute {
range_t get_optimal_lws(range_t &gws, const dim_idx_t mapped_vec_dim_idx,
const gpu_arch_t gpu_arch);
class dispatch_t {
public:
static constexpr int min_nesting_level = -1;
static constexpr dim_idx_t dim_not_found = -1;
dispatch_t(const intel::engine_t *engine = nullptr,
const memory_desc_t *md = nullptr);
nd_range_t nd_range() const {
assert(generate_called && "generate() must be called.");
return nd_range_;
}
std::string str() const;
void define_dim(const std::string &name, dim_idx_t md_hint_idx, dim_t size,
dim_t block = 1) {
define_dim_with_md_hint(name, md_hint_idx, size, block);
}
void define_dim(const std::string &name, dim_t size) {
define_dim_with_nesting_level(name, min_nesting_level, size);
}
void define_dim_with_nesting_level(const std::string &name,
int nesting_level, dim_t size, dim_t block = 1);
status_t vectorize_dim(const std::string &name, int vector_size);
void def_kernel_macros(kernel_ctx_t &kernel_ctx) const;
void set_kernel_attr_suffix(const std::string &suffix) {
attr_suffix_ = suffix;
}
void generate(bool generate_lws = true);
void generate_override(
const range_t &grange, const range_t &lrange = range_t());
void set_lws(const range_t &lrange);
struct dim_info_t {
std::string name;
dim_t size;
dim_t block;
int nesting_level;
int vector_size;
int gws_index;
};
protected:
void define_dim_with_md_hint(const std::string &name,
dim_idx_t md_hint_index, dim_t size, dim_t block = 1);
dim_idx_t find_vectorized_dim() const {
dim_idx_t vec_dim_idx = dim_not_found;
for (dim_idx_t i = 0; i < ndims_; ++i) {
if (dims_[i].vector_size != 1) {
assert(vec_dim_idx == dim_not_found);
assert(dims_[i].block > 0);
vec_dim_idx = i;
}
}
return vec_dim_idx;
}
dim_t get_gws_stride(int idx) const {
dim_t s = 1;
for (int i = 0; i < idx; ++i) {
if (dims_[i].gws_index == dims_[idx].gws_index) {
s *= utils::div_up(dims_[i].size, dims_[i].block);
}
}
return s;
}
const engine_t *engine_;
dim_idx_t md_ndims_ = 0;
int md_nesting_levels_[DNNL_MAX_NDIMS];
dim_idx_t ndims_ = 0;
dim_info_t dims_[DNNL_MAX_NDIMS];
std::string attr_suffix_ = "DEFAULT";
nd_range_t nd_range_;
bool generate_called = false;
};
} } } } }
#endif