1 #ifndef CAFFE2_CORE_QTENSOR_H_ 2 #define CAFFE2_CORE_QTENSOR_H_ 9 #include "caffe2/core/common.h" 10 #include "caffe2/core/context.h" 11 #include "caffe2/core/tensor.h" 12 #include "caffe2/core/typeid.h" 16 template <
class Context>
50 const std::vector<int>& dims,
51 const unsigned char precision,
52 const bool signbit =
false)
53 : precision_(precision), signed_(signbit) {
57 void Resize(std::vector<int> dim_source) {
58 if (dims_ != dim_source) {
59 size_t source_size = std::accumulate(
60 dim_source.begin(), dim_source.end(), 1, std::multiplies<int>());
61 if ((source_size * (precision_ + signed_)) > capacity_) {
71 SetBitAtIndex(
const unsigned char bit,
const size_t index,
const bool value) {
73 unsigned char* d = mutable_data();
76 bit < precision_ + signed_,
77 "Attempted to a set a bit that is not allocated.");
78 CAFFE_ENFORCE(bit * aligned_size() < capacity_);
80 auto idx = (aligned_size() * bit) / CHAR_BIT;
83 idx = index / CHAR_BIT;
84 auto shift = CHAR_BIT - (index % CHAR_BIT) - 1;
89 d[idx] &= ~(1 << shift);
93 bool GetBitAtIndex(
const unsigned char bit,
const size_t index)
const {
95 const unsigned char* d = data();
96 auto idx = (aligned_size() * bit) / CHAR_BIT;
99 idx = index / CHAR_BIT;
100 auto shift = CHAR_BIT - (index % CHAR_BIT) - 1;
102 return d[idx] & (1 << shift);
105 void SetPrecision(
const unsigned char precision) {
106 precision_ = precision;
110 void SetSigned(
const bool make_signed =
true) {
111 signed_ = make_signed;
115 void SetScale(
const double scale) {
119 void SetBias(
const double bias) {
123 unsigned char* mutable_data() {
125 auto ptr_and_deleter = Context::New(nbytes());
127 static_cast<unsigned char*>(ptr_and_deleter.first),
128 ptr_and_deleter.second);
129 capacity_ = nbytes() * CHAR_BIT;
131 CAFFE_ENFORCE(capacity_ == nbytes() * CHAR_BIT);
135 inline const unsigned char* data()
const {
139 inline size_t size()
const {
143 inline unsigned char alignment()
const {
147 inline unsigned char precision()
const {
151 inline const vector<int>& dims()
const {
155 inline bool is_signed()
const {
166 inline size_t aligned_size()
const {
167 return alignment_ * ((size_ + alignment_ - 1) / alignment_);
170 inline size_t nbytes()
const {
171 return (aligned_size() * (precision_ + signed_)) / CHAR_BIT;
174 inline double scale()
const {
178 inline double bias()
const {
185 inline int dim32(
const int i)
const {
186 DCHECK_LT(i, dims_.size()) <<
"Exceeding ndim limit " << dims_.size();
187 DCHECK_GE(i, 0) <<
"Cannot have negative index";
188 CAFFE_ENFORCE_LT(dims_[i], std::numeric_limits<int>::max());
189 return static_cast<int>(dims_[i]);
204 CAFFE_ENFORCE_GE(axis_index, -
ndim());
205 CAFFE_ENFORCE_LT(axis_index,
ndim());
206 if (axis_index < 0) {
207 return axis_index +
ndim();
217 for (
int i = k; i < dims_.size(); ++i) {
227 CAFFE_ENFORCE(k < dims_.size());
229 for (
int i = 0; i < k; ++i) {
236 std::vector<int> dims_;
240 unsigned char precision_ = CHAR_BIT;
242 unsigned char alignment_ = CHAR_BIT;
245 std::shared_ptr<unsigned char> data_;
250 bool signed_ =
false;
253 size_t capacity_ = 0;
257 #endif // CAFFE2_CORE_QTENSOR_H_ int canonical_axis_index(int axis_index) const
Returns the 'canonical' version of a (usually) user-specified axis, allowing for negative indexing (e...
int ndim() const
Returns the number of dimensions of the data.
QTensor(const std::vector< int > &dims, const unsigned char precision, const bool signbit=false)
Creates a quantized tensor of the given dimension.
TIndex size_from_dim(int k) const
Return product of all dimensions starting from K.
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
int dim32(const int i) const
Returns the i-th dimension of the qtensor in int.
TIndex size_to_dim(int k) const
Product of all dims up to.