1#ifndef TMVA_SOFIE_ROPERATOR_CONVTRANSPOSE_HXX
2#define TMVA_SOFIE_ROPERATOR_CONVTRANSPOSE_HXX
73 std::vector<size_t> kernelShape, std::vector<size_t> outputPadding,
74 std::vector<size_t> outputShape, std::vector<size_t> pads, std::vector<size_t> strides,
75 std::string nameX, std::string nameW, std::string nameB, std::string nameY)
84 fInputTensorNames.emplace_back(fNB);
87 if (std::is_same<T, float>::value) {
90 throw std::runtime_error(
"TMVA SOFIE Encountered unsupported type parsing a Conv operator");
97 std::vector<ETensorType>
TypeInference(std::vector<ETensorType> input)
override
106 std::vector<std::vector<size_t>>
ShapeInference(std::vector<std::vector<size_t>> )
override;
120 std::string
Generate(std::string opName)
override;
124 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Gemm"), std::string(
"Axpy") }; }
129 -> std::vector<std::vector<size_t>>
131 const std::vector<size_t> &inputShape = input[0];
132 const std::vector<size_t> &weightShape = input[1];
133 size_t size = inputShape.size();
148 for (
size_t i = 0; i <
fDim; i++)
158 std::vector<size_t> outShape(
size);
159 outShape[0] = inputShape[0];
168 throw std::runtime_error(
"ConvTranspose with output_shape explicitly set not yet supported.");
190 throw std::runtime_error(
"ConvTranspose with padding SAME_UPPER or SMAE_LOWER not supported");
195 for (
size_t i = 0; i <
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++)
208 std::vector<std::vector<size_t>>
ret({outShape});
217 if (!model.CheckIfTensorAlreadyExist(
fNX)) {
218 throw std::runtime_error(
"TMVA SOFIE Conv Transpose op Input Tensor " +
fNX +
" is not found in model");
223 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input data tensor" +
fNX +
224 " is not of 3,4 or 5 dimensions");
227 if (!model.CheckIfTensorAlreadyExist(
fNW)) {
228 throw std::runtime_error(
"TMVA SOFIE Conv op Input weight Tensor " +
fNW +
" is not found in model");
233 throw std::runtime_error(
"TMVA SOFIE Conv Transpose Op input weight tensor" +
fNW +
234 " is not of 3,4 or 5 dimensions");
238 model.AddIntermediateTensor(
fNY, model.GetTensorType(
fNX),
fShapeY);
240 if (!model.CheckIfTensorAlreadyExist(
fNB)) {
241 throw std::runtime_error(
"TMVA SOFIE ConvTrans op Input Tensor " +
fNB +
" is not found in model");
245 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has empty shape");
250 bool broadcast_needed = (bsize != ysize);
252 if (broadcast_needed) {
256 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Bias Tensor has wrong shape: " +
259 auto original_data = model.GetInitializedTensorData(
fNB);
261 if (
fType !=
"float")
262 throw std::runtime_error(
263 "TMVA SOFIE ConvTrans op: Broadcasting for non-float type tensors is not supported");
267 std::shared_ptr<void> new_data_ptr(
269 std::default_delete<
float[]>());
271 model.UpdateInitializedTensor(
fNB, model.GetTensorType(
fNB),
fShapeY, new_data_ptr);
283 throw std::runtime_error(
"TMVA SOFIE ConvTrans op: Broadcasting is not needed but bias has wrong shape" +
289 size_t kernelSize = 1;
290 size_t inputSize = 1;
291 for (
size_t i = 0; i <
fDim; i++) {
296 std::vector<size_t> shape1 = {
fShapeW[0],
fShapeW[1], kernelSize};
297 std::vector<size_t> shape2 = {
fShapeW[1], kernelSize, inputSize};
309 std::stringstream out;
316 out <<
SP <<
SP <<
"float * data = TMVA::Experimental::SOFIE::UTILITY::BroadcastConvBias<float>(tensor_" <<
fNB
320 out <<
SP <<
SP <<
"delete[] data;\n";
329 OpName =
"op_" + OpName;
332 throw std::runtime_error(
"TMVA SOFIE Conv Op called to Generate without being initialized first");
335 std::stringstream out;
350 out <<
"\n//---- operator ConvTranspose " << OpName <<
"\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;
367 size_t hstride = kWidth;
372 size_t dstride = kHeight * kWidth;
378 size_t icstride = kHeight * kWidth * kDepth;
379 size_t icstrideDil = 1;
380 for (
size_t i = 0; i <
fDim; i++)
382 size_t ocstride =
fShapeW[1] * icstride;
383 size_t ocstrideDil =
fShapeW[1] * icstrideDil;
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;
397 out <<
" + kd * " << dstrideDil;
399 out <<
" + kh * " << hstrideDil;
400 out <<
" + kw * " << wstrideDil <<
" ] = tensor_" <<
fNW <<
"[ic * " << ocstride <<
" + oc * " << icstride;
403 out <<
" + kd * " << dstride;
405 out <<
" + kh * " << hstride;
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";
423 out <<
SP <<
"int " << OpName <<
"_m = " << iHeight * iWidth * iDepth <<
";\n";
424 out <<
SP <<
"int " << OpName <<
"_n = " << icstrideDil *
fShapeW[1] <<
";\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";
430 out <<
SP <<
fType <<
" tensor_" <<
fNX <<
"_xcol[" <<
fShapeW[0] * icstrideDil * oDepth * oHeight * oWidth
435 out <<
SP <<
"for (size_t n = 0; n < " << bsize <<
"; n++) {\n";
446 std::cout <<
"TMVA SOFIE Operator Conv: asymmetric padding not supported. Assume an average padding "
454 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
462 std::cout <<
"TMVA SOFIE Operator ConvTranspose: asymmetric padding not supported. Assume an average padding "
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, &"
477 << OpName <<
"_n, &" << OpName <<
"_k, &" << OpName <<
"_alpha, "
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
491 <<
fShapeY[1] <<
"," << oHeight <<
"," << oWidth <<
",";
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
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, &"
532 << OpName <<
"_n, &" << OpName <<
"_k, &" << OpName <<
"_alpha, "
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
543 <<
fShapeY[1] <<
"," << oHeight <<
"," << oWidth <<
",";
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
580 out <<
SP <<
SP <<
"}\n";
586 out <<
SP <<
"int " << OpName <<
"_size = " <<
fShapeY[0] *
fShapeY[1] * oDepth * oHeight * oWidth <<
";\n";
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
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
const std::string SP
space used to correctly indent the generated C++ code
bool fUseSession
flag to identify if using the session class
std::vector< std::string_view > fOutputTensorNames
T * BroadcastConvBias(const T *data, const size_t channel, const std::vector< size_t > &targetShape)
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
ETensorType ConvertStringToType(std::string type)
std::string ConvertShapeToString(const std::vector< size_t > &shape)