3#include "onnx_proto3.pb.h"
10#include <unordered_map>
15namespace Experimental {
125 throw std::runtime_error(
"TMVA::SOFIE - Failed to read float initialized tensor - actual size is " + std::to_string(
tensor->float_data_size()));
126 tensor->mutable_float_data()->ExtractSubrange(0,
tensor->float_data_size(),
127 static_cast<float *
>(
data));
134 throw std::runtime_error(
"TMVA::SOFIE - Failed to read double initialized tensor - actual size is " + std::to_string(
tensor->double_data_size()));
135 tensor->mutable_double_data()->ExtractSubrange(0,
tensor->double_data_size(),
136 static_cast<double *
>(
data));
143 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int32 initialized tensor - actual size is " + std::to_string(
tensor->int32_data_size()));
144 tensor->mutable_int32_data()->ExtractSubrange(0,
tensor->int32_data_size(),
145 static_cast<int32_t *
>(
data));
152 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int64 initialized tensor - actual size is " + std::to_string(
tensor->int64_data_size()));
153 tensor->mutable_int64_data()->ExtractSubrange(0,
tensor->int64_data_size(),
154 static_cast<int64_t *
>(
data));
161 std::shared_ptr<void>
data(
malloc(tensor_size), free);
164 if (
tensorproto->data_location() != onnx::TensorProto::EXTERNAL) {
167 throw std::runtime_error(
"TMVA::SOFIE - Failed to read raw data of initialized tensor - actual raw size is " +
175 for (std::size_t k = 0; k < tensor_size; ++k)
200 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in BOOL not supported");
204 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in UINT8 not supported");
215 std::cout <<
"Initialized data are stored externally in file " <<
fDataFileName;
218 std::string location;
222 if (
kv.key() ==
"location") location =
kv.value();
223 else if (
kv.key() ==
"offset")
offset = std::stoull(
kv.value());
227 std::cout <<
" at location " << location <<
" offset " <<
offset <<
" and with length " <<
buffer_size << std::endl;
230 throw std::runtime_error(
"TMVA::SOFIE ONNX : invalid stored data size vs tensor size");
236 throw std::runtime_error(
"TMVA::SOFIE ONNX: error reading external weight ONNX data file " +
fDataFileName);
361 std::vector<std::string>
ops;
364 ops.emplace_back(it.first);
387std::unique_ptr<ROperator>
390 if (i >= nodes.size())
391 throw std::runtime_error(
"TMVA::SOFIE - Error in parsing ordered operators " + std::to_string(i) +
" is >= " + std::to_string(nodes.size()));
396 std::cout <<
"Parsing operator " <<
op_type << std::endl;
402 std::cout <<
"\tFusing operators " <<
graphproto.node(
idx1).name()
419 if (children.size() == 1) {
420 int idx2 = children.front();
438 }
else if (
nodeproto.op_type() ==
"Gemm") {
444 }
else if (
nodeproto.op_type() ==
"BatchNormalization") {
454 std::cout <<
"operator " <<
op_type <<
" is not supported" << std::endl;
455 throw std::runtime_error(
"TMVA::SOFIE Operator type " +
op_type +
" is not yet supported");
458 std::cout <<
"\tCreating operator " <<
op_type << std::endl;
472 throw std::runtime_error(
"TMVA::SOFIE - Failed to load onnx file " +
filename);
474 const onnx::GraphProto &graph = model->graph();
477 std::time_t
ttime = std::time(0);
488 if (
isep != std::string::npos) {
507 throw std::runtime_error(
"TMVA::SOFIE - Failed to parse ONNX model from input stream");
509 const onnx::GraphProto &graph = model->graph();
511 std::time_t
ttime = std::time(0);
521 std::fstream
input(
filename, std::ios::in | std::ios::binary);
523 std::cerr <<
"TMVA::SOFIE - Failed to open onnx file " <<
filename << std::endl;
532 auto model = std::make_unique<onnx::ModelProto>();
534 if (!model->ParseFromIstream(&
input)) {
535 std::cerr <<
"TMVA::SOFIE - Failed to parse ONNX model from input stream" << std::endl;
541 std::cout <<
"ONNX Version " << model->ir_version() << std::endl;
543 google::protobuf::ShutdownProtobufLibrary();
550 std::cout <<
"\n" << graph.name() <<
" Graph operator list\n";
551 for (
int i = 0; i < graph.node_size(); i++) {
552 const auto & node = graph.node(i);
553 const std::string
opType = node.op_type();
555 std::cout <<
"\tOperator " << i <<
" : " <<
opType <<
" (" << node.name() <<
"), " << graph.node(i).input_size()
558 std::cout << graph.node(i).input(
j);
559 if (
j < graph.node(i).input_size() - 1)
562 std::cout <<
" }" << std::endl;
568 for (
int j = 0;
j < node.attribute_size();
j++) {
583 if (!model)
return false;
585 const onnx::GraphProto &graph = model->graph();
588 std::cout <<
"\nModel operator list " << model->producer_name() <<
"\n";
595 std::cout <<
"List of missing operators for model loaded from file " <<
filename << std::endl;
597 std::cout <<
op.first <<
" " <<
op.second << std::endl;
601 std::cout <<
"All operators in the loaded model are supported!\n";
613 std::cout <<
"\nParsing Graph - " <<
graphName << std::endl;
616 for (
int i = 0; i < graph.initializer_size(); i++) {
621 std::cout <<
"Parsing model inputs...." << std::endl;
623 for (
int i = 0; i < graph.input_size(); i++) {
625 static_cast<ETensorType>(graph.input(i).type().tensor_type().elem_type()));
628 std::cout <<
"\tgraph input " << i <<
" name " << graph.input(i).name() <<
" type "
629 << graph.input(i).type().tensor_type().elem_type() << std::endl;
643 throw std::runtime_error(
"TMVA::SOFIE data node with no shape restrictions is not supported yet");
644 for (
int j = 0;
j <
valueinfoproto.type().tensor_type().shape().dim_size();
j++) {
647 onnx::TensorShapeProto_Dimension::ValueCase::kDimValue) {
656 }
else if (
valueinfoproto.type().tensor_type().shape().dim(
j).value_case() ==
657 onnx::TensorShapeProto_Dimension::ValueCase::kDimParam) {
662 throw std::runtime_error(
"TMVA::SOFIE ONNX file error: Valueinfoproto " +
input_name +
663 " has neither dim_value nor dim_param! \n");
667 if (
valueinfoproto.type().tensor_type().shape().dim_size() == 0) {
689 std::cout <<
"\nParsing graph initializer list and fill model initialized tensors" << std::endl;
691 for (
int i = 0; i < graph.initializer_size(); i++) {
692 onnx::TensorProto *
tensorproto =
const_cast<onnx::TensorProto *
>(&graph.initializer(i));
693 std::vector<std::size_t> shape;
701 std::string tensor_name = graph.initializer(i).name();
704 std::cout <<
"\t initializer " << i <<
" name " << tensor_name <<
" type " << graph.initializer(i).data_type()
717 std::cout <<
"add initialized tensor " << tensor_name <<
"with shape " <<
ConvertShapeToString(shape) <<
"and ";
719 std::cout <<
" float data: ";
723 std::cout <<
" int64 data: ";
727 std::cout <<
" uint8 data: ";
731 std::cout <<
" Boolean data: ";
734 std::cout << std::endl;
740 std::cout <<
"\nGraph operator list (ONNX order)\n";
741 for (
int i = 0; i < graph.node_size(); i++) {
742 std::cout <<
"\tOperator " << i <<
" : " << graph.node(i).op_type() <<
" , " << graph.node(i).input_size()
745 std::cout << graph.node(i).input(
j);
746 if (
j < graph.node(i).input_size() - 1)
749 std::cout <<
" }" << std::endl;
755 std::cout <<
"\n***********************\nRe-Order graph operator list\n*************************\n";
758 std::vector<bool>
foundNodes(graph.node_size());
762 for (
int i = 0; i < graph.input_size(); i++) {
767 for (
int i = 0; i < graph.node_size(); i++) {
775 std::cout <<
"Checking input of Node " << i <<
" : " << graph.node(i).name() << std::endl;
777 std::string
name = graph.node(i).input(
j);
783 std::cout <<
"\t\t input " <<
name <<
" "
792 std::cout <<
"skip node " << graph.node(i).op_type() <<
" " << graph.node(i).name() <<
" inputs are not existing ";
794 std::cout << graph.node(i).input(
j) <<
" ";
796 std::cout << std::endl;
803 std::cout <<
"===> New node " << graph.node(i).op_type() <<
" " << graph.node(i).name() <<
" order " << i << std::endl;
809 if (
fVerbose) std::cout <<
"\toutput : " << graph.node(i).output(
j) << std::endl;
816 std::cout <<
"cannot find a new node after " << graph.node(
ilast).op_type() <<
" " << graph.node(
ilast).name() << std::endl;
817 throw std::runtime_error(
"TMVA::SOFIE - cannot find a new node ");
819 }
while ((
int)
nodesOrder.size() < graph.node_size());
823 std::vector<std::vector<int>>
nodesChildren(graph.node_size());
825 for (
int k = 0; k < graph.node_size(); k++) {
828 if (graph.node(i).output_size() > 0)
nodesChildren[i].reserve(graph.node(i).output_size());
829 for (
const auto&
output_name : graph.node(i).output()) {
831 for (
int l = k;
l < graph.node_size();
l++) {
833 for (
const auto&
input_name : graph.node(
j).input()) {
843 std::cout <<
"\nGraph operator list (re-ordered)\n";
844 for (
int k = 0; k < graph.node_size(); k++) {
846 std::cout <<
"\tOperator " << i <<
" : " << graph.node(i).op_type() <<
" , " << graph.node(i).name() <<
" input tensors : {";
847 for (
int j = 0;
j < graph.node(i).input_size();
j++) {
848 std::cout << graph.node(i).input(
j);
849 if (
j < graph.node(i).input_size() - 1)
853 std::cout <<
" children : {";
855 std::cout <<
" [ " <<
ichild <<
" " << graph.node(
ichild).op_type() <<
" , " << graph.node(
ichild).name() <<
"]";
857 std::cout <<
"}" << std::endl;
863 std::cout <<
"Fill RModel with operators...\n";
869 for (
int i = 0; i < graph.node_size(); i++) {
873 std::cout <<
"\t" << i <<
" " <<
nodesOrder[i] <<
" parsing operator " <<
op_type << std::endl;
879 std::cout <<
"\t\tskipping operator since it is fused with previous one" << std::endl;
889 std::cout <<
"\nParsing Graph output list\n";
890 for (
int i = 0; i < graph.output_size(); i++) {
892 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 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 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
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)
ETensorType GetTensorType(const std::string &name)
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)
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 ParseLSTM
ParserFuncSignature ParseCast
ParserFuncSignature ParseReciprocal
ParserFuncSignature ParseSigmoid
ParserFuseFuncSignature ParseFuseConvAdd
ParserFuncSignature ParseAtan
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 ParseLessEq
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 ParseScatterElements
ParserFuncSignature ParseGemm
ParserFuncSignature ParseTile
ParserFuncSignature ParseMul
ParserFuseFuncSignature ParseFuseGemmRelu
ParserFuncSignature ParsePow
ParserFuncSignature ParseAbs
ParserFuncSignature ParseSin
ParserFuncSignature ParseReduceSumSquare
ParserFuncSignature ParseTanh
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