16#include <unordered_map>
21namespace Experimental {
140 throw std::runtime_error(
"TMVA::SOFIE - Failed to read float initialized tensor - actual size is " + std::to_string(
tensor->float_data_size()));
142 std::copy(
src.begin(),
src.end(),
static_cast<float *
>(
data));
149 throw std::runtime_error(
"TMVA::SOFIE - Failed to read double initialized tensor - actual size is " + std::to_string(
tensor->double_data_size()));
151 std::copy(
src.begin(),
src.end(),
static_cast<double *
>(
data));
158 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int32 initialized tensor - actual size is " + std::to_string(
tensor->int32_data_size()));
160 std::copy(
src.begin(),
src.end(),
static_cast<int32_t *
>(
data));
167 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int64 initialized tensor - actual size is " + std::to_string(
tensor->int64_data_size()));
169 std::copy(
src.begin(),
src.end(),
static_cast<int64_t *
>(
data));
179template <std::
size_t N>
183 auto dst =
static_cast<unsigned char *
>(
dest);
184 auto src =
static_cast<const unsigned char *
>(
source);
185 for (std::size_t k = 0; k <
nbytes; k +=
N) {
187 std::memcpy(&
v,
src + k,
N);
189 std::memcpy(
dst + k, &
v,
N);
205 throw std::runtime_error(
"Data type " +
ConvertTypeToString(tensor_type) +
" in tensor is not supported!\n");
215 std::shared_ptr<void>
data(
malloc(tensor_size), free);
221 throw std::runtime_error(
"TMVA::SOFIE - Failed to read raw data of initialized tensor - actual raw size is " +
233 switch (tensor_type) {
251 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in BOOL not supported");
255 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in UINT8 not supported");
259 throw std::runtime_error(
"Data type " +
ConvertTypeToString(tensor_type) +
" in weight tensor is not supported!\n");
267 std::string location;
271 if (
kv.key() ==
"location") location =
kv.value();
272 else if (
kv.key() ==
"offset")
offset = std::stoull(
kv.value());
284 throw std::runtime_error(
"TMVA::SOFIE ONNX : tensor " +
tensorproto->name() +
285 " has external data but no data file location is available");
288 std::cout <<
"Initialized data are stored externally in file " <<
dataFileName
289 <<
" at location " << location <<
" offset " <<
offset <<
" and with length " <<
buffer_size << std::endl;
292 throw std::runtime_error(
"TMVA::SOFIE ONNX : invalid stored data size vs tensor size");
300 throw std::runtime_error(
"TMVA::SOFIE ONNX: error reading external weight ONNX data file " +
dataFileName);
439 std::vector<std::string>
ops;
442 ops.emplace_back(it.first);
486std::unique_ptr<ROperator>
489 if (i >= nodes.size())
490 throw std::runtime_error(
"TMVA::SOFIE - Error in parsing ordered operators " + std::to_string(i) +
" is >= " + std::to_string(nodes.size()));
493 const std::string op_type =
nodeproto.op_type();
495 std::cout <<
"Parsing operator " << op_type << std::endl;
501 std::cout <<
"\tFusing operators " <<
graphproto.node(
idx1).name()
518 if (children.size() == 1) {
519 int idx2 = children.front();
520 if (op_type ==
"MatMul") {
538 }
else if (
nodeproto.op_type() ==
"Gemm") {
544 }
else if (
nodeproto.op_type() ==
"BatchNormalization") {
554 std::cout <<
"operator " << op_type <<
" is not supported" << std::endl;
555 throw std::runtime_error(
"TMVA::SOFIE Operator type " + op_type +
" is not yet supported");
558 std::cout <<
"\tCreating operator " << op_type << std::endl;
572 throw std::runtime_error(
"TMVA::SOFIE - Failed to load onnx file " +
filename);
577 std::time_t
ttime = std::time(0);
588 if (
isep != std::string::npos) {
609 throw std::runtime_error(
"TMVA::SOFIE - Failed to parse ONNX model from input stream");
613 std::time_t
ttime = std::time(0);
637 std::fstream
input(
filename, std::ios::in | std::ios::binary);
639 std::cerr <<
"TMVA::SOFIE - Failed to open onnx file " <<
filename << std::endl;
648 auto model = std::make_unique<onnx::ModelProto>();
650 if (!model->ParseFromIstream(&
input)) {
651 std::cerr <<
"TMVA::SOFIE - Failed to parse ONNX model from input stream" << std::endl;
657 std::cout <<
"ONNX Version " << model->ir_version() << std::endl;
664 std::cout <<
"\n" << graph.
name() <<
" Graph operator list\n";
665 for (
int i = 0; i < graph.
node_size(); i++) {
666 const auto & node = graph.
node(i);
667 const std::string
opType = node.op_type();
669 std::cout <<
"\tOperator " << i <<
" : " <<
opType <<
" (" << node.name() <<
"), " << graph.
node(i).input_size()
671 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
672 std::cout << graph.
node(i).input(
j);
673 if (
j < graph.
node(i).input_size() - 1)
676 std::cout <<
" }" << std::endl;
682 for (
int j = 0;
j < node.attribute_size();
j++) {
683 const auto & attribute = node.attribute(
j);
684 if (attribute.has_g()) {
685 const auto &
subGraph = attribute.g();
697 if (!model)
return false;
702 std::cout <<
"\nModel operator list " << model->producer_name() <<
"\n";
709 std::cout <<
"List of missing operators for model loaded from file " <<
filename << std::endl;
711 std::cout <<
op.first <<
" " <<
op.second << std::endl;
715 std::cout <<
"All operators in the loaded model are supported!\n";
727 std::cout <<
"\nParsing Graph - " <<
graphName << std::endl;
733 std::map<int, std::pair<EFusedOp, int>> &fMap;
734 std::map<int, std::pair<EFusedOp, int>> fSaved;
735 FusedOperatorsGuard(std::map<
int, std::pair<EFusedOp, int>> &map) : fMap(map) { fSaved.swap(fMap); }
745 std::cout <<
"Parsing model inputs...." << std::endl;
747 for (
int i = 0; i < graph.
input_size(); i++) {
752 std::cout <<
"\tgraph input " << i <<
" name " << graph.
input(i).name() <<
" type "
753 << graph.
input(i).type().tensor_type().elem_type() << std::endl;
767 throw std::runtime_error(
"TMVA::SOFIE data node with no shape restrictions is not supported yet");
768 for (
int j = 0;
j <
valueinfoproto.type().tensor_type().shape().dim_size();
j++) {
772 int dim_value =
valueinfoproto.type().tensor_type().shape().dim(
j).dim_value();
780 }
else if (
valueinfoproto.type().tensor_type().shape().dim(
j).value_case() ==
786 throw std::runtime_error(
"TMVA::SOFIE ONNX file error: Valueinfoproto " +
input_name +
787 " has neither dim_value nor dim_param! \n");
791 if (
valueinfoproto.type().tensor_type().shape().dim_size() == 0) {
813 std::cout <<
"\nParsing graph initializer list and fill model initialized tensors" << std::endl;
817 std::vector<std::size_t> shape;
825 std::string tensor_name = graph.
initializer(i).name();
828 std::cout <<
"\t initializer " << i <<
" name " << tensor_name <<
" type " << graph.
initializer(i).data_type()
837 rmodel.AddInitializedTensor(tensor_name, tensor_type, shape,
data);
841 std::cout <<
"add initialized tensor " << tensor_name <<
"with shape " <<
ConvertShapeToString(shape) <<
"and ";
843 std::cout <<
" float data: ";
847 std::cout <<
" int64 data: ";
851 std::cout <<
" uint8 data: ";
855 std::cout <<
" Boolean data: ";
858 std::cout << std::endl;
864 std::cout <<
"\nGraph operator list (ONNX order)\n";
865 for (
int i = 0; i < graph.
node_size(); i++) {
866 std::cout <<
"\tOperator " << i <<
" : " << graph.
node(i).op_type() <<
" , " << graph.
node(i).input_size()
868 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
869 std::cout << graph.
node(i).input(
j);
870 if (
j < graph.
node(i).input_size() - 1)
873 std::cout <<
" }" << std::endl;
879 std::cout <<
"\n***********************\nRe-Order graph operator list\n*************************\n";
886 for (
int i = 0; i < graph.
input_size(); i++) {
891 for (
int i = 0; i < graph.
node_size(); i++) {
896 int input_size = graph.
node(i).input_size();
899 std::cout <<
"Checking input of Node " << i <<
" : " << graph.
node(i).name() << std::endl;
900 for (
int j = 0;
j < input_size;
j++) {
901 std::string
name = graph.
node(i).input(
j);
907 std::cout <<
"\t\t input " <<
name <<
" "
916 std::cout <<
"skip node " << graph.
node(i).op_type() <<
" " << graph.
node(i).name() <<
" inputs are not existing ";
917 for (
int j = 0;
j < input_size;
j++) {
918 std::cout << graph.
node(i).input(
j) <<
" ";
920 std::cout << std::endl;
927 std::cout <<
"===> New node " << graph.
node(i).op_type() <<
" " << graph.
node(i).name() <<
" order " << i << std::endl;
932 for (
int j = 0;
j < graph.
node(i).output_size();
j++) {
933 if (
fVerbose) std::cout <<
"\toutput : " << graph.
node(i).output(
j) << std::endl;
940 std::cout <<
"cannot find a new node after " << graph.
node(
ilast).op_type() <<
" " << graph.
node(
ilast).name() << std::endl;
941 throw std::runtime_error(
"TMVA::SOFIE - cannot find a new node ");
949 for (
int k = 0; k < graph.
node_size(); k++) {
967 std::cout <<
"\nGraph operator list (re-ordered)\n";
968 for (
int k = 0; k < graph.
node_size(); k++) {
970 std::cout <<
"\tOperator " << i <<
" : " << graph.
node(i).op_type() <<
" , " << graph.
node(i).name() <<
" input tensors : {";
971 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
972 std::cout << graph.
node(i).input(
j);
973 if (
j < graph.
node(i).input_size() - 1)
977 std::cout <<
" children : {";
981 std::cout <<
"}" << std::endl;
987 std::cout <<
"Fill RModel with operators...\n";
993 for (
int i = 0; i < graph.
node_size(); i++) {
997 std::cout <<
"\t" << i <<
" " <<
nodesOrder[i] <<
" parsing operator " << op_type << std::endl;
1003 std::cout <<
"\t\tskipping operator since it is fused with previous one" << std::endl;
1013 std::cout <<
"\nParsing Graph output list\n";
1016 std::cout <<
"\toutput " << i <<
" name " << graph.
output(i).name() << std::endl;
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 data
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 dest
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
const_iterator begin() const
const_iterator end() const
std::string fDefaultDataFileName
std::string fOpenedDataFileName
void RegisterOperator(const std::string &name, ParserFuncSignature func)
std::unique_ptr< ROperator > ParseOperator(const size_t, const onnx::GraphProto &, const std::vector< size_t > &, const std::vector< int > &)
std::string fDataFileName
bool IsRegisteredOperator(const std::string &name)
void CheckGraph(const onnx::GraphProto &g, int &level, std::map< std::string, int > &missingOperators)
void ParseONNXGraph(RModel &model, const onnx::GraphProto &g, std::string name="")
RModelParser_ONNX() noexcept
std::unordered_map< std::string, ETensorType > fTensorTypeMap
RModel Parse(std::string const &filename, bool verbose=false)
std::shared_ptr< void > GetInitializedTensorData(onnx::TensorProto *tensorproto, size_t tensor_length, ETensorType type)
std::map< int, std::pair< EFusedOp, int > > fFusedOperators
bool IsRegisteredTensorType(const std::string &)
void RegisterTensorType(const std::string &, ETensorType)
void ResetExternalDataState()
ETensorType GetTensorType(const std::string &name)
std::string fModelDirectory
std::vector< std::string > GetRegisteredOperators()
std::unique_ptr< onnx::ModelProto > LoadModel(const std::string &filename)
std::unique_ptr< OperatorsMapImpl > fOperatorsMapImpl
bool CheckModel(std::string filename, bool verbose=false)
const ValueInfoProto & input(int i) const
const ValueInfoProto & output(int i) const
int initializer_size() const
const std::string & name() const
const NodeProto & node(int i) const
const TensorProto & initializer(int i) const
std::string Clean_name(std::string input_tensor_name)
ParserFuncSignature ParseIsNaN
ParserFuncSignature ParseSqrt
ParserFuncSignature ParseBatchNormalization
ParserFuncSignature ParseGreater
std::function< std::unique_ptr< ROperator >(RModelParser_ONNX &, const onnx::NodeProto &, const onnx::NodeProto &)> ParserFuseFuncSignature
ParserFuncSignature ParseReshape
ParserFuseFuncSignature ParseFuseConvTransposeAdd
ParserFuncSignature ParseReduceMean
ParserFuseFuncSignature ParseFuseMatMulAdd
ParserFuncSignature ParseGather
ParserFuncSignature ParseNeg
ParserFuncSignature ParseWhere
ParserFuncSignature ParseCos
ParserFuncSignature ParseLog
ParserFuncSignature ParseLeakyRelu
ParserFuncSignature ParseExp
std::function< std::unique_ptr< ROperator >(RModelParser_ONNX &, const onnx::NodeProto &)> ParserFuncSignature
ParserFuncSignature ParseEinsum
ParserFuncSignature ParsePool
ParserFuncSignature ParseDiv
ParserFuncSignature ParseLayerNormalization
ParserFuncSignature ParseConcat
ParserFuncSignature ParseTopK
ParserFuncSignature ParseMax
ParserFuncSignature ParseEq
ParserFuncSignature ParseIdentity
ParserFuncSignature ParseConvTranspose
ParserFuncSignature ParseReduceProd
ParserFuncSignature ParseNot
ParserFuncSignature ParseSlice
ParserFuncSignature ParseRandom
ParserFuncSignature ParseTranspose
ParserFuncSignature ParseLess
ParserFuncSignature ParseShape
ParserFuncSignature ParseClip
constexpr size_t GetTypeSize(ETensorType type)
ParserFuncSignature ParseScatterND
ParserFuncSignature ParseGRU
ParserFuncSignature ParseMatMul
ParserFuncSignature ParseErf
ParserFuncSignature ParseSub
ParserFuncSignature ParseAdd
ParserFuncSignature ParseNonZero
ParserFuncSignature ParseIf
ParserFuncSignature ParseRange
ParserFuncSignature ParseSoftplus
ParserFuncSignature ParseExpand
ParserFuncSignature ParseRNN
ParserFuncSignature ParseHardSigmoid
ParserFuncSignature ParseLSTM
ParserFuncSignature ParseCast
ParserFuncSignature ParseReciprocal
ParserFuncSignature ParseSwish
ParserFuncSignature ParseSigmoid
ParserFuseFuncSignature ParseFuseConvAdd
ParserFuncSignature ParseAtan
ParserFuncSignature ParseReduceMax
ParserFuncSignature ParseFloor
ParserFuseFuncSignature ParseFuseBatchnormRelu
ParserFuncSignature ParseIsInf
ParserFuncSignature ParseSoftmax
ParserFuncSignature ParseGreaterEq
ParserFuncSignature ParseMod
std::string ConvertTypeToString(ETensorType type)
ParserFuncSignature ParseGelu
ParserFuncSignature ParseMean
ParserFuncSignature ParseSplit
ParserFuncSignature ParseConstant
ParserFuncSignature ParseSelu
ParserFuncSignature ParseAsinh
ParserFuncSignature ParseLessEq
ParserFuncSignature ParseAcosh
ParserFuncSignature ParseHardSwish
ParserFuncSignature ParseGatherND
ParserFuncSignature ParseSum
ParserFuncSignature ParseEyeLike
ParserFuncSignature ParsePad
ParserFuncSignature ParseElu
std::string ConvertShapeToString(const std::vector< size_t > &shape)
ParserFuncSignature ParseMin
ParserFuncSignature ParseRelu
ParserFuncSignature ParseReduceSum
ParserFuncSignature ParseConv
ParserFuncSignature ParseInstanceNormalization
ParserFuncSignature ParseScatterElements
ParserFuncSignature ParseGemm
ParserFuncSignature ParseTile
ParserFuncSignature ParseMul
ParserFuseFuncSignature ParseFuseGemmRelu
ParserFuncSignature ParsePow
ParserFuncSignature ParseAbs
ParserFuncSignature ParseSin
ParserFuncSignature ParseAtanh
ParserFuncSignature ParseReduceSumSquare
ParserFuncSignature ParseTanh
ParserFuncSignature ParseReduceMin
create variable transformations
Helper templated class for swapping bytes; specializations for N={2,4,8} are provided below.
std::unordered_map< std::string, ParserFuncSignature > fOperatorsMap