Logo ROOT  
Reference Guide
SOFIE_common.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_SOFIE_COMMON
2#define TMVA_SOFIE_SOFIE_COMMON
3
4// #include "TMVA/RTensor.hxx"
5// #include "TMVA/Types.h"
6
7#include <type_traits>
8#include <cstdint>
9#include <string>
10#include <vector>
11#include <memory>
12#include <regex>
13
14namespace TMVA{
15namespace Experimental{
16namespace SOFIE{
17
18//typedef RTensor tensor_t;
19
20enum class ETensorType{
21 UNDEFINED = 0, FLOAT = 1, UNINT8 = 2, INT8 = 3, UINT16 = 4, INT16 = 5, INT32 = 6, INT64 = 7, STRING = 8, BOOL = 9, //order sensitive
22 FLOAT16 = 10, DOUBLE = 11, UINT32 = 12, UINT64 = 13, COMPLEX64 = 14, COMPLEX28 = 15, BFLOAT16 = 16
23};
24
25typedef std::int64_t int_t;
26
29
30struct Dim{
31 bool isParam = false;
32 size_t dim;
33 std::string param;
34};
35
36std::vector<Dim> ConvertShapeToDim(std::vector<size_t> shape);
37
38
41 std::vector<Dim> shape;
42};
43
46 std::vector<size_t> shape;
47};
48
49std::size_t ConvertShapeToLength(std::vector<size_t> shape);
50
51std::string ConvertShapeToString(std::vector<size_t> shape);
52
55 std::vector<std::size_t> fShape;
56 std::shared_ptr<void> fData; //! Transient
57 int fSize=1;
58 char* fPersistentData=nullptr; //[fSize] Persistent
59
61 for(auto item:fShape){
62 fSize*=(int)item;
63 }
64 switch(fType){
65 case ETensorType::FLOAT: fSize*=sizeof(float); break;
66 default:
67 throw std::runtime_error("TMVA::SOFIE doesn't yet supports serialising data-type " + ConvertTypeToString(fType));
68 }
69 fPersistentData=(char*)fData.get();
70 }
72 switch(fType){
73 case ETensorType::FLOAT: {
74 std::shared_ptr<void> tData(malloc(fSize * sizeof(float)), free);
75 std::memcpy(tData.get(), fPersistentData,fSize * sizeof(float));
76 fData=tData;
77 break;
78 }
79 default: {
80 throw std::runtime_error("TMVA::SOFIE doesn't yet supports serialising data-type " + ConvertTypeToString(fType));
81 }
82 }
83 }
84};
85
86template <typename T>
88 if (std::is_same<T, float>::value) return ETensorType::FLOAT;
89 if (std::is_same<T, uint8_t>::value) return ETensorType::UNINT8;
90 if (std::is_same<T, int8_t>::value) return ETensorType::INT8;
91 if (std::is_same<T, uint16_t>::value) return ETensorType::UINT16;
92 if (std::is_same<T, int16_t>::value) return ETensorType::INT16;
93 if (std::is_same<T, int32_t>::value) return ETensorType::INT32;
94 if (std::is_same<T, int64_t>::value) return ETensorType::INT64;
95 if (std::is_same<T, std::string>::value) return ETensorType::STRING;
96 if (std::is_same<T, bool>::value) return ETensorType::BOOL;
97 //float16 unimplemented
98 if (std::is_same<T, double>::value) return ETensorType::DOUBLE;
99 if (std::is_same<T, uint32_t>::value) return ETensorType::UINT32;
100 if (std::is_same<T, uint64_t>::value) return ETensorType::UINT64;
101 //complex 64, 28, bfloat 16 unimplemented
102}
103
104namespace UTILITY{
105template<typename T>
106T* Unidirectional_broadcast(const T* original_data, const std::vector<size_t> original_shape, const std::vector<size_t> target_shape);
107std::string Clean_name(std::string input_tensor_name);
108
109
110/// function to check if a >> 0 and a < MAX using a single comparison
111//// use trick casting to unsigned values so it becomes a single comparison
112inline bool is_a_ge_zero_and_a_lt_b(int a, int b) {
113 return static_cast<unsigned>(a) < static_cast<unsigned>(b);
114}
115
116
117/// im2col : efficient function to re-arrange input data of convolution to a matrix
118/// that can be used by BLAS
119/// Use trick to loop on each element of filtered region first and follow input data layout
120/// By doing this reads and writes are of consecutive data in memory and one gains in efficiency
121/// The resulting matrix will be already transposed and can be used directly in BLAS
122/// since output will be a matrix : (channels*kernel_h*kernel_w , output_h*output_w)
123/// Example: with an input matrix
124/// a1 a2 a3
125/// b1 b2 b3 and a 2x2 kernel (k1,k2,k3,k4) and padding 1 :
126/// c1 c2 c3
127/// outpout will be a matrix (4 x 16)
128/// the routine will follow output order :
129// first all elements which will be operated by k1 then k2 then k3
130/// -> ( 0 0 0 0 0 a1 a2 a3 0 b1 b2 b3 0 c1 c2 c3 ) all elements for k1
131/// ( 0 0 0 0 a1 a2 a3 0 b1 b2 b3 0 c1 c2 c3 0 ) for k2
132/// ( 0 a1 a2 a3 0 b1 b2 b3 0 c1 c2 c3 0 0 0 0 ) for k3
133/// ( a1 a2 a3 0 b1 b2 b3 0 c1 c2 c3 0 0 0 0 0 ) for k4
134///
135
136template <typename T>
137void Im2col(const T *data_im, const int channels, const int height, const int width, const int kernel_h,
138 const int kernel_w, const int pad_h, const int pad_w, const int stride_h, const int stride_w,
139 const int dilation_h, const int dilation_w, T *data_col)
140{
141 const int output_h = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
142 const int output_w = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
143 const int channel_size = height * width;
144 for (int channel = channels; channel--; data_im += channel_size) {
145 for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) {
146 for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
147 int input_row = -pad_h + kernel_row * dilation_h;
148 for (int output_rows = output_h; output_rows; output_rows--) {
149 if (!is_a_ge_zero_and_a_lt_b(input_row, height)) {
150 for (int output_cols = output_w; output_cols; output_cols--) {
151 *(data_col++) = 0;
152 }
153 } else {
154 int input_col = -pad_w + kernel_col * dilation_w;
155 for (int output_col = output_w; output_col; output_col--) {
156 if (is_a_ge_zero_and_a_lt_b(input_col, width)) {
157 *(data_col++) = data_im[input_row * width + input_col];
158 } else {
159 *(data_col++) = 0;
160 }
161 input_col += stride_w;
162 }
163 }
164 input_row += stride_h;
165 }
166 }
167 }
168 }
169}
170
171/// 3d implementation
172template <typename T>
173void Im2col_3d(const T *data_im, const int channels,
174 const int depth, const int height, const int width,
175 const int kernel_d, const int kernel_h, const int kernel_w,
176 const int pad_d, const int pad_h, const int pad_w,
177 const int stride_d, const int stride_h, const int stride_w,
178 const int dilation_d, const int dilation_h, const int dilation_w, T *data_col)
179{
180 const int output_h = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
181 const int output_w = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;
182 const int output_d = (depth + 2 * pad_d - (dilation_d * (kernel_d - 1) + 1)) / stride_d + 1;
183 const int channel_size = height * width * depth;
184 // assume data are c x d x h x w
185 for (int channel = channels; channel--; data_im += channel_size) {
186 for (int kernel_depth = 0; kernel_depth < kernel_d; kernel_depth++) {
187 for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) {
188 for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
189 int input_dep = -pad_d + kernel_depth * dilation_d;
190 for (int output_dep = output_d; output_dep; output_dep--) {
191 if (!is_a_ge_zero_and_a_lt_b(input_dep, depth)) {
192 for (int output_rows = output_h; output_rows; output_rows--) {
193 for (int output_cols = output_w; output_cols; output_cols--) {
194 *(data_col++) = 0;
195 }
196 }
197 } else {
198 int input_row = -pad_h + kernel_row * dilation_h;
199 for (int output_rows = output_h; output_rows; output_rows--) {
200 if (!is_a_ge_zero_and_a_lt_b(input_row, height)) {
201 for (int output_cols = output_w; output_cols; output_cols--) {
202 *(data_col++) = 0;
203 }
204 } else {
205 int input_col = -pad_w + kernel_col * dilation_w;
206 for (int output_col = output_w; output_col; output_col--) {
207 if (is_a_ge_zero_and_a_lt_b(input_col, width)) {
208 *(data_col++) = data_im[input_dep * width * height + input_row * width + input_col];
209 } else {
210 *(data_col++) = 0;
211 }
212 input_col += stride_w;
213 }
214 }
215 input_row += stride_h;
216 }
217 }
218 input_dep += stride_d;
219 }
220 }
221 }
222 }
223 }
224}
225
226
227
228} // end namespace UTILITY
229
230namespace BLAS{
231extern "C" void sgemm_(const char * transa, const char * transb, const int * m, const int * n, const int * k,
232 const float * alpha, const float * A, const int * lda, const float * B, const int * ldb,
233 const float * beta, float * C, const int * ldc);
234}//BLAS
235}//SOFIE
236}//Experimental
237}//TMVA
238
239#endif //TMVA_SOFIE_RMODEL
#define b(i)
Definition: RSha256.hxx:100
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
int type
Definition: TGX11.cxx:121
#define free
Definition: civetweb.c:1539
#define malloc
Definition: civetweb.c:1536
double beta(double x, double y)
Calculates the beta function.
const Int_t n
Definition: legend1.C:16
static double B[]
static double A[]
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
void sgemm_(const char *transa, const char *transb, const int *m, const int *n, const int *k, const float *alpha, const float *A, const int *lda, const float *B, const int *ldb, const float *beta, float *C, const int *ldc)
void Im2col_3d(const T *data_im, const int channels, const int depth, const int height, const int width, const int kernel_d, const int kernel_h, const int kernel_w, const int pad_d, const int pad_h, const int pad_w, const int stride_d, const int stride_h, const int stride_w, const int dilation_d, const int dilation_h, const int dilation_w, T *data_col)
3d implementation
std::string Clean_name(std::string input_tensor_name)
bool is_a_ge_zero_and_a_lt_b(int a, int b)
function to check if a >> 0 and a < MAX using a single comparison / use trick casting to unsigned val...
void Im2col(const T *data_im, const int channels, const int height, const int width, const int kernel_h, const int kernel_w, const int pad_h, const int pad_w, const int stride_h, const int stride_w, const int dilation_h, const int dilation_w, T *data_col)
im2col : efficient function to re-arrange input data of convolution to a matrix that can be used by B...
T * Unidirectional_broadcast(const T *original_data, const std::vector< size_t > original_shape, const std::vector< size_t > target_shape)
std::vector< Dim > ConvertShapeToDim(std::vector< size_t > shape)
Definition: SOFIE_common.cxx:9
ETensorType GetTemplatedType(T)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::string ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations
auto * m
Definition: textangle.C:8
auto * a
Definition: textangle.C:12