private static ConcreteFunction buildFromGraph()

in tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/ConcreteFunction.java [535:618]


  private static ConcreteFunction buildFromGraph(Graph graph, Signature signature) {
    try (PointerScope scope = new PointerScope();
        Reference ref = graph.ref()) {
      TF_Status status = TF_Status.newStatus();

      List<Operand<?>> inputs =
          signature.getInputs().entrySet().stream()
              .map(
                  (x) ->
                      TensorFunction.validateDescription(x.getValue(), graph, x.getKey(), "Input"))
              .collect(Collectors.toList());

      List<Operand<?>> outputs =
          signature.getOutputs().entrySet().stream()
              .map(
                  (x) ->
                      TensorFunction.validateDescription(x.getValue(), graph, x.getKey(), "Output"))
              .collect(Collectors.toList());

      List<GraphOperation> ops =
          new ArrayList<>(graph.completeSubgraph(new HashSet<>(inputs), new HashSet<>(outputs)));

      inputs.forEach(input -> ops.remove((GraphOperation) input.op()));

      ops.forEach(
          x -> {
            if (x.type().equals(Placeholder.OP_NAME)
                || x.type().equals(PlaceholderWithDefault.OP_NAME)) {
              throw new IllegalArgumentException(
                  "Can't calculate outputs ("
                      + outputs
                      + ") from inputs ("
                      + inputs
                      + "), "
                      + "they also depend on \""
                      + x
                      + "\"");
            }
          });

      // Python sometimes has NoOps as outputs
      Ops tf = Ops.create(graph).withSubScope("functionControlOutputs");
      for (int i = 0; i < outputs.size(); i++) {
        Operand<?> output = outputs.get(i);
        if (output.op().numOutputs() < 1) {
          Operand<TBool> realOutput =
              tf.withControlDependencies(Collections.singletonList(output))
                  .withName(output.op().name() + "_control")
                  .constant(false);
          ops.add((GraphOperation) realOutput.op());
          outputs.set(i, realOutput);
        }
      }

      PointerPointer<TF_Operation> operations = new PointerPointer<>(ops.size());
      for (int i = 0; i < ops.size(); i++) {
        operations.put(i, ops.get(i).getUnsafeNativeHandle());
      }

      TF_Function handle =
          TF_GraphToFunction(
              ref.nativeHandle(),
              new BytePointer(signature.key()),
              (byte) 1,
              ops.size(),
              operations,
              inputs.size(),
              resolveToOutput(graph, inputs),
              outputs.size(),
              resolveToOutput(graph, outputs),
              null,
              null,
              new BytePointer(
                  signature.methodName() != null
                      ? signature.methodName()
                      : "Method " + signature.key()),
              status);

      handle.withDeallocator();
      status.throwExceptionIfNotOK();
      return new ConcreteFunction(
          signature, new NativeFunction(handle), graph.getNativeFunctions(scope));
    }
  }