12#include <unordered_map>
17namespace Experimental {
131 throw std::runtime_error(
"TMVA::SOFIE - Failed to read float initialized tensor - actual size is " + std::to_string(
tensor->float_data_size()));
133 std::copy(
src.begin(),
src.end(),
static_cast<float *
>(
data));
140 throw std::runtime_error(
"TMVA::SOFIE - Failed to read double initialized tensor - actual size is " + std::to_string(
tensor->double_data_size()));
142 std::copy(
src.begin(),
src.end(),
static_cast<double *
>(
data));
149 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int32 initialized tensor - actual size is " + std::to_string(
tensor->int32_data_size()));
151 std::copy(
src.begin(),
src.end(),
static_cast<int32_t *
>(
data));
158 throw std::runtime_error(
"TMVA::SOFIE - Failed to read int64 initialized tensor - actual size is " + std::to_string(
tensor->int64_data_size()));
160 std::copy(
src.begin(),
src.end(),
static_cast<int64_t *
>(
data));
170template <std::
size_t N>
174 auto dst =
static_cast<unsigned char *
>(
dest);
175 auto src =
static_cast<const unsigned char *
>(
source);
176 for (std::size_t k = 0; k <
nbytes; k +=
N) {
178 std::memcpy(&
v,
src + k,
N);
180 std::memcpy(
dst + k, &
v,
N);
196 throw std::runtime_error(
"Data type " +
ConvertTypeToString(tensor_type) +
" in tensor is not supported!\n");
206 std::shared_ptr<void>
data(
malloc(tensor_size), free);
212 throw std::runtime_error(
"TMVA::SOFIE - Failed to read raw data of initialized tensor - actual raw size is " +
224 switch (tensor_type) {
242 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in BOOL not supported");
246 throw std::runtime_error(
"TMVA::SOFIE - ExtractData from TP in UINT8 not supported");
250 throw std::runtime_error(
"Data type " +
ConvertTypeToString(tensor_type) +
" in weight tensor is not supported!\n");
257 std::cout <<
"Initialized data are stored externally in file " <<
fDataFileName;
260 std::string location;
264 if (
kv.key() ==
"location") location =
kv.value();
265 else if (
kv.key() ==
"offset")
offset = std::stoull(
kv.value());
269 std::cout <<
" at location " << location <<
" offset " <<
offset <<
" and with length " <<
buffer_size << std::endl;
272 throw std::runtime_error(
"TMVA::SOFIE ONNX : invalid stored data size vs tensor size");
278 throw std::runtime_error(
"TMVA::SOFIE ONNX: error reading external weight ONNX data file " +
fDataFileName);
411 std::vector<std::string>
ops;
414 ops.emplace_back(it.first);
437std::unique_ptr<ROperator>
440 if (i >= nodes.size())
441 throw std::runtime_error(
"TMVA::SOFIE - Error in parsing ordered operators " + std::to_string(i) +
" is >= " + std::to_string(nodes.size()));
444 const std::string op_type =
nodeproto.op_type();
446 std::cout <<
"Parsing operator " << op_type << std::endl;
452 std::cout <<
"\tFusing operators " <<
graphproto.node(
idx1).name()
469 if (children.size() == 1) {
470 int idx2 = children.front();
471 if (op_type ==
"MatMul") {
488 }
else if (
nodeproto.op_type() ==
"Gemm") {
494 }
else if (
nodeproto.op_type() ==
"BatchNormalization") {
504 std::cout <<
"operator " << op_type <<
" is not supported" << std::endl;
505 throw std::runtime_error(
"TMVA::SOFIE Operator type " + op_type +
" is not yet supported");
508 std::cout <<
"\tCreating operator " << op_type << std::endl;
522 throw std::runtime_error(
"TMVA::SOFIE - Failed to load onnx file " +
filename);
527 std::time_t
ttime = std::time(0);
538 if (
isep != std::string::npos) {
557 throw std::runtime_error(
"TMVA::SOFIE - Failed to parse ONNX model from input stream");
561 std::time_t
ttime = std::time(0);
571 std::fstream
input(
filename, std::ios::in | std::ios::binary);
573 std::cerr <<
"TMVA::SOFIE - Failed to open onnx file " <<
filename << std::endl;
582 auto model = std::make_unique<onnx::ModelProto>();
584 if (!model->ParseFromIstream(&
input)) {
585 std::cerr <<
"TMVA::SOFIE - Failed to parse ONNX model from input stream" << std::endl;
591 std::cout <<
"ONNX Version " << model->ir_version() << std::endl;
598 std::cout <<
"\n" << graph.
name() <<
" Graph operator list\n";
599 for (
int i = 0; i < graph.
node_size(); i++) {
600 const auto & node = graph.
node(i);
601 const std::string
opType = node.op_type();
603 std::cout <<
"\tOperator " << i <<
" : " <<
opType <<
" (" << node.name() <<
"), " << graph.
node(i).input_size()
605 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
606 std::cout << graph.
node(i).input(
j);
607 if (
j < graph.
node(i).input_size() - 1)
610 std::cout <<
" }" << std::endl;
616 for (
int j = 0;
j < node.attribute_size();
j++) {
617 const auto & attribute = node.attribute(
j);
618 if (attribute.has_g()) {
619 const auto &
subGraph = attribute.g();
631 if (!model)
return false;
636 std::cout <<
"\nModel operator list " << model->producer_name() <<
"\n";
643 std::cout <<
"List of missing operators for model loaded from file " <<
filename << std::endl;
645 std::cout <<
op.first <<
" " <<
op.second << std::endl;
649 std::cout <<
"All operators in the loaded model are supported!\n";
661 std::cout <<
"\nParsing Graph - " <<
graphName << std::endl;
669 std::cout <<
"Parsing model inputs...." << std::endl;
671 for (
int i = 0; i < graph.
input_size(); i++) {
676 std::cout <<
"\tgraph input " << i <<
" name " << graph.
input(i).name() <<
" type "
677 << graph.
input(i).type().tensor_type().elem_type() << std::endl;
691 throw std::runtime_error(
"TMVA::SOFIE data node with no shape restrictions is not supported yet");
692 for (
int j = 0;
j <
valueinfoproto.type().tensor_type().shape().dim_size();
j++) {
696 int dim_value =
valueinfoproto.type().tensor_type().shape().dim(
j).dim_value();
704 }
else if (
valueinfoproto.type().tensor_type().shape().dim(
j).value_case() ==
710 throw std::runtime_error(
"TMVA::SOFIE ONNX file error: Valueinfoproto " +
input_name +
711 " has neither dim_value nor dim_param! \n");
715 if (
valueinfoproto.type().tensor_type().shape().dim_size() == 0) {
737 std::cout <<
"\nParsing graph initializer list and fill model initialized tensors" << std::endl;
741 std::vector<std::size_t> shape;
749 std::string tensor_name = graph.
initializer(i).name();
752 std::cout <<
"\t initializer " << i <<
" name " << tensor_name <<
" type " << graph.
initializer(i).data_type()
761 rmodel.AddInitializedTensor(tensor_name, tensor_type, shape,
data);
765 std::cout <<
"add initialized tensor " << tensor_name <<
"with shape " <<
ConvertShapeToString(shape) <<
"and ";
767 std::cout <<
" float data: ";
771 std::cout <<
" int64 data: ";
775 std::cout <<
" uint8 data: ";
779 std::cout <<
" Boolean data: ";
782 std::cout << std::endl;
788 std::cout <<
"\nGraph operator list (ONNX order)\n";
789 for (
int i = 0; i < graph.
node_size(); i++) {
790 std::cout <<
"\tOperator " << i <<
" : " << graph.
node(i).op_type() <<
" , " << graph.
node(i).input_size()
792 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
793 std::cout << graph.
node(i).input(
j);
794 if (
j < graph.
node(i).input_size() - 1)
797 std::cout <<
" }" << std::endl;
803 std::cout <<
"\n***********************\nRe-Order graph operator list\n*************************\n";
810 for (
int i = 0; i < graph.
input_size(); i++) {
815 for (
int i = 0; i < graph.
node_size(); i++) {
820 int input_size = graph.
node(i).input_size();
823 std::cout <<
"Checking input of Node " << i <<
" : " << graph.
node(i).name() << std::endl;
824 for (
int j = 0;
j < input_size;
j++) {
825 std::string
name = graph.
node(i).input(
j);
831 std::cout <<
"\t\t input " <<
name <<
" "
840 std::cout <<
"skip node " << graph.
node(i).op_type() <<
" " << graph.
node(i).name() <<
" inputs are not existing ";
841 for (
int j = 0;
j < input_size;
j++) {
842 std::cout << graph.
node(i).input(
j) <<
" ";
844 std::cout << std::endl;
851 std::cout <<
"===> New node " << graph.
node(i).op_type() <<
" " << graph.
node(i).name() <<
" order " << i << std::endl;
856 for (
int j = 0;
j < graph.
node(i).output_size();
j++) {
857 if (
fVerbose) std::cout <<
"\toutput : " << graph.
node(i).output(
j) << std::endl;
864 std::cout <<
"cannot find a new node after " << graph.
node(
ilast).op_type() <<
" " << graph.
node(
ilast).name() << std::endl;
865 throw std::runtime_error(
"TMVA::SOFIE - cannot find a new node ");
873 for (
int k = 0; k < graph.
node_size(); k++) {
891 std::cout <<
"\nGraph operator list (re-ordered)\n";
892 for (
int k = 0; k < graph.
node_size(); k++) {
894 std::cout <<
"\tOperator " << i <<
" : " << graph.
node(i).op_type() <<
" , " << graph.
node(i).name() <<
" input tensors : {";
895 for (
int j = 0;
j < graph.
node(i).input_size();
j++) {
896 std::cout << graph.
node(i).input(
j);
897 if (
j < graph.
node(i).input_size() - 1)
901 std::cout <<
" children : {";
905 std::cout <<
"}" << std::endl;
911 std::cout <<
"Fill RModel with operators...\n";
917 for (
int i = 0; i < graph.
node_size(); i++) {
921 std::cout <<
"\t" << i <<
" " <<
nodesOrder[i] <<
" parsing operator " << op_type << std::endl;
927 std::cout <<
"\t\tskipping operator since it is fused with previous one" << std::endl;
937 std::cout <<
"\nParsing Graph output list\n";
940 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
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)
const std::string & name() const
const ValueInfoProto & output(int i) const
int initializer_size() const
const ValueInfoProto & input(int i) 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 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 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 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