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);
309 std::stringstream out;
313 if (
bsize !=
ysize && !fNBroadcastedB.empty()) {
316 out << SP << SP <<
"float * data = TMVA::Experimental::SOFIE::UTILITY::BroadcastConvBias<float>(tensor_" << fNB
318 out << SP << SP <<
"std::copy(data, data + " <<
ConvertShapeToLength(fShapeY) <<
", tensor_" << fNBroadcastedB
320 out << SP << SP <<
"delete[] data;\n";
331 if (fShapeX.empty() || fShapeW.empty() || (fNB !=
"" && fShapeB.empty()) || fShapeY.empty()) {
332 throw std::runtime_error(
"TMVA SOFIE Conv Op called to Generate without being initialized first");
335 std::stringstream out;
337 size_t bsize = fShapeX[0];
338 size_t kDepth = (fDim > 2) ? fShapeW[2] : 1;
339 size_t kHeight = (fDim > 1) ? fShapeW[fDim] : 1;
340 size_t kWidth = fShapeW[fDim + 1];
342 size_t iDepth = (fDim > 2) ? fShapeX[2] : 1;
343 size_t iHeight = (fDim > 1) ? fShapeX[fDim] : 1;
344 size_t iWidth = fShapeX[fDim + 1];
346 size_t oDepth = (fDim > 2) ? fShapeY[2] : 1;
347 size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1;
348 size_t oWidth = fShapeY[fDim + 1];
350 out <<
"\n//---- operator ConvTranspose " <<
OpName <<
"\n";
357 out << SP << fType <<
" tensor_" << fNX <<
"_f[" << fShapeW[0] * fShapeW[1] *
kernelSize <<
"] = {0};\n";
363 size_t id = (fDim > 2) ? fDim - 3 : 2;
364 size_t ih = (fDim > 1) ? fDim - 2 : 1;
365 size_t iw = fDim - 1;
380 for (
size_t i = 0; i < fDim; i++)
386 out << SP <<
"for (std::size_t ic = 0; ic < " << fShapeW[0] <<
"; ic++) {\n";
387 out << SP << SP <<
"for (std::size_t oc = 0; oc < " << fShapeW[1] <<
"; oc++) {\n";
390 out << SP << SP << SP <<
"for (std::size_t kd = 0; kd < " << kDepth <<
"; kd++) {\n";
392 out << SP << SP << SP <<
"for (std::size_t kh = 0; kh < " <<
kHeight <<
"; kh++) {\n";
393 out << SP << SP << SP << SP <<
"for (std::size_t kw = 0; kw < " <<
kWidth <<
"; kw++) {\n";
395 out << SP << SP << SP << SP << SP <<
"tensor_" << fNX <<
"_f[ic * " <<
ocstrideDil <<
" + oc * " <<
icstrideDil;
412 out << SP << SP << SP << SP <<
"}\n";
414 out << SP << SP << SP <<
"}\n";
416 out << SP << SP << SP <<
"}\n";
418 out << SP << SP <<
"}\n";
421 out << SP <<
"char " <<
OpName <<
"_transA = 'N';\n";
422 out << SP <<
"char " <<
OpName <<
"_transB = 'T';\n";
425 out << SP <<
"int " <<
OpName <<
"_k = " << fShapeW[0] <<
";\n";
426 out << SP <<
"float " <<
OpName <<
"_alpha = 1.0;\n";
427 out << SP <<
"float " <<
OpName <<
"_beta = 0.0;\n";
435 out << SP <<
"for (size_t n = 0; n < " <<
bsize <<
"; n++) {\n";
445 if (fAttrPads[0] != fAttrPads[1]) {
446 std::cout <<
"TMVA SOFIE Operator Conv: asymmetric padding not supported. Assume an average padding "
448 fAttrPads[0] = (fAttrPads[0] + fAttrPads[1]) / 2;
453 if (fAttrPads[0] != fAttrPads[2] || fAttrPads[1] != fAttrPads[3]) {
454 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
456 fAttrPads[0] = (fAttrPads[0] + fAttrPads[2]) / 2;
457 fAttrPads[1] = (fAttrPads[1] + fAttrPads[3]) / 2;
461 if (fAttrPads[0] != fAttrPads[3] || fAttrPads[1] != fAttrPads[4] || fAttrPads[2] != fAttrPads[5]) {
462 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
464 fAttrPads[0] = (fAttrPads[0] + fAttrPads[3]) / 2;
465 fAttrPads[1] = (fAttrPads[1] + fAttrPads[4]) / 2;
466 fAttrPads[2] = (fAttrPads[2] + fAttrPads[5]) / 2;
470 if (fAttrGroup == 1) {
471 out << SP << SP <<
"size_t x_offset = n * " << fShapeX[1] *
iDepth *
iHeight *
iWidth <<
";\n";
472 out << SP << SP <<
"size_t out_offset = n * " << fShapeY[1] *
oDepth *
oHeight *
oWidth <<
";\n";
476 out << SP << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
478 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
480 out << SP << SP << SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
481 <<
"_xcol, &" <<
OpName <<
"_m);\n";
487 out << SP << SP <<
"TMVA::Experimental::SOFIE::UTILITY::col2im<float>(tensor_" << fNX
493 out <<
"1, " << fAttrKernelShape[0] <<
",0," << fAttrPads[0] <<
",1," << fAttrStrides[0] <<
",1,"
494 << fAttrDilations[0];
496 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1]
497 <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrDilations[0] <<
","
498 << fAttrDilations[1];
499 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
502 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
503 out << SP << SP <<
"TMVA::Experimental::SOFIE::UTILITY::Im2col_3d<float>(tensor_" << fNX
508 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
509 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1] <<
","
510 << fAttrPads[2] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
","
511 << fAttrDilations[0] <<
"," << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
",tensor_" << fNX
524 out << SP << SP <<
"for (size_t g = 0; g < " << fAttrGroup <<
"; g++) {\n";
525 out << SP << SP <<
"size_t x_offset = n * " << fShapeX[1] *
iHeight *
iWidth <<
" + g * "
527 out << SP << SP <<
"size_t out_offset = n * " << fShapeY[1] *
oHeight *
oWidth <<
" + g * "
531 out << SP << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
533 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
535 out << SP << SP << SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
536 <<
"_xcol , &" <<
OpName <<
"_m);\n";
539 out << SP << SP <<
"TMVA::Experimental::SOFIE::UTILITY::col2im<float>(tensor_" << fNX
545 out <<
"1, " << fAttrKernelShape[0] <<
",0," << fAttrPads[0] <<
",1," << fAttrStrides[0] <<
",1,"
546 << fAttrDilations[0];
548 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1]
549 <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrDilations[0] <<
","
550 << fAttrDilations[1];
551 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
554 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
556 out << SP << SP <<
"TMVA::Experimental::SOFIE::UTILITY::Im2col_3d<float>(tensor_" << fNX
561 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
562 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[1] <<
","
563 << fAttrPads[2] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
","
564 << fAttrDilations[0] <<
"," << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
"," <<
"tensor_" << fNX
580 out << SP << SP <<
"}\n";
585 if (fNBroadcastedB !=
"") {
587 out << SP <<
"float " <<
OpName <<
"_gamma = 1.0;\n";
588 out << SP <<
"int " <<
OpName <<
"_incx = 1;\n";
589 out << SP <<
"int " <<
OpName <<
"_incy = 1;\n";
591 out << SP <<
"BLAS::saxpy_(&" <<
OpName <<
"_size, &" <<
OpName <<
"_gamma, tensor_" << fNBroadcastedB <<
", &"
592 <<
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
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)