24#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 
   25#include <numpy/arrayobject.h> 
   29namespace Experimental{
 
  143   if(fLayerType == 
"Reshape"){
 
  147      std::vector<size_t>fTargetShape = GetDataFromTuple(fPTargetShape);
 
  148      std::shared_ptr<void> fData(
malloc(fTargetShape.size() * 
sizeof(int64_t)), 
free);
 
  149      std::copy(fTargetShape.begin(),fTargetShape.end(),(int64_t*)fData.get());
 
  168      std::string fLayerActivation = 
PyStringAsString(PyObject_GetAttrString(fPActivation,
"__name__"));
 
  170      if(fLayerActivation == 
"selu" || fLayerActivation == 
"sigmoid")
 
  175      if(fLayerActivation != 
"linear"){
 
  178         std::string fActivationLayerOutput = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  180         if(fLayerType == 
"Conv2D"){
 
  181            std::unique_ptr<ROperator> op_pre_transpose;
 
  185            PyList_SetItem(fInputs,0,PyUnicode_FromString((fLayerName+
"PreTrans").c_str()));
 
  186            PyDict_SetItemString(fLayer,
"layerInput",fInputs);
 
  190         PyList_SetItem(fOutputs,0,PyUnicode_FromString((fLayerName+fLayerType).c_str()));
 
  191         PyDict_SetItemString(fLayer,
"layerOutput",fOutputs);
 
  194         std::string fActivationLayerInput = fLayerName+fLayerType;
 
  195         if(fLayerType == 
"Conv2D"){
 
  196            std::unique_ptr<ROperator> op_post_transpose;
 
  199            fActivationLayerInput = fLayerName+
"PostTrans";
 
  202         PyList_SetItem(fInputs,0,PyUnicode_FromString(fActivationLayerInput.c_str()));
 
  203         PyList_SetItem(fOutputs,0,PyUnicode_FromString(fActivationLayerOutput.c_str()));
 
  204         PyDict_SetItemString(fLayer,
"layerInput",fInputs);
 
  205         PyDict_SetItemString(fLayer,
"layerOutput",fOutputs);
 
  207         auto findActivationLayer = 
mapKerasLayer.find(fLayerActivation);
 
  209            throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras Activation layer " + fLayerActivation + 
" is not yet supported");
 
  211         rmodel.
AddOperator((findActivationLayer->second)(fLayer));
 
  221      throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras layer " + fLayerType + 
" is not yet supported");
 
  241      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  250      std::unique_ptr<ROperator> op;
 
  252      float attr_alpha = 1.0;
 
  253      float attr_beta  = 1.0;
 
  254      int_t attr_transA = 0;
 
  255      int_t attr_transB = 0;
 
  259         op.reset(
new ROperator_Gemm<float>(attr_alpha, attr_beta, attr_transA, attr_transB, fLayerInputName, fKernelName, fBiasName, fLayerOutputName));
 
  263         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Gemm does not yet support input type " + fLayerDType);
 
  287      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  303      std::vector<size_t> fAttrDilations = GetDataFromTuple(fDilations);
 
  306      size_t fAttrGroup = PyLong_AsLong(fGroup);
 
  307      std::vector<size_t> fAttrKernelShape = GetDataFromTuple(fKernelShape);
 
  308      std::vector<size_t> fAttrStrides     = GetDataFromTuple(fStrides);
 
  309      std::string fAttrAutopad;
 
  310      std::vector<size_t>fAttrPads;
 
  314      if(fKerasPadding == 
"valid"){
 
  315         fAttrAutopad = 
"VALID";
 
  317      else if(fKerasPadding == 
"same"){
 
  318         fAttrAutopad=
"NOTSET";
 
  320         long inputHeight = PyLong_AsLong(PyTuple_GetItem(fInputShape,1));
 
  321         long inputWidth = PyLong_AsLong(PyTuple_GetItem(fInputShape,2));
 
  323         long outputHeight = std::ceil(
float(inputHeight) / 
float(fAttrStrides[0]));
 
  324         long outputWidth  = std::ceil(
float(inputWidth) / 
float(fAttrStrides[1]));
 
  326         long padding_height = std::max(
long((outputHeight - 1) * fAttrStrides[0] + fAttrKernelShape[0] - inputHeight),0L);
 
  327         long padding_width = std::max(
long((outputWidth - 1) * fAttrStrides[1] + fAttrKernelShape[1] - inputWidth),0L);
 
  329         size_t padding_top = std::floor(padding_height/2);
 
  330         size_t padding_bottom   = padding_height - padding_top;
 
  331         size_t padding_left = std::floor(padding_width/2);
 
  332         size_t padding_right   = padding_width - padding_left;
 
  333         fAttrPads = {padding_top,padding_bottom,padding_left,padding_right};
 
  336         throw std::runtime_error(
"TMVA::SOFIE - RModel Keras Parser doesn't yet supports Convolution layer with padding " + fKerasPadding);
 
  339      std::unique_ptr<ROperator> op;
 
  343         op.reset(
new ROperator_Conv<float>(fAttrAutopad, fAttrDilations, fAttrGroup, fAttrKernelShape, fAttrPads, fAttrStrides, fLayerInputName, fKernelName, fBiasName, fLayerOutputName));
 
  347         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Conv does not yet support input type " + fLayerDType);
 
  364      std::string fLayerActivation = 
PyStringAsString(PyObject_GetAttrString(fPActivation,
"__name__"));
 
  368         throw std::runtime_error(
"TMVA::SOFIE - Parsing Keras Activation layer " + fLayerActivation + 
" is not yet supported");
 
  370      return (findLayer->second)(fLayer);
 
  389      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  391      std::unique_ptr<ROperator> op;
 
  397         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Relu does not yet support input type " + fLayerDType);
 
  417      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  419      std::unique_ptr<ROperator> op;
 
  425         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Selu does not yet support input type " + fLayerDType);
 
  445      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  447      std::unique_ptr<ROperator> op;
 
  453         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fLayerDType);
 
  472      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  474      std::unique_ptr<ROperator> op;
 
  480         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fLayerDType);
 
  501      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  502      float fAlpha = (float)PyFloat_AsDouble(
GetValueFromDict(fAttributes,
"alpha"));
 
  503      std::unique_ptr<ROperator> op;
 
  509         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fLayerDType);
 
  528      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  530      std::unique_ptr<ROperator> op;
 
  536         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fLayerDType);
 
  560      std::string fLayerOutputName     = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  564      std::vector<int_t>fPermuteDims;
 
  567      for(
Py_ssize_t tupleIter=0;tupleIter<PyTuple_Size(fAttributePermute);++tupleIter){
 
  569         fPermuteDims.push_back((
int_t)PyLong_AsLong(PyTuple_GetItem(fAttributePermute,tupleIter)));
 
  571      std::unique_ptr<ROperator> op;
 
  576            if (!fPermuteDims.empty()){
 
  585            throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Transpose does not yet support input type " + fLayerDType);
 
  609      std::string fNScale  = 
PyStringAsString(PyObject_GetAttrString(fGamma,
"name"));
 
  611      std::string fNMean  = 
PyStringAsString(PyObject_GetAttrString(fMoving_Mean,
"name"));
 
  612      std::string fNVar  = 
PyStringAsString(PyObject_GetAttrString(fMoving_Var,
"name"));
 
  613      float fEpsilon = (float)PyFloat_AsDouble(
GetValueFromDict(fAttributes,
"epsilon"));
 
  614      float fMomentum = (float)PyFloat_AsDouble(
GetValueFromDict(fAttributes,
"momentum"));
 
  616      std::unique_ptr<ROperator> op;
 
  639      std::string fNameShape     = fLayerName + 
"ReshapeAxes";
 
  640      std::unique_ptr<ROperator> op;
 
  656      std::vector<std::string> inputs;
 
  657      for(
Py_ssize_t i=0; i<PyList_Size(fInputs); ++i){
 
  663      std::unique_ptr<ROperator> op;
 
  688      std::unique_ptr<ROperator> op;
 
  691            if(fLayerType == 
"Add")
 
  693            else if(fLayerType == 
"Subtract")
 
  700         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Sigmoid does not yet support input type " + fLayerDType);
 
  720      std::string fLayerOutputName = 
PyStringAsString(PyList_GetItem(fOutputs,0));
 
  722      std::unique_ptr<ROperator> op;
 
  728         throw std::runtime_error(
"TMVA::SOFIE - Unsupported - Operator Identity does not yet support input type " + fLayerDType);
 
  779   std::string filename_nodir = 
filename;
 
  780   if (isep != std::string::npos){
 
  785   if(!std::ifstream(
filename).good()){
 
  786        throw std::runtime_error(
"Model file "+filename_nodir+
" not found!");
 
  790   std::time_t ttime = std::time(0);
 
  791   std::tm* gmt_time = std::gmtime(&ttime);
 
  792   std::string parsetime (std::asctime(gmt_time));
 
  794   RModel rmodel(filename_nodir, parsetime);
 
  802       throw std::runtime_error(
"Can't init global namespace for Python");
 
  805       throw std::runtime_error(
"Can't init local namespace for Python");
 
  812   PyRunString(
"import tensorflow",fGlobalNS,fLocalNS);
 
  813   PyRunString(
"import tensorflow.keras as keras",fGlobalNS,fLocalNS);
 
  814   PyRunString(
"from tensorflow.keras.models import load_model",fGlobalNS,fLocalNS);
 
  815   PyRunString(
"print('TF/Keras Version: '+ tensorflow.__version__)",fGlobalNS,fLocalNS);
 
  818   PyRunString(
"globals().update(locals())",fGlobalNS,fLocalNS);
 
  820   PyRunString(
"for idx in range(len(model.layers)):\n" 
  821               "  layer=model.get_layer(index=idx)\n" 
  823               "  layerData['layerType']=layer.__class__.__name__\n" 
  824               "  layerData['layerAttributes']=layer.__dict__\n" 
  825               "  layerData['layerInput']=[x.name for x in layer.input] if isinstance(layer.input,list) else [layer.input.name]\n" 
  826               "  layerData['layerOutput']=[x.name for x in layer.output] if isinstance(layer.output,list) else [layer.output.name]\n" 
  827               "  layerData['layerDType']=layer.dtype\n" 
  828               "  layerData['layerWeight']=[x.name for x in layer.weights]\n" 
  829               "  modelData.append(layerData)",fGlobalNS,fLocalNS);
 
  835   std::string fLayerType;
 
  839   for(
Py_ssize_t fModelIterator=0;fModelIterator<fModelSize;++fModelIterator){
 
  840      fLayer     = PyList_GetItem(fPModel,fModelIterator);
 
  844      if(fLayerType == 
"InputLayer")
 
  849      else if(fLayerType == 
"Dense")
 
  851      else if (fLayerType == 
"BatchNormalization")
 
  853      else if(fLayerType == 
"Conv1D" || fLayerType == 
"Conv2D" || fLayerType == 
"Conv3D")
 
  864   PyRunString(
"for idx in range(len(model.get_weights())):\n" 
  866               "  weightProp['name']=model.weights[idx].name\n" 
  867               "  weightProp['dtype']=(model.get_weights())[idx].dtype.name\n" 
  868               "  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" 
  869               "  weight.append(weightProp)",fGlobalNS,fLocalNS);
 
  872   PyArrayObject *fWeightTensorValue;
 
  873   std::string fWeightName;
 
  876   std::vector<std::size_t> fWeightTensorShape;
 
  877   std::size_t fWeightTensorSize;
 
  880   for (
Py_ssize_t weightIter = 0; weightIter < PyList_Size(fPWeight); weightIter++){
 
  881      fWeightTensor      = PyList_GetItem(fPWeight, weightIter);
 
  885      fWeightTensorValue = (PyArrayObject*)
GetValueFromDict(fWeightTensor,
"value");
 
  887      fWeightTensorShape.clear();
 
  890      for(
int j=0; j<PyArray_NDIM(fWeightTensorValue); ++j){
 
  891       fWeightTensorShape.push_back((std::size_t)(PyArray_DIM(fWeightTensorValue,j)));
 
  892       fWeightTensorSize*=(std::size_t)(PyArray_DIM(fWeightTensorValue,j));
 
  895   switch(fWeightDType){
 
  897       float* fWeightArray = (
float*)PyArray_DATA(fWeightTensorValue);
 
  898       std::shared_ptr<void> fData(
malloc(fWeightTensorSize * 
sizeof(
float)), 
free);
 
  899       std::memcpy(fData.get(),fWeightArray, fWeightTensorSize * 
sizeof(
float));
 
  904          throw std::runtime_error(
"Type error: TMVA SOFIE does not yet weight data layer type"+
ConvertTypeToString(fWeightDType));
 
  913   PyRunString(
"inputNames=model.input_names",fGlobalNS,fLocalNS);
 
  914   PyRunString(
"inputShapes=model.input_shape if type(model.input_shape)==list else [model.input_shape]",fGlobalNS,fLocalNS);
 
  916   PyRunString(
"for idx in range(len(model.inputs)):\n" 
  917               "  inputTypes.append(model.inputs[idx].dtype.__str__()[9:-2])",fGlobalNS,fLocalNS);
 
  923   std::string fInputName;
 
  930   if(PyTuple_Check(fPInputShapes)){
 
  939         std::vector<size_t>fInputShape = GetDataFromTuple(fPInputShapes);
 
  940         if (
static_cast<int>(fInputShape[0]) <= 0){
 
  942            std::cout << 
"Model has not a defined batch size, assume is 1 - input shape : " 
  951         throw std::runtime_error(
"Type error: TMVA SOFIE does not yet support data type"+
ConvertTypeToString(fInputDType));
 
  959      for(
Py_ssize_t inputIter = 0; inputIter < PyList_Size(fPInputs);++inputIter){
 
  966         PyObject* fInputShapeTuple=PyList_GetItem(fPInputShapes,inputIter);
 
  968         std::vector<size_t>fInputShape = GetDataFromTuple(fInputShapeTuple);
 
  969         if (
static_cast<int>(fInputShape[0]) <= 0){
 
  971            std::cout << 
"Model has not a defined batch size, assume is 1 - input shape for tensor " 
  980         throw std::runtime_error(
"Type error: TMVA SOFIE does not yet support data type"+
ConvertTypeToString(fInputDType));
 
  990   PyRunString(
"for layerName in model.output_names:\n" 
  991               "    outputNames.append(model.get_layer(layerName).output.name)",fGlobalNS,fLocalNS);
 
  993   std::vector<std::string> fOutputNames;
 
  994   for(
Py_ssize_t outputIter = 0; outputIter < PyList_Size(fPOutputs);++outputIter){
 
  995         fOutputNames.push_back(
PyStringAsString(PyList_GetItem(fPOutputs,outputIter)));
 
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
 
void AddOutputTensorNameList(std::vector< std::string > outputtensornames)
 
void AddInputTensorInfo(std::string input_name, ETensorType type, std::vector< Dim > shape)
 
void AddInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
 
void AddBlasRoutines(std::vector< std::string > routines)
 
void AddInputTensorName(std::string name)
 
void AddNeededStdLib(std::string libname)
 
void AddOperator(std::unique_ptr< ROperator > op, int order_execution=-1)
 
static std::vector< size_t > GetDataFromTuple(PyObject *tupleObject)
Utility function which retrieves and returns the values of the Tuple object as a vector of size_t.
 
static const char * PyStringAsString(PyObject *string)
Returns const char* from Python string in PyObject.
 
static PyObject * GetValueFromDict(PyObject *dict, const char *key)
Utility function which checks if a given key is present in a Python dictionary object and returns the...
 
void PyRunString(TString code, TString errorMessage="Failed to run python code", int start=256)
Execute Python code from string.
 
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::unique_ptr< ROperator > MakeKerasPermute(PyObject *fLayer)
Prepares a ROperator object for Keras Permute layer.
 
std::unordered_map< std::string, std::unique_ptr< ROperator >(*)(PyObject *fLayer)> KerasMethodMap
 
std::unique_ptr< ROperator > MakeKerasBatchNorm(PyObject *fLayer)
Prepares a ROperator object for Keras BatchNorm layer.
 
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::unordered_map< std::string, std::unique_ptr< ROperator >(*)(PyObject *fLayer)> KerasMethodMapWithActivation
 
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.
 
const KerasMethodMap mapKerasLayer
 
std::unique_ptr< ROperator > MakeKerasActivation(PyObject *fLayer)
Prepares a ROperator object for Keras activation layer.
 
static void(&) PyRunString(TString, PyObject *, PyObject *)
 
static PyObject *(&) GetValueFromDict(PyObject *, const char *)
 
static const char *(&) PyStringAsString(PyObject *)
 
RModel Parse(std::string filename)
Parser function for translatng Keras .h5 model into a RModel object.
 
std::string ConvertShapeToString(std::vector< size_t > shape)
 
std::string ConvertTypeToString(ETensorType type)
 
ETensorType ConvertStringToType(std::string type)
 
create variable transformations