24#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
25#include <numpy/arrayobject.h>
38 std::cout <<
"\nPython error message:\n";
40 throw std::runtime_error(
"\nFailed to run python code: " + code);
44const char *PyStringAsString(
PyObject *
string)
175 std::string
fLayerType = PyStringAsString(GetValueFromDict(fLayer,
"layerType"));
178 PyObject* fAttributes=GetValueFromDict(fLayer,
"layerAttributes");
179 std::string
fLayerName = PyStringAsString(GetValueFromDict(fAttributes,
"_name"));
197 PyObject* fAttributes=GetValueFromDict(fLayer,
"layerAttributes");
199 std::string
fLayerName = PyStringAsString(GetValueFromDict(fAttributes,
"_name"));
205 rmodel.AddNeededStdLib(
"cmath");
211 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
243 throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras Activation layer " +
fLayerActivation +
" is not yet supported");
255 throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras layer " +
fLayerType +
" is not yet supported");
270 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
272 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
284 std::unique_ptr<ROperator>
op;
297 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Gemm does not yet support input type " +
fLayerDType);
315 PyObject* fAttributes = GetValueFromDict(fLayer,
"layerAttributes");
316 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
318 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
332 PyObject* fGroup = GetValueFromDict(fAttributes,
"groups");
334 PyObject* fPads = GetValueFromDict(fAttributes,
"padding");
335 PyObject* fStrides = GetValueFromDict(fAttributes,
"strides");
337 std::vector<size_t> fAttrDilations = GetDataFromTuple(
fDilations);
341 std::vector<size_t> fAttrKernelShape = GetDataFromTuple(
fKernelShape);
342 std::vector<size_t> fAttrStrides = GetDataFromTuple(fStrides);
343 std::string fAttrAutopad;
344 std::vector<size_t>fAttrPads;
349 fAttrAutopad =
"VALID";
352 fAttrAutopad=
"NOTSET";
353 PyObject* fInputShape = GetValueFromDict(fAttributes,
"_batch_input_shape");
357 long outputHeight = std::ceil(
float(inputHeight) /
float(fAttrStrides[0]));
358 long outputWidth = std::ceil(
float(inputWidth) /
float(fAttrStrides[1]));
370 throw std::runtime_error(
"TMVA::SOFIE - RModel Keras Parser doesn't yet supports Convolution layer with padding " +
fKerasPadding);
373 std::unique_ptr<ROperator>
op;
381 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Conv does not yet support input type " +
fLayerDType);
396 PyObject* fAttributes=GetValueFromDict(fLayer,
"layerAttributes");
402 throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras Activation layer " +
fLayerActivation +
" is not yet supported");
418 PyObject* fInputs=GetValueFromDict(fLayer,
"layerInput");
421 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
425 std::unique_ptr<ROperator>
op;
431 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Relu does not yet support input type " +
fLayerDType);
446 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
449 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
453 std::unique_ptr<ROperator>
op;
459 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Selu does not yet support input type " +
fLayerDType);
474 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
477 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
481 std::unique_ptr<ROperator>
op;
487 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " +
fLayerDType);
501 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
504 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
508 std::unique_ptr<ROperator>
op;
514 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " +
fLayerDType);
529 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
531 PyObject* fAttributes=GetValueFromDict(fLayer,
"layerAttributes");
533 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
536 float fAlpha = (float)
PyFloat_AsDouble(GetValueFromDict(fAttributes,
"alpha"));
537 std::unique_ptr<ROperator>
op;
543 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " +
fLayerDType);
557 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
560 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
564 std::unique_ptr<ROperator>
op;
570 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Tanh does not yet support input type " +
fLayerDType);
584 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
587 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
591 std::unique_ptr<ROperator>
op;
597 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Swish does not yet support input type " +
fLayerDType);
614 PyObject* fAttributes=GetValueFromDict(fLayer,
"layerAttributes");
615 PyObject* fInputs=GetValueFromDict(fLayer,
"layerInput");
618 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
631 std::unique_ptr<ROperator>
op;
645 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Transpose does not yet support input type " +
fLayerDType);
658 PyObject* fAttributes = GetValueFromDict(fLayer,
"layerAttributes");
659 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
661 PyObject* fGamma = GetValueFromDict(fAttributes,
"gamma");
662 PyObject* fBeta = GetValueFromDict(fAttributes,
"beta");
666 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
673 float fEpsilon = (float)
PyFloat_AsDouble(GetValueFromDict(fAttributes,
"epsilon"));
674 float fMomentum = (float)
PyFloat_AsDouble(GetValueFromDict(fAttributes,
"momentum"));
676 std::unique_ptr<ROperator>
op;
689 PyObject* fAttributes = GetValueFromDict(fLayer,
"layerAttributes");
690 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
693 std::string
fLayerName = PyStringAsString(GetValueFromDict(fAttributes,
"_name"));
696 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
700 std::unique_ptr<ROperator>
op;
712 PyObject* fAttributes = GetValueFromDict(fLayer,
"layerAttributes");
713 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
716 std::vector<std::string>
inputs;
723 std::unique_ptr<ROperator>
op;
739 PyObject* fInputs = GetValueFromDict(fLayer,
"layerInput");
742 std::string
fLayerType = PyStringAsString(GetValueFromDict(fLayer,
"layerType"));
743 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
748 std::unique_ptr<ROperator>
op;
760 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " +
fLayerDType);
775 PyObject* fInputs=GetValueFromDict(fLayer,
"layerInput");
778 std::string
fLayerDType = PyStringAsString(GetValueFromDict(fLayer,
"layerDType"));
782 std::unique_ptr<ROperator>
op;
788 throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Identity does not yet support input type " +
fLayerDType);
844 if (
isep != std::string::npos){
849 if(!std::ifstream(
filename).good()){
850 throw std::runtime_error(
"Model file "+
filename_nodir+
" not found!");
854 std::time_t
ttime = std::time(0);
866 throw std::runtime_error(
"Can't init global namespace for Python");
869 throw std::runtime_error(
"Can't init local namespace for Python");
876 PyRunString(
"import tensorflow",fGlobalNS,fLocalNS);
877 PyRunString(
"import tensorflow.keras as keras",fGlobalNS,fLocalNS);
878 PyRunString(
"from tensorflow.keras.models import load_model",fGlobalNS,fLocalNS);
879 PyRunString(
"print('TF/Keras Version: '+ tensorflow.__version__)",fGlobalNS,fLocalNS);
882 PyRunString(
"globals().update(locals())",fGlobalNS,fLocalNS);
883 PyRunString(
"modelData=[]",fGlobalNS,fLocalNS);
884 PyRunString(
"for idx in range(len(model.layers)):\n"
885 " layer=model.get_layer(index=idx)\n"
887 " layerData['layerType']=layer.__class__.__name__\n"
888 " layerData['layerAttributes']=layer.__dict__\n"
889 " layerData['layerInput']=[x.name for x in layer.input] if isinstance(layer.input,list) else [layer.input.name]\n"
890 " layerData['layerOutput']=[x.name for x in layer.output] if isinstance(layer.output,list) else [layer.output.name]\n"
891 " layerData['layerDType']=layer.dtype\n"
892 " layerData['layerWeight']=[x.name for x in layer.weights]\n"
893 " modelData.append(layerData)",fGlobalNS,fLocalNS);
905 fLayerType = PyStringAsString(GetValueFromDict(fLayer,
"layerType"));
914 rmodel.AddBlasRoutines({
"Gemm",
"Gemv"});
916 rmodel.AddBlasRoutines({
"Copy",
"Axpy"});
918 rmodel.AddBlasRoutines({
"Gemm",
"Axpy"});
927 PyRunString(
"weight=[]",fGlobalNS,fLocalNS);
928 PyRunString(
"for idx in range(len(model.get_weights())):\n"
930 " weightProp['name']=model.weights[idx].name\n"
931 " weightProp['dtype']=(model.get_weights())[idx].dtype.name\n"
932 " weightProp['value']=(model.get_weights())[idx].transpose((3,2,0,1)).copy() if ('conv' in model.weights[idx].name and model.weights[idx].shape.ndims == 4) else (model.get_weights())[idx]\n"
933 " weight.append(weightProp)",fGlobalNS,fLocalNS);
939 fPWeight = GetValueFromDict(fLocalNS,
"weight");
977 PyRunString(
"inputNames=model.input_names",fGlobalNS,fLocalNS);
978 PyRunString(
"inputShapes=model.input_shape if type(model.input_shape)==list else [model.input_shape]",fGlobalNS,fLocalNS);
979 PyRunString(
"inputTypes=[]",fGlobalNS,fLocalNS);
980 PyRunString(
"for idx in range(len(model.inputs)):\n"
981 " inputTypes.append(model.inputs[idx].dtype.__str__()[9:-2])",fGlobalNS,fLocalNS);
1003 std::vector<size_t>fInputShape = GetDataFromTuple(
fPInputShapes);
1004 if (
static_cast<int>(fInputShape[0]) <= 0){
1006 std::cout <<
"Model has not a defined batch size ";
1007 if (
batch_size <=0) std::cout <<
" assume is 1 ";
1008 else std::cout <<
" use given value of " <<
batch_size;
1009 std::cout <<
" - input shape for tensor " <<
fInputName <<
" : "
1036 if (
static_cast<int>(fInputShape[0]) <= 0){
1038 std::cout <<
"Model has not a defined batch size ";
1039 if (
batch_size <=0) std::cout <<
" assume is 1 ";
1040 else std::cout <<
" use given value of " <<
batch_size;
1041 std::cout <<
" - input shape for tensor "
1059 PyRunString(
"outputNames=[]",fGlobalNS,fLocalNS);
1060 PyRunString(
"for layerName in model.output_names:\n"
1061 " outputNames.append(model.get_layer(layerName).output.name)",fGlobalNS,fLocalNS);
1063 std::vector<std::string> fOutputNames;
1067 rmodel.AddOutputTensorNameList(fOutputNames);
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 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
const_iterator begin() const
const_iterator end() const
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
std::unique_ptr< ROperator > MakeKerasConv(PyObject *fLayer)
Prepares a ROperator object for Keras Conv Layer.
std::unordered_map< std::string, std::unique_ptr< ROperator >(*)(PyObject *fLayer)> KerasMethodMap
std::unique_ptr< ROperator > MakeKerasPermute(PyObject *fLayer)
Prepares a ROperator object for Keras Permute layer.
std::unique_ptr< ROperator > MakeKerasBatchNorm(PyObject *fLayer)
Prepares a ROperator object for Keras BatchNorm layer.
std::unique_ptr< ROperator > MakeKerasSwish(PyObject *fLayer)
Prepares a ROperator object for Keras Swish activation.
void AddKerasLayer(RModel &rmodel, PyObject *fLayer)
Adds equivalent ROperator with respect to Keras model layer into the referenced RModel object.
std::unique_ptr< ROperator > MakeKerasConcat(PyObject *fLayer)
Prepares a ROperator object for Keras Concat layer.
std::unique_ptr< ROperator > MakeKerasLeakyRelu(PyObject *fLayer)
Prepares a ROperator object for Keras Leaky Relu activation.
std::unique_ptr< ROperator > MakeKerasDense(PyObject *fLayer)
Prepares a ROperator object for Keras Dense Layer.
std::unique_ptr< ROperator > MakeKerasBinary(PyObject *fLayer)
Prepares a ROperator object for Keras binary operations like Add, subtract, and multiply.
std::unique_ptr< ROperator > MakeKerasTanh(PyObject *fLayer)
Prepares a ROperator object for Keras Tanh activation.
std::unique_ptr< ROperator > MakeKerasSoftmax(PyObject *fLayer)
Prepares a ROperator object for Keras Softmax activation.
std::unique_ptr< ROperator > MakeKerasReshape(PyObject *fLayer)
Prepares a ROperator object for Keras Reshape layer.
std::unique_ptr< ROperator > MakeKerasReLU(PyObject *fLayer)
Prepares a ROperator object for Keras ReLU activation.
const KerasMethodMapWithActivation mapKerasLayerWithActivation
std::unique_ptr< ROperator > MakeKerasIdentity(PyObject *fLayer)
Prepares a ROperator object for Keras Identity and Dropout Layer.
std::unique_ptr< ROperator > MakeKerasSigmoid(PyObject *fLayer)
Prepares a ROperator object for Keras Sigmoid activation.
std::unique_ptr< ROperator > MakeKerasSelu(PyObject *fLayer)
Prepares a ROperator object for Keras Selu activation.
std::unordered_map< std::string, std::unique_ptr< ROperator >(*)(PyObject *fLayer)> KerasMethodMapWithActivation
const KerasMethodMap mapKerasLayer
std::unique_ptr< ROperator > MakeKerasActivation(PyObject *fLayer)
Prepares a ROperator object for Keras activation layer.
RModel Parse(std::string filename, int batch_size=-1)
Parser function for translatng Keras .h5 model into a RModel object.
std::string ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
std::string ConvertShapeToString(const std::vector< size_t > &shape)