Skip to content

[MLIR] Tablegen code generation issue adding extra double quotes  #171217

@Sunny-Anand

Description

@Sunny-Anand

Summary

Code generated by Table gen is adding an extra " to some of the generated code from the onnx.td , this does not compile, it should not be adding that extra " as shown in the example below.
The errors occurred to I64ArrayAttr and StrAttr. The error code is like this:

return emitOpError(""requires attribute 'to'");

Two quotation mark at the beginning of the string.

Another error code is like this:

return emitError(loc, "'onnx.ConcatFromSequence' op "requires attribute 'axis'");

There shouldn't be any quotations before the requires.

It seems that MLIR mixed the two cases.

Expanded Explanation

Upgrading to the newer LLVM commit and stablehlo project in onnx-mlir is failing due to the MLIR codegen issue for operation definitions.
llvm commit: 0c2701f
stablehlo commit: 1ef9e390b5295e676d2b864fe1924bc2f3f4cf0f

In file included from /workdir/onnx-mlir/src/Accelerators/NNPA/Dialect/ZLow/ZLowOps.cpp:411:

/workdir/onnx-mlir/build/src/Accelerators/NNPA/Dialect/ZLow/ZLowOps.cpp.inc:281:45: error: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wreserved-user-defined-literal]

      return emitError(loc, "'zlow.add' op "requires attribute 'layout'");

                                            ^

                                             

/workdir/onnx-mlir/build/src/Accelerators/NNPA/Dialect/ZLow/ZLowOps.cpp.inc:281:45: error: expected ')'

/workdir/onnx-mlir/build/src/Accelerators/NNPA/Dialect/ZLow/ZLowOps.cpp.inc:281:23: note: to match this '('

      return emitError(loc, "'zlow.add' op "requires attribute 'layout'");

                      ^

/workdir/onnx-mlir/build/src/Accelerators/NNPA/Dialect/ZLow/ZLowOps.cpp.inc:281:72: warning: missing terminating '"' character [-Winvalid-pp-token]

      return emitError(loc, "'zlow.add' op "requires attribute 'layout'");

The issue happens for some of the ops such as add op as shown above but also for ops in other dialects like ONNX, KRNL.

Below is the generated code via MLIR tablegen



//===----------------------------------------------------------------------===//
// ::onnx_mlir::zlow::ZLowAddOp definitions
//===----------------------------------------------------------------------===//

namespace detail {

::mlir::StringAttr ZLowAddOpGenericAdaptorBase::getLayoutAttr() {
  assert(odsAttrs && "no attributes when constructing adapter");
  auto attr = ::llvm::cast<::mlir::StringAttr>(::mlir::impl::getAttrFromSortedRange(odsAttrs.begin() + 0, odsAttrs.end() - 0, ZLowAddOp::getLayoutAttrName(*odsOpName)));
  return attr;
}

::llvm::StringRef ZLowAddOpGenericAdaptorBase::getLayout() {
  auto attr = getLayoutAttr();
  return attr.getValue();
}


} // namespace detail
ZLowAddOpAdaptor::ZLowAddOpAdaptor(ZLowAddOp op) : ZLowAddOpGenericAdaptor(op->getOperands(), op) {}

::llvm::LogicalResult ZLowAddOpAdaptor::verify(::mlir::Location loc) {
  auto namedAttrRange = odsAttrs;
  auto namedAttrIt = namedAttrRange.begin();
  ::mlir::Attribute tblgen_layout;

  while (true) {
    if (namedAttrIt == namedAttrRange.end())
      return emitError(loc, "'zlow.add' op requires attribute 'layout'");
    if (namedAttrIt->getName() == ZLowAddOp::getLayoutAttrName(*odsOpName)) {
      tblgen_layout = namedAttrIt->getValue();
      break;
    }
    ++namedAttrIt;
  }

  if (tblgen_layout && !((::llvm::isa<::mlir::StringAttr>(tblgen_layout))))
    return emitError(loc, "'zlow.add' op attribute 'layout' failed to satisfy constraint: string attribute");
  return ::mlir::success();
}

::llvm::StringRef ZLowAddOp::getLayout() {
  auto attr = getLayoutAttr();
  return attr.getValue();
}

void ZLowAddOp::setLayout(::llvm::StringRef attrValue) {
  (*this)->setAttr(getLayoutAttrName(), ::mlir::Builder((*this)->getContext()).getStringAttr(attrValue));
}

void ZLowAddOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  odsState.addOperands(X);
  odsState.addOperands(Y);
  odsState.addOperands(shape);
  odsState.addOperands(Out);
  odsState.addAttribute(getLayoutAttrName(odsState.name), layout);
}

ZLowAddOp ZLowAddOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  ::mlir::OperationState __state__(location, getOperationName());
  build(builder, __state__, X, Y, shape, Out, layout);
  auto __res__ = ::llvm::dyn_cast<ZLowAddOp>(builder.create(__state__));
  assert(__res__ && "builder didn't return the right type");
  return __res__;
}

ZLowAddOp ZLowAddOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  return create(builder, builder.getLoc(), X, Y, shape, Out, layout);
}

void ZLowAddOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  odsState.addOperands(X);
  odsState.addOperands(Y);
  odsState.addOperands(shape);
  odsState.addOperands(Out);
  odsState.addAttribute(getLayoutAttrName(odsState.name), layout);
  assert(resultTypes.size() == 0u && "mismatched number of results");
  odsState.addTypes(resultTypes);
}

ZLowAddOp ZLowAddOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  ::mlir::OperationState __state__(location, getOperationName());
  build(builder, __state__, resultTypes, X, Y, shape, Out, layout);
  auto __res__ = ::llvm::dyn_cast<ZLowAddOp>(builder.create(__state__));
  assert(__res__ && "builder didn't return the right type");
  return __res__;
}

ZLowAddOp ZLowAddOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::mlir::StringAttr layout) {
  return create(builder, builder.getLoc(), resultTypes, X, Y, shape, Out, layout);
}

void ZLowAddOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  odsState.addOperands(X);
  odsState.addOperands(Y);
  odsState.addOperands(shape);
  odsState.addOperands(Out);
  odsState.addAttribute(getLayoutAttrName(odsState.name), odsBuilder.getStringAttr(layout));
}

ZLowAddOp ZLowAddOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  ::mlir::OperationState __state__(location, getOperationName());
  build(builder, __state__, X, Y, shape, Out, layout);
  auto __res__ = ::llvm::dyn_cast<ZLowAddOp>(builder.create(__state__));
  assert(__res__ && "builder didn't return the right type");
  return __res__;
}

ZLowAddOp ZLowAddOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  return create(builder, builder.getLoc(), X, Y, shape, Out, layout);
}

void ZLowAddOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  odsState.addOperands(X);
  odsState.addOperands(Y);
  odsState.addOperands(shape);
  odsState.addOperands(Out);
  odsState.addAttribute(getLayoutAttrName(odsState.name), odsBuilder.getStringAttr(layout));
  assert(resultTypes.size() == 0u && "mismatched number of results");
  odsState.addTypes(resultTypes);
}

ZLowAddOp ZLowAddOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  ::mlir::OperationState __state__(location, getOperationName());
  build(builder, __state__, resultTypes, X, Y, shape, Out, layout);
  auto __res__ = ::llvm::dyn_cast<ZLowAddOp>(builder.create(__state__));
  assert(__res__ && "builder didn't return the right type");
  return __res__;
}

ZLowAddOp ZLowAddOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value X, ::mlir::Value Y, ::mlir::Value shape, ::mlir::Value Out, ::llvm::StringRef layout) {
  return create(builder, builder.getLoc(), resultTypes, X, Y, shape, Out, layout);
}

void ZLowAddOp::build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
  assert(operands.size() == 4u && "mismatched number of parameters");
  odsState.addOperands(operands);
  odsState.addAttributes(attributes);
  assert(resultTypes.size() == 0u && "mismatched number of return types");
  odsState.addTypes(resultTypes);
}

ZLowAddOp ZLowAddOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
  ::mlir::OperationState __state__(location, getOperationName());
  build(builder, __state__, resultTypes, operands, attributes);
  auto __res__ = ::llvm::dyn_cast<ZLowAddOp>(builder.create(__state__));
  assert(__res__ && "builder didn't return the right type");
  return __res__;
}

ZLowAddOp ZLowAddOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
  return create(builder, builder.getLoc(), resultTypes, operands, attributes);
}

::llvm::LogicalResult ZLowAddOp::verifyInvariantsImpl() {
  auto namedAttrRange = (*this)->getAttrs();
  auto namedAttrIt = namedAttrRange.begin();
  ::mlir::Attribute tblgen_layout;

  while (true) {
    if (namedAttrIt == namedAttrRange.end())
      return emitOpError("requires attribute 'layout'");
    if (namedAttrIt->getName() == getLayoutAttrName()) {
      tblgen_layout = namedAttrIt->getValue();
      break;
    }
    ++namedAttrIt;
  }

  if (::mlir::failed(__mlir_ods_local_attr_constraint_ZLow1(*this, tblgen_layout, "layout")))
    return ::mlir::failure();
  {
    unsigned index = 0; (void)index;
    auto valueGroup0 = getODSOperands(0);

    for (auto v : valueGroup0) {
      if (::mlir::failed(__mlir_ods_local_type_constraint_ZLow1(*this, v.getType(), "operand", index++)))
        return ::mlir::failure();
    }
    auto valueGroup1 = getODSOperands(1);

    for (auto v : valueGroup1) {
      if (::mlir::failed(__mlir_ods_local_type_constraint_ZLow1(*this, v.getType(), "operand", index++)))
        return ::mlir::failure();
    }
    auto valueGroup2 = getODSOperands(2);

    for (auto v : valueGroup2) {
      if (::mlir::failed(__mlir_ods_local_type_constraint_ZLow2(*this, v.getType(), "operand", index++)))
        return ::mlir::failure();
    }
    auto valueGroup3 = getODSOperands(3);

    for (auto v : valueGroup3) {
      if (::mlir::failed(__mlir_ods_local_type_constraint_ZLow1(*this, v.getType(), "operand", index++)))
        return ::mlir::failure();
    }
  }
  return ::mlir::success();
}

::llvm::LogicalResult ZLowAddOp::verifyInvariants() {
  return verifyInvariantsImpl();
}


} // namespace onnx_mlir::zlow
MLIR_DEFINE_EXPLICIT_TYPE_ID(::onnx_mlir::zlow::ZLowAddOp)


The zlow.td definition for the op

def ZLowAddOp:ZLow_Op<"add", [MemRefsNormalizable,
    DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
  let summary = "ZLow add operation";
  let description = [{
  ZLow operation to perform an add.
  }];
  let arguments = (ins ZMemRef:$X,
                       ZMemRef:$Y,
                       MemRefOf<[I64]>:$shape,
                       ZMemRef:$Out,
                       StrAttr:$layout);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions