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() {
126 static_cast<unsigned char*>(Context::New(nbytes())), Context::Delete);
127 capacity_ = nbytes() * CHAR_BIT;
129 CAFFE_ENFORCE(capacity_ == nbytes() * CHAR_BIT);
133 inline const unsigned char* data()
const {
137 inline size_t size()
const {
141 inline unsigned char alignment()
const {
145 inline unsigned char precision()
const {
149 inline const vector<int>& dims()
const {
153 inline bool is_signed()
const {
164 inline size_t aligned_size()
const {
165 return alignment_ * ((size_ + alignment_ - 1) / alignment_);
168 inline size_t nbytes()
const {
169 return (aligned_size() * (precision_ + signed_)) / CHAR_BIT;
172 inline double scale()
const {
176 inline double bias()
const {
183 inline int dim32(
const int i)
const {
184 DCHECK_LT(i, dims_.size()) <<
"Exceeding ndim limit " << dims_.size();
185 DCHECK_GE(i, 0) <<
"Cannot have negative index";
186 CAFFE_ENFORCE_LT(dims_[i], std::numeric_limits<int>::max());
187 return static_cast<int>(dims_[i]);
202 CAFFE_ENFORCE_GE(axis_index, -
ndim());
203 CAFFE_ENFORCE_LT(axis_index,
ndim());
204 if (axis_index < 0) {
205 return axis_index +
ndim();
215 for (
int i = k; i < dims_.size(); ++i) {
225 CAFFE_ENFORCE(k < dims_.size());
227 for (
int i = 0; i < k; ++i) {
234 std::vector<int> dims_;
238 unsigned char precision_ = CHAR_BIT;
240 unsigned char alignment_ = CHAR_BIT;
243 std::shared_ptr<unsigned char> data_;
251 size_t capacity_ = 0;
255 #endif // CAFFE2_CORE_QTENSOR_H_ int ndim() const
Returns the number of dimensions of the data.
Simple registry implementation in Caffe2 that uses static variables to register object creators durin...
int canonical_axis_index(int axis_index) const
Returns the 'canonical' version of a (usually) user-specified axis, allowing for negative indexing (e...
QTensor(const std::vector< int > &dims, const unsigned char precision, const bool signbit=false)
Creates a quantized tensor of the given dimension.
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.
TIndex size_from_dim(int k) const
Return product of all dimensions starting from K.