Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
SOFIE_common.cxx
Go to the documentation of this file.
2#include<cctype>
3#include <sstream>
4#include <stdexcept>
5
6namespace TMVA{
7namespace Experimental{
8namespace SOFIE{
9
10/// @brief Convert shape from integer format to dynamic one (based on Dim)
11/// @param shape
12/// @return shape based on Dim
13std::vector<Dim> ConvertShapeToDim(std::vector<size_t> shape){
14 std::vector<Dim> ret_shape(shape.size());
15 for (size_t i =0; i < shape.size(); i++){
16 ret_shape[i].dim = shape[i];
17 }
18 return ret_shape;
19}
20
21/// @brief Convert shape based on Dim to integer format
22/// @param shape
23/// @return shape based on integer. Return an empty shape in case shape is dynamic (has a parameter)
24std::vector<size_t> ConvertShapeToInt(std::vector<Dim> shape){
25 std::vector<size_t> ret_shape(shape.size());
26 for (size_t i =0; i < shape.size(); i++){
27 if (shape[i].isParam) {
28 // try converting to integer in case string is a number >=0
29 int val = -1;
30 try {
31 val = std::stoi(shape[i].param);
32 if (val >= 0) ret_shape[i] = static_cast<size_t>(val);
33 else {
34 ret_shape.clear();
35 break;
36 }
37 }
38 catch (const std::invalid_argument& ) {
39 ret_shape.clear();
40 break;
41 }
42 } else {
43 ret_shape[i] = shape[i].dim;
44 }
45 }
46 return ret_shape;
47}
48
49
50std::size_t ConvertShapeToLength(std::vector<size_t> shape){
51 // Empty shape represent scalar values, so we return a length=1
52 std::size_t fLength = 1;
53 for (auto& dim: shape) fLength *= dim;
54 return fLength;
55}
56
58 switch(type){
59 case ETensorType::FLOAT : {
60 return "float";
61 }
62 case ETensorType::INT16 : {
63 return "int16_t";
64 }
65 case ETensorType::INT32 : {
66 return "int32_t";
67 }
68 case ETensorType::INT64 : {
69 return "int64_t";
70 }
71 case ETensorType::UINT16 : {
72 return "uint16_t";
73 }
74 case ETensorType::UINT32 : {
75 return "uint32_t";
76 }
77 case ETensorType::UINT64 : {
78 return "uint64_t";
79 }
80 case ETensorType::DOUBLE : {
81 return "double";
82 }
83 case ETensorType::BOOL : {
84 return "bool";
85 }
86 default:{
87 return "other";
88 }
89 }
90}
91
93 if(type == "float32" || type == "float" || type == "Float"){
94 return ETensorType::FLOAT;
95 }
96 else if(type == "int64" || type == "int64_t"){
97 return ETensorType::INT64;
98 }
99 else if (type == "double" || type == "float64"){
100 return ETensorType::DOUBLE;
101 }
102 else if (type == "bool" ){
103 return ETensorType::BOOL;
104 }
105 else{
107 }
108}
109
110std::string ConvertShapeToString(std::vector<size_t> shape) {
111 std::stringstream out;
112 out << "{ ";
113 for (size_t i = 0; i < shape.size(); i++) {
114 out << shape[i];
115 if (i < shape.size()-1) out << " , ";
116 }
117 out << " }";
118 return out.str();
119}
120
121std::string ConvertDynamicShapeToString(std::vector<Dim> shape) {
122 std::stringstream out;
123 out << "{ ";
124 for (size_t i = 0; i < shape.size(); i++) {
125 out << shape[i].GetVal();
126 if (i < shape.size()-1) out << " , ";
127 }
128 out << " }";
129 return out.str();
130}
131
132std::string ConvertDynamicShapeToLength(std::vector<Dim> shape) {
133 // convert generic shape to a string
134 // multiply all the integer specified dimensions of the shape
135 std::string length;
136 size_t int_length = 0;
137 for (size_t i = 0; i < shape.size(); i++) {
138 if (shape[i].isParam) {
139 if (!length.empty()) length += " * ";
140 length += shape[i].param;
141 } else {
142 if (int_length == 0)
143 int_length = shape[i].dim;
144 else
145 int_length *= shape[i].dim;
146 }
147 }
148 // multiply the integer components to the parametric one
149 if (int_length > 0) {
150 if (!length.empty()) length += " * ";
151 length += std::to_string(int_length);
152 }
153 return length;
154}
155
156namespace{
157template<typename T>
158static inline void copy_vector_data(int_t no_of_copies, int_t input_size, T* input, T* target){ //only visible within this translation unit
159 std::memcpy(target, input, input_size * sizeof(T));
160 int_t already_copied = 1;
161
162 while (already_copied * 2 <= no_of_copies){
163 std::memcpy(target + already_copied * input_size, target, already_copied * input_size * sizeof(T));
164 already_copied *= 2;
165 }
166
167 if (already_copied < no_of_copies){
168 std::memcpy(target + already_copied * input_size, target, (no_of_copies - already_copied) * input_size * sizeof(T));
169 }
170}
171}
172
173bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<size_t>& shapeB) {
174 if (shapeA.size() != shapeB.size()) {
175 return false;
176 }
177 for (size_t dim = 0; dim < shapeA.size(); dim++) {
178 if (shapeA[dim] != shapeB[dim]) {
179 return false;
180 }
181 }
182 return true;
183}
184bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<Dim>& shapeB) {
185 if (shapeA.size() != shapeB.size()) {
186 return false;
187 }
188 for (size_t dim = 0; dim < shapeA.size(); dim++) {
189 if (shapeB[dim].isParam) return false;
190 if (shapeA[dim] != shapeB[dim].dim) {
191 return false;
192 }
193 }
194 return true;
195}
196bool UTILITY::AreSameShape(const std::vector<Dim>& shapeA, const std::vector<Dim>& shapeB) {
197 if (shapeA.size() != shapeB.size()) {
198 return false;
199 }
200 for (size_t dim = 0; dim < shapeA.size(); dim++) {
201 if (shapeA[dim].GetVal() != shapeB[dim].GetVal()) {
202 return false;
203 }
204 }
205 return true;
206}
207
208std::vector<size_t> UTILITY::MultidirectionalBroadcastShape(std::vector<std::vector<size_t>> shape)
209{
210 if (shape.size() < 2) {
211 throw
212 std::runtime_error("TMVA::SOFIE - MultidirectionalBroadcastShape requires at least 2 input shapes.");
213 }
214 // Number of input shapes to broadcast
215 size_t n = shape.size();
216 // Size of the output shape
217 size_t targetSize = shape[0].size();
218 for (size_t i = 1; i < n; i++) {
219 targetSize = std::max(targetSize, shape[i].size());
220 }
221 // Check if they have the same size
222 bool sameSize = true;
223 for (size_t i = 0; i < n; i++) {
224 if (shape[i].size() != targetSize) {
225 sameSize = false;
226 break;
227 }
228 }
229 if (sameSize) {
230 // Check if they have the same shape
231 bool sameShape = true;
232 for (size_t i = 1; i < n; i++) {
233 for (size_t dim = 0; dim < shape[0].size(); dim++) {
234 if (shape[i][dim] != shape[0][dim]) {
235 sameShape = false;
236 break;
237 }
238 }
239 if (!sameShape) {
240 break;
241 }
242 }
243 if (sameShape) {
244 return shape[0];
245 } else {
246 // Set the target shape
247 std::vector<size_t> targetShape(targetSize, 1);
248 for (size_t i = 0; i < n; i++) {
249 for (size_t dim = 0; dim < targetSize; dim++) {
250 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
251 }
252 }
253 // Check if the input shapes are broadcastable to targetShape
254 bool broadcastable = true;
255 for (size_t i = 0; i < n; i++) {
256 for (size_t dim = 0; dim < targetSize; dim++) {
257 if (shape[i][dim] != 1 && targetShape[dim] != 1 && shape[i][dim] != targetShape[dim]) {
258 broadcastable = false;
259 break;
260 }
261 if (!broadcastable) {
262 break;
263 }
264 }
265 }
266 // They have the same shape and they are broadcastable to targetShape
267 if (broadcastable) {
268 return targetShape;
269 } else {
270 std::stringstream ss;
271 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
272 for (size_t i = 0; i < n; i++) {
273 ss << ConvertShapeToString(shape[i]);
274 if (n > 2 && i < n - 2) {
275 ss << ", ";
276 } else if ( n >=2 && i == n - 2) {
277 ss << " and ";
278 }
279 }
280 ss << " to the same shape.";
281 throw
282 std::runtime_error(ss.str());
283 }
284 } // end sameShape
285 } // end sameSize
286 // Prepend the ith shape with ones
287 for (size_t i = 0; i < n; i++) {
288 if (shape[i].size() < targetSize) {
289 std::vector<size_t> newShape(targetSize, 1);
290 size_t offset = targetSize - shape[i].size();
291 std::copy(shape[i].begin(), shape[i].end(), newShape.begin() + offset);
292 shape[i] = newShape;
293 }
294 }
295 // Set the target shape
296 std::vector<size_t> targetShape(targetSize, 1);
297 for (size_t i = 0; i < n; i++) {
298 for (size_t dim = 0; dim < targetSize; dim++) {
299 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
300 }
301 }
302 // Check if the shapes are broadcastable to targetShape
303 bool broadcastable = true;
304 for (size_t i = 0; i < n; i++) {
305 for (size_t dim = 0; dim < targetSize; dim++) {
306 if (shape[i][dim] != targetShape[dim] && shape[i][dim] != 1 && targetShape[dim] != 1) {
307 broadcastable = false;
308 break;
309 }
310 }
311 if (!broadcastable) {
312 break;
313 }
314 }
315 if (broadcastable) {
316 return targetShape;
317 } else {
318 std::stringstream ss;
319 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
320 for (size_t i = 0; i < n; i++) {
321 ss << ConvertShapeToString(shape[i]);
322 if (n > 2 && i < n - 2) {
323 ss << ", ";
324 } else if ( n >=2 && i == n - 2) {
325 ss << " and ";
326 }
327 }
328 ss << " to the same shape.";
329 throw
330 std::runtime_error(ss.str());
331 }
332}
333
334std::vector<size_t> UTILITY::UnidirectionalBroadcastShape(std::vector<size_t> shapeA, std::vector<size_t> shapeB)
335{
336 size_t sizeA = shapeA.size();
337 size_t sizeB = shapeB.size();
338 // Check if A and B have the same shape
339 if (UTILITY::AreSameShape(shapeA, shapeB)){
340 return shapeA;
341 }
342 // Find the common shape of A and B
343 size_t size = std::max(sizeA, sizeB);
344 if (sizeA < size) {
345 std::vector<size_t> newShapeA(size, 1);
346 size_t offset = size - sizeA;
347 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() + offset);
348 shapeA = std::move(newShapeA);
349 }
350 if (sizeB < size) {
351 std::vector<size_t> newShapeB(size, 1);
352 size_t offset = size - sizeB;
353 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() + offset);
354 shapeB = std::move(newShapeB);
355 }
356 bool broadcastable = true;
357 for (size_t i = 0; i < size; i++) {
358 if (shapeA[i] != shapeB[i] && shapeA[i] != 1 && shapeB[i] != 1) {
359 broadcastable = false;
360 break;
361 }
362 }
363 if (broadcastable) {
364 // The output shape is max(outShape, targetShape)
365 std::vector<size_t> targetShape(size, 1);
366 for (size_t i = 0; i < size; i++) {
367 targetShape[i] = std::max(shapeA[i], shapeB[i]);
368 }
369 return targetShape;
370 } else {
371 throw
372 std::runtime_error("TMVA::SOFIE - Error unidirectional broadcasting tensors of shape "
373 + ConvertShapeToString(shapeA) + " and " + ConvertShapeToString(shapeB)
374 + " to a common shape.");
375 }
376}
377
378std::string UTILITY::Clean_name(std::string input_tensor_name){
379 std::string s (input_tensor_name);
380 std::replace( s.begin(), s.end(), '-', '_');
381 // replace all non-alpohanumeric character except for "_"
382 s.erase(std::remove_if(s.begin(), s.end(), []( char const& c ) -> bool { return !std::isalnum(c) && c != '_'; } ), s.end());
383 return s;
384}
385
386std::vector<size_t> UTILITY::ComputeStrideFromShape(const std::vector<size_t> & shape) {
387 // assume row major layout
388 const auto size = shape.size();
389 std::vector<size_t> strides(size,1);
390 for (std::size_t i = 1; i < size; i++) {
391 strides[size - 1 - i] = strides[size - i ] * shape[size - i];
392 }
393 return strides;
394}
395
396std::vector<Dim> UTILITY::ComputeStrideFromShape(const std::vector<Dim> & shape) {
397 // assume row major layout
398 const auto size = shape.size();
399 std::vector<Dim> strides(size);
400 strides[size-1] = Dim{1};
401 for (std::size_t i = 1; i < size; i++) {
402 if (!shape[size-i].isParam && !strides[size-i].isParam)
403 strides[size - 1 - i] = Dim{strides[size-i].dim * shape[size-i].dim};
404 else
405 strides[size - 1 - i] = Dim{std::string(strides[size-i].GetVal() + "*" + shape[size-i].GetVal())};
406 }
407 return strides;
408}
409
410
411}//SOFIE
412}//Experimental
413}//TMVA
#define c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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 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 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::vector< Dim > ConvertShapeToDim(std::vector< size_t > shape)
Convert shape from integer format to dynamic one (based on Dim)
std::string ConvertDynamicShapeToLength(std::vector< Dim > shape)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::string ConvertTypeToString(ETensorType type)
std::string ConvertDynamicShapeToString(std::vector< Dim > shape)
ETensorType ConvertStringToType(std::string type)
std::vector< size_t > ConvertShapeToInt(std::vector< Dim > shape)
Convert shape based on Dim to integer format.
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations