onnx / onnx-mlir

Representation and Reference Lowering of ONNX Models in MLIR Compiler Infrastructure
Apache License 2.0
754 stars 321 forks source link

document policy for optional-not-present, empty tensors, empty shapes #2274

Open sorenlassen opened 1 year ago

sorenlassen commented 1 year ago

As discussed in https://github.com/onnx/onnx-mlir/issues/2241#issuecomment-1560271489_ it would be good to document our policy for optional-not-present, empty tensors, and empty shapes.

I'm happy to draft a policy but I'm not sure where to to put it so that it is easily found. Suggestions are welcome.

cc @AlexandreEichenberger

AlexandreEichenberger commented 1 year ago

I wonder if there is a header file where there is some support for the not-present / empty tensors... that might be a natural place to put some of this info. In the code, less likely to be obsolete as we would update the helper methods... just a thought

AlexandreEichenberger commented 1 year ago

Maybe we can add to this also info about scalar; I currently found 3 definitions in the code.

DequantizeLinear.cpp

  // Is tensor known to be a scalar (rank 0 or rank 1 with 1 element)?
  auto isScalar = [](RankedTensorType t) -> bool {
    return t.getRank() == 0 || (t.getRank() == 1 && t.getDimSize(0) == 1);
  };

and ONNXToKrnlCommon.cpp

bool isScalarValue(Value value) {
  ShapedType stype = value.getType().dyn_cast<ShapedType>();
  assert(stype && "expected shaped type");
  return stype.getRank() == 0;
}

...

// Check if we have a 'tensor<' ('1x')* 'x type>' type, namely a scalar or a
// n-dimensional tensor of size 1 along all dimensions.
bool hasOneElement(Value value) {
  if (isScalarValue(value))
    return true;
  ShapedType type = value.getType().dyn_cast<ShapedType>();
  assert(type && "expected shaped type");
  for (int64_t s : type.getShape())
    if (s != 1)
      return false;
  return true;
}

Maybe these definitions should be somewhere under Dialect/ONNX

AlexandreEichenberger commented 1 year ago

Personally not aware if there are cases where we need to distinguish between rank=0 scalar, rank=1/dim=1 scalar, and the more generic case. Would be nice to have clear definitions and know when to use which one.

ONNX discussed this and decided to keep the def vague, for the best of my understanding. https://github.com/onnx/onnx/issues/2428