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