docs: public Map<String,INDArray> run(Map<String,INDArray> inputs) {
          if(graph == null) {
              throw new IllegalStateException("Graph not initialized.");
          }
  
          if(inputs.size() != inputOrder.size()) {
              throw new IllegalArgumentException("Number of inputs specified do not match number of arrays specified.");
          }
  
  
          if(savedModelConfig != null) {
              Map<String,INDArray> outputArrays = new LinkedHashMap<>();
  
              Map<String,TF_Operation> opsByName = new HashMap<>();
              TF_Output inputOut = new TF_Output(savedModelConfig.getSavedModelInputOrder().size());
  
              TF_Tensor[] inputTensors = new TF_Tensor[savedModelConfig.getSavedModelInputOrder().size()];
              for(int i = 0; i < savedModelConfig.getSavedModelInputOrder().size(); i++) {
                  String[] name = savedModelConfig.getSavedModelInputOrder().get(i).split(":");
                  TF_Operation inputOp = TF_GraphOperationByName(graph, name[0]);
                  opsByName.put(savedModelConfig.getSavedModelInputOrder().get(i),inputOp);
                  inputOut.position(i).oper(inputOp).index(name.length > 1 ? Integer.parseInt(name[1]) : 0);
                  TF_Tensor tf_tensor = conversion.tensorFromNDArray(inputs.get(inputOrder != null && !inputOrder.isEmpty()
                          ? inputOrder.get(i) : savedModelConfig.getSavedModelInputOrder().get(i)));
                  inputTensors[i] = tf_tensor;
              }
  
  
              //reset the position of the pointer for execution
              inputOut.position(0);
  
              TF_Output outputOut = new TF_Output(savedModelConfig.getSaveModelOutputOrder().size());
              //only setup the output ops
              for(int i = 0; i < savedModelConfig.getSaveModelOutputOrder().size(); i++) {
                  String[] name =savedModelConfig.getSaveModelOutputOrder().get(i).split(":");
                  TF_Operation outputOp = TF_GraphOperationByName(graph, name[0]);
                  opsByName.put(savedModelConfig.getSaveModelOutputOrder().get(i),outputOp);
                  outputOut.position(i).oper(outputOp).index(name.length > 1 ? Integer.parseInt(name[1]) : 0);
              }
  
              //reset the position of the pointer for execution
              outputOut.position(0);
  
  
  
              //these are references to the nd4j ndarrays wrapped for tensorflow
              PointerPointer<TF_Tensor> inputTensorsPointer = new PointerPointer<>(inputTensors);
              //note that these are the result pointers
              //the result pointers are null, and will be populated automatically by the session run
              PointerPointer<TF_Tensor> outputTensorsPointer = new PointerPointer<>(savedModelConfig.getSaveModelOutputOrder().size());
  
  
              TF_SessionRun(
                      session,
                      null,
                      //inputs
                      inputOut, inputTensorsPointer, inputTensors.length,
                      //outputs
                      outputOut, outputTensorsPointer, savedModelConfig.getSaveModelOutputOrder().size(),
                      //targets
                      null, 0,
                      null,
                      status);
  
  
              if (TF_GetCode(status) != TF_OK) {
                  throw new IllegalStateException("ERROR: Unable to run session " + TF_Message(status).getString());
              } else {
                  for(int i = 0; i < outputOrder.size(); i++) {
                      INDArray to = conversion.ndArrayFromTensor(new TF_Tensor(outputTensorsPointer.get(i)));
                      outputArrays.put(outputOrder != null && !outputOrder.isEmpty() ? outputOrder.get(i) :
                              savedModelConfig.getSaveModelOutputOrder().get(i),to);
                  }
  
              }
  
              return outputArrays;
  
          }
          else {
              Map<String,INDArray> outputArrays = new LinkedHashMap<>();
  
              Map<String,TF_Operation> opsByName = new HashMap<>();
              TF_Output inputOut = new TF_Output(inputOrder.size());
  
              TF_Tensor[] inputTensors = new TF_Tensor[inputOrder.size()];
              for(int i = 0; i < inputOrder.size(); i++) {
                  String[] name = inputOrder.get(i).split(":");
                  TF_Operation inputOp = TF_GraphOperationByName(graph, name[0]);
                  opsByName.put(inputOrder.get(i),inputOp);
                  inputOut.position(i).oper(inputOp).index(name.length > 1 ? Integer.parseInt(name[1]) : 0);
                  TF_Tensor tf_tensor = conversion.tensorFromNDArray(inputs.get(inputOrder.get(i)));
                  inputTensors[i] = tf_tensor;
              }
  
  
              //reset the position of the pointer for execution
              inputOut.position(0);
  
              TF_Output outputOut = new TF_Output(outputOrder.size());
              //only setup the output ops
              for(int i = 0; i < outputOrder.size(); i++) {
                  String[] name = outputOrder.get(i).split(":");
                  TF_Operation outputOp = TF_GraphOperationByName(graph, name[0]);
                  if(outputOp == null) {
                      throw new IllegalArgumentException("Illegal input found " + inputOrder.get(i) + " - no op found! Mis specified name perhaps?");
                  }
  
                  opsByName.put(outputOrder.get(i),outputOp);
                  outputOut.position(i).oper(outputOp).index(name.length > 1 ? Integer.parseInt(name[1]) : 0);
              }
  
              //reset the position of the pointer for execution
              outputOut.position(0);
  
  
  
              //these are references to the nd4j ndarrays wrapped for tensorflow
              PointerPointer<TF_Tensor> inputTensorsPointer = new PointerPointer<>(inputTensors);
              //note that these are the result pointers
              //the result pointers are null, and will be populated automatically by the session run
              PointerPointer<TF_Tensor> outputTensorsPointer = new PointerPointer<>(outputOrder.size());
  
  
              TF_SessionRun(
                      session,
                      null,
                      //inputs
                      inputOut, inputTensorsPointer, inputTensors.length,
                      //outputs
                      outputOut, outputTensorsPointer, outputOrder.size(),
                      //targets
                      null, 0,
                      null,
                      status);
  
  
              if (TF_GetCode(status) != TF_OK) {
                  throw new IllegalStateException("ERROR: Unable to run session " + TF_Message(status).getString());
              } else {
                  for(int i = 0; i < outputOrder.size(); i++) {
                      INDArray to = conversion.ndArrayFromTensor(new TF_Tensor(outputTensorsPointer.get(i)));
                      outputArrays.put(outputOrder.get(i),to);
                  }
  
              }
  
              return outputArrays;
  
          }
  
      }