128 -> std::vector<std::vector<size_t>>
130 const std::vector<size_t> &inputShape =
input[0];
131 const std::vector<size_t> &weightShape =
input[1];
132 size_t size = inputShape.size();
138 if (fAttrStrides.empty()) {
139 fAttrStrides = std::vector<size_t>(fDim, 1);
141 if (fAttrDilations.empty()) {
142 fAttrDilations = std::vector<size_t>(fDim, 1);
145 if (fAttrKernelShape.empty()) {
146 fAttrKernelShape.resize(fDim);
147 for (
size_t i = 0; i < fDim; i++)
148 fAttrKernelShape[i] = fShapeW[i + 2] + (fAttrDilations[i] - 1) * (fShapeW[i + 2] - 1);
150 if (fAttrOutputPadding.empty())
151 fAttrOutputPadding = std::vector<size_t>(fDim, 0);
157 std::vector<size_t> outShape(
size);
158 outShape[0] = inputShape[0];
159 outShape[1] = weightShape[1] * fAttrGroup;
162 if (fAttrPads.empty()) {
163 fAttrPads = std::vector<size_t>(2 * fDim, 0);
165 if (fAttrAutopad !=
"NOTSET") {
166 throw std::runtime_error(
"ConvTranspose with padding SAME_UPPER or SMAE_LOWER not supported");
169 if (fAttrOutputShape.empty()) {
170 fAttrOutputShape.resize(fDim);
171 for (
size_t i = 0; i < fDim; i++) {
173 fAttrOutputShape[i] = fAttrStrides[i] * (inputShape[j] - 1) + fAttrKernelShape[i] + fAttrOutputPadding[i] -
174 fAttrPads[i] - fAttrPads[fDim + i];
178 fAttrPads = std::vector<size_t>(2 * fDim, 0);
179 for (
size_t i = 0; i < fDim; ++i) {
180 size_t input_shape = inputShape[i + 2];
181 size_t output_shape = fAttrOutputShape[i];
182 size_t kernel_shape = weightShape[i + 2];
184 size_t stride = fAttrStrides[i];
185 size_t dilation = fAttrDilations[i];
186 size_t output_padding = fAttrOutputPadding[i];
188 size_t effective_kernel_shape = (kernel_shape - 1) * dilation + 1;
189 size_t expected_shape_without_pad = (input_shape - 1) * stride + output_padding + effective_kernel_shape;
191 if (expected_shape_without_pad < output_shape) {
192 throw std::runtime_error(
"ConvTranspose: explicitly set output_shape is too large for "
193 "the given input and kernel shapes.");
196 size_t total_padding = expected_shape_without_pad - output_shape;
198 fAttrPads[i + fDim] = total_padding / 2;
199 fAttrPads[i] = total_padding - fAttrPads[i + fDim];
203 for (
size_t i = 0; i < fDim; i++)
204 outShape[i + 2] = fAttrOutputShape[i];
205 std::vector<std::vector<size_t>> ret({outShape});
213 if (!model.CheckIfTensorAlreadyExist(fNX)) {
214 throw std::runtime_error(
"TMVA SOFIE Conv Transpose op Input Tensor " + fNX +
" is not found in model");
216 fShapeX = model.GetTensorShape(fNX);
217 if (fShapeX.size() < 3 || fShapeX.size() > 5) {
219 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input data tensor" + fNX +
220 " is not of 3,4 or 5 dimensions");
222 fDim = fShapeX.size() - 2;
223 if (!model.CheckIfTensorAlreadyExist(fNW)) {
224 throw std::runtime_error(
"TMVA SOFIE Conv op Input weight Tensor " + fNW +
" is not found in model");
226 fShapeW = model.GetTensorShape(fNW);
227 if (fShapeW.size() < 3 || fShapeW.size() > 5) {
229 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input weight tensor" + fNW +
230 " is not of 3,4 or 5 dimensions");
232 fShapeY = ShapeInference({fShapeX, fShapeW})[0];
234 model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY);
236 if (!model.CheckIfTensorAlreadyExist(fNB)) {
237 throw std::runtime_error(
"TMVA SOFIE ConvTrans op Input Tensor " + fNB +
" is not found in model");
239 fShapeB = model.GetTensorShape(fNB);
240 if (fShapeB.size() < 1)
241 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has empty shape");
246 bool broadcast_needed = (bsize != ysize);
248 if (broadcast_needed) {
251 if (bsize != fShapeY[1])
252 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has wrong shape: " +
255 if (fType !=
"float")
256 throw std::runtime_error(
257 "TMVA SOFIE ConvTrans op: Broadcasting for non-float type tensors is not supported");
260 fNBroadcastedB =
"Broadcasted" + fNB;
261 model.AddIntermediateTensor(fNBroadcastedB, model.GetTensorType(fNB), fShapeY);
264 if (fShapeY != fShapeB)
265 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Broadcasting is not needed but bias has wrong shape" +
267 fNBroadcastedB = fNB;
271 size_t kernelSize = 1;
272 size_t inputSize = 1;
273 for (
size_t i = 0; i < fDim; i++) {
274 inputSize *= fShapeX[2 + i];
275 kernelSize *= fAttrKernelShape[i];
278 std::vector<size_t> shape1 = {fShapeW[0], fShapeW[1], kernelSize};
279 std::vector<size_t> shape2 = {fShapeW[1], kernelSize, inputSize};
284 fImcol = fNY +
"_xcol";
285 fOutputTensorNames.emplace_back(fConvK);
286 fOutputTensorNames.emplace_back(fImcol);
290 model.AddNeededHelperFunction(
"col2im");
292 model.AddNeededHelperFunction(
"BroadcastConvBias");
318 OpName =
"op_" + OpName;
320 if (fShapeX.empty() || fShapeW.empty() || (fNB !=
"" && fShapeB.empty()) || fShapeY.empty()) {
321 throw std::runtime_error(
"TMVA SOFIE Conv Op called to Generate without being initialized first");
324 std::stringstream out;
326 size_t bsize = fShapeX[0];
327 size_t kDepth = (fDim > 2) ? fShapeW[2] : 1;
328 size_t kHeight = (fDim > 1) ? fShapeW[fDim] : 1;
329 size_t kWidth = fShapeW[fDim + 1];
331 size_t iDepth = (fDim > 2) ? fShapeX[2] : 1;
332 size_t iHeight = (fDim > 1) ? fShapeX[fDim] : 1;
333 size_t iWidth = fShapeX[fDim + 1];
335 size_t oDepth = (fDim > 2) ? fShapeY[2] : 1;
336 size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1;
337 size_t oWidth = fShapeY[fDim + 1];
339 out <<
"\n//---- operator ConvTranspose " << OpName <<
"\n";
344 size_t id = (fDim > 2) ? fDim - 3 : 2;
345 size_t ih = (fDim > 1) ? fDim - 2 : 1;
346 size_t iw = fDim - 1;
347 size_t wstrideDil = fAttrDilations[iw];
348 size_t hstride = kWidth;
349 size_t hstrideDil = fAttrKernelShape[iw];
351 hstrideDil *= fAttrDilations[ih];
353 size_t dstride = kHeight * kWidth;
354 size_t dstrideDil = fAttrKernelShape[iw];
356 dstrideDil *= fAttrKernelShape[ih];
358 dstrideDil *= fAttrDilations[
id];
359 size_t icstride = kHeight * kWidth * kDepth;
360 size_t icstrideDil = 1;
361 for (
size_t i = 0; i < fDim; i++)
362 icstrideDil *= fAttrKernelShape[i];
363 size_t ocstride = fShapeW[1] * icstride;
364 size_t ocstrideDil = fShapeW[1] * icstrideDil;
367 out <<
SP <<
"for (std::size_t ic = 0; ic < " << fShapeW[0] <<
"; ic++) {\n";
368 out <<
SP <<
SP <<
"for (std::size_t oc = 0; oc < " << fShapeW[1] <<
"; oc++) {\n";
371 out <<
SP <<
SP <<
SP <<
"for (std::size_t kd = 0; kd < " << kDepth <<
"; kd++) {\n";
373 out <<
SP <<
SP <<
SP <<
"for (std::size_t kh = 0; kh < " << kHeight <<
"; kh++) {\n";
374 out <<
SP <<
SP <<
SP <<
SP <<
"for (std::size_t kw = 0; kw < " << kWidth <<
"; kw++) {\n";
376 out <<
SP <<
SP <<
SP <<
SP <<
SP <<
"tensor_" << fConvK <<
"[ic * " << ocstrideDil <<
" + oc * " << icstrideDil;
378 out <<
" + kd * " << dstrideDil;
380 out <<
" + kh * " << hstrideDil;
381 out <<
" + kw * " << wstrideDil <<
" ] = tensor_" << fNW <<
"[ic * " << ocstride <<
" + oc * " << icstride;
384 out <<
" + kd * " << dstride;
386 out <<
" + kh * " << hstride;
393 out <<
SP <<
SP <<
SP <<
SP <<
"}\n";
395 out <<
SP <<
SP <<
SP <<
"}\n";
397 out <<
SP <<
SP <<
SP <<
"}\n";
399 out <<
SP <<
SP <<
"}\n";
402 out <<
SP <<
"char " << OpName <<
"_transA = 'N';\n";
403 out <<
SP <<
"char " << OpName <<
"_transB = 'T';\n";
404 out <<
SP <<
"int " << OpName <<
"_m = " << iHeight * iWidth * iDepth <<
";\n";
405 out <<
SP <<
"int " << OpName <<
"_n = " << icstrideDil * fShapeW[1] <<
";\n";
406 out <<
SP <<
"int " << OpName <<
"_k = " << fShapeW[0] <<
";\n";
407 out <<
SP <<
"float " << OpName <<
"_alpha = 1.0;\n";
408 out <<
SP <<
"float " << OpName <<
"_beta = 0.0;\n";
411 out <<
SP <<
"for (size_t n = 0; n < " << bsize <<
"; n++) {\n";
421 if (fAttrGroup == 1) {
422 out <<
SP <<
SP <<
"size_t x_offset = n * " << fShapeX[1] * iDepth * iHeight * iWidth <<
";\n";
423 out <<
SP <<
SP <<
"size_t out_offset = n * " << fShapeY[1] * oDepth * oHeight * oWidth <<
";\n";
427 out <<
SP <<
SP <<
"BLAS::sgemm_(&" << OpName <<
"_transA, &" << OpName <<
"_transB, &" << OpName <<
"_m, &"
428 << OpName <<
"_n, &" << OpName <<
"_k, &" << OpName <<
"_alpha, "
429 <<
"tensor_" << fNX <<
" + x_offset, &" << OpName
431 out <<
SP <<
SP <<
SP <<
"tensor_" << fConvK <<
", &" << OpName <<
"_n, &" << OpName <<
"_beta, tensor_" << fImcol
432 <<
", &" << OpName <<
"_m);\n";
438 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fImcol
442 << fShapeY[1] <<
"," << oHeight <<
"," << oWidth <<
",";
444 out <<
"1, " << fAttrKernelShape[0] <<
",0,0," << fAttrPads[0] <<
"," << fAttrPads[1] <<
",1,"
445 << fAttrStrides[0] <<
",1," << fAttrDilations[0];
447 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[2]
448 <<
"," << fAttrPads[1] <<
"," << fAttrPads[3] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
","
449 << fAttrDilations[0] <<
"," << fAttrDilations[1];
450 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
453 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
454 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
459 << fShapeX[1] <<
"," << oDepth <<
"," << oHeight <<
"," << oWidth <<
"," << fAttrKernelShape[0] <<
","
460 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
461 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
462 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
"," << fAttrDilations[0] <<
","
463 << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
",tensor_" << fImcol <<
");\n\n ";
475 out <<
SP <<
SP <<
"for (size_t g = 0; g < " << fAttrGroup <<
"; g++) {\n";
476 out <<
SP <<
SP <<
"size_t x_offset = n * " << fShapeX[1] * iHeight * iWidth <<
" + g * "
477 << fShapeX[1] * iHeight * iWidth / fAttrGroup <<
";\n ";
478 out <<
SP <<
SP <<
"size_t out_offset = n * " << fShapeY[1] * oHeight * oWidth <<
" + g * "
479 << fShapeY[1] * oHeight * oWidth / fAttrGroup <<
";\n ";
482 out <<
SP <<
SP <<
"BLAS::sgemm_(&" << OpName <<
"_transA, &" << OpName <<
"_transB, &" << OpName <<
"_m, &"
483 << OpName <<
"_n, &" << OpName <<
"_k, &" << OpName <<
"_alpha, "
484 <<
"tensor_" << fNX <<
" + x_offset, &" << OpName
486 out <<
SP <<
SP <<
SP <<
"tensor_" << fConvK <<
", &" << OpName <<
"_n, &" << OpName <<
"_beta, tensor_" << fImcol
487 <<
" , &" << OpName <<
"_m);\n";
490 out <<
SP <<
SP <<
"UTILITY::col2im<float>(tensor_" << fImcol
494 << fShapeY[1] <<
"," << oHeight <<
"," << oWidth <<
",";
496 out <<
"1, " << fAttrKernelShape[0] <<
",0,0," << fAttrPads[0] <<
"," << fAttrPads[1] <<
",1,"
497 << fAttrStrides[0] <<
",1," << fAttrDilations[0];
499 out << fAttrKernelShape[0] <<
"," << fAttrKernelShape[1] <<
"," << fAttrPads[0] <<
"," << fAttrPads[2]
500 <<
"," << fAttrPads[1] <<
"," << fAttrPads[3] <<
"," << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
","
501 << fAttrDilations[0] <<
"," << fAttrDilations[1];
502 out <<
", tensor_" << fNY <<
" + out_offset);\n\n ";
505 throw std::runtime_error(
"TMVA SOFIE 3D Conv Transpose not yet supported");
507 out <<
SP <<
SP <<
"UTILITY::Im2col_3d<float>(tensor_" << fNX
512 << fShapeX[1] <<
"," << oDepth <<
"," << oHeight <<
"," << oWidth <<
"," << fAttrKernelShape[0] <<
","
513 << fAttrKernelShape[1] <<
"," << fAttrKernelShape[2] <<
"," << fAttrPads[0] <<
"," << fAttrPads[3] <<
","
514 << fAttrPads[1] <<
"," << fAttrPads[4] <<
"," << fAttrPads[2] <<
"," << fAttrPads[5] <<
","
515 << fAttrStrides[0] <<
"," << fAttrStrides[1] <<
"," << fAttrStrides[2] <<
"," << fAttrDilations[0] <<
","
516 << fAttrDilations[1] <<
"," << fAttrDilations[2] <<
"," <<
"tensor_" << fImcol <<
");\n\n ";
531 out <<
SP <<
SP <<
"}\n";
536 if (fNBroadcastedB !=
"") {
537 out <<
SP <<
"int " << OpName <<
"_size = " << fShapeY[0] * fShapeY[1] * oDepth * oHeight * oWidth <<
";\n";
538 out <<
SP <<
"float " << OpName <<
"_gamma = 1.0;\n";
539 out <<
SP <<
"int " << OpName <<
"_incx = 1;\n";
540 out <<
SP <<
"int " << OpName <<
"_incy = 1;\n";
542 out <<
SP <<
"BLAS::saxpy_(&" << OpName <<
"_size, &" << OpName <<
"_gamma, tensor_" << fNBroadcastedB <<
", &"
543 << OpName <<
"_incx, tensor_" << fNY <<
", &" << OpName <<
"_incy);\n";
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.