1#ifndef TMVA_SOFIE_ROPERATOR_GEMM
2#define TMVA_SOFIE_ROPERATOR_GEMM
17namespace Experimental{
55 static_assert(std::is_same_v<T, float>,
56 "TMVA::SOFIE - Unsupported type parsing a Gemm operator");
79 if (
input.size() > 3)
throw std::runtime_error(
"TMVA SOFIE Gemm Op Shape Inference only need 2 or 3 input tensor");
84 throw std::runtime_error(
"TMVA SOFIE Gemm Op Shape Inference only accept input tensor with >=2 dimensions");
89 if (
input.size() == 3){
111 for (
size_t i = 0; i <
input[0].size()-2; i++) {
115 if (
valueB.GetVal() ==
"1")
117 else if (
valueA.GetVal() ==
"1")
120 throw std::runtime_error(
"TMVA SOFIE Gemm Op - invalid input shapes " +
valueA.GetVal() +
" and "
135 throw std::runtime_error(
"TMVA SOFIE Gemm Op - invalid input shapes " +
valueA.GetVal() +
" and "
149 std::vector<std::vector<size_t>>
ret;
164 throw std::runtime_error(
"TMVA SOFIE Gemm Op Input Tensor " +
fNA +
" or " +
fNB +
" is not found in model");
168 throw std::runtime_error(
"TMVA SOFIE Gemm Op Input Tensor" +
fNC +
" is not found in model");
217 throw std::runtime_error(
"TMVA SOFIE Gemm Op Input Tensor" +
fNC +
" is dynamic and is not supported");
265 std::cout <<
"Gemm (or MatMul) " <<
" ---> " <<
fNY <<
" shape ";
279 throw std::runtime_error(
"TMVA SOFIE Gemm Op called to Generate without being initialized first");
281 std::stringstream out;
289 throw std::runtime_error(
"TMVA SOFIE Gemm(MatMul) has invalid shape for inputs or output");
299 for (int64_t i = 0; i <
dimY-2; i++) {
312 throw std::runtime_error(
"TMVA SOFIE Gemm Op " +
opName +
" Bias tensor has not correct size "
323 throw std::runtime_error(
"TMVA SOFIE Gemm Op " +
opName +
" Bias tensor is not present but beta value in Gemm is not zero");
350 out <<
SP <<
"size_t " <<
opName <<
"_y_offset = 0;\n";
352 out <<
SP <<
"size_t " <<
opName <<
"_A_offset = 0;\n";
354 out <<
SP <<
"size_t " <<
opName <<
"_B_offset = 0;\n";
355 out <<
SP <<
"for (size_t i = 0; i < " <<
lengthExtra_Y <<
"; i++){\n";
360 out <<
SP <<
"for (size_t j = 0; j < " <<
sY[0] <<
"; j++) { \n";
361 out <<
SP <<
SP <<
"size_t y_index = ";
363 out <<
opName <<
"_y_offset + ";
364 if (
sY[1].GetVal() !=
"1")
365 out <<
sY[1] <<
" * j;\n";
369 out <<
SP <<
SP <<
"for (size_t k = 0; k < " <<
sY[1] <<
"; k++) { \n";
381 out <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[y_index + k] = " <<
"tensor_" <<
fNC <<
"[" <<
bias_index <<
"];\n";
382 out <<
SP <<
SP <<
"}\n";
386 if (
fType ==
"float"){
388 out <<
SP <<
"TMVA::Experimental::SOFIE::Gemm_Call("
394 <<
n <<
", " <<
m <<
", " << k <<
", ";
395 out << std::setprecision(std::numeric_limits<float>::max_digits10) <<
fAttrAlpha <<
", tensor_" <<
fNB;
397 out <<
", tensor_" <<
fNA;
399 out <<
", " << std::setprecision(std::numeric_limits<float>::max_digits10) <<
fAttrBeta <<
",";
402 out <<
"tensor_" <<
fNC;
409 out <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[id] = ((tensor_" <<
fNY <<
"[id] > 0 )? tensor_" <<
fNY <<
"[id] : 0);\n";
427 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Gemm"), std::string(
"Gemv") }; }
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 void char Point_t Rectangle_t WindowAttributes_t Float_t r
const_iterator begin() const
const_iterator end() const
void AddNeededStdLib(std::string libname)
std::vector< size_t > GetTensorShape(const std::string &name) const
bool IsDynamicTensor(const std::string &name) const
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
bool CheckIfTensorAlreadyExist(std::string tensor_name)
void AddDynamicTensor(std::string tensor_name, ETensorType type, std::vector< Dim > shape)
bool IsDimInputTensor(const std::string &name) const
std::vector< Dim > GetDynamicTensorShape(const std::string &name) const
ETensorType GetTensorType(std::string name) const
const std::vector< std::string > & GetDimShapeNames() const
ROperator_Gemm(float alpha, float beta, int_t transA, int_t transB, std::string nameA, std::string nameB, std::string nameC, std::string nameY, EActivationType activation=EActivationType::UNDEFINED)
std::vector< Dim > DynamicShapeInference(const std::vector< std::vector< Dim > > &input)
std::vector< Dim > fShapeY
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
ROperator_Gemm(float alpha, float beta, int_t transA, int_t transB, std::string nameA, std::string nameB, std::string nameY, EActivationType activation=EActivationType::UNDEFINED)
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
std::vector< U > DoShapeInference(const std::vector< std::vector< U > > &input)
std::vector< Dim > fShapeA
std::vector< Dim > fShapeB
std::vector< size_t > fShapeC
std::string Generate(std::string opName) override
void Initialize(RModel &model) override
EActivationType fActivation
std::vector< std::string > GetBlasRoutines() override
std::vector< std::string_view > fInputTensorNames
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
std::string ConvertDimShapeToString(const std::vector< Dim > &shape)
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
std::vector< Dim > ConvertShapeToDim(const std::vector< size_t > &shape)
Convert shape from integer format to dynamic one (based on Dim)
std::vector< size_t > ConvertShapeToInt(const std::vector< Dim > &shape)
Convert shape based on Dim to integer format.
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations