Caffe2 - C++ API
A deep learning, cross platform ML framework
stats_put_ops.h
1 #include <limits>
2 #include "caffe2/core/operator.h"
3 #include "caffe2/core/stats.h"
4 #include "caffe2/core/tensor.h"
5 #include "caffe2/core/types.h"
6 
7 namespace caffe2 {
8 
9 template <typename T>
10 struct TemplatePutOp : public Operator<CPUContext> {
11  explicit TemplatePutOp(const OperatorDef& operator_def, Workspace* ws)
12  : Operator(operator_def, ws),
13  given_name_(GetSingleArgument<std::string>(
14  "stat_name",
15  operator_def.input().Get(0))),
16  magnitude_expand_(GetSingleArgument<int64_t>("magnitude_expand", 1)),
17  bound_(GetSingleArgument<bool>("bound", false)),
18  has_default_(HasSingleArgumentOfType<float>("default_value")),
19  default_value_(GetSingleArgument<float>("default_value", 0.0)),
20  stat_(given_name_) {}
21 
22  bool RunOnDevice() override {
24  int,
25  float,
26  uint8_t,
27  int8_t,
28  uint16_t,
29  int16_t,
30  int64_t,
31  at::Half,
32  double>>::call(this, Input(0));
33  }
34 
35  template <typename V>
36  bool DoRunWithType() {
37  V input = default_value_;
38 
39  // If we receive an empty tensor
40  if (Input(0).template data<V>()) {
41  input = *Input(0).template data<V>();
42  } else if (!has_default_) {
43  CAFFE_THROW(
44  "Default value must be provided when recieving empty tensors for ",
45  given_name_);
46  }
47 
48  int64_t bound_value =
49  std::numeric_limits<int64_t>::max() / magnitude_expand_;
50 
51  int64_t int_value;
52  if (bound_) {
53  if (isNan(input)) {
54  int_value = 0;
55  } else if (input <= -bound_value) {
56  int_value = std::numeric_limits<int64_t>::min();
57  } else if (input >= bound_value) {
58  int_value = std::numeric_limits<int64_t>::max();
59  } else {
60  int_value = input * magnitude_expand_;
61  }
62  } else {
63  CAFFE_ENFORCE(
64  std::abs(static_cast<int64_t>(input)) < bound_value,
65  "Input value is too large for the given magnitude expansion!");
66  CAFFE_ENFORCE(!isNan(input), "Input value cannot be NaN!");
67  int_value = input * magnitude_expand_;
68  }
69 
70  CAFFE_EVENT(stat_, stat_value, int_value);
71 
72  return true;
73  }
74 
75  private:
76  const std::string given_name_;
77  const int64_t magnitude_expand_;
78  const bool bound_;
79  const bool has_default_;
80  const float default_value_;
81  T stat_;
82 
83  template <typename V>
84  bool isNan(V input) {
85  /*
86  Checks if given number of is NaN, while being permissive with different
87  implementations of the standard libraries between operating systems.
88 
89  Uses the preperties of NaN, defined by IEEE.
90  https://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
91  */
92  return input != input;
93  }
94 };
95 } // namespace caffe2
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
Definition: workspace.h:47
const Tensor & Input(int idx, DeviceType type=CPUContext::GetDeviceType())
Retrieve a non-owning reference to the input at position &#39;idx&#39; for this operator. ...
Definition: operator.h:702
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13