Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
SOFIE_common.cxx
Go to the documentation of this file.
2
3#include <cctype>
4#include <sstream>
5#include <stdexcept>
6#include <charconv>
7#include <unordered_map>
8#include <set>
9
10namespace TMVA {
11namespace Experimental {
12namespace SOFIE {
13
14/// @brief Convert shape from integer format to dynamic one (based on Dim)
15/// @param shape
16/// @return shape based on Dim
17std::vector<Dim> ConvertShapeToDim(const std::vector<size_t> & shape){
18 std::vector<Dim> ret_shape(shape.size());
19 for (size_t i =0; i < shape.size(); i++){
20 ret_shape[i].dim = shape[i];
21 }
22 return ret_shape;
23}
24
25/// @brief Convert shape based on Dim to integer format
26/// @param shape
27/// @return shape based on integer. Return an empty shape in case shape is dynamic (has a parameter)
28std::vector<size_t> ConvertShapeToInt(const std::vector<Dim> & shape){
29 std::vector<size_t> ret_shape(shape.size());
30 for (size_t i =0; i < shape.size(); i++){
31 if (shape[i].isParam) {
32 // try converting to integer in case string is a number >=0
33 int val = -1;
34 try {
35 val = std::stoi(shape[i].param);
36 if (val >= 0) ret_shape[i] = static_cast<size_t>(val);
37 else {
38 ret_shape.clear();
39 break;
40 }
41 }
42 catch (const std::invalid_argument& ) {
43 ret_shape.clear();
44 break;
45 }
46 catch (const std::out_of_range& ) {
47 ret_shape.clear();
48 break;
49 }
50 } else {
51 ret_shape[i] = shape[i].dim;
52 }
53 }
54 return ret_shape;
55}
56
57
58std::size_t ConvertShapeToLength(const std::vector<size_t> & shape){
59 // Empty shape represent scalar values, so we return a length=1
60 std::size_t fLength = 1;
61 for (const auto &dim : shape)
62 fLength *= dim;
63 return fLength;
64}
65
67 switch(type){
68 case ETensorType::FLOAT : {
69 return "float";
70 }
71 case ETensorType::INT8 : {
72 return "int8_t";
73 }
74 case ETensorType::INT16 : {
75 return "int16_t";
76 }
77 case ETensorType::INT32 : {
78 return "int32_t";
79 }
80 case ETensorType::INT64 : {
81 return "int64_t";
82 }
83 case ETensorType::UINT8 : {
84 return "uint8_t";
85 }
86 case ETensorType::UINT16 : {
87 return "uint16_t";
88 }
89 case ETensorType::UINT32 : {
90 return "uint32_t";
91 }
92 case ETensorType::UINT64 : {
93 return "uint64_t";
94 }
95 case ETensorType::DOUBLE : {
96 return "double";
97 }
98 case ETensorType::BOOL : {
99 return "uint8_t";
100 }
101 default:{
102 return "other_" + std::to_string( (int) type);
103 }
104 }
105}
106
107// invert function might now work correctly for booleans
108// prefer avoid using it if possible
110 if(type == "float32" || type == "float" || type == "Float"){
111 return ETensorType::FLOAT;
112 }
113 else if(type == "int64" || type == "int64_t"){
114 return ETensorType::INT64;
115 }
116 else if(type == "int32" || type == "int32_t"){
117 return ETensorType::INT32;
118 }
119 else if (type == "double" || type == "float64"){
120 return ETensorType::DOUBLE;
121 }
122 else if (type == "bool" || type == "uint8_t" ){
123 return ETensorType::BOOL;
124 }
125 else{
127 }
128}
129
130std::string ConvertShapeToString(const std::vector<size_t> & shape) {
131 std::stringstream out;
132 out << "{ ";
133 for (size_t i = 0; i < shape.size(); i++) {
134 out << shape[i];
135 if (i < shape.size()-1) out << " , ";
136 }
137 out << " }";
138 return out.str();
139}
140
141std::string ConvertDimShapeToString(const std::vector<Dim> & shape) {
142 std::stringstream out;
143 out << "{ ";
144 for (size_t i = 0; i < shape.size(); i++) {
145 out << shape[i];
146 if (i < shape.size()-1) out << " , ";
147 }
148 out << " }";
149 return out.str();
150}
151
152std::string ConvertDimShapeToLength(const std::vector<Dim> & shape) {
153 // convert generic shape to a string
154 // multiply all the integer specified dimensions of the shape
155 std::string length;
156 // case of empty vectors return 1
157 if (shape.empty()) return "1";
158 int64_t int_length = -1;
159 for (size_t i = 0; i < shape.size(); i++) {
160 if (shape[i].isParam) {
161 if (!length.empty()) length += " * ";
162 length += shape[i].param;
163 } else {
164 if (int_length == -1)
165 int_length = shape[i].dim;
166 else
167 int_length *= shape[i].dim;
168 }
169 }
170 // multiply the integer components to the parametric one
171 // if larger than 1 - otherwise returns -1
172 if (int_length >= 0) {
173 if (!length.empty() && int_length > 1) {
174 length += " * ";
175 length += std::to_string(int_length);
176 } else if (length.empty()) { // case is full known shape
177 length = std::to_string(int_length);
178 }
179 }
180 return length;
181}
182
183
184namespace{
185template<typename T>
186static inline void copy_vector_data(int_t no_of_copies, int_t input_size, T* input, T* target){ //only visible within this translation unit
187 std::memcpy(target, input, input_size * sizeof(T));
189
190 while (already_copied * 2 <= no_of_copies){
191 std::memcpy(target + already_copied * input_size, target, already_copied * input_size * sizeof(T));
192 already_copied *= 2;
193 }
194
196 std::memcpy(target + already_copied * input_size, target, (no_of_copies - already_copied) * input_size * sizeof(T));
197 }
198}
199}
200
201bool IsInteger(const std::string & s) {
202 int value;
203 auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value);
204 return ec == std::errc() && ptr == s.data() + s.size();
205}
206
207bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<size_t>& shapeB) {
208 if (shapeA.size() != shapeB.size()) {
209 return false;
210 }
211 for (size_t dim = 0; dim < shapeA.size(); dim++) {
212 if (shapeA[dim] != shapeB[dim]) {
213 return false;
214 }
215 }
216 return true;
217}
218bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<Dim>& shapeB) {
219 if (shapeA.size() != shapeB.size()) {
220 return false;
221 }
222 for (size_t dim = 0; dim < shapeA.size(); dim++) {
223 if (shapeB[dim].isParam) return false;
224 if (shapeA[dim] != shapeB[dim].dim) {
225 return false;
226 }
227 }
228 return true;
229}
230bool UTILITY::AreSameShape(const std::vector<Dim>& shapeA, const std::vector<Dim>& shapeB) {
231 if (shapeA.size() != shapeB.size()) {
232 return false;
233 }
234 for (size_t dim = 0; dim < shapeA.size(); dim++) {
235 if (shapeA[dim].GetVal() != shapeB[dim].GetVal()) {
236 return false;
237 }
238 }
239 return true;
240}
241
242std::vector<size_t> UTILITY::MultidirectionalBroadcastShape(std::vector<std::vector<size_t>> shape)
243{
244 if (shape.size() < 2) {
245 throw
246 std::runtime_error("TMVA::SOFIE - MultidirectionalBroadcastShape requires at least 2 input shapes.");
247 }
248 // Number of input shapes to broadcast
249 size_t n = shape.size();
250 // Size of the output shape
251 size_t targetSize = shape[0].size();
252 for (size_t i = 1; i < n; i++) {
253 targetSize = std::max(targetSize, shape[i].size());
254 }
255 // Check if they have the same size
256 bool sameSize = true;
257 for (size_t i = 0; i < n; i++) {
258 if (shape[i].size() != targetSize) {
259 sameSize = false;
260 break;
261 }
262 }
263 if (sameSize) {
264 // Check if they have the same shape
265 bool sameShape = true;
266 for (size_t i = 1; i < n; i++) {
267 for (size_t dim = 0; dim < shape[0].size(); dim++) {
268 if (shape[i][dim] != shape[0][dim]) {
269 sameShape = false;
270 break;
271 }
272 }
273 if (!sameShape) {
274 break;
275 }
276 }
277 if (sameShape) {
278 return shape[0];
279 } else {
280 // Set the target shape
281 std::vector<size_t> targetShape(targetSize, 1);
282 for (size_t i = 0; i < n; i++) {
283 for (size_t dim = 0; dim < targetSize; dim++) {
284 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
285 }
286 }
287 // Check if the input shapes are broadcastable to targetShape
288 bool broadcastable = true;
289 for (size_t i = 0; i < n; i++) {
290 for (size_t dim = 0; dim < targetSize; dim++) {
291 if (shape[i][dim] != 1 && targetShape[dim] != 1 && shape[i][dim] != targetShape[dim]) {
292 broadcastable = false;
293 break;
294 }
295 if (!broadcastable) {
296 break;
297 }
298 }
299 }
300 // They have the same shape and they are broadcastable to targetShape
301 if (broadcastable) {
302 return targetShape;
303 } else {
304 std::stringstream ss;
305 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
306 for (size_t i = 0; i < n; i++) {
307 ss << ConvertShapeToString(shape[i]);
308 if (n > 2 && i < n - 2) {
309 ss << ", ";
310 } else if ( n >=2 && i == n - 2) {
311 ss << " and ";
312 }
313 }
314 ss << " to the same shape.";
315 throw
316 std::runtime_error(ss.str());
317 }
318 } // end sameShape
319 } // end sameSize
320 // Prepend the ith shape with ones
321 for (size_t i = 0; i < n; i++) {
322 if (shape[i].size() < targetSize) {
323 std::vector<size_t> newShape(targetSize, 1);
324 size_t offset = targetSize - shape[i].size();
325 std::copy(shape[i].begin(), shape[i].end(), newShape.begin() + offset);
326 shape[i] = newShape;
327 }
328 }
329 // Set the target shape
330 std::vector<size_t> targetShape(targetSize, 1);
331 for (size_t i = 0; i < n; i++) {
332 for (size_t dim = 0; dim < targetSize; dim++) {
333 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
334 }
335 }
336 // Check if the shapes are broadcastable to targetShape
337 bool broadcastable = true;
338 for (size_t i = 0; i < n; i++) {
339 for (size_t dim = 0; dim < targetSize; dim++) {
340 if (shape[i][dim] != targetShape[dim] && shape[i][dim] != 1 && targetShape[dim] != 1) {
341 broadcastable = false;
342 break;
343 }
344 }
345 if (!broadcastable) {
346 break;
347 }
348 }
349 if (broadcastable) {
350 return targetShape;
351 } else {
352 std::stringstream ss;
353 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
354 for (size_t i = 0; i < n; i++) {
355 ss << ConvertShapeToString(shape[i]);
356 if (n > 2 && i < n - 2) {
357 ss << ", ";
358 } else if ( n >=2 && i == n - 2) {
359 ss << " and ";
360 }
361 }
362 ss << " to the same shape.";
363 throw
364 std::runtime_error(ss.str());
365 }
366}
367
368// check multi-directional broadcasting of two shapes (need to pass inputs by non const ref. since we might prepends with one's
369// return a pair of integer flag and new broadcasted shape
370// if flag = 0: shape are identical
371// flag = 1: return shape is equal to A, we broadcast B
372// flag = 2: return shape is equal to B we broadcast A
373// flag = 3: return shape is common of two we broadcast A and B to output
374std::pair<int, std::vector<size_t>> UTILITY::MultidirectionalBroadcastShape(std::vector<size_t> & shapeA, std::vector<size_t> & shapeB)
375{
376 size_t sizeA = shapeA.size();
377 size_t sizeB = shapeB.size();
378 // Check if A and B have the same shape
380 return std::make_pair(0, shapeA);
381 }
382 // Find the common shape of A and B
383 size_t size = std::max(sizeA, sizeB);
384 if (sizeA < size) {
385 // prepend 1's in A to make of same shape as B
386 std::vector<size_t> newShapeA(size, 1);
387 size_t offset = size - sizeA;
388 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() + offset);
389 shapeA = std::move(newShapeA);
390 }
391 if (sizeB < size) {
392 std::vector<size_t> newShapeB(size, 1);
393 size_t offset = size - sizeB;
394 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() + offset);
395 shapeB = std::move(newShapeB);
396 }
397 bool broadcastable = true;
398 for (size_t i = 0; i < size; i++) {
399 if (shapeA[i] != shapeB[i] && shapeA[i] != 1 && shapeB[i] != 1) {
400 broadcastable = false;
401 break;
402 }
403 }
404 int broadcastFlag = 0;
405 if (broadcastable) {
406 // The output shape is max(outShape, targetShape)
407 std::vector<size_t> targetShape(size, 1);
408 for (size_t i = 0; i < size; i++) {
409 targetShape[i] = std::max(shapeA[i], shapeB[i]);
410 if (shapeB[i] < targetShape[i]) broadcastFlag |= 1;
411 if (shapeA[i] < targetShape[i]) broadcastFlag |= 2;
412 }
413 return std::make_pair(broadcastFlag, targetShape);
414 } else {
415 throw
416 std::runtime_error("TMVA::SOFIE - Error multidirectional broadcasting tensors of shape "
418 + " to a common shape.");
419 }
420}
421// unidirectional broadcast- of shape A to target B
422std::vector<size_t> UTILITY::UnidirectionalBroadcastShape(std::vector<size_t> & shapeA, std::vector<size_t> & shapeB)
423{
425 if (ret.first > 1) {
426 throw
427 std::runtime_error("TMVA::SOFIE - Error unidirectional broadcasting tensors of shape "
429 + " in a common shape.");
430 }
431 return ret.second;
432}
433
434// for broadcasting Dim shapes
435// flag indicates also which vector needs to be broadcasted
436// flag & 1 == 1 : broadcast B -> A
437// flag & 2 == 2 : broadcast A -> B
438// flag & 4 == 4 a run time check is needed on shapes with values
439std::pair<int, std::vector<Dim>> UTILITY::MultidirectionalBroadcastShape(std::vector<Dim> & shapeA, std::vector<Dim> & shapeB) {
440 size_t sizeA = shapeA.size();
441 size_t sizeB = shapeB.size();
442 // Check if A and B have the same shape
444 return std::make_pair(0, shapeA);
445 }
446 // Find the common shape of A and B
447 size_t size = std::max(sizeA, sizeB);
448 if (sizeA < size) {
449 // prepend 1's in A to make of same shape as B
450 std::vector<Dim> newShapeA(size, Dim{1});
451 size_t offset = size - sizeA;
452 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() + offset);
453 shapeA = std::move(newShapeA);
454 }
455 if (sizeB < size) {
456 std::vector<Dim> newShapeB(size, Dim{1});
457 size_t offset = size - sizeB;
458 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() + offset);
459 shapeB = std::move(newShapeB);
460 }
461
462 int broadcastFlag = 0;
463 // The output shape is targetShape
464 std::vector<Dim> targetShape(size);
465 for (size_t i = 0; i < size; i++) {
466 // assume we broadcast to the parametric value
467 if (shapeA[i] == shapeB[i]) {
468 targetShape[i] = shapeA[i];
469 } else if (shapeA[i].isParam && shapeB[i].GetVal() == "1" ) {
470 // broadcast B to A (case A is parametric with )
471 targetShape[i] = shapeA[i];
472 broadcastFlag |= 1;
473 } else if (shapeA[i].GetVal() == "1" && shapeB[i].isParam) {
474 // broadcast A to B
475 targetShape[i] = shapeB[i];
476 broadcastFlag |= 2;
477 } else if (!shapeA[i].isParam && !shapeB[i].isParam) {
478 if (shapeB[i].dim == 1) {
479 targetShape[i] = shapeA[i];
480 broadcastFlag |= 1;
481 } else if (shapeA[i].dim == 1) {
482 targetShape[i] = shapeB[i];
483 broadcastFlag |= 2;
484 } else {
485 // non broadcastable case cannot have A and B two different defined shapes different than one
486 broadcastFlag = -1;
487 }
488 } else if (shapeA[i].isParam && shapeB[i].isParam) {
489 // full dynamic case - we will decided at run time
490 std::stringstream s;
491 s << "std::max(" << shapeA[i] << "," << shapeB[i] << ")";
492 // use -1 for dim to indicate is an expression
493 targetShape[i] = Dim { s.str() , static_cast<size_t>(-1)};
494 broadcastFlag |= 4;
495 } else if (shapeA[i].isParam && !shapeB[i].isParam) {
496 // A -> B need to check at run time if consistent
497 targetShape[i] = shapeB[i];
498 broadcastFlag |= 6;
499 } else if (!shapeA[i].isParam && shapeB[i].isParam) {
500 // B -> A need to check at run time if consistent
501 targetShape[i] = shapeA[i];
502 broadcastFlag |= 5;
503 } else {
504 // all cases should be covered
505 throw std::runtime_error("TMVA::SOFIE - Fatal error in MultiDirectionalBroadCastDimShape");
506 }
507 }
508 if (broadcastFlag == -1) {
509 throw std::runtime_error("TMVA::SOFIE - Error multidirectional broadcasting tensors of shape " +
511 " to a common shape.");
512 }
513
514 return std::make_pair(broadcastFlag, targetShape);
515}
516
517std::string UTILITY::Clean_name(std::string input_tensor_name){
518 std::string s (input_tensor_name);
519 std::replace( s.begin(), s.end(), '-', '_');
520 // replace all non-alpohanumeric character except for "_"
521 s.erase(std::remove_if(s.begin(), s.end(), []( char const& c ) -> bool { return !std::isalnum(static_cast<unsigned char>(c)) && c != '_'; } ), s.end());
522 return s;
523}
524
525std::vector<size_t> UTILITY::ComputeStrideFromShape(const std::vector<size_t> & shape) {
526 // assume row major layout
527 const auto size = shape.size();
528 std::vector<size_t> strides(size,1);
529 for (std::size_t i = 1; i < size; i++) {
530 strides[size - 1 - i] = strides[size - i ] * shape[size - i];
531 }
532 return strides;
533}
534
535std::vector<Dim> UTILITY::ComputeStrideFromShape(const std::vector<Dim> & shape) {
536 // assume row major layout
537 const auto size = shape.size();
538 std::vector<Dim> strides(size);
539 if (size > 0) {
540 strides[size-1] = Dim{1};
541 for (std::size_t i = 1; i < size; i++) {
542 if (!shape[size-i].isParam && !strides[size-i].isParam)
543 strides[size - 1 - i] = Dim{strides[size-i].dim * shape[size-i].dim};
544 else {
545 if (strides[size-i].GetVal() == "1")
546 strides[size - 1 - i] = shape[size-i];
547 else if (shape[size-i].GetVal() == "1")
548 strides[size - 1 - i] = strides[size-i];
549 else
550 strides[size - 1 - i] = Dim{std::string(strides[size-i].GetVal() + "*" + shape[size-i].GetVal())};
551 }
552 }
553 }
554 return strides;
555}
556
557// utilities functions for generating code
558
559// ------------------------------------------------------------------ //
560// Emit 'rank' nested for-loops: for(size_t idx_i=0; idx_i<dim_i; ) //
561// ------------------------------------------------------------------ //
562const std::string SP = " ";
563void EmitNestedLoops(std::stringstream &out, size_t loopRank, const std::vector<Dim> shape) {
564 for (size_t i = 0; i < loopRank; ++i) {
565 for (size_t s = 0; s < i + 2; ++s) out << SP;
566
567 out << "for (size_t idx_" << i << " = 0; idx_" << i
568 << " < " << shape[i] << "; ++idx_" << i << ") {\n";
569 }
570}
571void CloseNestedLoops(std::stringstream &out, size_t loopRank) {
572 for (int64_t i = loopRank - 1; i >= 0; --i) {
573 for (int64_t s = 0; s < i + 2; ++s) out << SP;
574 out << "}\n";
575 }
576}
577
578
579} // namespace SOFIE
580} // namespace Experimental
581} // namespace TMVA
#define c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
const_iterator begin() const
const_iterator end() const
const Int_t n
Definition legend1.C:16
bool AreSameShape(const std::vector< size_t > &, const std::vector< size_t > &)
std::vector< size_t > UnidirectionalBroadcastShape(std::vector< size_t > &, std::vector< size_t > &)
std::string Clean_name(std::string input_tensor_name)
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
std::vector< size_t > ComputeStrideFromShape(const std::vector< size_t > &shape)
compute stride of a tensor given its shape (assume layout is row-major)
std::string ConvertDimShapeToString(const std::vector< Dim > &shape)
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
std::vector< Dim > ConvertShapeToDim(const std::vector< size_t > &shape)
Convert shape from integer format to dynamic one (based on Dim)
std::vector< size_t > ConvertShapeToInt(const std::vector< Dim > &shape)
Convert shape based on Dim to integer format.
std::string ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
void EmitNestedLoops(std::stringstream &out, size_t loopRank, const std::vector< Dim > shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
void CloseNestedLoops(std::stringstream &out, size_t loopRank)
bool IsInteger(const std::string &s)
create variable transformations