Tensor Tiling Library
 
Loading...
Searching...
No Matches
TTL_cpp/TTL_tensors.h
Go to the documentation of this file.
1/*
2 * TTL_tensors_common.h
3 *
4 * Copyright (c) 2025 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#pragma once
20
21#include "TTL_types.h"
22
23/************************************************************************************************************
24 * Allow for sizeof anything - deals with sizeof(void)
25 ************************************************************************************************************/
26
27/**
28 * @def TTL_SIZEOF
29 *
30 * @brief opencl doesn't like sizeof(void) so for it to be 1 like normal c
31 *
32 * OpenCl will produce error: invalid application of 'sizeof' to a void type
33 *
34 * This will need to be expanded with more types - or a different language used!
35 */
36#define TTL_SIZEOF(type) sizeof(type)
37
38/************************************************************************************************************
39 * Define Layout
40 ***********************************************************************************************************/
41
42/**
43 * @brief Description of a Tensor layout in memory
44 *
45 * Each logical tensor is embedded in both global and local memories within some
46 * enclosing physical tensors.
47 *
48 * This embedding is referred to as 'layout', which specifies the actual distance in elements
49 * between the start of consecutive data elements in each dimension.
50 *
51 * For the first axis the distance is always 1 element and and so this value is not stored.
52 *
53 * line_length and plane_area in memory, in units of an element.
54 */
55struct TTL_layout {
56 /**
57 * @brief Create a 3D Description of a Tensor layout in memory
58 *
59 * @see TTL_layout for more information.
60 *
61 * @param row_spacing; The distance between the start of consequtive rows in units of elements.
62 * @param plane_spacing; The distance between the start of consequtive planes in units of elements.
63 *
64 */
67
68 TTL_dim row_spacing; ///< The distance between the start of consequtive rows in units of elements.
69 TTL_dim plane_spacing; ///< The distance between the start of consequtive planes in units of elements.
70};
71
72/**
73 * @brief Calculate the absolute linear offset in elements, based on a given
74 * tensor offset and layout
75 *
76 * @param offset The 3D offset of the required linear offset.
77 * @param layout The layout of the offset being calculated
78 *
79 * @return The offset in linear address space of the 3D offset
80 */
81static inline TTL_offset_dim TTL_linearize(const TTL_offset &offset, const TTL_layout &layout) {
82 return ((offset.z * layout.plane_spacing) + (offset.y * layout.row_spacing) + offset.x);
83}
84
85/************************************************************************************************************
86 * Structure of a tensor
87 ***********************************************************************************************************/
88
89/**
90 * @brief A poor mans base class for an a tensor in the passed address space
91 *
92 * TTL_tensor contains both the logical dimensions of a tile as well as
93 * its physical mapping to memory.
94 *
95 * @param TTL_scope The scope of the creation can be TTL_global or TTL_local
96 * @param const_1 The const name to place after the prefix - should be empty or const_
97 * @param location The location of the tensor - should be ext or int
98 * @param type The type of the tensor - should be any valid c type
99 * @param const_2 The const type to create - should be empty or const
100 */
101template <typename TENSORTYPE>
103 /**
104 * @brief TTL_tensor(TTL_create_, const_2, location, type, sub, _5_params)
105 *
106 * @param base The ## TTL_scope ## base address of the tensor in ## location ## memory
107 * @param shape Description of the shape of the tensor that base points
108 * @param layout The layout of the ## location ## tensor
109 * @param offset The offset of the tensor from the base. @see TTL_offset
110 * @param elem_size The size of a single element in the
111 *
112 * @return return a TTL_tensor(TTL_, const_1, location, type, sub, _t)
113 */
114 TTL_tensor(TENSORTYPE *base, const TTL_shape &shape, const TTL_layout &layout, const TTL_offset &offset,
115 const TTL_dim elem_size)
117
118 /**
119 * @brief Create an empty location tensor. Empty means it has all dimensions set
120 * to zero
121 *
122 * Most operations on an empty tensor should turn into no-ops and so an empty
123 * tensor is the safest default state.
124 */
126
127 /**
128 * @brief Create an empty location tensor. Empty means it has all dimensions set
129 * to zero
130 *
131 * Most operations on an empty tensor should turn into no-ops and so an empty
132 * tensor is the safest default state.
133 */
134 // TTL_tensor(const TTL_tensor &tensor)
135 // : TTL_tensor(tensor.base, tensor.shape, tensor.layout, TTL_offset(), tensor.elem_size){};
136
137 /**
138 * @brief TTL_tensor(TTL_create_, const_1, location, type, sub, )
139 *
140 * @param base The ## TTL_scope ## base address of the tensor in ## location ## memory
141 * @param shape Description of the shape of the tensor that base points
142 * @param layout The layout of the ## location ## tensor
143 * @param elem_size The size of a single element in the tensor
144 *
145 * @details
146 * The layout of the created tensor will have an offset of (0, 0, 0)
147 *
148 * @return return a TTL_tensor(TTL_, const_1, location, type, sub, _t)
149 */
150 TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout, const TTL_dim elem_size)
152
153 /**
154 * @brief TTL_tensor(TTL_create_, const_1, location, type, sub, )
155 *
156 * @param base A pointer to a global address
157 * @param shape Description of the shape of the tensor that base points
158 * @param layout The layout of the ## location ## tensor
159 *
160 * @details
161 * The layout of the created tensor will have an offset of (0, 0, 0)\n
162 * The element size is inferred from the base_address pointer type.\n
163 *
164 * @return return a TTL_tensor(TTL_, const_1, location, type, sub, _t)
165 */
166 TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout)
168
169 /**
170 * @brief TTL_tensor(TTL_create_, const_1, location, type, sub, )
171 *
172 * @param base A pointer to a global address
173 * @param shape Description of the shape of the tensor that base points to
174 * @param elem_size The size of a single element in the tensor
175 *
176 * @details
177 * Layout is inferred from the shape.
178 * Offset is taken to be zero.
179 *
180 * @return return a TTL_tensor(TTL_, const_1, location, type, sub, _t)
181 */
182 TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_dim elem_size)
183 : TTL_tensor(base, shape, TTL_layout(shape.width, shape.height), TTL_offset(), elem_size) {}
184
185 /**
186 * @brief TTL_tensor(TTL_create_, const_1, location, type, sub, )
187 *
188 * @param base A pointer to a global address
189 * @param shape Description of the shape of the tensor that base points to
190 *
191 * @details
192 * Element size is inferred from the base_address pointer type.
193 * Layout is inferred from the shape.
194 * Offset is taken to be zero.
195 *
196 * @return return a TTL_tensor(TTL_, const_1, location, type, sub, _t)
197 */
198 TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape)
199 : TTL_tensor(base, shape, TTL_layout(shape.width, shape.height), TTL_offset(), TTL_SIZEOF(*base)) {}
200
201 /**
202 * @brief Cast a TTL_tensor(_, const_1, location, type, , ) to a TTL_tensor(TTL_,
203 * const_1, location, type, , _t)
204 *
205 * This is a safe cast, and implimented as a function with helper macro for type safety
206 *
207 * @param tensor The TTL_tensor(TTL_, , location, type, , _t) to be cast to a
208 * TTL_tensor(TTL_, const_1, location, type, , _t)
209 *
210 * @return A TTL_tensor(TTL_, const_1, location, type, , _t) version of the input tensor
211 */
215
216 /**
217 * @brief Read a value from a tensor
218 *
219 * @param x The offset in the x dimension
220 * @param y The offset in the y dimension
221 * @param z The offset in the z dimension
222 *
223 * No bounds checking is performed.
224 *
225 * @return The value read
226 */
227 const TENSORTYPE &read(const unsigned int x, const unsigned int y = 0, const unsigned int z = 0) const {
228 return base[x + (layout.row_spacing * y) + (layout.plane_spacing * z)];
229 }
230
231 /**
232 * @brief Write a value to a tensor
233 *
234 * @param value The value to write
235 * @param x The offset in the x dimension
236 * @param y The offset in the y dimension
237 * @param z The offset in the z dimension
238 */
239 TENSORTYPE write(const TENSORTYPE value, const unsigned int x, const unsigned int y = 0, const unsigned int z = 0) {
240 base[x + (layout.row_spacing * y) + (layout.plane_spacing * z)] = value;
241 return value;
242 }
243
244 /**
245 * @brief A Tensor is empty if its shape is empty @see TTL_shape_empty
246 *
247 * @param tensor The tensor to test for emptiness
248 *
249 * @return true is the tensor is empty
250 * @return false is the tensor is not empty
251 */
252 bool empty() {
253 return shape.empty();
254 }
255
256 TENSORTYPE *base; /*!< The base address of the tensor in the local address space */
257 TTL_dim elem_size; /*!< The sizeof the elements in the tensor */
258 TTL_layout layout; /*!< The layout of the tensor, @see TTL_layout */
259 TTL_shape shape; /*!< The shape of the tensor in 3 dimensions */
260};
261
262/**
263 * @brief A tensor plus its reference to its parent tensor
264 *
265 * TTL_sub_tensor contains both the logical dimensions of a tile as well as
266 * its physical mapping to memory.
267 *
268 * @param TTL_scope The scope of the creation can be TTL_global or TTL_local
269 * @param const_1 The const name to place after the prefix - should be empty or const_
270 * @param location The location of the tensor - should be ext or int
271 * @param type The type of the tensor - should be any valid c type
272 * @param const_2 The const type to create - should be empty or const
273 */
274template <typename TENSORTYPE>
276 /**
277 * @brief TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _7_params)
278 *
279 * @param base The ## TTL_scope ## base address of the tensor in ## location ## memory
280 * @param shape Description of the shape of the tensor that base points
281 * @param layout The layout of the ## location ## tensor
282 * @param elem_size The size of a single element in the
283 * @param offset The offset of the tensor from the base. @see TTL_offset
284 * @param origin_shape The shape of the tensor that originated the sub tensor
285 * @param origin_offset The offset of the tensor from the souce tensor. @see TTL_offset
286 *
287 * @return return a TTL_sub_tensor(TTL_, const_1, location, type, sub, _t)
288 */
289 TTL_sub_tensor(TENSORTYPE *base, const TTL_shape &shape, const TTL_layout &layout, const TTL_dim elem_size,
290 const TTL_offset offset, const TTL_shape origin_shape, TTL_offset origin_offset)
291 : tensor(base, shape, layout, offset, elem_size), origin(origin_shape, origin_offset) {}
292
293 /**
294 * @brief TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _5_params)
295 *
296 * @param base The ## TTL_scope ## base address of the tensor in ## location ## memory
297 * @param shape Description of the shape of the tensor that base points
298 * @param layout The layout of the ## location ## tensor
299 * @param origin_tensor The tensor that originated the sub tensor
300 * @param sub_offset The offset of the tensor from the souce tensor. @see TTL_offset
301 *
302 * @details
303 * The element size of the tensor is taken from the origin tensor
304 * The offset of the sub tensor is taken to be (0, 0, 0)
305 *
306 * @return return a TTL_sub_tensor(TTL_, const_1, location, type, sub, _t)
307 */
308 TTL_sub_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout,
309 const TTL_tensor<TENSORTYPE> &origin_tensor, const TTL_offset &sub_offset)
310 : TTL_sub_tensor(base, shape, layout, origin_tensor.elem_size, TTL_offset(), origin_tensor.shape, sub_offset) {}
311
312 /**
313 * @brief TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _2_params)
314 *
315 * Simply create a sub_tensor from an origin tensor
316 *
317 * @param base The ## TTL_scope ## base address of the tensor in ## location ## memory
318 * @param origin_tensor The tensor that originated the sub tensor
319 *
320 * @details
321 * The element size of the tensor is taken from the origin tensor
322 * The offset of the sub tensor is taken to be (0, 0, 0)
323 * The offset of the sub tensor relative to the source tensor is taken to be (0, 0, 0)
324 *
325 * @return return a TTL_sub_tensor(TTL_, const_1, location, type, sub, _t)
326 */
327 TTL_sub_tensor(TENSORTYPE const base, const TTL_tensor<TENSORTYPE> &origin_tensor)
328 : TTL_sub_tensor(base, origin_tensor.shape, origin_tensor.layout, origin_tensor.elem_size, TTL_offset(),
329 origin_tensor.shape, TTL_offset()) {}
330
331 /**
332 * @brief TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _1_param)
333 *
334 * Simply create a sub_tensor from an origin tensor
335 *
336 * @param origin_tensor The tensor that originated the sub tensor
337 *
338 * @details
339 * Effective creates a sub-tensor that is a tensor covering 100% of the source tensor
340 *
341 * @return return a TTL_sub_tensor(TTL_, const_1, location, type, sub, _t)
342 */
344 : TTL_sub_tensor(origin_tensor.base, origin_tensor.shape, origin_tensor.layout, origin_tensor.elem_size,
345 TTL_offset(), origin_tensor.shape, TTL_offset()) {}
346
347 /**
348 * @brief Create an empty tiled internal tensor. Empty means it has all dimensions set
349 * to zero
350 *
351 * Most operations on an empty tensor should turn into no-ops and so an empty
352 * tensor is the safest default state.
353 */
355
356 /**
357 * @brief Read a value from a sub_tensor
358 *
359 * @param x The offset in the x dimension
360 * @param y The offset in the y dimension
361 * @param z The offset in the z dimension
362 *
363 * No bounds checking is performed.
364 *
365 * @return The value read
366 */
367 const TENSORTYPE &read(const unsigned int x, const unsigned int y = 0, const unsigned int z = 0) const {
368 return tensor.read(x, y, z);
369 }
370
371 /**
372 * @brief Write a value to a sub_tensor
373 *
374 * @param value The value to write
375 * @param x The offset in the x dimension
376 * @param y The offset in the y dimension
377 * @param z The offset in the z dimension
378 */
379 TENSORTYPE write(const TENSORTYPE value, const unsigned int x, const unsigned int y = 0, const unsigned int z = 0) {
380 return tensor.write(value, x, y, z);
381 }
382
383 /**
384 * @brief A Tensor is empty if its shape is empty @see TTL_shape_empty
385 *
386 * @param tensor The tensor to test for emptiness
387 *
388 * @return true is the tensor is empty
389 * @return false is the tensor is not empty
390 */
391 bool empty() {
392 return tensor.empty();
393 }
394 struct Origin {
395 /**
396 * @Brief Store of the origin information.
397 *
398 * @param shape The shape of the origin tensor in 3 dimensions
399 * @param sub_offset The offset of the sub tensor from the origin sensor
400 */
402
403 TTL_shape shape; ///< The shape of the origin tensor in 3 dimensions
404 TTL_offset sub_offset; ///< The offset of the sub tensor from the origin sensor
405 };
406
409};
#define TTL_SIZEOF(type)
opencl doesn't like sizeof(void) so for it to be 1 like normal c
static TTL_offset_dim TTL_linearize(const TTL_offset &offset, const TTL_layout &layout)
Calculate the absolute linear offset in elements, based on a given tensor offset and layout.
uint32_t TTL_dim
The type used to hold the size of an object along any dimension.
int32_t TTL_offset_dim
The type used to hold offsets and origins.
Description of a Tensor layout in memory.
TTL_dim plane_spacing
The distance between the start of consequtive planes in units of elements.
TTL_dim row_spacing
The distance between the start of consequtive rows in units of elements.
TTL_layout(const TTL_dim row_spacing=0, const TTL_dim plane_spacing=0)
Create a 3D Description of a Tensor layout in memory.
Description of the 3D offset of an object.
TTL_offset_dim z
Offset in dimension z.
TTL_offset_dim y
Offset in dimension y.
TTL_offset_dim x
Offset in dimension x.
Description of a Shape.
Origin(TTL_shape shape, TTL_offset sub_offset)
TTL_offset sub_offset
The offset of the sub tensor from the origin sensor.
TTL_shape shape
The shape of the origin tensor in 3 dimensions.
TTL_sub_tensor(const TTL_tensor< TENSORTYPE > &origin_tensor)
TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _1_param)
TTL_sub_tensor()
Create an empty tiled internal tensor. Empty means it has all dimensions set to zero.
TTL_sub_tensor(TENSORTYPE const base, const TTL_tensor< TENSORTYPE > &origin_tensor)
TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _2_params)
TTL_tensor< TENSORTYPE > tensor
TTL_sub_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout, const TTL_tensor< TENSORTYPE > &origin_tensor, const TTL_offset &sub_offset)
TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _5_params)
const TENSORTYPE & read(const unsigned int x, const unsigned int y=0, const unsigned int z=0) const
Read a value from a sub_tensor.
TENSORTYPE write(const TENSORTYPE value, const unsigned int x, const unsigned int y=0, const unsigned int z=0)
Write a value to a sub_tensor.
bool empty()
A Tensor is empty if its shape is empty.
TTL_sub_tensor(TENSORTYPE *base, const TTL_shape &shape, const TTL_layout &layout, const TTL_dim elem_size, const TTL_offset offset, const TTL_shape origin_shape, TTL_offset origin_offset)
TTL_sub_tensor(TTL_create_, const_1, location, type, sub, _7_params)
A poor mans base class for an a tensor in the passed address space.
bool empty()
A Tensor is empty if its shape is empty.
TENSORTYPE write(const TENSORTYPE value, const unsigned int x, const unsigned int y=0, const unsigned int z=0)
Write a value to a tensor.
TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout, const TTL_dim elem_size)
Create an empty location tensor. Empty means it has all dimensions set to zero.
TTL_tensor()
Create an empty location tensor. Empty means it has all dimensions set to zero.
const TENSORTYPE & read(const unsigned int x, const unsigned int y=0, const unsigned int z=0) const
Read a value from a tensor.
TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape)
TTL_tensor(TTL_create_, const_1, location, type, sub, )
TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_dim elem_size)
TTL_tensor(TTL_create_, const_1, location, type, sub, )
TTL_tensor(TENSORTYPE *const base, const TTL_shape &shape, const TTL_layout &layout)
TTL_tensor(TTL_create_, const_1, location, type, sub, )
TTL_tensor(TENSORTYPE *base, const TTL_shape &shape, const TTL_layout &layout, const TTL_offset &offset, const TTL_dim elem_size)
TTL_tensor(TTL_create_, const_2, location, type, sub, _5_params)
TENSORTYPE * base