File: half_float_ops_test.cc

package info (click to toggle)
pytorch 1.13.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 139,252 kB
  • sloc: cpp: 1,100,274; python: 706,454; ansic: 83,052; asm: 7,618; java: 3,273; sh: 2,841; javascript: 612; makefile: 323; xml: 269; ruby: 185; yacc: 144; objc: 68; lex: 44
file content (111 lines) | stat: -rw-r--r-- 3,401 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <map>

#include "caffe2/core/flags.h"
#include "caffe2/core/logging.h"
#include "caffe2/operators/half_float_ops.h"
#include "caffe2/utils/conversions.h"

#include <c10/util/irange.h>

#include <gtest/gtest.h>
C10_DECLARE_string(caffe_test_root);

namespace caffe2 {

TEST(Float16, SimpleTest) {
  Workspace ws;
  vector<float> data = {0.1f, 0.23f, 1.6f, 8.2f, -13.9f};

  // loading input data
  Blob* dataBlob = ws.CreateBlob("data");
  auto tensor = BlobGetMutableTensor(dataBlob, CPU);
  tensor->Resize(data.size());
  for (auto i = 0; i < tensor->numel(); ++i) {
    tensor->mutable_data<float>()[i] = data[i];
  }

  // encoding fp32 -> fp16
  OperatorDef def;
  def.set_name("test");
  def.set_type("FloatToHalf");
  def.add_input("data");
  def.add_output("data16");
  unique_ptr<OperatorBase> op(CreateOperator(def, &ws));
  EXPECT_NE(nullptr, op.get());
  EXPECT_TRUE(op->Run());

  // run some sanity checks
  Blob* outputBlob = ws.GetBlob("data16");
  EXPECT_NE(nullptr, outputBlob);
  EXPECT_TRUE(outputBlob->IsType<Tensor>());
  const TensorCPU& outputTensor = outputBlob->Get<Tensor>();
  EXPECT_EQ(outputTensor.numel(), 5);
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto,hicpp-avoid-goto)
  EXPECT_NO_THROW(outputTensor.data<at::Half>());

  // decode fp16 -> fp32
  OperatorDef def2;
  def2.set_name("test");
  def2.set_type("HalfToFloat");
  def2.add_input("data16");
  def2.add_output("result");
  unique_ptr<OperatorBase> op2(CreateOperator(def2, &ws));
  EXPECT_NE(nullptr, op2.get());
  EXPECT_TRUE(op2->Run());

  // validate result
  Blob* resultBlob = ws.GetBlob("result");
  EXPECT_NE(nullptr, resultBlob);
  EXPECT_TRUE(resultBlob->IsType<Tensor>());
  const TensorCPU& resultTensor = resultBlob->Get<Tensor>();
  EXPECT_EQ(resultTensor.numel(), 5);

  for (const auto i : c10::irange(data.size())) {
    EXPECT_NEAR(resultTensor.data<float>()[i], data[i], 0.01);
  }
}

TEST(Float16, UniformDistributionTest) {
  Workspace ws;

  OperatorDef def;
  def.set_name("test");
  def.set_type("Float16UniformFill");
  int64_t size = 5000000L;
  std::vector<int64_t> shape = {size, 32};
  long tot_size = shape[0];
  for (const auto i : c10::irange(1, shape.size())) {
    tot_size *= shape[i];
  }
  caffe2::AddArgument<std::vector<int64_t>>("shape", shape, &def);
  caffe2::AddArgument<float>("min", -20.0, &def);
  caffe2::AddArgument<float>("max", 20.0, &def);
  def.add_output("result");

  unique_ptr<OperatorBase> op(CreateOperator(def, &ws));
  EXPECT_NE(nullptr, op.get());
  EXPECT_TRUE(op->Run());

  Blob* resultBlob = ws.GetBlob("result");
  const TensorCPU& resultTensor = resultBlob->Get<Tensor>();
  EXPECT_EQ(resultTensor.numel(), tot_size);
  double mean = 0.0, var = 0.0;
  const at::Half* data = resultTensor.data<at::Half>();
  for (auto i = 0; i < resultTensor.numel(); i++) {
    float x = caffe2::convert::Get<float, at::Half>(data[i]);
    mean += x;
    var += x * x;
  }
  // NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions,bugprone-narrowing-conversions)
  mean /= tot_size;
  // NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions,bugprone-narrowing-conversions)
  var /= tot_size;
  LOG(INFO) << "m " << mean << " " << var;

  // The uniform distribution of [-20,20] should have a mean of 0
  // and a variance of 40^2/12
  EXPECT_TRUE(fabs(mean) < 0.1);
  EXPECT_TRUE(fabs(var - 133.33) / 133.33 < 0.1);
}

} // namespace caffe2