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