#include "common/primitive_attr_quant.hpp"
#include "common/primitive_hashing.hpp"
#include "common/verbose.hpp"
namespace dnnl {
namespace impl {
const quant_entry_t &default_quant_entry() {
static const quant_entry_t default_quant_entry;
return default_quant_entry;
}
size_t quant_entry_t::get_hash() const {
size_t seed = 0;
seed = hash_combine(seed, mask_);
seed = hash_combine(seed, static_cast<size_t>(data_type_));
seed = hash_combine(seed, group_ndims_);
if (group_ndims_ > 0)
seed = primitive_hashing::get_array_hash(
seed, group_dims_, group_ndims_);
seed = hash_combine(seed, is_host_scalar_);
seed = hash_combine(seed, qmode_);
return seed;
}
void quant_entry_t::serialize(serialization_stream_t &sstream) const {
sstream.append(mask_);
sstream.append(data_type_);
sstream.append_array(group_ndims_, group_dims_);
sstream.append(is_host_scalar_);
sstream.append(qmode_);
}
quant_entry_t quant_entry_t::deserialize(deserializer_t &d) {
quant_entry_t e;
d.pop(e.mask_);
d.pop(e.data_type_);
size_t group_ndims;
d.pop_array(group_ndims, e.group_dims_);
e.group_ndims_ = static_cast<int>(group_ndims);
d.pop(e.is_host_scalar_);
d.pop(e.qmode_);
return e;
}
std::string quant_entry_t::get_verbose() const {
std::string s;
s.append(std::to_string(mask_));
s.append(":").append(dnnl_dt2str(data_type_));
if (group_ndims_ > 0) {
s.append(":")
.append(std::to_string(group_dims_[0]))
.append("x")
.append(std::to_string(group_dims_[1]));
}
if (is_host_scalar_) { s.append(":host_scalar"); }
if (qmode_ != quantization_mode::static_sazp) {
s.append(":").append(dnnl_quantization_mode2str(qmode_));
}
return s;
}
std::ostream &operator<<(std::ostream &ss, const quant_entry_t &e) {
ss << e.get_verbose();
return ss;
}
size_t quant_entries_t::get_hash() const {
size_t seed = 0;
for (const auto &e : entries_) {
seed = hash_combine(seed, e.first);
seed = hash_combine(seed, e.second.get_hash());
}
return seed;
}
void quant_entries_t::serialize(serialization_stream_t &sstream) const {
sstream.append(entries_.size());
for (const auto &e : entries_) {
sstream.append(e.first);
sstream.append(e.second);
}
}
template <typename T>
T deserialize_entries(deserializer_t &d) {
T entries;
size_t size = d.pop<size_t>();
for (size_t i = 0; i < size; i++) {
int arg = d.pop<int>();
entries.set(arg, d.pop<quant_entry_t>());
}
return entries;
}
std::string quant_entries_t::get_verbose() const {
std::string s;
std::string empty_delim, attr_delim = "+";
std::string delim = empty_delim;
for (const auto &scale : entries_) {
const auto &q = scale.second;
if (q.has_default_values()) continue;
int arg = scale.first;
s.append(delim)
.append(arg2str(arg))
.append(":")
.append(q.get_verbose());
delim = attr_delim;
}
return s;
}
scales_t scales_t::deserialize(deserializer_t &d) {
return deserialize_entries<scales_t>(d);
}
zero_points_t zero_points_t::deserialize(deserializer_t &d) {
return deserialize_entries<zero_points_t>(d);
}
precomputed_reductions_t precomputed_reductions_t::deserialize(
deserializer_t &d) {
return deserialize_entries<precomputed_reductions_t>(d);
}
} }