// TensorFromElementsOp
//===----------------------------------------------------------------------===//
-def TensorFromElementsOp : Std_Op<"tensor_from_elements",
- [NoSideEffect, SameOperandsAndResultElementType]> {
+def TensorFromElementsOp : Std_Op<"tensor_from_elements", [
+ NoSideEffect,
+ SameOperandsAndResultElementType,
+ TypesMatchWith<"operand types match result element type",
+ "result", "elements", "SmallVector<Type, 2>("
+ "$_self.cast<ShapedType>().getDimSize(0), "
+ "$_self.cast<ShapedType>().getElementType())">
+ ]> {
string summary = "tensor from elements operation.";
string description = [{
Create a 1D tensor from a range of same-type arguments.
}];
let arguments = (ins Variadic<AnyType>:$elements);
- let results = (outs AnyTensor:$result);
+ let results = (outs 1DTensorOf<[AnyType]>:$result);
+
+ let assemblyFormat = "$elements attr-dict `:` type($result)";
+
+ // This op is fully verified by its traits.
+ let verifier = ?;
- let skipDefaultBuilders = 1;
let builders = [
OpBuilder<"OpBuilder &b, OperationState &result, ValueRange elements">
];
// TensorFromElementsOp
//===----------------------------------------------------------------------===//
-static ParseResult parseTensorFromElementsOp(OpAsmParser &parser,
- OperationState &result) {
- SmallVector<OpAsmParser::OperandType, 4> elementsOperands;
- Type resultType;
- if (parser.parseOperandList(elementsOperands) ||
- parser.parseOptionalAttrDict(result.attributes) ||
- parser.parseColonType(resultType))
- return failure();
-
- if (parser.resolveOperands(elementsOperands,
- resultType.cast<ShapedType>().getElementType(),
- result.operands))
- return failure();
-
- result.addTypes(resultType);
- return success();
-}
-
-static void print(OpAsmPrinter &p, TensorFromElementsOp op) {
- p << "tensor_from_elements " << op.elements();
- p.printOptionalAttrDict(op.getAttrs());
- p << " : " << op.getType();
-}
-
-static LogicalResult verify(TensorFromElementsOp op) {
- auto resultTensorType = op.result().getType().dyn_cast<RankedTensorType>();
- if (!resultTensorType)
- return op.emitOpError("expected result type to be a ranked tensor");
-
- int64_t elementsCount = static_cast<int64_t>(op.elements().size());
- if (resultTensorType.getRank() != 1 ||
- resultTensorType.getShape().front() != elementsCount)
- return op.emitOpError()
- << "expected result type to be a 1D tensor with " << elementsCount
- << (elementsCount == 1 ? " element" : " elements");
- return success();
-}
-
void TensorFromElementsOp::build(OpBuilder &builder, OperationState &result,
ValueRange elements) {
assert(!elements.empty() && "expected at least one element");
- result.addOperands(elements);
- result.addTypes(RankedTensorType::get({static_cast<int64_t>(elements.size())},
- *elements.getTypes().begin()));
+ Type resultTy = RankedTensorType::get({static_cast<int64_t>(elements.size())},
+ elements.front().getType());
+ build(builder, result, resultTy, elements);
}
namespace {
// -----
func @tensor_from_elements_wrong_result_type() {
- // expected-error@+2 {{expected result type to be a ranked tensor}}
+ // expected-error@+2 {{'result' must be 1D tensor of any type values, but got 'tensor<*xi32>'}}
%c0 = constant 0 : i32
%0 = tensor_from_elements %c0 : tensor<*xi32>
return
// -----
func @tensor_from_elements_wrong_elements_count() {
- // expected-error@+2 {{expected result type to be a 1D tensor with 1 element}}
+ // expected-error@+2 {{1 operands present, but expected 2}}
%c0 = constant 0 : index
%0 = tensor_from_elements %c0 : tensor<2xindex>
return