Caffe2 - C++ API
A deep learning, cross platform ML framework
GLResize.cc
1 
2 #include "../core/GLFilter.h"
3 #include "../core/GLImage.h"
4 #include "../core/ImageAllocator.h"
5 
6 #include "caffe2/core/operator.h"
7 #include "caffe2/core/timer.h"
8 #include <iostream>
9 #include <vector>
10 
11 class GLResizeNearest : public GLFilter {
12  public:
13  binding* inputData;
14  binding* outputSize;
15  binding* scale_reverse;
16 
18  : GLFilter("GLResizeNearest",
19  vertex_shader,
20  fragment_shader,
21  std::vector<binding*>({BINDING(outputSize), BINDING(scale_reverse), BINDING(inputData)}),
22  {/* no uniform blocks*/},
23  {/* no attributes */},
24  {/* replacements */}) {}
25 
26  template <typename T>
27  void resize(const GLImageVector<T>& input_images,
28  const GLImageVector<T>& output_images,
29  float width_scale_rev,
30  float height_scale_rev);
31 
32  static const char* fragment_shader;
33 };
34 
35 // MARK: GLSL
36 
37 const char* GLResizeNearest::fragment_shader = R"GLSL(#version 300 es
38 
39 precision mediump float;
40 precision mediump int;
41 
42 in highp vec2 v_texCoord;
43 
44 uniform ivec2 outputSize;
45 uniform highp vec2 scale_reverse;
46 
47 TEXTURE_INPUT(inputData);
48 TEXTURE_OUTPUT(0, outputData);
49 
50 void main() {
51  // it clamps to the edge by default
52  ivec2 texelCoord = ivec2(v_texCoord * vec2(outputSize) * scale_reverse);
53  vec4 value = TEXTURE_LOAD(inputData, texelCoord);
54  outputData = TEXTURE_STORE(value);
55 }
56 )GLSL";
57 
58 template <typename T>
59 void GLResizeNearest::resize(const GLImageVector<T>& input_images,
60  const GLImageVector<T>& output_images,
61  float width_scale_rev,
62  float height_scale_rev) {
63  for (int i = 0; i < input_images.size(); i++) {
64  auto input_image = input_images[i];
65  auto output_image = output_images[i];
66  int input_slices = input_image->slices;
67  int output_slices = output_image->slices;
68 
69  for (int is = 0; is < input_slices; is++) {
70  std::vector<texture_attachment> input_attachments({{input_image->textures[is], inputData}});
71 
72  run(input_attachments,
73  {output_image->textures.begin() + is, output_image->textures.begin() + is + 1},
74  [&]() {
75  glUniform2i(outputSize->location, output_image->texture_width, output_image->texture_height);
76  glUniform2f(scale_reverse->location, width_scale_rev, height_scale_rev);
77  },
78  output_image->texture_width,
79  output_image->texture_height);
80  }
81  }
82 }
83 
84 namespace caffe2 {
85 
86 template <class T>
87 class OpenGLResizeNearestOp final : public Operator<CPUContext>, ImageAllocator<T> {
88  public:
89  OpenGLResizeNearestOp(const OperatorDef& operator_def, Workspace* ws)
90  : Operator<CPUContext>(operator_def, ws), width_scale_(1), height_scale_(1) {
91  if (HasArgument("width_scale")) {
92  width_scale_ = static_cast<float>(OperatorBase::GetSingleArgument<float>("width_scale", 1));
93  }
94  if (HasArgument("height_scale")) {
95  height_scale_ = static_cast<float>(OperatorBase::GetSingleArgument<float>("height_scale", 1));
96  }
97  }
98 
99  bool RunOnDevice() override {
100  const GLImageVector<T>& input = Inputs()[0]->template Get<GLImageVector<T>>();
101  const int num_images = input.size();
102  const int input_width = input.width();
103  const int input_height = input.height();
104  const int input_channels = input.channels();
105 
106  const int output_width = input_width * width_scale_;
107  const int output_height = input_height * height_scale_;
108  const int output_channels = input_channels;
109 
110  const int input_tile_x = input.tile_x(), input_tile_y = input.tile_y();
111  const int output_tile_x = input_tile_x, output_tile_y = input_tile_y;
112 
113  int is_last = OperatorBase::GetSingleArgument<int>("is_last", 0);
115  num_images, output_width, output_height, output_channels, output_tile_x, output_tile_y, is_last);
116 
117  if (!resizeNearest_) {
118  resizeNearest_.reset(new GLResizeNearest());
119  }
120  resizeNearest_->resize(input, *output, 1.0 / width_scale_, 1.0 / height_scale_);
121  Outputs()[0]->Reset(output);
122 
123  return true;
124  }
125 
126  protected:
127  float width_scale_;
128  float height_scale_;
129  std::unique_ptr<GLResizeNearest> resizeNearest_;
130 };
131 
132 REGISTER_CPU_OPERATOR(OpenGLResizeNearest, OpenGLResizeNearestOp<float16_t>);
133 OPERATOR_SCHEMA(OpenGLResizeNearest).NumInputs(1).NumOutputs(1);
134 
135 } // namespace caffe2
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 ...