1#ifndef TMVA_SOFIE_ROPERATOR_POOL
2#define TMVA_SOFIE_ROPERATOR_POOL
16namespace Experimental {
74 fNX(UTILITY::Clean_name(nameX)),
fNY(UTILITY::Clean_name(nameY))
76 if(std::is_same<T, float>::value) {
80 std::runtime_error(
"TMVA SOFIE Encountered unsupported type parsing a Pool operator");
91 if (
input.size() != 1 ) {
92 throw std::runtime_error(
"TMVA SOFIE" +
Name() +
"Op Shape inference need 1 input tensor");
95 throw std::runtime_error(
"TMVA SOFIE" +
Name() +
"Op Shape inference only accept tensor with at least 3 dimensions");
99 throw std::runtime_error(
"TMVA SOFIE" +
Name() +
"Op : tensors with dimension " + std::to_string(
input[0].
size()) +
" are not yet supported");
104 std::runtime_error(
"TMVA SOFIE Pool Op Shape inference - invalid inputs ");
112 size_t i1 = (
fDim > 1) ? ((
fDim > 2) ? 3 : 2) : 1;
113 size_t i2 = (
fDim > 2) ? 4 : 3;
143 for (
size_t d = 0;
d <
fDim; ++
d) {
144 size_t inSize =
input[0][
d + 2];
146 size_t outSize = (inSize + stride_d - 1) / stride_d;
147 int totalPad = std::max(0, (
int)((outSize - 1) * stride_d +
fAttrKernelShape[
d]) - (
int)inSize);
152 fAttrPads[
d] = (size_t)(totalPad - totalPad / 2);
158 std::runtime_error(
"TMVA SOFIE" +
Name() +
"Op invalid Autopad value : " +
fAttrAutopad);
163 size_t input1 =
input[0][2];
164 size_t input2 = (
fDim > 1) ?
input[0][3] : 1;
165 size_t input3 = (
fDim > 2) ?
input[0][4] : 1;
170 auto poolOutDim = [
this](
size_t in,
size_t padBegin,
size_t padEnd,
size_t kern,
size_t stride) ->
size_t {
171 size_t n = in + padBegin + padEnd - kern;
173 return n / stride + 1;
174 return std::min((
n + stride - 1) / stride, (in - 1 + padBegin) / stride) + 1;
179 size_t batch_size =
input[0][0];
180 size_t output_channels =
input[0][1];
182 std::vector<std::vector<size_t>> ret({{ batch_size, output_channels, output1 }});
189 ret[0].push_back(output2);
196 ret[0].push_back(output3);
202 if (!model.CheckIfTensorAlreadyExist(
fNX)) {
204 std::runtime_error(
"TMVA SOFIE Pool op Input Tensor " +
fNX +
" is not found in model");
210 std::runtime_error(
"TMVA SOFIE Pool Op input data tensor" +
fNX +
" is not of 3,4 or 5 dimensions");
228 model.AddIntermediateTensor(
fNY, model.GetTensorType(
fNX),
fShapeY);
236 std::stringstream out;
241 std::string
Generate(std::string OpName)
override {
242 OpName =
"op_" + OpName;
245 throw std::runtime_error(
"TMVA SOFIE Pool Op called to Generate without being initialized first");
248 std::stringstream out;
250 out <<
"\n//---- operator " <<
Name() <<
" " << OpName <<
"\n";
259 auto clipToInput = [
this](
int upper,
size_t size) {
287 out <<
SP <<
"constexpr int hsize = " <<
fShapeX[2] <<
";\n";
288 out <<
SP <<
"constexpr int hmin = " <<
hmin <<
";\n";
289 out <<
SP <<
"constexpr int hmax = " <<
hmax <<
";\n";
293 out <<
SP <<
"constexpr int wsize = " << wsize <<
";\n";
294 out <<
SP <<
"constexpr int wmin = " <<
wmin <<
";\n";
295 out <<
SP <<
"constexpr int wmax = " <<
wmax <<
";\n";
299 out <<
SP <<
"constexpr int dsize = " << dsize <<
";\n";
300 out <<
SP <<
"constexpr int dwsize = " << dsize*wsize <<
";\n";
301 out <<
SP <<
"constexpr int dmin = " << dmin <<
";\n";
302 out <<
SP <<
"constexpr int dmax = " << dmax <<
";\n";
308 bool doPadding =
false;
310 doPadding |= (
e > 0);
320 auto windowExtent = [
this](
const std::string &var,
const std::string &kern,
size_t size,
size_t padEnd) {
323 return "((" + var +
" + " + kern +
" < " +
hi +
" ? " + var +
" + " + kern +
" : " +
hi +
")"
330 out <<
SP <<
"size_t outIndex = 0;\n";
331 out <<
SP <<
"for (size_t n = 0; n < " <<
fShapeX[0]*
fShapeX[1] <<
"; n++) {\n";
332 out <<
SP <<
SP <<
"size_t inputOffset = n*" <<
fShapeX[2] <<
";\n";
333 out <<
SP <<
SP <<
"for (int i = hmin; i < hmax; i+=" <<
fAttrStrides[0] <<
") {\n";
336 out <<
SP <<
SP <<
SP <<
SP <<
"float value = -INFINITY;\n";
338 out <<
SP <<
SP <<
SP <<
SP <<
"float value = 0;\n";
340 out <<
SP <<
SP <<
SP <<
SP <<
"const int nsum = "
343 out <<
SP <<
SP <<
SP <<
SP <<
"constexpr int nsum = kh;\n";
346 out <<
SP <<
SP <<
SP <<
SP <<
"for (int l = i; l < i + kh; l++) {\n";
347 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (l < 0 || l >= hsize) continue;\n";
348 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"int index = inputOffset + l;\n";
350 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"auto xval = tensor_" <<
fNX <<
"[index];\n";
351 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (xval > value) value = xval;\n";
355 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"value += tensor_" <<
fNX <<
"[index];\n";
360 out <<
SP <<
SP <<
SP <<
SP <<
"value /= float(nsum);\n";
363 out <<
SP <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[outIndex++] = value;\n";
365 out <<
SP <<
SP <<
"}\n";
370 out <<
SP <<
"size_t outIndex = 0;\n";
371 out <<
SP <<
"for (size_t n = 0; n < " <<
fShapeX[0]*
fShapeX[1] <<
"; n++) {\n";
373 out <<
SP <<
SP <<
"for (int i = hmin; i < hmax; i+=" <<
fAttrStrides[0] <<
") {\n";
374 out <<
SP <<
SP <<
SP <<
"for (int j = wmin; j < wmax; j+=" <<
fAttrStrides[1] <<
") {\n";
377 out <<
SP <<
SP <<
SP <<
SP <<
"float value = -INFINITY;\n";
379 out <<
SP <<
SP <<
SP <<
SP <<
"float value = 0;\n";
381 out <<
SP <<
SP <<
SP <<
SP <<
"const int nsum = "
385 out <<
SP <<
SP <<
SP <<
SP <<
"constexpr int nsum = kw*kh;\n";
388 out <<
SP <<
SP <<
SP <<
SP <<
"for (int l = i; l < i + kh; l++) {\n";
389 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (l < 0 || l >= hsize) continue;\n";
391 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"for (int m = j; m < j + kw; m++) {\n";
392 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (m < 0 || m >= wsize) continue;\n";
393 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"int index = inputOffset + l*wsize + m;\n";
395 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"auto xval = tensor_" <<
fNX <<
"[index];\n";
396 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (xval > value) value = xval;\n";
400 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"value += tensor_" <<
fNX <<
"[index];\n";
406 out <<
SP <<
SP <<
SP <<
SP <<
"value /= float(nsum);\n";
408 out <<
SP <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[outIndex++] = value;\n";
409 out <<
SP <<
SP <<
SP <<
"}\n";
410 out <<
SP <<
SP <<
"}\n";
415 out <<
SP <<
"size_t outIndex = 0;\n";
416 out <<
SP <<
"for (size_t n = 0; n < " <<
fShapeX[0]*
fShapeX[1] <<
"; n++) {\n";
418 out <<
SP <<
SP <<
"for (int i = hmin; i < hmax; i+=" <<
fAttrStrides[0] <<
") {\n";
419 out <<
SP <<
SP <<
SP <<
"for (int j = wmin; j < wmax; j+=" <<
fAttrStrides[1] <<
") {\n";
420 out <<
SP <<
SP <<
SP <<
SP <<
"for (int k = dmin; k < dmax; k+=" <<
fAttrStrides[2] <<
") {\n";
423 out <<
SP <<
SP <<
SP <<
SP <<
"float value = -INFINITY;\n";
425 out <<
SP <<
SP <<
SP <<
SP <<
"float value = 0;\n";
427 out <<
SP <<
SP <<
SP <<
SP <<
"const int nsum = "
432 out <<
SP <<
SP <<
SP <<
SP <<
"constexpr int nsum = kw*kh*kd;\n";
435 out <<
SP <<
SP <<
SP <<
SP <<
"for (int l = i; l < i + kh; l++) {\n";
436 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (l < 0 || l >= hsize) continue;\n";
438 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"for (int m = j; m < j + kw; m++) {\n";
439 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (m < 0 || m >= wsize) continue;\n";
441 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"for (int p = k; p < k + kd; p++) {\n";
442 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (p < 0 || p >= dsize) continue;\n";
443 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"int index = inputOffset + l*dwsize + m*dsize + p;\n";
446 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"auto xval = tensor_" <<
fNX <<
"[index];\n";
447 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"if (xval > value) value = xval;\n";
451 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
SP <<
"value += tensor_" <<
fNX <<
"[index];\n";
455 out <<
SP <<
SP <<
SP <<
SP <<
"}\n";
458 out <<
SP <<
SP <<
SP <<
SP <<
"value /= float(nsum);\n";
461 out <<
SP <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[outIndex++] = value;\n";
462 out <<
SP <<
SP <<
SP <<
SP <<
"}\n" ;
463 out <<
SP <<
SP <<
SP <<
"}\n";
464 out <<
SP <<
SP <<
"}\n";
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 hmin
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmax
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t wmin
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t wmax
std::string GenerateInitCode() override
std::vector< size_t > fShapeY
size_t fAttrCountIncludePad
std::vector< size_t > fAttrKernelShape
std::vector< size_t > fAttrStrides
std::vector< size_t > fAttrDilations
std::vector< size_t > fAttrPads
void Initialize(RModel &model) override
std::string Generate(std::string OpName) override
std::vector< size_t > fShapeX
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input)
ROperator_Pool(PoolOpMode mode, RAttributes_Pool attr, std::string nameX, std::string nameY)
std::vector< std::string_view > fInputTensorNames
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations
std::vector< size_t > pads
std::vector< size_t > kernel_shape
std::vector< size_t > dilations
std::vector< size_t > strides