Caffe2 - C++ API
A deep learning, cross platform ML framework
GLSub.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 GLSub : public GLFilter {
12  public:
13  binding* inputData[2];
14  binding* outputSize;
15 
16  GLSub()
17  : GLFilter("GLSub",
18  vertex_shader,
19  fragment_shader,
20  std::vector<binding*>({BINDING(outputSize), BINDING(inputData[0]), BINDING(inputData[1])}),
21  {/* no uniform blocks */},
22  {/* no attributes */},
23  {/* no replacements */}) {}
24 
25  template <typename T>
26  void sub(const GLImageVector<T>& input_image0,
27  const GLImageVector<T>& input_image1,
28  const GLImageVector<T>& output_image);
29 
30  static const char* fragment_shader;
31 };
32 
33 // MARK: GLSL
34 
35 const char* GLSub::fragment_shader = R"GLSL(#version 300 es
36 
37 precision mediump float;
38 precision mediump int;
39 
40 in highp vec2 v_texCoord;
41 
42 uniform ivec2 outputSize;
43 
44 TEXTURE_INPUT(inputData[2]);
45 TEXTURE_OUTPUT(0, outputData);
46 
47 void main() {
48  ivec2 texelCoord = ivec2(v_texCoord * vec2(outputSize));
49  vec4 A = TEXTURE_LOAD(inputData[0], texelCoord);
50  vec4 B = TEXTURE_LOAD(inputData[1], texelCoord);
51  vec4 value = A - B;
52  outputData = TEXTURE_STORE(value);}
53 
54 )GLSL";
55 
56 template <typename T>
57 void GLSub::sub(const GLImageVector<T>& input_images0,
58  const GLImageVector<T>& input_images1,
59  const GLImageVector<T>& output_images) {
60  const int num_images = input_images0.size();
61  for (int i = 0; i < num_images; i++) {
62  GLImage<T>* input_image0 = input_images0[i];
63  GLImage<T>* input_image1 = input_images1[i];
64  int input_slices = input_image0->slices;
65  GLImage<T>* output_image = output_images[i];
66  int output_slices = output_image->slices;
67 
68  for (int is = 0; is < input_slices; is++) {
69  std::vector<texture_attachment> input_attachments;
70  input_attachments.push_back({input_image0->textures[is], inputData[0]});
71  input_attachments.push_back({input_image1->textures[is], inputData[1]});
72 
73  run(input_attachments,
74  {output_image->textures.begin() + is, output_image->textures.begin() + is + 1},
75  [&]() { glUniform2i(outputSize->location, output_image->width, output_image->height); },
76  output_image->width,
77  output_image->height);
78  }
79  }
80 }
81 
82 namespace caffe2 {
83 template <typename T>
84 class OpenGLSubOp final : public Operator<CPUContext>, ImageAllocator<T> {
85  public:
86  OpenGLSubOp(const OperatorDef& operator_def, Workspace* ws)
87  : Operator<CPUContext>(operator_def, ws) {
88  OPERATOR_NEEDS_FEATURE(OperatorBase::HasArgument("broadcast") == false, "OpenGLSub does not support broadcast");
89 
90  OPERATOR_NEEDS_FEATURE(OperatorBase::HasArgument("axis") == false, "OpenGLSub does not support axis");
91  }
92 
93  bool RunOnDevice() override {
94  const GLImageVector<T>& input0 = Inputs()[0]->template Get<GLImageVector<T>>();
95  const GLImageVector<T>& input1 = Inputs()[1]->template Get<GLImageVector<T>>();
96 
97  CAFFE_ENFORCE_EQ(input0.size(), input1.size());
98 
99  const int num_images = input0.size();
100  const int input_channels = input0.channels();
101  const int input_width = input0.width();
102  const int input_height = input0.height();
103  CAFFE_ENFORCE_EQ(input1.channels(), input_channels);
104  CAFFE_ENFORCE_EQ(input1.width(), input_width);
105  CAFFE_ENFORCE_EQ(input1.height(), input_height);
106 
107  const int output_channels = input_channels;
108  const int output_width = input_width;
109  const int output_height = input_height;
110 
111  int is_last = OperatorBase::GetSingleArgument<int>("is_last", 0);
112 
114  num_images, output_width, output_height, output_channels, is_last);
115 
116  if (!_sub) {
117  _sub.reset(new GLSub());
118  }
119 
120  _sub->sub(input0, input1, *output);
121 
122  Outputs()[0]->Reset(output);
123 
124  return true;
125  }
126 
127  private:
128  std::unique_ptr<GLSub> _sub;
129 };
130 
131 REGISTER_CPU_OPERATOR(OpenGLSub, OpenGLSubOp<float16_t>);
132 OPERATOR_SCHEMA(OpenGLSub).NumInputs(2).NumOutputs(1);
133 } // 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 ...
Definition: GLSub.cc:11