1 #ifndef CAFFE2_OPERATORS_INT8_RESIZE_NEAREST_OP_H_ 2 #define CAFFE2_OPERATORS_INT8_RESIZE_NEAREST_OP_H_ 4 #include "caffe2/core/context.h" 5 #include "caffe2/core/operator.h" 6 #include "caffe2/core/tensor_int8.h" 7 #include "caffe2/operators/quantized/int8_utils.h" 15 template <
class... Args>
18 width_scale_ = this->
template GetSingleArgument<float>(
"width_scale", 1);
19 height_scale_ = this->
template GetSingleArgument<float>(
"height_scale", 1);
20 CAFFE_ENFORCE_GT(width_scale_, 0);
21 CAFFE_ENFORCE_GT(height_scale_, 0);
24 bool RunOnDevice()
override {
26 const auto& X = Inputs()[0]->template Get<Int8TensorCPU>();
27 auto* Y = Outputs()[0]->template GetMutable<Int8TensorCPU>();
29 CAFFE_ENFORCE_EQ(4, X.t.dim());
30 const int N = X.t.dim32(0);
31 const int IH = X.t.dim32(1);
32 const int IW = X.t.dim32(2);
33 const int C = X.t.dim32(3);
34 const int OW = IW * width_scale_;
35 const int OH = IH * height_scale_;
39 Y->zero_point = X.zero_point;
41 int32_t Y_offset = this->
template GetSingleArgument<int>(
"Y_zero_point", 0);
42 auto Y_scale = this->
template GetSingleArgument<float>(
"Y_scale", 1);
43 CHECK_EQ(Y_offset, X.zero_point);
44 CHECK_EQ(Y_scale, X.scale);
46 const uint8_t* Xdata = X.t.data<uint8_t>();
47 uint8_t* Ydata = Y->t.mutable_data<uint8_t>();
49 for (
int n = 0; n < N; ++n) {
50 for (
int y = 0; y < OH; ++y) {
51 const int in_y = std::min((
int)(y / height_scale_), (IH - 1));
52 for (
int x = 0; x < OW; ++x) {
53 const int in_x = std::min((
int)(x / width_scale_), (IW - 1));
55 &Ydata[C * x + C * OW * y + C * OW * OH * n],
56 &Xdata[C * in_x + C * IW * in_y + C * IW * IH * n],
73 #endif // CAFFE2_OPERATORS_INT8_RESIZE_NEAREST_OP_H_ void ReinitializeTensor(Tensor *tensor, at::IntArrayRef dims, at::TensorOptions options)
Reinitialize a Tensor to given dims and options if necessary, note that this will not do anything if ...
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...