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,
95 if (std::is_same<T, float>::value) {
98 throw std::runtime_error(
"TMVA SOFIE Encountered unsupported type parsing a Conv operator");
114 std::vector<std::vector<size_t>>
ShapeInference(std::vector<std::vector<size_t>> )
override;
132 std::vector<std::string>
GetBlasRoutines()
override {
return {std::string(
"Gemm"), std::string(
"Axpy")}; }
137 -> std::vector<std::vector<size_t>>
147 if (fAttrStrides.empty()) {
148 fAttrStrides = std::vector<size_t>(fDim, 1);
150 if (fAttrDilations.empty()) {
151 fAttrDilations = std::vector<size_t>(fDim, 1);
154 if (fAttrKernelShape.empty()) {
155 fAttrKernelShape.resize(fDim);
156 for (
size_t i = 0; i < fDim; i++)
157 fAttrKernelShape[i] = fShapeW[i + 2] + (fAttrDilations[i] - 1) * (fShapeW[i + 2] - 1);
159 if (fAttrOutputPadding.empty())
160 fAttrOutputPadding = std::vector<size_t>(fDim, 0);
171 if (fAttrPads.empty()) {
172 fAttrPads = std::vector<size_t>(2 * fDim, 0);
174 if (fAttrAutopad !=
"NOTSET") {
175 throw std::runtime_error(
"ConvTranspose with padding SAME_UPPER or SMAE_LOWER not supported");
178 if (fAttrOutputShape.empty()) {
179 fAttrOutputShape.resize(fDim);
180 for (
size_t i = 0; i < fDim; i++) {
182 fAttrOutputShape[i] = fAttrStrides[i] * (
inputShape[
j] - 1) + fAttrKernelShape[i] + fAttrOutputPadding[i] -
183 fAttrPads[i] - fAttrPads[fDim + i];
187 fAttrPads = std::vector<size_t>(2 * fDim, 0);
188 for (
size_t i = 0; i < fDim; ++i) {
193 size_t stride = fAttrStrides[i];
194 size_t dilation = fAttrDilations[i];
201 throw std::runtime_error(
"ConvTranspose: explicitly set output_shape is too large for "
202 "the given input and kernel shapes.");
212 for (
size_t i = 0; i < fDim; i++)
213 outShape[i + 2] = fAttrOutputShape[i];
222 fUseSession = model.UseSession();
223 if (!model.CheckIfTensorAlreadyExist(fNX)) {
224 throw std::runtime_error(
"TMVA SOFIE Conv Transpose op Input Tensor " + fNX +
" is not found in model");
226 fShapeX = model.GetTensorShape(fNX);
227 if (fShapeX.size() < 3 || fShapeX.size() > 5) {
229 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input data tensor" + fNX +
230 " is not of 3,4 or 5 dimensions");
232 fDim = fShapeX.size() - 2;
233 if (!model.CheckIfTensorAlreadyExist(fNW)) {
234 throw std::runtime_error(
"TMVA SOFIE Conv op Input weight Tensor " + fNW +
" is not found in model");
236 fShapeW = model.GetTensorShape(fNW);
237 if (fShapeW.size() < 3 || fShapeW.size() > 5) {
239 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input weight tensor" + fNW +
240 " is not of 3,4 or 5 dimensions");
242 fShapeY = ShapeInference({fShapeX, fShapeW})[0];
244 model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY);
246 if (!model.CheckIfTensorAlreadyExist(fNB)) {
247 throw std::runtime_error(
"TMVA SOFIE ConvTrans op Input Tensor " + fNB +
" is not found in model");
249 fShapeB = model.GetTensorShape(fNB);
250 if (fShapeB.size() < 1)
251 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has empty shape");
261 if (
bsize != fShapeY[1])
262 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has wrong shape: " +
267 if (fType !=
"float")
268 throw std::runtime_error(
269 "TMVA SOFIE ConvTrans op: Broadcasting for non-float type tensors is not supported");
274 UTILITY::BroadcastConvBias<float>(
static_cast<float *
>(
original_data.get()),
bsize, fShapeY),
275 std::default_delete<
float[]>());
277 model.UpdateInitializedTensor(fNB, model.GetTensorType(fNB), fShapeY,
new_data_ptr);
278 fShapeB = model.GetTensorShape(fNB);
279 fNBroadcastedB = fNB;
283 fNBroadcastedB =
"Broadcasted" + fNB;
284 model.AddIntermediateTensor(fNBroadcastedB, model.GetTensorType(fNB), fShapeY);
288 if (fShapeY != fShapeB)
289 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Broadcasting is not needed but bias has wrong shape" +
291 fNBroadcastedB = fNB;
296 size_t inputSize = 1;
297 for (
size_t i = 0; i < fDim; i++) {
298 inputSize *= fShapeX[2 + i];
307 fImcol = fNX +
"_xcol";
308 fOutputTensorNames.emplace_back(fConvK);
309 fOutputTensorNames.emplace_back(fImcol);
313 model.AddNeededHelperFunction(
"col2im");
315 model.AddNeededHelperFunction(
"BroadcastConvBias");
321 std::stringstream out;
325 if (
bsize !=
ysize && !fNBroadcastedB.empty()) {
328 out <<
SP <<
SP <<
"float * data = UTILITY::BroadcastConvBias<float>(tensor_" << fNB <<
", " <<
bsize <<
", "
332 out <<
SP <<
SP <<
"delete[] data;\n";
343 if (fShapeX.empty() || fShapeW.empty() || (fNB !=
"" && fShapeB.empty()) || fShapeY.empty()) {
344 throw std::runtime_error(
"TMVA SOFIE Conv Op called to Generate without being initialized first");
347 std::stringstream out;
349 size_t bsize = fShapeX[0];
350 size_t kDepth = (fDim > 2) ? fShapeW[2] : 1;
351 size_t kHeight = (fDim > 1) ? fShapeW[fDim] : 1;
352 size_t kWidth = fShapeW[fDim + 1];
354 size_t iDepth = (fDim > 2) ? fShapeX[2] : 1;
355 size_t iHeight = (fDim > 1) ? fShapeX[fDim] : 1;
356 size_t iWidth = fShapeX[fDim + 1];
358 size_t oDepth = (fDim > 2) ? fShapeY[2] : 1;
359 size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1;
360 size_t oWidth = fShapeY[fDim + 1];
362 out <<
"\n//---- operator ConvTranspose " <<
OpName <<
"\n";
369 out <<
SP << fType <<
" tensor_" << fNX <<
"_f[" << fShapeW[0] * fShapeW[1] *
kernelSize <<
"] = {0};\n";
375 size_t id = (fDim > 2) ? fDim - 3 : 2;
376 size_t ih = (fDim > 1) ? fDim - 2 : 1;
377 size_t iw = fDim - 1;
392 for (
size_t i = 0; i < fDim; i++)
398 out <<
SP <<
"for (std::size_t ic = 0; ic < " << fShapeW[0] <<
"; ic++) {\n";
399 out <<
SP <<
SP <<
"for (std::size_t oc = 0; oc < " << fShapeW[1] <<
"; oc++) {\n";
402 out <<
SP <<
SP <<
SP <<
"for (std::size_t kd = 0; kd < " << kDepth <<
"; kd++) {\n";
404 out <<
SP <<
SP <<
SP <<
"for (std::size_t kh = 0; kh < " <<
kHeight <<
"; kh++) {\n";
405 out <<
SP <<
SP <<
SP <<
SP <<
"for (std::size_t kw = 0; kw < " <<
kWidth <<
"; kw++) {\n";
424 out <<
SP <<
SP <<
SP <<
SP <<
"}\n";
426 out <<
SP <<
SP <<
SP <<
"}\n";
428 out <<
SP <<
SP <<
SP <<
"}\n";
430 out <<
SP <<
SP <<
"}\n";
433 out <<
SP <<
"char " <<
OpName <<
"_transA = 'N';\n";
434 out <<
SP <<
"char " <<
OpName <<
"_transB = 'T';\n";
437 out <<
SP <<
"int " <<
OpName <<
"_k = " << fShapeW[0] <<
";\n";
438 out <<
SP <<
"float " <<
OpName <<
"_alpha = 1.0;\n";
439 out <<
SP <<
"float " <<
OpName <<
"_beta = 0.0;\n";
447 out <<
SP <<
"for (size_t n = 0; n < " <<
bsize <<
"; n++) {\n";
457 if (fAttrGroup == 1) {
463 out <<
SP <<
SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
465 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
467 out <<
SP <<
SP <<
SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
468 <<
"_xcol, &" <<
OpName <<
"_m);\n";
474 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fNX
480 out <<
"1, " << fAttrKernelShape[0] <<
",0,0," << fAttrPads[0] <<
"," << fAttrPads[1] <<
",1,"
481 << fAttrStrides[0] <<
",1," << fAttrDilations[0];
483 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[2]
484 <<
"," << fAttrPads[1] <<
"," << fAttrPads[3] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
","
485 << fAttrDilations[0] <<
"," << fAttrDilations[1];
486 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
489 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
490 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
495 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
496 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
497 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
498 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
"," << fAttrDilations[0] <<
","
499 << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
",tensor_" << fNX <<
"_xcol);\n\n ";
511 out <<
SP <<
SP <<
"for (size_t g = 0; g < " << fAttrGroup <<
"; g++) {\n";
512 out <<
SP <<
SP <<
"size_t x_offset = n * " << fShapeX[1] *
iHeight *
iWidth <<
" + g * "
514 out <<
SP <<
SP <<
"size_t out_offset = n * " << fShapeY[1] *
oHeight *
oWidth <<
" + g * "
518 out <<
SP <<
SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transA, &" <<
OpName <<
"_transB, &" <<
OpName <<
"_m, &"
520 <<
"tensor_" << fNX <<
" + x_offset, &" <<
OpName
522 out <<
SP <<
SP <<
SP <<
"tensor_" << fNX <<
"_f, &" <<
OpName <<
"_n, &" <<
OpName <<
"_beta, tensor_" << fNX
523 <<
"_xcol , &" <<
OpName <<
"_m);\n";
526 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fNX
532 out <<
"1, " << fAttrKernelShape[0] <<
",0,0," << fAttrPads[0] <<
"," << fAttrPads[1] <<
",1,"
533 << fAttrStrides[0] <<
",1," << fAttrDilations[0];
535 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[2]
536 <<
"," << fAttrPads[1] <<
"," << fAttrPads[3] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
","
537 << fAttrDilations[0] <<
"," << fAttrDilations[1];
538 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
541 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
543 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
548 << fShapeX[1] <<
"," <<
oDepth <<
"," <<
oHeight <<
"," <<
oWidth <<
"," << fAttrKernelShape[0] <<
","
549 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
550 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
551 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
"," << fAttrDilations[0] <<
","
552 << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
"," <<
"tensor_" << fNX <<
"_xcol);\n\n ";
567 out <<
SP <<
SP <<
"}\n";
572 if (fNBroadcastedB !=
"") {
574 out <<
SP <<
"float " <<
OpName <<
"_gamma = 1.0;\n";
575 out <<
SP <<
"int " <<
OpName <<
"_incx = 1;\n";
576 out <<
SP <<
"int " <<
OpName <<
"_incy = 1;\n";
578 out <<
SP <<
"BLAS::saxpy_(&" <<
OpName <<
"_size, &" <<
OpName <<
"_gamma, tensor_" << fNBroadcastedB <<
", &"
579 <<
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
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)