Caffe2 - C++ API
A deep learning, cross platform ML framework
int8_leaky_relu_op.h
1 #ifndef CAFFE2_OPERATORS_INT8_LEAKY_RELU_OP_H_
2 #define CAFFE2_OPERATORS_INT8_LEAKY_RELU_OP_H_
3 
4 #include <qnnpack.h>
5 
6 #include "caffe2/core/context.h"
7 #include "caffe2/core/operator.h"
8 #include "caffe2/core/tensor_int8.h"
9 #include "caffe2/operators/quantized/int8_utils.h"
10 
11 namespace caffe2 {
12 
13 namespace int8 {
14 
15 class Int8LeakyReluOp final : public Operator<CPUContext> {
16  public:
17  explicit Int8LeakyReluOp(const OperatorDef& operator_def, Workspace* ws)
18  : Operator<CPUContext>(operator_def, ws), ws_(ws) {
19  const float alpha = this->template GetSingleArgument<float>("alpha", 0.01);
20  CAFFE_ENFORCE_GT(alpha, 0.0);
21  CAFFE_ENFORCE_LT(alpha, 1.0);
22  this->alpha_ = alpha;
23  }
24 
25  ~Int8LeakyReluOp() {
26  if (this->qnnpackOperator_ != nullptr) {
27  qnnp_delete_operator(this->qnnpackOperator_);
28  this->qnnpackOperator_ = nullptr;
29  }
30  }
31 
32  bool RunOnDevice() override {
33  const auto& X = Inputs()[0]->template Get<Int8TensorCPU>();
34  auto* Y = Outputs()[0]->template GetMutable<Int8TensorCPU>();
35  const int32_t Y_zero_point =
36  this->template GetSingleArgument<int>("Y_zero_point", 0);
37  const float Y_scale =
38  this->template GetSingleArgument<float>("Y_scale", 1);
39  CHECK_GE(Y_zero_point, std::numeric_limits<uint8_t>::min());
40  CHECK_LE(Y_zero_point, std::numeric_limits<uint8_t>::max());
41 
42  /*
43  * Record quantization parameters for the input, because if the op is
44  * in-place, we may overwrite these parameters later, when we set
45  * quantization parameters for output tensor.
46  */
47  const uint8_t X_zero_point = X.zero_point;
48  const float X_scale = X.scale;
49 
50  Y->scale = Y_scale;
51  Y->zero_point = Y_zero_point;
52  Y->t.ResizeLike(X.t);
53 
54  initQNNPACK();
55 
56  if (this->qnnpackOperator_ == nullptr) {
57  const qnnp_status createStatus = qnnp_create_leaky_relu_nc_q8(
58  1 /* channels */,
59  this->alpha_,
60  static_cast<uint8_t>(X_zero_point), X_scale,
61  static_cast<uint8_t>(Y_zero_point), Y_scale,
62  0 /* output min */,
63  255 /* output max */,
64  0 /* flags */,
65  &qnnpackOperator_);
66  CAFFE_ENFORCE(
67  createStatus == qnnp_status_success,
68  "failed to create QNNPACK Leaky ReLU operator");
69  CAFFE_ENFORCE(this->qnnpackOperator_ != nullptr);
70  }
71 
72  const qnnp_status setupStatus = qnnp_setup_leaky_relu_nc_q8(
73  this->qnnpackOperator_,
74  X.t.numel() /* batch size */,
75  X.t.template data<uint8_t>(),
76  1 /* X stride */,
77  Y->t.template mutable_data<uint8_t>(),
78  1 /* Y stride */);
79  CAFFE_ENFORCE(
80  setupStatus == qnnp_status_success,
81  "failed to setup QNNPACK Leaky ReLU operator");
82 
83 #ifdef FBCODE_CAFFE2
84  const qnnp_status runStatus =
85  qnnp_run_operator(this->qnnpackOperator_, nullptr /* thread pool */);
86 #else
87  pthreadpool_t threadpool =
88  reinterpret_cast<pthreadpool_t>(ws_->GetThreadPool());
89  const qnnp_status runStatus =
90  qnnp_run_operator(this->qnnpackOperator_, threadpool);
91 #endif
92  CAFFE_ENFORCE(
93  runStatus == qnnp_status_success,
94  "failed to run QNNPACK Leaky ReLU operator");
95 
96  return true;
97  }
98 
99  private:
100  float alpha_;
101  Workspace* ws_;
102  // QNNPACK Leaky ReLU operator
103  qnnp_operator_t qnnpackOperator_{nullptr};
104 };
105 
106 } // namespace int8
107 
108 } // namespace caffe2
109 
110 #endif // CAFFE2_OPERATORS_INT8_LEAKY_RELU_OP_H_
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
Definition: workspace.h:47
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13