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 <c10/util/typeid.h> 16 template <
class Context>
52 const unsigned char precision,
53 const bool signbit =
false)
54 : precision_(precision), signed_(signbit) {
59 if (dims_ != dim_source) {
60 size_t source_size = std::accumulate(
61 dim_source.begin(), dim_source.end(), 1, std::multiplies<int>());
62 if ((source_size * (precision_ + signed_)) > capacity_) {
66 dims_ = dim_source.vec();
72 SetBitAtIndex(
const unsigned char bit,
const size_t index,
const bool value) {
74 unsigned char* d = mutable_data();
77 bit < precision_ + signed_,
78 "Attempted to a set a bit that is not allocated.");
79 CAFFE_ENFORCE(bit * aligned_size() < capacity_);
81 auto idx = (aligned_size() * bit) / CHAR_BIT;
84 idx = index / CHAR_BIT;
85 auto shift = CHAR_BIT - (index % CHAR_BIT) - 1;
90 d[idx] &= ~(1 << shift);
94 bool GetBitAtIndex(
const unsigned char bit,
const size_t index)
const {
96 const unsigned char* d = data();
97 auto idx = (aligned_size() * bit) / CHAR_BIT;
100 idx = index / CHAR_BIT;
101 auto shift = CHAR_BIT - (index % CHAR_BIT) - 1;
103 return d[idx] & (1 << shift);
106 void SetPrecision(
const unsigned char precision) {
107 precision_ = precision;
111 void SetSigned(
const bool make_signed =
true) {
112 signed_ = make_signed;
116 void SetScale(
const double scale) {
120 void SetBias(
const double bias) {
124 unsigned char* mutable_data() {
126 data_ptr_ = Context::New(nbytes());
127 capacity_ = nbytes() * CHAR_BIT;
129 CAFFE_ENFORCE(capacity_ == nbytes() * CHAR_BIT);
130 return static_cast<unsigned char*
>(data_ptr_.get());
133 inline const unsigned char* data()
const {
134 return static_cast<unsigned char*
>(data_ptr_.get());
137 inline size_t size()
const {
141 inline unsigned char alignment()
const {
145 inline unsigned char precision()
const {
158 inline bool is_signed()
const {
169 inline size_t aligned_size()
const {
170 return alignment_ * ((size_ + alignment_ - 1) / alignment_);
173 inline size_t nbytes()
const {
174 return (aligned_size() * (precision_ + signed_)) / CHAR_BIT;
177 inline double scale()
const {
181 inline double bias()
const {
188 inline int dim32(
const int i)
const {
189 DCHECK_LT(i, dims_.size()) <<
"Exceeding ndim limit " << dims_.size();
190 DCHECK_GE(i, 0) <<
"Cannot have negative index";
191 CAFFE_ENFORCE_LT(dims_[i], std::numeric_limits<int>::max());
192 return static_cast<int>(dims_[i]);
207 CAFFE_ENFORCE_GE(axis_index, -ndim());
208 CAFFE_ENFORCE_LT(axis_index, ndim());
209 if (axis_index < 0) {
210 return axis_index + ndim();
220 for (
int i = k; i < dims_.size(); ++i) {
230 CAFFE_ENFORCE(k < dims_.size());
232 for (
int i = 0; i < k; ++i) {
239 std::vector<int> dims_;
243 unsigned char precision_ = CHAR_BIT;
245 unsigned char alignment_ = CHAR_BIT;
253 bool signed_ =
false;
256 size_t capacity_ = 0;
260 #endif // CAFFE2_CORE_QTENSOR_H_ int64_t size_to_dim(int k) const
Product of all dims up to.
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.
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.
QTensor(at::ArrayRef< int > dims, const unsigned char precision, const bool signbit=false)
Creates a quantized tensor of the given dimension.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
int64_t size_from_dim(int k) const
Return product of all dimensions starting from K.