Caffe2 - C++ API
A deep learning, cross platform ML framework
GLImage.h
1 
2 #pragma once
3 
4 #include "GLTexture.h"
5 #include "caffe2/core/logging.h"
6 
7 #include <functional>
8 #include <vector>
9 
10 template <typename T>
11 class GLImage {
12  public:
13  const int width;
14  const int height;
15  const int channels;
16  const int data_size;
17 
18  const int tile_x;
19  const int tile_y;
20  const int texture_width;
21  const int texture_height;
22  const int slices;
23 
24  const std::vector<const GLTexture*> textures;
25 
26  constexpr static int slice_channels = 4;
27 
28  static constexpr int channels_to_slices(int channels, int tile_x, int tile_y) {
29  return ((channels + slice_channels - 1) / slice_channels + tile_x * tile_y - 1) /
30  (tile_x * tile_y);
31  }
32 
33  static const std::vector<const GLTexture*> allocate_textures(
34  int slices, std::function<const GLTexture*(int slice)> texture_loader) {
35  std::vector<const GLTexture*> textures;
36  for (int i = 0; i < slices; i++) {
37  textures.push_back(texture_loader(i));
38  }
39  return textures;
40  }
41 
42  GLImage(int _width,
43  int _height,
44  int _channels,
45  int _tile_x,
46  int _tile_y,
47  std::function<const GLTexture*(int slice)> texture_loader)
48  : width(_width),
49  height(_height),
50  channels(_channels),
51  data_size(sizeof(T)),
52  tile_x(_tile_x),
53  tile_y(_tile_y),
54  texture_width(_width * _tile_x),
55  texture_height(_height * _tile_y),
56  slices(channels_to_slices(_channels, _tile_x, _tile_y)),
57  textures(allocate_textures(slices, texture_loader)) {
58  CAFFE_ENFORCE_EQ(
59  slices, ((channels + 3) / 4 + tile_x * tile_y - 1) / (tile_x * tile_y));
60  }
61 
62  GLImage(int _width,
63  int _height,
64  int _channels,
65  int _tile_x,
66  int _tile_y,
67  bool _destroy,
68  std::function<const GLTexture*(int slice)> texture_loader)
69  : width(_width),
70  height(_height),
71  channels(_channels),
72  data_size(sizeof(T)),
73  tile_x(_tile_x),
74  tile_y(_tile_y),
75  texture_width(_width * _tile_x),
76  texture_height(_height * _tile_y),
77  slices(channels_to_slices(_channels, _tile_x, _tile_y)),
78  textures(allocate_textures(slices, texture_loader)) {
79  CAFFE_ENFORCE_EQ(slices * tile_x * tile_y, (channels + 3) / 4);
80  }
81 
82  GLImage()
83  : width(0),
84  height(0),
85  channels(0),
86  data_size(sizeof(T)),
87  tile_x(0),
88  tile_y(0),
89  texture_width(0),
90  texture_height(0),
91  slices(0){};
92 
93  virtual ~GLImage() {
94  gl_log(GL_VERBOSE, "deleting GLImage\n");
95  for (auto&& texture : textures) {
96  delete texture;
97  }
98  }
99 };
100 
101 template <typename T>
103  private:
104  std::vector<GLImage<T>*> images_;
105  int num_images_ = 0;
106  int width_ = 0;
107  int height_ = 0;
108  int channels_ = 0;
109  int tile_x_ = 0;
110  int tile_y_ = 0;
111 
112  public:
113  GLImage<T>* operator[](int index) const {
114  CAFFE_ENFORCE_LT(index, num_images_, "Out of bounds when accessing GLImageVector");
115  return images_[index];
116  }
117 
118  void push_back(GLImage<T>* image) {
119  CAFFE_ENFORCE_EQ(image->channels, channels_);
120  CAFFE_ENFORCE_EQ(image->width, width_);
121  CAFFE_ENFORCE_EQ(image->height, height_);
122  CAFFE_ENFORCE_EQ(image->tile_x, tile_x_);
123  CAFFE_ENFORCE_EQ(image->tile_y, tile_y_);
124  images_.push_back(image);
125  CAFFE_ENFORCE_LE(images_.size(), num_images_);
126  }
127 
128  int size() const { return images_.size(); }
129  int channels() const { return channels_; }
130  int width() const { return width_; }
131  int height() const { return height_; }
132  int tile_x() const { return tile_x_; }
133  int tile_y() const { return tile_y_; }
134  int slices() const { return size() > 0 ? images_[0]->slices : 0; }
135 
136  GLImageVector(int num_images, int width, int height, int channels, int tile_x = 1, int tile_y = 1)
137  : num_images_(num_images),
138  width_(width),
139  height_(height),
140  channels_(channels),
141  tile_x_(tile_x),
142  tile_y_(tile_y) {}
143 
144  GLImageVector() {}
145 
146  ~GLImageVector() {
147  for (int i = 0; i < images_.size(); i++) {
148  delete images_[i];
149  }
150  }
151 };