1#ifndef TMVA_SOFIE_ROPERATOR_CONVTRANSPOSE_HXX
2#define TMVA_SOFIE_ROPERATOR_CONVTRANSPOSE_HXX
74 std::vector<size_t>
outputShape, std::vector<size_t> pads, std::vector<size_t> strides,
87 if (std::is_same<T, float>::value) {
90 throw std::runtime_error(
"TMVA SOFIE Encountered unsupported type parsing a Conv operator");
106 std::vector<std::vector<size_t>>
ShapeInference(std::vector<std::vector<size_t>> )
override;
124 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Gemm"), std::string(
"Axpy") }; }
129 -> std::vector<std::vector<size_t>>
139 if (fAttrStrides.empty()) {
140 fAttrStrides = std::vector<size_t>(fDim, 1);
142 if (fAttrDilations.empty()) {
143 fAttrDilations = std::vector<size_t>(fDim, 1);
146 if (fAttrKernelShape.empty()) {
147 fAttrKernelShape.resize(fDim);
148 for (
size_t i = 0; i < fDim; i++)
149 fAttrKernelShape[i] = fShapeW[i + 2] + (fAttrDilations[i] - 1) * (fShapeW[i + 2] - 1);
151 if (fAttrOutputPadding.empty())
152 fAttrOutputPadding = std::vector<size_t>(fDim, 0);
163 if (fAttrPads.empty()) {
164 fAttrPads = std::vector<size_t>(2 * fDim, 0);
165 if (fAttrOutputShape.size() == fDim) {
168 throw std::runtime_error(
"ConvTranspose with output_shape explicitly set not yet supported.");
189 if (fAttrAutopad !=
"NOTSET") {
190 throw std::runtime_error(
"ConvTranspose with padding SAME_UPPER or SMAE_LOWER not supported");
193 if (fAttrOutputShape.empty()) {
194 fAttrOutputShape.resize(fDim);
195 for (
size_t i = 0; i < fDim; i++) {
197 fAttrOutputShape[i] = fAttrStrides[i] * (
inputShape[
j] - 1) + fAttrKernelShape[i] + fAttrOutputPadding[i] -
198 fAttrPads[i] - fAttrPads[fDim + i];
203 throw std::runtime_error(
"ConvTranspose with output_shape explicitly set not yet supported.");
206 for (
size_t i = 0; i < fDim; i++)
207 outShape[i + 2] = fAttrOutputShape[i];
218 throw std::runtime_error(
"TMVA SOFIE Conv Transpose op Input Tensor " + fNX +
" is not found in model");
221 if (fShapeX.size() < 3 || fShapeX.size() > 5) {
223 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input data tensor" + fNX +
224 " is not of 3,4 or 5 dimensions");
226 fDim = fShapeX.size() - 2;
228 throw std::runtime_error(
"TMVA SOFIE Conv op Input weight Tensor " + fNW +
" is not found in model");
231 if (fShapeW.size() < 3 || fShapeW.size() > 5) {
233 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input weight tensor" + fNW +
234 " is not of 3,4 or 5 dimensions");
236 fShapeY = ShapeInference({fShapeX, fShapeW})[0];
241 throw std::runtime_error(
"TMVA SOFIE ConvTrans op Input Tensor " + fNB +
" is not found in model");
244 if (fShapeB.size() < 1)
245 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has empty shape");
255 if (
bsize != fShapeY[1])
256 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has wrong shape: " +
261 if (fType !=
"float")
262 throw std::runtime_error(
263 "TMVA SOFIE ConvTrans op: Broadcasting for non-float type tensors is not supported");
268 UTILITY::BroadcastConvBias<float>(
static_cast<float *
>(
original_data.get()),
bsize, fShapeY),
269 std::default_delete<
float[]>());
273 fNBroadcastedB = fNB;
277 fNBroadcastedB =
"Broadcasted" + fNB;
282 if (fShapeY != fShapeB)
283 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Broadcasting is not needed but bias has wrong shape" +
285 fNBroadcastedB = fNB;
290 size_t inputSize = 1;
291 for (
size_t i = 0; i < fDim; i++) {
292 inputSize *= fShapeX[2 + i];
301 fImcol = fNX +
"_xcol";
302 fOutputTensorNames.emplace_back(fConvK);
303 fOutputTensorNames.emplace_back(fImcol);
315 std::stringstream out;
319 if (
bsize !=
ysize && !fNBroadcastedB.empty()) {
322 out <<
SP <<
SP <<
"float * data = UTILITY::BroadcastConvBias<float>(tensor_" << fNB
326 out <<
SP <<
SP <<
"delete[] data;\n";
337 if (fShapeX.empty() || fShapeW.empty() || (fNB !=
"" && fShapeB.empty()) || fShapeY.empty()) {
338 throw std::runtime_error(
"TMVA SOFIE Conv Op called to Generate without being initialized first");
341 std::stringstream out;
343 size_t bsize = fShapeX[0];
344 size_t kDepth = (fDim > 2) ? fShapeW[2] : 1;
345 size_t kHeight = (fDim > 1) ? fShapeW[fDim] : 1;
346 size_t kWidth = fShapeW[fDim + 1];
348 size_t iDepth = (fDim > 2) ? fShapeX[2] : 1;
349 size_t iHeight = (fDim > 1) ? fShapeX[fDim] : 1;
350 size_t iWidth = fShapeX[fDim + 1];
352 size_t oDepth = (fDim > 2) ? fShapeY[2] : 1;
353 size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1;
354 size_t oWidth = fShapeY[fDim + 1];
356 out <<
"\n//---- operator ConvTranspose " <<
OpName <<
"\n";
363 out <<
SP << fType <<
" tensor_" << fNX <<
"_f[" << fShapeW[0] * fShapeW[1] *
kernelSize <<
"] = {0};\n";
369 size_t id = (fDim > 2) ? fDim - 3 : 2;
370 size_t ih = (fDim > 1) ? fDim - 2 : 1;
371 size_t iw = fDim - 1;
386 for (
size_t i = 0; i < fDim; i++)
392 out <<
SP <<
"for (std::size_t ic = 0; ic < " << fShapeW[0] <<
"; ic++) {\n";
393 out <<
SP <<
SP <<
"for (std::size_t oc = 0; oc < " << fShapeW[1] <<
"; oc++) {\n";
396 out <<
SP <<
SP <<
SP <<
"for (std::size_t kd = 0; kd < " << kDepth <<
"; kd++) {\n";
398 out <<
SP <<
SP <<
SP <<
"for (std::size_t kh = 0; kh < " <<
kHeight <<
"; kh++) {\n";
399 out <<
SP <<
SP <<
SP <<
SP <<
"for (std::size_t kw = 0; kw < " <<
kWidth <<
"; kw++) {\n";
418 out <<
SP <<
SP <<
SP <<
SP <<
"}\n";
420 out <<
SP <<
SP <<
SP <<
"}\n";
422 out <<
SP <<
SP <<
SP <<
"}\n";
424 out <<
SP <<
SP <<
"}\n";
427 out <<
SP <<
"char " <<
OpName <<
"_transA = 'N';\n";
428 out <<
SP <<
"char " <<
OpName <<
"_transB = 'T';\n";
431 out <<
SP <<
"int " <<
OpName <<
"_k = " << fShapeW[0] <<
";\n";
432 out <<
SP <<
"float " <<
OpName <<
"_alpha = 1.0;\n";
433 out <<
SP <<
"float " <<
OpName <<
"_beta = 0.0;\n";
441 out <<
SP <<
"for (size_t n = 0; n < " <<
bsize <<
"; n++) {\n";
451 if (fAttrPads[0] != fAttrPads[1]) {
452 std::cout <<
"TMVA SOFIE Operator Conv: asymmetric padding not supported. Assume an average padding "
454 fAttrPads[0] = (fAttrPads[0] + fAttrPads[1]) / 2;
459 if (fAttrPads[0] != fAttrPads[2] || fAttrPads[1] != fAttrPads[3]) {
460 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
462 fAttrPads[0] = (fAttrPads[0] + fAttrPads[2]) / 2;
463 fAttrPads[1] = (fAttrPads[1] + fAttrPads[3]) / 2;
467 if (fAttrPads[0] != fAttrPads[3] || fAttrPads[1] != fAttrPads[4] || fAttrPads[2] != fAttrPads[5]) {
468 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
470 fAttrPads[0] = (fAttrPads[0] + fAttrPads[3]) / 2;
471 fAttrPads[1] = (fAttrPads[1] + fAttrPads[4]) / 2;
472 fAttrPads[2] = (fAttrPads[2] + fAttrPads[5]) / 2;
476 if (fAttrGroup == 1) {
482 out <<
SP <<
SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
484 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
486 out <<
SP <<
SP <<
SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
487 <<
"_xcol, &" <<
OpName <<
"_m);\n";
493 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fNX
499 out <<
"1, " << fAttrKernelShape[0] <<
",0," << fAttrPads[0] <<
",1," << fAttrStrides[0] <<
",1,"
500 << fAttrDilations[0];
502 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1]
503 <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrDilations[0] <<
","
504 << fAttrDilations[1];
505 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
508 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
509 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
514 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
515 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
516 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
517 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
","
518 << fAttrDilations[0] <<
"," << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
",tensor_" << fNX
531 out <<
SP <<
SP <<
"for (size_t g = 0; g < " << fAttrGroup <<
"; g++) {\n";
532 out <<
SP <<
SP <<
"size_t x_offset = n * " << fShapeX[1] *
iHeight *
iWidth <<
" + g * "
534 out <<
SP <<
SP <<
"size_t out_offset = n * " << fShapeY[1] *
oHeight *
oWidth <<
" + g * "
538 out <<
SP <<
SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
540 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
542 out <<
SP <<
SP <<
SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
543 <<
"_xcol , &" <<
OpName <<
"_m);\n";
546 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fNX
552 out <<
"1, " << fAttrKernelShape[0] <<
",0," << fAttrPads[0] <<
",1," << fAttrStrides[0] <<
",1,"
553 << fAttrDilations[0];
555 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1]
556 <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrDilations[0] <<
","
557 << fAttrDilations[1];
558 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
561 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
563 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
568 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
569 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
570 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
571 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
","
572 << fAttrDilations[0] <<
"," << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
"," <<
"tensor_" << fNX
588 out <<
SP <<
SP <<
"}\n";
593 if (fNBroadcastedB !=
"") {
595 out <<
SP <<
"float " <<
OpName <<
"_gamma = 1.0;\n";
596 out <<
SP <<
"int " <<
OpName <<
"_incx = 1;\n";
597 out <<
SP <<
"int " <<
OpName <<
"_incy = 1;\n";
599 out <<
SP <<
"BLAS::saxpy_(&" <<
OpName <<
"_size, &" <<
OpName <<
"_gamma, tensor_" << fNBroadcastedB <<
", &"
600 <<
OpName <<
"_incx, tensor_" << fNY <<
", &" <<
OpName <<
"_incy);\n";
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 input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
void AddNeededHelperFunction(std::string name)
std::vector< size_t > GetTensorShape(const std::string &name) const
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
bool CheckIfTensorAlreadyExist(std::string tensor_name)
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
ETensorType GetTensorType(std::string name) const
void UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Transposed Convolution operator.
std::vector< size_t > fAttrOutputPadding
std::vector< std::string > GetBlasRoutines() override
Returns the blas routines needed to compile the generated code.
std::vector< size_t > fAttrPads
ROperator_ConvTranspose(std::string autopad, std::vector< size_t > dilations, size_t group, std::vector< size_t > kernelShape, std::vector< size_t > outputPadding, std::vector< size_t > outputShape, std::vector< size_t > pads, std::vector< size_t > strides, std::string nameX, std::string nameW, std::string nameB, std::string nameY)
Constructor of ROperator_ConvTranspose from the attributes.
void Initialize(RModel &) override
Initialize the model.
ROperator_ConvTranspose()
Default constructor of ROperator_ConvTranspose.
std::vector< size_t > fAttrKernelShape
std::vector< size_t > fAttrDilations
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
Infers the type of the output tensor.
std::string fNBroadcastedB
std::string GenerateInitCode() override
Generate code for initializing the op.
std::string Generate(std::string opName) override
Generate the inference code.
std::vector< size_t > fAttrStrides
std::vector< size_t > fShapeX
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > >) override
Infers the shape of the input tensors.
std::vector< size_t > fShapeW
std::vector< size_t > fShapeB
std::vector< size_t > fShapeY
std::vector< size_t > fAttrOutputShape
std::vector< std::string_view > fInputTensorNames
std::vector< std::string_view > fOutputTensorNames
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
ETensorType ConvertStringToType(std::string type)
std::string ConvertShapeToString(const std::vector< size_t > &shape)