Tensor Tiling Library
 
Loading...
Searching...
No Matches
TTL_tiles.h
Go to the documentation of this file.
1/*
2 * TTL_tiles.h
3 *
4 * Copyright (c) 2023 Mobileye
5 *
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/******************************************************
20 * AUGMENTATION
21 *****************************************************/
22
23/**
24 * @brief Augment an input tensor with logical padding
25 *
26 * When an input tensor is imported using a tiler the resulting tensors
27 * may have elements beyond the space of the original tensor. In terms of the
28 * origin tensor the subtensor may for example start at offset(-1, -1, -1) in
29 * this case the elements at (-1, -1, -1), (-1, 0, 0) etc. needed to be created
30 * from a process of augmentation.
31 *
32 * Currently the only dynamic part of the augmentation is the size of the
33 * augmentation the augmented values are simply hardcode.
34 *
35 * A TTL_augmented_dim_t is the number of elements to augment.
36 */
37
38typedef unsigned char TTL_augmented_dim_t; ///< A number of a "augmented" elements in the unit of elements
39
40/**
41 * @brief 3D description of the augmented margins
42 *
43 * TTL_augmentation_t represents the number of elements that a tensor will be expanded in each dimension.
44 *
45 * For example if left = 1 then one column of elements will be added to a tensor thereby increasing its width by 1.
46 *
47 * The type used to hold the augmentation of tiles along all dimensions
48 */
49typedef struct {
50 TTL_augmented_dim_t left; ///< Left hand augmentation in elements
51 TTL_augmented_dim_t right; ///< Right hand augmentation in elements
52 TTL_augmented_dim_t top; ///< Top augmentation in elements
53 TTL_augmented_dim_t bottom; ///< Bottom augmentation in elements
54 TTL_augmented_dim_t front; ///< Front augmentation in elements
55 TTL_augmented_dim_t back; ///< Back augmentation in elements
57
58/**
59 * @brief Create a 3D Description of a Tile augmentation
60 *
61 * @see TTL_overlap_t for more information.
62 *
63 * @param left ///< Left hand augmentation in elements
64 * @param right ///< Right hand augmentation in elements
65 * @param top ///< Top augmentation in elements
66 * @param bottom ///< Bottom augmentation in elements
67 * @param front ///< Front augmentation in elements
68 * @param back ///< Back augmentation in elements
69 *
70 * @return A TTL_augmentation_t describing in 3D the overlap requested.
71 */
72static inline TTL_augmentation_t __attribute__((overloadable)) TTL_create_augmentation(
73 const TTL_augmented_dim_t left, const TTL_augmented_dim_t right, const TTL_augmented_dim_t top,
74 const TTL_augmented_dim_t bottom, const TTL_augmented_dim_t front, const TTL_augmented_dim_t back) {
75 const TTL_augmentation_t res = { left, right, top, bottom, front, back };
76 return res;
77}
78
79/**
80 * @brief Create a 2D Description of a Tile augmentation
81 *
82 * @see TTL_overlap_t for more information.
83 *
84 * @param left ///< Left hand augmentation in elements
85 * @param right ///< Right hand augmentation in elements
86 * @param top ///< Top augmentation in elements
87 * @param bottom ///< Bottom augmentation in elements
88 *
89 * front and back default to 0
90 *
91 * @return A TTL_augmentation_t describing in 3D the overlap requested.
92 */
93static inline TTL_augmentation_t __attribute__((overloadable)) TTL_create_augmentation(TTL_augmented_dim_t left,
96 TTL_augmented_dim_t bottom) {
97 return TTL_create_augmentation(left, right, top, bottom, 0, 0);
98}
99
100/**
101 * @brief Create a 1D Description of a Tile augmentation
102 *
103 * @see TTL_overlap_t for more information.
104 *
105 * @param left ///< Left hand augmentation in elements
106 * @param right ///< Right hand augmentation in elements
107 *
108 * top, bottom, front and back default to 0
109 *
110 * @return A TTL_augmentation_t describing in 3D the overlap requested.
111 */
112static inline TTL_augmentation_t __attribute__((overloadable)) TTL_create_augmentation(TTL_augmented_dim_t left,
113 TTL_augmented_dim_t right) {
114 return TTL_create_augmentation(left, right, 0, 0, 0, 0);
115}
116
117/***
118 * @brief A Tile is described by its Shape and the offset from the beginning of
119 * the Space
120 *
121 * The type used to hold a tile of a space having a given shape and offset from
122 * the beginning of the space
123 */
124typedef struct {
125 TTL_shape_t shape; ///< @see TTL_shape_t
126 TTL_offset_t offset; ///< @see TTL_offset_t
127} TTL_tile_t;
128
129/**
130 * @brief TTL_tiler_t is the basic unit that describes how a tile is subdivided.
131 *
132 * The TTL_tiler_t type represents the tiling of a 3D space into 3D tiles with
133 * operational overlap
134 */
135typedef struct {
136 TTL_shape_t space; ///< Represents the space to be tiled such as an image
137 TTL_shape_t tile; ///< All tiles will be of this shape, except for clamping at
138 ///< the end of the space
139 TTL_overlap_t overlap; ///< When zeroes represent no overlap
140 TTL_augmentation_t augmentation; ///< The augmentation that the tile produces.
141
142 /**
143 * @brief Precomputed information to speed up later reuse
144 */
145 struct {
151 } cache;
153
154/**
155 * @brief Return the number of tiles that this tile can produce.
156 *
157 * @param tiler The tiler in question.
158 *
159 * @return int The number of tiles produced by the tiler.
160 */
161static inline int TTL_number_of_tiles(TTL_tiler_t tiler) {
162 return tiler.cache.number_of_tiles;
163}
164
165/**
166 * @brief Given a tile ID return true or false to indicate if the id is valid
167 *
168 * @param tile_id The ID to validate.
169 * @param tiler The tiler in question.
170 *
171 * @return int The number of tiles produced by the tiler.
172 */
173static inline int TTL_valid_tile_id(int tile_id, TTL_tiler_t tiler) {
174 return ((tile_id >= 0) && (tile_id < (int)tiler.cache.number_of_tiles));
175}
176
177/**
178 * @brief Return the ceil value of a/b i.e. ceil(a/b)
179 *
180 * Implementation of ceil(a/b) without requiring a library or floating-point.
181 *
182 * Internal TTL function not part of the API.
183 *
184 * @param a The dividend to use in the calculation
185 * @param b The divisor to use in the calculation
186 *
187 * @todo b is a shape dimension of a tensor, so it is not zero. Remove dynamic
188 * check for zero b, w/o crashing the compiler.
189 */
190static inline int TTL_ceil_of_a_div_b(const int a, const int b) {
191 return b ? ((a + b - 1) / b) : 0;
192}
193
194/**
195 * @brief Return a TTL_tiler_t based on a shape, a tile, and an overlap
196 *
197 * @param tensor_shape The shape to be tiled
198 * @param tile_shape The description of the tile that the shape will be sub-divided to.
199 * @param overlap The overlap between tiles
200 * @param augmentation The augomentation to apply at the edges durring import.
201 *
202 * Complete description of what not how here.
203 *
204 * @return A tiler that can produce a tile for any given index.
205 */
206static inline TTL_tiler_t TTL_create_overlap_tiler(const TTL_shape_t tensor_shape, const TTL_shape_t tile_shape,
207 const TTL_overlap_t overlap, const TTL_augmentation_t augmentation) {
208 const TTL_dim_t tiles_in_width = TTL_ceil_of_a_div_b(
209 tensor_shape.width + augmentation.left + augmentation.right - overlap.width, tile_shape.width - overlap.width);
210 const TTL_dim_t tiles_in_height =
211 TTL_ceil_of_a_div_b(tensor_shape.height + augmentation.top + augmentation.bottom - overlap.height,
212 tile_shape.height - overlap.height);
213 const TTL_dim_t tiles_in_depth = TTL_ceil_of_a_div_b(
214 tensor_shape.depth + augmentation.front + augmentation.back - overlap.depth, tile_shape.depth - overlap.depth);
215
216 const TTL_dim_t tiles_in_plane = tiles_in_width * tiles_in_height;
217 const TTL_dim_t number_of_tiles = tiles_in_plane * tiles_in_depth;
218
219 const TTL_tiler_t result = { tensor_shape,
220 tile_shape,
221 overlap,
222 augmentation,
223 { number_of_tiles, tiles_in_width, tiles_in_height, tiles_in_depth, tiles_in_plane } };
224
225 return result;
226}
227
228// Simplify creation of non-overlap tiler
229static inline TTL_tiler_t TTL_create_tiler(const TTL_shape_t shape, const TTL_shape_t tile) {
230 const TTL_overlap_t overlap = TTL_create_overlap(0);
231 const TTL_augmentation_t augmentation = TTL_create_augmentation(0, 0);
232 return TTL_create_overlap_tiler(shape, tile, overlap, augmentation);
233}
234
236 return t.cache.tiles_in_width;
237}
238
240 return t.cache.tiles_in_height;
241}
242
244 return t.cache.tiles_in_depth;
245}
246
247/**
248 * @brief Check if the tile passed is empty.
249 *
250 * Empty is defined as width of the shape being equal to 0.
251 *
252 * @param tile The tile to check the emptiness of.
253 *
254 * @return true if shape is empty
255 * @return false if shape is not empty
256 */
257static inline int TTL_tile_empty(TTL_tile_t tile) {
258 return TTL_shape_empty(tile.shape);
259}
260
261/**
262 * @brief Create an empty tile. Empty means it has all dimensions set to zero
263 *
264 * Most operations on an empty tile should turn into no-ops and so an empty tile
265 * is the safest default state.
266 */
268 TTL_tile_t result = { TTL_create_shape(0), TTL_create_offset(0, 0, 0) };
269 return result;
270}
271
272/**
273 * @brief Returns a tile at a position from a tiler and respective coordinates.
274 *
275 * @param x The x position of the tile being created
276 * @param y The y position of the tile being created
277 * @param z The z position of the tile being created
278 * @param tiler The tiler from which the tiler can be calculated.
279 *
280 * @return The created TTL_tile_t type
281 */
283 TTL_tile_t result;
284
285 // Calculate the offset in 3D
286 result.offset = TTL_create_offset((x * (tiler.tile.width - tiler.overlap.width)) - tiler.augmentation.left,
287 (y * (tiler.tile.height - tiler.overlap.height)) - tiler.augmentation.top,
288 (z * (tiler.tile.depth - tiler.overlap.depth)) - tiler.augmentation.front);
289
290 // Set the tile shape, clamping at the end of each dimension
291 result.shape = tiler.tile;
292
293 if (x == tiler.cache.tiles_in_width - 1)
294 result.shape.width = tiler.space.width - result.offset.x + tiler.augmentation.right;
295
296 if (y == tiler.cache.tiles_in_height - 1)
297 result.shape.height = tiler.space.height - result.offset.y + tiler.augmentation.bottom;
298
299 if (z == tiler.cache.tiles_in_depth - 1)
300 result.shape.depth = tiler.space.depth - result.offset.z + tiler.augmentation.back;
301
302 return result;
303}
304
305/**
306 * @brief Return the tile_id'th tile of a tile array in row-major order.
307 *
308 * Return the tile_id'th tile, starting from tile_id=0, in row-major order.
309 * Returns an invalid tile if tile_id is not valid (not from [0,
310 number_of_tiles))
311
312 * @param tile_id The tile id to return - if out of bounds then an invalid tile
313 is returned
314 * @param tiler The containing with the shape and tiling information
315 *
316 * @return The tile that is represented by tile_id when interpreted in row-major
317 order.
318 */
319static inline TTL_tile_t TTL_get_tile(const int tile_id, const TTL_tiler_t tiler) {
320 if (!TTL_valid_tile_id(tile_id, tiler)) {
321 TTL_tile_t invalid = { 0 };
322 return invalid;
323 }
324
325 // Compute the 3D coordinates of the tile in order to compute its offset
326 const TTL_dim_t z = tile_id / tiler.cache.tiles_in_plane;
327 const TTL_dim_t tid_in_plane = tile_id % tiler.cache.tiles_in_plane;
328 const TTL_dim_t y = tid_in_plane / tiler.cache.tiles_in_width;
329 const TTL_dim_t x = tid_in_plane % tiler.cache.tiles_in_width;
330
331 return TTL_create_tile(x, y, z, tiler);
332}
333
334/**
335 * @brief Return the tile_id'th tile of a tile array in column-major order.
336 *
337 * Return the tile_id'th tile, starting from tile_id=0, in column-major order.
338 * Returns an invalid tile if tile_id is not valid (not from [0,
339 number_of_tiles))
340
341 * @param tile_id The tile id to return - if out of bounds then an invalid tile
342 is returned
343 * @param tiler The tiler containing the shape and tiling information
344 *
345 * @return The tile that is represented by tile_id when interpreted in
346 column-major order.
347 */
348static inline TTL_tile_t TTL_get_tile_column_major(const int tile_id, const TTL_tiler_t tiler) {
349 // Compute the 3D coordinates of the tile in order to compute its offset
350 const TTL_dim_t z = tile_id / tiler.cache.tiles_in_plane;
351 const TTL_dim_t tid_in_plane = tile_id % tiler.cache.tiles_in_plane;
352 const TTL_dim_t y = tid_in_plane % tiler.cache.tiles_in_height;
353 const TTL_dim_t x = tid_in_plane / tiler.cache.tiles_in_height;
354
355 return TTL_create_tile(x, y, z, tiler);
356}
static TTL_dim_t TTL_tiles_in_height(TTL_tiler_t t)
Definition TTL_tiles.h:239
static int TTL_valid_tile_id(int tile_id, TTL_tiler_t tiler)
Given a tile ID return true or false to indicate if the id is valid.
Definition TTL_tiles.h:173
static TTL_tile_t TTL_get_tile_column_major(const int tile_id, const TTL_tiler_t tiler)
Return the tile_id'th tile of a tile array in column-major order.
Definition TTL_tiles.h:348
static int TTL_tile_empty(TTL_tile_t tile)
Check if the tile passed is empty.
Definition TTL_tiles.h:257
unsigned char TTL_augmented_dim_t
Augment an input tensor with logical padding.
Definition TTL_tiles.h:38
static TTL_tile_t TTL_get_tile(const int tile_id, const TTL_tiler_t tiler)
Return the tile_id'th tile of a tile array in row-major order.
Definition TTL_tiles.h:319
static int TTL_number_of_tiles(TTL_tiler_t tiler)
Return the number of tiles that this tile can produce.
Definition TTL_tiles.h:161
static TTL_dim_t TTL_tiles_in_width(TTL_tiler_t t)
Definition TTL_tiles.h:235
static TTL_tile_t TTL_create_tile(TTL_dim_t x, TTL_dim_t y, TTL_dim_t z, TTL_tiler_t tiler)
Returns a tile at a position from a tiler and respective coordinates.
Definition TTL_tiles.h:282
static TTL_tile_t TTL_create_empty_tile()
Create an empty tile. Empty means it has all dimensions set to zero.
Definition TTL_tiles.h:267
static TTL_augmentation_t TTL_create_augmentation(const TTL_augmented_dim_t left, const TTL_augmented_dim_t right, const TTL_augmented_dim_t top, const TTL_augmented_dim_t bottom, const TTL_augmented_dim_t front, const TTL_augmented_dim_t back)
Create a 3D Description of a Tile augmentation.
Definition TTL_tiles.h:72
static TTL_tiler_t TTL_create_overlap_tiler(const TTL_shape_t tensor_shape, const TTL_shape_t tile_shape, const TTL_overlap_t overlap, const TTL_augmentation_t augmentation)
Return a TTL_tiler_t based on a shape, a tile, and an overlap.
Definition TTL_tiles.h:206
static TTL_tiler_t TTL_create_tiler(const TTL_shape_t shape, const TTL_shape_t tile)
Definition TTL_tiles.h:229
static int TTL_ceil_of_a_div_b(const int a, const int b)
Return the ceil value of a/b i.e. ceil(a/b)
Definition TTL_tiles.h:190
static TTL_dim_t TTL_tiles_in_depth(TTL_tiler_t t)
Definition TTL_tiles.h:243
unsigned int TTL_dim_t
The type used to hold the size of an object along any dimension.
3D description of the augmented margins
Definition TTL_tiles.h:49
TTL_augmented_dim_t right
Right hand augmentation in elements.
Definition TTL_tiles.h:51
TTL_augmented_dim_t back
Back augmentation in elements.
Definition TTL_tiles.h:55
TTL_augmented_dim_t bottom
Bottom augmentation in elements.
Definition TTL_tiles.h:53
TTL_augmented_dim_t top
Top augmentation in elements.
Definition TTL_tiles.h:52
TTL_augmented_dim_t left
Left hand augmentation in elements.
Definition TTL_tiles.h:50
TTL_augmented_dim_t front
Front augmentation in elements.
Definition TTL_tiles.h:54
Description of the 3D offset of an object.
TTL_offset_dim_t z
Offset in dimension z.
TTL_offset_dim_t y
Offset in dimension y.
TTL_offset_dim_t x
Offset in dimension x.
Description of the overlap in 3D space of adjacent tiles.
TTL_overlap_dim_t depth
depth overlap in elements
TTL_overlap_dim_t height
height overlap in elements
TTL_overlap_dim_t width
width overlap in elements
Description of a Shape.
TTL_dim_t depth
Number of planes along dimension z.
TTL_dim_t width
Number of elements along dimension x.
TTL_dim_t height
Number of rows along dimension y.
TTL_offset_t offset
Definition TTL_tiles.h:126
TTL_shape_t shape
Definition TTL_tiles.h:125
TTL_tiler_t is the basic unit that describes how a tile is subdivided.
Definition TTL_tiles.h:135
TTL_dim_t tiles_in_width
Definition TTL_tiles.h:147
struct TTL_tiler_t::@346103000177117034076065313020113027262217277043 cache
Precomputed information to speed up later reuse.
TTL_shape_t tile
Definition TTL_tiles.h:137
TTL_overlap_t overlap
When zeroes represent no overlap.
Definition TTL_tiles.h:139
TTL_dim_t tiles_in_depth
Definition TTL_tiles.h:149
TTL_augmentation_t augmentation
The augmentation that the tile produces.
Definition TTL_tiles.h:140
TTL_dim_t tiles_in_plane
Definition TTL_tiles.h:150
TTL_shape_t space
Represents the space to be tiled such as an image.
Definition TTL_tiles.h:136
TTL_dim_t tiles_in_height
Definition TTL_tiles.h:148
TTL_dim_t number_of_tiles
Definition TTL_tiles.h:146
static bool TTL_shape_empty(TTL_shape_t shape)
A Shape is empty if its width is 0.
static TTL_overlap_t TTL_create_overlap(const TTL_overlap_dim_t width, const TTL_overlap_dim_t height, const TTL_overlap_dim_t depth)
Create a 3D Description of a Tile overlap.
static TTL_shape_t TTL_create_shape(TTL_dim_t width, TTL_dim_t height, TTL_dim_t depth)
Create a description of a Shape.
static TTL_offset_t TTL_create_offset(void)
Returns a TTL_offset_t.