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::INT8 : {
63 return "int8_t";
64 }
65 case ETensorType::INT16 : {
66 return "int16_t";
67 }
68 case ETensorType::INT32 : {
69 return "int32_t";
70 }
71 case ETensorType::INT64 : {
72 return "int64_t";
73 }
74 case ETensorType::UINT8 : {
75 return "uint8_t";
76 }
77 case ETensorType::UINT16 : {
78 return "uint16_t";
79 }
80 case ETensorType::UINT32 : {
81 return "uint32_t";
82 }
83 case ETensorType::UINT64 : {
84 return "uint64_t";
85 }
86 case ETensorType::DOUBLE : {
87 return "double";
88 }
89 case ETensorType::BOOL : {
90 return "bool";
91 }
92 default:{
93 return "other_" + std::to_string( (int) type);
94 }
95 }
96}
97
99 if(type == "float32" || type == "float" || type == "Float"){
100 return ETensorType::FLOAT;
101 }
102 else if(type == "int64" || type == "int64_t"){
103 return ETensorType::INT64;
104 }
105 else if (type == "double" || type == "float64"){
106 return ETensorType::DOUBLE;
107 }
108 else if (type == "bool" ){
109 return ETensorType::BOOL;
110 }
111 else{
113 }
114}
115
116std::string ConvertShapeToString(std::vector<size_t> shape) {
117 std::stringstream out;
118 out << "{ ";
119 for (size_t i = 0; i < shape.size(); i++) {
120 out << shape[i];
121 if (i < shape.size()-1) out << " , ";
122 }
123 out << " }";
124 return out.str();
125}
126
127std::string ConvertDynamicShapeToString(std::vector<Dim> shape) {
128 std::stringstream out;
129 out << "{ ";
130 for (size_t i = 0; i < shape.size(); i++) {
131 out << shape[i].GetVal();
132 if (i < shape.size()-1) out << " , ";
133 }
134 out << " }";
135 return out.str();
136}
137
138std::string ConvertDynamicShapeToLength(std::vector<Dim> shape) {
139 // convert generic shape to a string
140 // multiply all the integer specified dimensions of the shape
141 std::string length;
142 size_t int_length = 0;
143 for (size_t i = 0; i < shape.size(); i++) {
144 if (shape[i].isParam) {
145 if (!length.empty()) length += " * ";
146 length += shape[i].param;
147 } else {
148 if (int_length == 0)
149 int_length = shape[i].dim;
150 else
151 int_length *= shape[i].dim;
152 }
153 }
154 // multiply the integer components to the parametric one
155 if (int_length > 0) {
156 if (!length.empty()) length += " * ";
157 length += std::to_string(int_length);
158 }
159 return length;
160}
161
162namespace{
163template<typename T>
164static inline void copy_vector_data(int_t no_of_copies, int_t input_size, T* input, T* target){ //only visible within this translation unit
165 std::memcpy(target, input, input_size * sizeof(T));
167
168 while (already_copied * 2 <= no_of_copies){
169 std::memcpy(target + already_copied * input_size, target, already_copied * input_size * sizeof(T));
170 already_copied *= 2;
171 }
172
174 std::memcpy(target + already_copied * input_size, target, (no_of_copies - already_copied) * input_size * sizeof(T));
175 }
176}
177}
178
179bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<size_t>& shapeB) {
180 if (shapeA.size() != shapeB.size()) {
181 return false;
182 }
183 for (size_t dim = 0; dim < shapeA.size(); dim++) {
184 if (shapeA[dim] != shapeB[dim]) {
185 return false;
186 }
187 }
188 return true;
189}
190bool UTILITY::AreSameShape(const std::vector<size_t>& shapeA, const std::vector<Dim>& shapeB) {
191 if (shapeA.size() != shapeB.size()) {
192 return false;
193 }
194 for (size_t dim = 0; dim < shapeA.size(); dim++) {
195 if (shapeB[dim].isParam) return false;
196 if (shapeA[dim] != shapeB[dim].dim) {
197 return false;
198 }
199 }
200 return true;
201}
202bool UTILITY::AreSameShape(const std::vector<Dim>& shapeA, const std::vector<Dim>& shapeB) {
203 if (shapeA.size() != shapeB.size()) {
204 return false;
205 }
206 for (size_t dim = 0; dim < shapeA.size(); dim++) {
207 if (shapeA[dim].GetVal() != shapeB[dim].GetVal()) {
208 return false;
209 }
210 }
211 return true;
212}
213
214std::vector<size_t> UTILITY::MultidirectionalBroadcastShape(std::vector<std::vector<size_t>> shape)
215{
216 if (shape.size() < 2) {
217 throw
218 std::runtime_error("TMVA::SOFIE - MultidirectionalBroadcastShape requires at least 2 input shapes.");
219 }
220 // Number of input shapes to broadcast
221 size_t n = shape.size();
222 // Size of the output shape
223 size_t targetSize = shape[0].size();
224 for (size_t i = 1; i < n; i++) {
225 targetSize = std::max(targetSize, shape[i].size());
226 }
227 // Check if they have the same size
228 bool sameSize = true;
229 for (size_t i = 0; i < n; i++) {
230 if (shape[i].size() != targetSize) {
231 sameSize = false;
232 break;
233 }
234 }
235 if (sameSize) {
236 // Check if they have the same shape
237 bool sameShape = true;
238 for (size_t i = 1; i < n; i++) {
239 for (size_t dim = 0; dim < shape[0].size(); dim++) {
240 if (shape[i][dim] != shape[0][dim]) {
241 sameShape = false;
242 break;
243 }
244 }
245 if (!sameShape) {
246 break;
247 }
248 }
249 if (sameShape) {
250 return shape[0];
251 } else {
252 // Set the target shape
253 std::vector<size_t> targetShape(targetSize, 1);
254 for (size_t i = 0; i < n; i++) {
255 for (size_t dim = 0; dim < targetSize; dim++) {
256 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
257 }
258 }
259 // Check if the input shapes are broadcastable to targetShape
260 bool broadcastable = true;
261 for (size_t i = 0; i < n; i++) {
262 for (size_t dim = 0; dim < targetSize; dim++) {
263 if (shape[i][dim] != 1 && targetShape[dim] != 1 && shape[i][dim] != targetShape[dim]) {
264 broadcastable = false;
265 break;
266 }
267 if (!broadcastable) {
268 break;
269 }
270 }
271 }
272 // They have the same shape and they are broadcastable to targetShape
273 if (broadcastable) {
274 return targetShape;
275 } else {
276 std::stringstream ss;
277 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
278 for (size_t i = 0; i < n; i++) {
279 ss << ConvertShapeToString(shape[i]);
280 if (n > 2 && i < n - 2) {
281 ss << ", ";
282 } else if ( n >=2 && i == n - 2) {
283 ss << " and ";
284 }
285 }
286 ss << " to the same shape.";
287 throw
288 std::runtime_error(ss.str());
289 }
290 } // end sameShape
291 } // end sameSize
292 // Prepend the ith shape with ones
293 for (size_t i = 0; i < n; i++) {
294 if (shape[i].size() < targetSize) {
295 std::vector<size_t> newShape(targetSize, 1);
296 size_t offset = targetSize - shape[i].size();
297 std::copy(shape[i].begin(), shape[i].end(), newShape.begin() + offset);
298 shape[i] = newShape;
299 }
300 }
301 // Set the target shape
302 std::vector<size_t> targetShape(targetSize, 1);
303 for (size_t i = 0; i < n; i++) {
304 for (size_t dim = 0; dim < targetSize; dim++) {
305 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
306 }
307 }
308 // Check if the shapes are broadcastable to targetShape
309 bool broadcastable = true;
310 for (size_t i = 0; i < n; i++) {
311 for (size_t dim = 0; dim < targetSize; dim++) {
312 if (shape[i][dim] != targetShape[dim] && shape[i][dim] != 1 && targetShape[dim] != 1) {
313 broadcastable = false;
314 break;
315 }
316 }
317 if (!broadcastable) {
318 break;
319 }
320 }
321 if (broadcastable) {
322 return targetShape;
323 } else {
324 std::stringstream ss;
325 ss << "TMVA::SOFIE - Error multidirectional broadcasting shapes ";
326 for (size_t i = 0; i < n; i++) {
327 ss << ConvertShapeToString(shape[i]);
328 if (n > 2 && i < n - 2) {
329 ss << ", ";
330 } else if ( n >=2 && i == n - 2) {
331 ss << " and ";
332 }
333 }
334 ss << " to the same shape.";
335 throw
336 std::runtime_error(ss.str());
337 }
338}
339
340std::vector<size_t> UTILITY::UnidirectionalBroadcastShape(std::vector<size_t> shapeA, std::vector<size_t> shapeB)
341{
342 size_t sizeA = shapeA.size();
343 size_t sizeB = shapeB.size();
344 // Check if A and B have the same shape
346 return shapeA;
347 }
348 // Find the common shape of A and B
349 size_t size = std::max(sizeA, sizeB);
350 if (sizeA < size) {
351 std::vector<size_t> newShapeA(size, 1);
352 size_t offset = size - sizeA;
353 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() + offset);
354 shapeA = std::move(newShapeA);
355 }
356 if (sizeB < size) {
357 std::vector<size_t> newShapeB(size, 1);
358 size_t offset = size - sizeB;
359 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() + offset);
360 shapeB = std::move(newShapeB);
361 }
362 bool broadcastable = true;
363 for (size_t i = 0; i < size; i++) {
364 if (shapeA[i] != shapeB[i] && shapeA[i] != 1 && shapeB[i] != 1) {
365 broadcastable = false;
366 break;
367 }
368 }
369 if (broadcastable) {
370 // The output shape is max(outShape, targetShape)
371 std::vector<size_t> targetShape(size, 1);
372 for (size_t i = 0; i < size; i++) {
373 targetShape[i] = std::max(shapeA[i], shapeB[i]);
374 }
375 return targetShape;
376 } else {
377 throw
378 std::runtime_error("TMVA::SOFIE - Error unidirectional broadcasting tensors of shape "
380 + " to a common shape.");
381 }
382}
383
384// UNidirectional boradcast specializaiton for vector<bool>
385
386// specialization for vector of boolean
387void UTILITY::UnidirectionalBroadcast(const std::vector<bool> & data, const std::vector<size_t>& shape, const std::vector<size_t>& targetShape, std::vector<bool> & broadcastedData)
388 {
389 // Prepend shape with ones
390 auto ncdata = const_cast<std::vector<bool> &>(data);
391 if (shape.size() < targetShape.size()) {
392 size_t targetSize = targetShape.size();
393 std::vector<size_t> newShape(targetSize, 1);
394 size_t offset = targetSize - shape.size();
395 std::copy(shape.begin(), shape.end(), newShape.begin() + offset);
396 UTILITY::BroadcastTensor<bool, const std::vector<bool> &, std::vector<bool> &>(ncdata, newShape, targetShape, broadcastedData);
397 }
398 UTILITY::BroadcastTensor<bool, const std::vector<bool> &, std::vector<bool> &>(ncdata, shape, targetShape, broadcastedData);
399}
400
401std::string UTILITY::Clean_name(std::string input_tensor_name){
402 std::string s (input_tensor_name);
403 std::replace( s.begin(), s.end(), '-', '_');
404 // replace all non-alpohanumeric character except for "_"
405 s.erase(std::remove_if(s.begin(), s.end(), []( char const& c ) -> bool { return !std::isalnum(c) && c != '_'; } ), s.end());
406 return s;
407}
408
409std::vector<size_t> UTILITY::ComputeStrideFromShape(const std::vector<size_t> & shape) {
410 // assume row major layout
411 const auto size = shape.size();
412 std::vector<size_t> strides(size,1);
413 for (std::size_t i = 1; i < size; i++) {
414 strides[size - 1 - i] = strides[size - i ] * shape[size - i];
415 }
416 return strides;
417}
418
419std::vector<Dim> UTILITY::ComputeStrideFromShape(const std::vector<Dim> & shape) {
420 // assume row major layout
421 const auto size = shape.size();
422 std::vector<Dim> strides(size);
423 strides[size-1] = Dim{1};
424 for (std::size_t i = 1; i < size; i++) {
425 if (!shape[size-i].isParam && !strides[size-i].isParam)
426 strides[size - 1 - i] = Dim{strides[size-i].dim * shape[size-i].dim};
427 else
428 strides[size - 1 - i] = Dim{std::string(strides[size-i].GetVal() + "*" + shape[size-i].GetVal())};
429 }
430 return strides;
431}
432
433
434}//SOFIE
435}//Experimental
436}//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 data
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_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 > >)
T * UnidirectionalBroadcast(const T *data, const std::vector< size_t > &shape, const std::vector< size_t > &targetShape)
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