docs: public void convertToConstants(List<SDVariable> variables){
          if(variables.size() == 0)
              return;
          boolean allConst = true;
          for(SDVariable variable : variables) {
              if (variable.getVariableType() != VariableType.CONSTANT) {
                  allConst = false;
                  Preconditions.checkState(variable.getVariableType() != VariableType.ARRAY, "Cannot convert variable of type ARRAY to a constant: %s", variable);
              }
          }
          if(allConst){
              return; //No op
          }
  
          //Remove all sessions in case they have any cached arrays/state
          sessions.clear();
  
          //If gradient function has been defined, remove it (so it will be recreated later)
          sameDiffFunctionInstances.remove("grad");
  
          for(SDVariable variable : variables ) {
              String n = variable.getVarName();
              INDArray arr = variable.getArr();
              Preconditions.checkNotNull(arr, "Could not get array for variable %s: if this is a placeholder, use SDVariable.setArray before converting", variable);
  
              constantArrays.put(n, new DeviceLocalNDArray(arr));
              variablesArrays.remove(n);
              if(!placeholdersPerThread.isEmpty()){
                  for(Map<String,INDArray> m : placeholdersPerThread.values()){
                      m.remove(n);
                  }
              }
  
              variable.setVariableType(VariableType.CONSTANT);
          }
  
  
          if(trainingConfig != null){
              Set<String> toRemove = new HashSet<>();
              boolean anyTrainableParmsModified = false;
              List<String> origTrainableParams = trainingConfig.getTrainableParams();
              for(SDVariable v : variables){
                  toRemove.add(v.getVarName());
                  if(!anyTrainableParmsModified && origTrainableParams.contains(v.getVarName())){
                      anyTrainableParmsModified = true;
                  }
              }
  
  
              //Remove updater state for this variable: updaterState, updaterViews, updaterMap
              if(anyTrainableParmsModified) {
                  List<String> newTrainableParams = new ArrayList<>();
                  for (String s : origTrainableParams) {
                      if (!toRemove.contains(s)) {
                          newTrainableParams.add(s);
                      }
                  }
                  trainingConfig.setTrainableParams(newTrainableParams);
              }
  
              if(initializedTraining){
                  List<INDArray> newUpdaterState = new ArrayList<>();
                  for (String s : origTrainableParams) {
                      INDArray stateArr = updaterViews.get(s);
                      if (!toRemove.contains(s)) {
                          newUpdaterState.add(stateArr);
                      }
                  }
  
                  updaterState = newUpdaterState.isEmpty() ? null : Nd4j.concat(0, newUpdaterState.toArray(new INDArray[newUpdaterState.size()]));
                  //Now, update updaterViews map:
                  long viewSoFar = 0;
                  updaterViews = new HashMap<>();
                  updaterMap = new HashMap<>();
                  for(String s : trainingConfig.getTrainableParams()) {
                      long thisSize = trainingConfig.getUpdater().stateSize(this.variables.get(s).getVariable().getArr().length());
                      INDArray view = (updaterState == null || thisSize == 0 ? null :
                              updaterState.get(NDArrayIndex.interval(0, 1), NDArrayIndex.interval(viewSoFar, viewSoFar + thisSize)));
  
                      updaterViews.put(s, view);
                      updaterMap.put(s, trainingConfig.getUpdater().instantiate(view, false));
                      viewSoFar += thisSize;
                  }
              }
          }
      }