Beatmup
cnn.cpp
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2020, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "cnn.h"
20 
21 #ifdef ENABLE_PROFILING
22 #include "../../../utils/profiler.h"
23 #include <iostream>
24 #endif
25 
26 
27 using namespace Beatmup;
28 
29 GLES20X2UpsamplingNetwork::Layer::Layer(GL::RecycleBin& recycleBin, GraphicPipeline& gpu, Storage& outputStorage, const char* sourceCode):
30  shader(recycleBin), output(outputStorage)
31 {
32  shader.setSourceCode(sourceCode);
33 }
34 
35 
37  // reshape or instantiate output if needed
38  bool sizeChange = false;
39  if (output && (output->getWidth() != input.getWidth() || output->getHeight() != input.getHeight())) {
40  output->reshape(input.getWidth(), input.getHeight());
41  sizeChange = true;
42  }
43  else if (!output) {
44  output = new InternalBitmap(ctx, PixelFormat::QuadByte, input.getWidth(), input.getHeight(), false);
45  sizeChange = true;
46  }
47 
48  // reset size if needed
49  if (sizeChange) {
50  shader.setFloat("d1", 1.0f / input.getWidth(), 1.0f / input.getHeight());
51  shader.setFloat("d2", 2.0f / input.getWidth(), 2.0f / input.getHeight());
52  }
53 
54  // process
55  {
57  shader.prepare(gpu, &input, TextureParam::INTERP_NEAREST, output, AffineMapping::IDENTITY);
58  shader.process(gpu);
59  }
60 }
61 
62 
64  const InternalBitmap& input = inputs[0]->getOutput();
65  if (output && (output->getWidth() != input.getWidth() || output->getHeight() != input.getHeight()))
66  output->reshape(input.getWidth(), input.getHeight());
67  else if (!output)
68  output = new InternalBitmap(ctx, PixelFormat::QuadByte, input.getWidth(), input.getHeight(), false);
69 
70  // prepare and process
71  {
73  shader.setFloat("d1", 1.0f / input.getWidth(), 1.0f / input.getHeight());
74  shader.prepare(gpu, nullptr, output);
75 
76  // bind images
77  for (int i = 0; i < inputsCount; ++i)
78  gpu.bind(inputs[i]->getOutput(), i, TextureParam::INTERP_NEAREST);
79  shader.bindSamplerArray("images", 0, inputsCount);
80 
81  // process
82  shader.process(gpu);
83  }
84 }
85 
86 
88  // disable alpha blend
90  Context& ctx = output.getContext();
91 
92 #ifdef ENABLE_PROFILING
93  Profiler profiler;
94  profiler("layer 1");
95 #endif
96 
97  for (int i = 0; i < L1_SIZE; ++i)
98  layer1[i]->process(ctx, gpu, input);
99 
100 #ifdef ENABLE_PROFILING
101  gpu.flush();
102  profiler.lap();
103  profiler("layer 2");
104 #endif
105 
106  layer2[0]->process(ctx, gpu, layer1 + 0, 3);
107  layer2[1]->process(ctx, gpu, layer1 + 0, 3);
108  layer2[2]->process(ctx, gpu, layer1 + 3, 3);
109  layer2[3]->process(ctx, gpu, layer1 + 3, 3);
110  layer2[4]->process(ctx, gpu, layer1 + 6, 3);
111  layer2[5]->process(ctx, gpu, layer1 + 6, 3);
112  layer2[6]->process(ctx, gpu, layer1 + 9, 3);
113  layer2[7]->process(ctx, gpu, layer1 + 9, 3);
114 
115 #ifdef ENABLE_PROFILING
116  gpu.flush();
117  profiler.lap();
118  profiler("layer 3");
119 #endif
120 
121  for (int i = 0; i < L3_SIZE; ++i)
122  layer3[i]->process(ctx, gpu, layer2, L2_SIZE);
123 
124 #ifdef ENABLE_PROFILING
125  gpu.flush();
126  profiler.lap();
127  profiler("layer 4");
128 #endif
129 
130  layer4[0]->process(ctx, gpu, layer3 + 0, 3);
131  layer4[1]->process(ctx, gpu, layer3 + 0, 3);
132  layer4[2]->process(ctx, gpu, layer3 + 3, 3);
133  layer4[3]->process(ctx, gpu, layer3 + 3, 3);
134 
135 #ifdef ENABLE_PROFILING
136  gpu.flush();
137  profiler.lap();
138  profiler("layer 5");
139 #endif
140 
141  layer5->process(ctx, gpu, layer4, L4_SIZE);
142 
143 #ifdef ENABLE_PROFILING
144  gpu.flush();
145  profiler.lap();
146  profiler("demux");
147 #endif
148 
149  demux.setInteger("convnetOutput", 1);
152  demux.process(gpu);
153 
154  gpu.flush();
155 
156 #ifdef ENABLE_PROFILING
157  profiler.lap();
158  profiler.report(std::cout);
159 #endif
160 }
161 
162 
164  demux(recycleBin)
165 {
166  for (int i = 0; i < STORAGE_SIZE; ++i)
167  storage[i] = nullptr;
168 
169  int i = 0;
170 #define STRINGIFY(...) BEATMUP_SHADER_CODE(__VA_ARGS__)
171 
172  layer1[0] = new Layer(recycleBin, gpu, nextStorage(i),
173 #include "l1__0.glsl"
174  );
175 
176  layer1[1] = new Layer(recycleBin, gpu, nextStorage(i),
177 #include "l1__1.glsl"
178  );
179 
180  layer1[2] = new Layer(recycleBin, gpu, nextStorage(i),
181 #include "l1__2.glsl"
182  );
183 
184  layer1[3] = new Layer(recycleBin, gpu, nextStorage(i),
185 #include "l1__3.glsl"
186  );
187 
188  layer1[4] = new Layer(recycleBin, gpu, nextStorage(i),
189 #include "l1__4.glsl"
190  );
191 
192  layer1[5] = new Layer(recycleBin, gpu, nextStorage(i),
193 #include "l1__5.glsl"
194  );
195 
196  layer1[6] = new Layer(recycleBin, gpu, nextStorage(i),
197 #include "l1__6.glsl"
198  );
199 
200  layer1[7] = new Layer(recycleBin, gpu, nextStorage(i),
201 #include "l1__7.glsl"
202  );
203 
204  layer1[8] = new Layer(recycleBin, gpu, nextStorage(i),
205 #include "l1__8.glsl"
206  );
207 
208  layer1[9] = new Layer(recycleBin, gpu, nextStorage(i),
209 #include "l1__9.glsl"
210  );
211 
212  layer1[10] = new Layer(recycleBin, gpu, nextStorage(i),
213 #include "l1__10.glsl"
214  );
215 
216  layer1[11] = new Layer(recycleBin, gpu, nextStorage(i),
217 #include "l1__11.glsl"
218  );
219 
220 
221  layer2[0] = new Layer(recycleBin, gpu, nextStorage(i),
222 #include "l2-0__0.glsl"
223  );
224 
225  layer2[1] = new Layer(recycleBin, gpu, nextStorage(i),
226 #include "l2-0__1.glsl"
227  );
228 
229  layer2[2] = new Layer(recycleBin, gpu, nextStorage(i),
230 #include "l2-1__0.glsl"
231  );
232 
233  layer2[3] = new Layer(recycleBin, gpu, nextStorage(i),
234 #include "l2-1__1.glsl"
235  );
236 
237  layer2[4] = new Layer(recycleBin, gpu, nextStorage(i),
238 #include "l2-2__0.glsl"
239  );
240 
241  layer2[5] = new Layer(recycleBin, gpu, nextStorage(i),
242 #include "l2-2__1.glsl"
243  );
244 
245  layer2[6] = new Layer(recycleBin, gpu, nextStorage(i),
246 #include "l2-3__0.glsl"
247  );
248 
249  layer2[7] = new Layer(recycleBin, gpu, nextStorage(i),
250 #include "l2-3__1.glsl"
251  );
252 
253 
254  layer3[0] = new Layer(recycleBin, gpu, nextStorage(i),
255 #include "l3__0.glsl"
256  );
257 
258  layer3[1] = new Layer(recycleBin, gpu, nextStorage(i),
259 #include "l3__1.glsl"
260  );
261 
262  layer3[2] = new Layer(recycleBin, gpu, nextStorage(i),
263 #include "l3__2.glsl"
264  );
265 
266  layer3[3] = new Layer(recycleBin, gpu, nextStorage(i),
267 #include "l3__3.glsl"
268  );
269 
270  layer3[4] = new Layer(recycleBin, gpu, nextStorage(i),
271 #include "l3__4.glsl"
272  );
273 
274  layer3[5] = new Layer(recycleBin, gpu, nextStorage(i),
275 #include "l3__5.glsl"
276  );
277 
278 
279  layer4[0] = new Layer(recycleBin, gpu, nextStorage(i),
280 #include "l4-0__0.glsl"
281  );
282 
283  layer4[1] = new Layer(recycleBin, gpu, nextStorage(i),
284 #include "l4-0__1.glsl"
285  );
286 
287  layer4[2] = new Layer(recycleBin, gpu, nextStorage(i),
288 #include "l4-1__0.glsl"
289  );
290 
291  layer4[3] = new Layer(recycleBin, gpu, nextStorage(i),
292 #include "l4-1__1.glsl"
293  );
294 
295 
296  layer5 = new Layer(recycleBin, gpu, nextStorage(i),
297 #include "l5.glsl"
298  );
299 
301 #include "ycbcr_demuxer.glsl"
302  );
303 }
304 
305 
307  for (int i = 0; i < L1_SIZE; ++i)
308  delete layer1[i];
309  for (int i = 0; i < L2_SIZE; ++i)
310  delete layer2[i];
311  for (int i = 0; i < L3_SIZE; ++i)
312  delete layer3[i];
313  for (int i = 0; i < L4_SIZE; ++i)
314  delete layer4[i];
315  delete layer5;
316 
317  for (int i = 0; i < STORAGE_SIZE; ++i)
318  if (storage[i])
319  delete storage[i];
320 }
Makes a bitmap writable for a specific target device.
A very basic class for any image.
Context & getContext() const
static const AffineMapping IDENTITY
Definition: geometry.h:717
Basic class: task and memory management, any kind of static data.
Definition: context.h:59
Layer(GL::RecycleBin &recycleBin, GraphicPipeline &gpu, Storage &outputStorage, const char *sourceCode)
Definition: cnn.cpp:29
InternalBitmap & getOutput()
Definition: cnn.h:43
void process(Context &ctx, GraphicPipeline &gpu, GL::TextureHandler &input)
Definition: cnn.cpp:36
GLES20X2UpsamplingNetwork(GL::RecycleBin &recycleBin, GraphicPipeline &gpu)
Definition: cnn.cpp:163
static const int L1_SIZE
Definition: cnn.h:49
void process(GraphicPipeline &gpu, GL::TextureHandler &input, AbstractBitmap &output)
Definition: cnn.cpp:87
Layer * layer1[L1_SIZE]
Definition: cnn.h:58
InternalBitmap * storage[STORAGE_SIZE]
Definition: cnn.h:55
static const int L2_SIZE
Definition: cnn.h:50
static const int STORAGE_SIZE
Definition: cnn.h:53
static const int L4_SIZE
Definition: cnn.h:52
Layer * layer3[L3_SIZE]
Definition: cnn.h:60
Layer * layer2[L2_SIZE]
Definition: cnn.h:59
Layer * layer4[L4_SIZE]
Definition: cnn.h:61
static const int L3_SIZE
Definition: cnn.h:51
Layer::Storage & nextStorage(int &i)
Definition: cnn.h:66
Stores references to GPU resources that will not be used anymore and needed to be recycled in a threa...
Definition: recycle_bin.h:34
virtual const int getHeight() const =0
Height of the texture in pixels.
virtual const int getWidth() const =0
Width of the texture in pixels.
void setInteger(std::string name, int value)
Sets a scalar integer uniform value.
Internal low-level GPU control API.
Definition: pipeline.h:33
void switchMode(Mode mode)
Switches GPU mode.
Definition: pipeline.cpp:941
@ INFERENCE
Textures are feature maps computed in fragment shaders.
void flush()
Waits until all operations submitted to GPU are finished.
Definition: pipeline.cpp:931
void bind(GL::TextureHandler &texture, size_t texUnit, const TextureParam param)
Definition: pipeline.cpp:881
void process(GraphicPipeline &gpu)
Apply the shader to produce an image.
void prepare(GraphicPipeline &gpu, GL::TextureHandler *input, const TextureParam texParam, AbstractBitmap *output, const AffineMapping &mapping)
Conducts required preparations for blending.
void setSourceCode(const std::string &sourceCode)
Passes new source code to the fragment shader.
Bitmap whose memory is managed by the Beatmup engine.
const int getHeight() const
Height of the texture in pixels.
const int getWidth() const
Width of the texture in pixels.
void reshape(int width, int height)
Changes bitmap size.
Collects running time statistics of multiple tracks.
Definition: profiler.h:31
void report(std::ostream &, ReportType type=ReportType::FULL) const
Definition: profiler.cpp:56
@ QuadByte
4 channels of 8 bits per pixel (like RGBA), unsigned integer values
@ INTERP_LINEAR
bilinear pixel interpolation
@ INTERP_NEAREST
nearest neighbor pixel interpolation
Beatmup::Context * ctx