#ifndef GEMMSTONE_INCLUDE_GEMMSTONE_DSL_HW_HPP
#define GEMMSTONE_INCLUDE_GEMMSTONE_DSL_HW_HPP
#include <cstddef>
#include <cstdint>
#include <string>
#include "gemmstone/config.hpp"
#include "internal/utils.hpp"
namespace ngen {
enum class Core;
using HW = Core;
enum class ProductFamily : int;
struct Product;
}
GEMMSTONE_NAMESPACE_START
namespace dsl {
namespace hw {
enum class attr_t {
none = 0,
large_grf = 1,
systolic = 2,
atomic_fp64 = 4,
efficient_64bit = 8
};
constexpr attr_t operator&(attr_t a, attr_t b) {
return static_cast<attr_t>(
static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
}
constexpr attr_t operator|(attr_t a, attr_t b) {
return static_cast<attr_t>(
static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
}
constexpr attr_t operator~(attr_t a) {
return static_cast<attr_t>(~static_cast<uint32_t>(a));
}
constexpr bool any(attr_t a) {
return a != static_cast<attr_t>(0);
}
inline attr_t &operator|=(attr_t &a, attr_t b) {
return a = a | b;
}
inline attr_t &operator&=(attr_t &a, attr_t b) {
return a = a & b;
}
}
class hw_t : public stringify_t<hw_t> {
public:
using attr_t = hw::attr_t;
hw_t() = default;
explicit hw_t(const ngen::Product &product, int eu_count, int max_wg_size,
size_t l3_cache_size, attr_t attr);
ngen::Product product() const;
ngen::ProductFamily family() const;
int stepping() const;
ngen::HW ngen_hw() const { return hw_; }
operator ngen::HW() const { return hw_; }
bool has_fp64_atomic_support() const {
return any(attr_ & attr_t::atomic_fp64);
}
int eu_count() const { return eu_count_; }
int large_grf_support() const { return any(attr_ & attr_t::large_grf); }
int grf_size() const;
int systolic_support() const { return any(attr_ & attr_t::systolic); }
size_t l3_cache_size() const { return l3_cache_size_; }
bool efficient_64_bit() const {
return any(attr_ & attr_t::efficient_64bit);
}
size_t max_tg_size(int regs, int simd) const;
int eus_per_core() const;
int threads_per_eu(int regs = 128) const;
int cache_line_size() const;
std::string str() const;
bool operator<(ngen::HW rhs) const { return hw_ < rhs; }
bool operator>(ngen::HW rhs) const { return hw_ > rhs; }
bool operator<=(ngen::HW rhs) const { return hw_ <= rhs; }
bool operator>=(ngen::HW rhs) const { return hw_ >= rhs; }
bool operator==(ngen::HW rhs) const { return hw_ == rhs; }
bool operator!=(ngen::HW rhs) const { return hw_ != rhs; }
#if __cplusplus >= 202002L
bool operator==(const hw_t &other) const = default;
#endif
protected:
struct alignas(int) product_t {
unsigned char data[12] = {};
product_t() = default;
product_t(const ngen::Product &product);
const ngen::Product &operator()() const;
#if __cplusplus >= 202002L
bool operator==(const product_t &other) const = default;
#endif
};
product_t product_;
private:
size_t max_wg_size(int regs = 128) const {
bool is_large_grf = (regs > 128);
return is_large_grf ? max_wg_size_ / 2 : max_wg_size_;
}
ngen::HW hw_ = {};
int eu_count_ = 0;
size_t max_wg_size_ = 0;
size_t l3_cache_size_ = 0;
attr_t attr_ = attr_t::none;
};
} GEMMSTONE_NAMESPACE_END
#endif