Caffe2 - C++ API
A deep learning, cross platform ML framework
half_float_ops.cc
1 #include "caffe2/operators/half_float_ops.h"
2 #include <c10/util/Half.h>
3 
4 namespace caffe2 {
5 
6 template <>
7 bool FloatToHalfOp<CPUContext>::RunOnDevice() {
8  auto& input = Input(0);
9 
10  auto* output = Output(0, input.sizes(), at::dtype<at::Half>());
11  const float* data = input.template data<float>();
12  at::Half* out = output->template mutable_data<at::Half>();
13  auto N = input.numel();
14 
15  for (size_t i = 0; i < N; i++) {
16  out[i] = data[i];
17  }
18 
19  return true;
20 }
21 
22 template <>
23 bool HalfToFloatOp<CPUContext>::RunOnDevice() {
24  auto& input = Input(0);
25 
26  auto* output = Output(0, input.sizes(), at::dtype<float>());
27  const at::Half* data = input.template data<at::Half>();
28  float* out = output->template mutable_data<float>();
29  auto N = input.numel();
30 
31  for (size_t i = 0; i < N; i++) {
32  out[i] = data[i];
33  }
34  return true;
35 }
36 
37 REGISTER_CPU_OPERATOR(FloatToHalf, FloatToHalfOp<CPUContext>);
38 REGISTER_CPU_OPERATOR(HalfToFloat, HalfToFloatOp<CPUContext>);
39 
40 OPERATOR_SCHEMA(FloatToHalf)
41  .NumInputs(1)
42  .NumOutputs(1)
43  .TensorInferenceFunction([](const OperatorDef& /* unused */,
44  const vector<TensorShape>& in) {
45  vector<TensorShape> out;
46  const TensorShape& X = in[0];
47  out.push_back(X);
48  out[0].set_data_type(TensorProto_DataType_FLOAT16);
49 
50  return out;
51  });
52 
53 OPERATOR_SCHEMA(HalfToFloat)
54  .NumInputs(1)
55  .NumOutputs(1)
56  .TensorInferenceFunction([](const OperatorDef& /* unused */,
57  const vector<TensorShape>& in) {
58  vector<TensorShape> out;
59  const TensorShape& X = in[0];
60  out.push_back(X);
61  out[0].set_data_type(TensorProto_DataType_FLOAT);
62 
63  return out;
64  });
65 
66 bool Float16ConstantFillOp::RunOnDevice() {
67  auto* output = Output(0, shape_, at::dtype<at::Half>());
68  const float givenValue =
69  this->template GetSingleArgument<float>("value", 0.0f);
70  at::Half givenFp16Value = givenValue;
71 
72  if (output->numel()) {
73  at::Half* out = output->template mutable_data<at::Half>();
74  std::fill(out, out + output->numel(), givenFp16Value);
75  }
76  return true;
77 }
78 
79 bool Float16UniformFillOp::RunOnDevice() {
80  auto* output = Output(0, shape_, at::dtype<at::Half>());
81  at::Half* out = output->template mutable_data<at::Half>();
82 
83  // Get a batch row by row and convert
84  auto leading_dim_sz = output->size(0);
85  int rowsz = output->numel() / output->size(0);
86 
87  vector<float> intermediate_data_;
88  intermediate_data_.resize(rowsz);
89  for (uint64_t i = 0; i < leading_dim_sz; i++) {
90  math::RandUniform<float, CPUContext>(
91  rowsz, min_, max_, intermediate_data_.data(), &context_);
92  for (uint64_t j = 0; j < rowsz; j++) {
93  out[i * rowsz + j] = intermediate_data_[j];
94  }
95  }
96  return true;
97 }
98 
99 REGISTER_CPU_OPERATOR(Float16ConstantFill, Float16ConstantFillOp);
100 REGISTER_CPU_OPERATOR(Float16UniformFill, Float16UniformFillOp);
101 OPERATOR_SCHEMA(Float16UniformFill)
102  .NumInputs(0)
103  .NumOutputs(1)
104  .TensorInferenceFunction(Float16FillerTensorInference)
105  .SetDoc(
106  "Fills a half float tensor of a specified shape with"
107  " values from a uniform distribution[min,max]")
108  .Arg("shape", "Shape of the tensor")
109  .Arg("min", "Minimim value to generate")
110  .Arg("max", "Maximum value to generate");
111 NO_GRADIENT(Float16UniformFill);
112 
113 OPERATOR_SCHEMA(Float16ConstantFill)
114  .NumInputs(0)
115  .NumOutputs(1)
116  .TensorInferenceFunction(Float16FillerTensorInference)
117  .Arg("value", "The value for the elements of the output tensor.")
118  .Arg("shape", "The shape of the output tensor.")
119  .Output(
120  0,
121  "output",
122  "Output tensor of constant values specified by 'value'");
123 
125  using GradientMakerBase::GradientMakerBase;
126  vector<OperatorDef> GetGradientDefs() override {
127  return SingleGradientDef(
128  "HalfToFloat", "", vector<string>{GO(0)}, vector<string>{GI(0)});
129  }
130 };
131 REGISTER_GRADIENT(FloatToHalf, GetFloatToHalfGradient);
132 
134  using GradientMakerBase::GradientMakerBase;
135  vector<OperatorDef> GetGradientDefs() override {
136  return SingleGradientDef(
137  "FloatToHalf", "", vector<string>{GO(0)}, vector<string>{GI(0)});
138  }
139 };
140 REGISTER_GRADIENT(HalfToFloat, GetHalfToFloatGradient);
141 NO_GRADIENT(Float16ConstantFill);
142 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13