public TensorType getTensorType(String onnxName, Map<String, TensorType> inputTypes) {
        OnnxTypeInfo onnxTypeInfo = outputs.get(onnxName);
        if (onnxTypeInfo == null) {
            throw new IllegalArgumentException("Could not find type for output '" + onnxName + "'");
        }
        if (onnxTypeInfo.containsUnknownDimensionSizes()) {
            Set<Long> unboundSizes = new HashSet<>();
            Map<String, Long> symbolicSizes = new HashMap<>();
            resolveUnknownDimensionSizes(inputTypes, symbolicSizes, unboundSizes);

            TensorType type = TensorType.empty;
            if (!inputTypes.isEmpty() && onnxTypeInfo.needModelProbe(symbolicSizes)) {
                type = OnnxModelProbe.probeModel(app, Path.fromString(modelPath), onnxName, inputTypes);
            }
            if (type.equals(TensorType.empty)) {
                type = onnxTypeInfo.toVespaTensorType(symbolicSizes, unboundSizes);
            }
            return type;
        }
        return vespaTypes.computeIfAbsent(onnxName, v -> onnxTypeInfo.toVespaTensorType());
    }
Return the tensor type for an ONNX model for the given context.
An ONNX model can have dynamic/symbolic dimension sizes. If so, the output
type depends on the input types for the given context (rank profile).
config-model/src/main/java/com/yahoo/vespa/model/ml/OnnxModelInfo.java