/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |* *| |* Op Declarations *| |* *| |* Automatically generated file, do not edit! *| |* From: LinalgRelayoutOps.td *| |* *| \*===----------------------------------------------------------------------===*/ namespace mlir::linalg { /// linalg.pack operation /// The "pack" operation converts a source tensor of rank `n` into a result /// tensor of rank `n + k` with a tiled and packed layout (maybe with padding) /// and optionally transposes the tiled source tensor dimensions. /// /// `inner_tiles` (mandatory) specifies `k` tile sizes. These tile sizes /// correspond to the least significant ("inner") result tensor dimension sizes, /// in the same order. Tile sizes can be static or dynamic. /// /// `inner_dims_pos` (mandatory) specifies `k` source tensor dimensions that are /// being tiled, where `0 <= k <= n`. /// - `inner_dims_pos[i]` specifies the source tensor dimension tiled by /// `inner_tiles[i]` where `0 <= i < k`. All the values in `inner_dims_pos` are /// within [0, n). /// - The tiled dimensions (of size `inner_tiles`) are added to the end of the /// result tensor in the order in which they appear, i.e. /// `shape(result)[rank(source) + i] = inner_tiles[i]` for `0 <= i < k`. /// - The following relationship for the tiled dimensions holds: /// `shape(result)[inner_dims_pos[i]] = shape(source)[inner_dims_pos[i]] / inner_tiles[i]`, /// where (⌈/⌉ indicates CeilDiv). /// /// /// Example: If `inner_tiles = [16, 32]`, the result tensor has a shape of /// `...x16x32`. If `inner_dims_pos = [0, 1]`, the 0th source dimension is tiled /// by 16 and the 1st source dimension is tiled by 32. Other source dimensions /// (if any) are not tiled. If `inner_dims_pos = [1, 0]`, the 1st dimension is /// tiled by 16 and the 0th dimension is tiled by 32. /// /// Example: /// ```mlir /// // NC to NCnc /// %0 = linalg.pack %source inner_dims_pos = [0, 1] inner_tiles = [8, 32] /// into %dest : tensor<128x256xf32> -> tensor<16x8 x 8x32 xf32> /// // \ / \ / /// // Outer Dims: 16x8 Inner Dims: 8x32 /// /// // CHW to CHWhw /// %0 = linalg.pack %source inner_dims_pos = [2, 1] inner_tiles = [4, 2] /// into %dest : tensor<3x20x24xf32> -> tensor<3x10x6 x 4x2 xf32> /// // \ / \ / /// // Outer Dims: 3x10x6 Inner Dims: 4x2 /// /// // HCW to HCWhw /// %0 = linalg.pack %source inner_dims_pos = [2, 0] inner_tiles = [4, 2] /// into %dest : tensor<18x3x32xf32> -> tensor<9x3x8 x 4x2 xf32> /// // \ / \ / /// // Outer Dims: 9x3x8 Inner Dims: 4x2 /// ``` /// /// `outer_dims_perm` (optional) specifies a permutation for the outer /// dimensions. If specified, it must have `n` elements. /// /// Example: /// ```mlir /// // CK to KCck /// %0 = linalg.pack %source outer_dims_perm = [1, 0] inner_dims_pos = [0, 1] /// inner_tiles = [8, 32] into %dest /// : tensor<128x256xf32> -> tensor<8x16 x 8x32 xf32> /// // \ / /// // compare with "NC to NCnc": outer dims are transposed /// ``` /// /// `padding_value` specifies a padding value at the boundary on non-perfectly /// divisible dimensions. Padding is optional: /// - If absent, it is assumed that for all inner tiles, /// `shape(source)[inner_dims_pos[i]] % inner_tiles[i] == 0`, i.e. all inner /// tiles divide perfectly the corresponding outer dimension in the result /// tensor. It is UB if the tile does not perfectly divide the dimension. /// - If present, it will pad along high dimensions (high-padding) to make the /// tile complete. Note that it is not allowed to have artificial padding that /// is not strictly required by linalg.pack (i.e., padding past what is needed /// to complete the last tile along each packed dimension). It is UB if extra /// padding is requested. /// It is not possible to verify the requirements statically with dynamic /// shapes, so they are treated as UB. /// /// Example: /// ```mlir /// %0 = linalg.pack %arg0 padding_value(%pad : f32) outer_dims_perm = [2, 1, 0] /// inner_dims_pos = [1] inner_tiles = [2] into %arg1 /// : tensor<200x127x256xf32> -> tensor<256x64x200x2xf32> /// // \ /// // padded and tiled dim /// // /// // Source dimension 1 is tiled. 64 does not divide 127 evenly, so 1 padded /// // element is added at the end. /// // /// // Note: Only tiled dimensions can be padded. /// ``` /// /// Invalid example that has artificial padding: /// ```mlir /// %0 = linalg.pack %src padding_value(%cst : f32) inner_dims_pos = [0] /// inner_tiles = [8] into %dest /// : tensor<9xf32> -> tensor<3x8xf32> /// // \ /// // expect tensor<2x8xf32> because CeilDiv(9, 8) = 2 /// ``` class PackOp; } // namespace mlir::linalg namespace mlir::linalg { /// linalg.unpack operation /// The "unpack" operation converts a source tensor of rank `n` with a tiled and /// packed layout to a result tensor of rank `n - k`. /// /// `inner_tiles` (mandatory) specifies `k` tile sizes. These tile sizes /// correspond to the least significant ("inner") source tensor dimension sizes. /// The behavior of this op is undefined if: /// - `inner_tiles` do not exactly match with the corresponding source tensor /// dimension sizes. /// - Or, `inner_tiles[i]` does not divide the size of dimension /// `inner_dims_pos[i]` (assuming that `outer_dims_perm` is not specified) /// evenly. /// /// `inner_dims_pos` (mandatory) specifies `k` result tensor (i.e. unpacked /// tensor) dimensions that were tiled with the `inner_tiles` to create the /// packed source tensor. The source tensor (i.e. packed tensor) dimensions can /// be unpacked given `inner_dims_pos` as follows. /// - For `0 <= i < k` the following relationship holds: /// `shape(result)[inner_dims_pos[i]] <= shape(source)[n-k+i] * shape(source)[inner_dims_pos[i]]`. /// - For `0 <= j < n-k` and `j` not in `inner_dims_pos` the following relationship holds: /// `shape(result)[j] = shape(source)[j]`. /// /// `outer_dims_perm` (optional) specifies a permutation for the outer /// dimensions. If specified, it must have `n - k` elements. If specified, this /// permutation is applied before combining any dimensions. /// /// Note, the unpack operation may drop any padding introduced by the pack /// operation and hence the following holds /// `NumElementsOf(source) >= NumElementsOf(result)`. /// /// Examples: /// /// ```mlir /// // NCnc to NC: /// %0 = linalg.unpack %source inner_dims_pos = [0, 1] inner_tiles = [8, 32] /// into %dest : tensor<16x8 x 8x32 xf32> -> tensor<128x256xf32> /// // \ / \ / /// // Outer Dims: 16x8 Inner Dims: 8x32 /// /// // CK to KCck: /// %0 = linalg.unpack %source outer_dims_perm = [1, 0] inner_dims_pos = [0, 1] /// inner_tiles = [8, 32] /// into %dest : tensor<8x16 x 8x32 xf32> -> tensor<128x256xf32> /// // \ / \ / /// // Outer Dims: 8x16 Inner Dims: 8x32 /// /// // CHW to CHWhw: /// %0 = linalg.unpack %source inner_dims_pos = [2, 1] inner_tiles = [4, 2] /// into %dest : tensor<3x10x6 x 4x2 xf32> -> tensor<3x20x24xf32> /// // \ / \ / /// // Outer Dims: 3x10x6 Inner Dims: 4x2 /// /// // HCW to HCWhw /// %0 = linalg.unpack %source inner_dims_pos = [2, 0] inner_tiles = [4, 2] /// into %dest : tensor<9x3x8 x 4x2 xf32> -> tensor<18x3x32xf32> /// // \ / \ / /// // Outer Dims: 9x3x8 Inner Dims: 4x2 /// ``` class UnPackOp; } // namespace mlir::linalg #ifdef GET_OP_CLASSES #undef GET_OP_CLASSES namespace mlir::linalg { //===----------------------------------------------------------------------===// // ::mlir::linalg::PackOp declarations //===----------------------------------------------------------------------===// namespace detail { class PackOpGenericAdaptorBase { public: struct Properties { using inner_dims_posTy = ::mlir::DenseI64ArrayAttr; inner_dims_posTy inner_dims_pos; auto getInnerDimsPos() const { auto &propStorage = this->inner_dims_pos; return ::llvm::cast<::mlir::DenseI64ArrayAttr>(propStorage); } void setInnerDimsPos(const ::mlir::DenseI64ArrayAttr &propValue) { this->inner_dims_pos = propValue; } using outer_dims_permTy = ::mlir::DenseI64ArrayAttr; outer_dims_permTy outer_dims_perm; auto getOuterDimsPerm() const { auto &propStorage = this->outer_dims_perm; return ::llvm::dyn_cast_or_null<::mlir::DenseI64ArrayAttr>(propStorage); } void setOuterDimsPerm(const ::mlir::DenseI64ArrayAttr &propValue) { this->outer_dims_perm = propValue; } using static_inner_tilesTy = ::mlir::DenseI64ArrayAttr; static_inner_tilesTy static_inner_tiles; auto getStaticInnerTiles() const { auto &propStorage = this->static_inner_tiles; return ::llvm::cast<::mlir::DenseI64ArrayAttr>(propStorage); } void setStaticInnerTiles(const ::mlir::DenseI64ArrayAttr &propValue) { this->static_inner_tiles = propValue; } using operandSegmentSizesTy = std::array; operandSegmentSizesTy operandSegmentSizes; ::llvm::ArrayRef getOperandSegmentSizes() const { auto &propStorage = this->operandSegmentSizes; return propStorage; } void setOperandSegmentSizes(::llvm::ArrayRef propValue) { auto &propStorage = this->operandSegmentSizes; ::llvm::copy(propValue, propStorage.begin()); } bool operator==(const Properties &rhs) const { return rhs.inner_dims_pos == this->inner_dims_pos && rhs.outer_dims_perm == this->outer_dims_perm && rhs.static_inner_tiles == this->static_inner_tiles && rhs.operandSegmentSizes == this->operandSegmentSizes && true; } bool operator!=(const Properties &rhs) const { return !(*this == rhs); } }; protected: ::mlir::DictionaryAttr odsAttrs; ::std::optional<::mlir::OperationName> odsOpName; Properties properties; ::mlir::RegionRange odsRegions; public: PackOpGenericAdaptorBase(::mlir::DictionaryAttr attrs, const Properties &properties, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), properties(properties), odsRegions(regions) { if (odsAttrs) odsOpName.emplace("linalg.pack", odsAttrs.getContext()); } PackOpGenericAdaptorBase(PackOp op); std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); const Properties &getProperties() { return properties; } ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } ::mlir::DenseI64ArrayAttr getOuterDimsPermAttr(); ::llvm::ArrayRef getOuterDimsPerm(); ::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() { auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos); return attr; } ::llvm::ArrayRef getInnerDimsPos(); ::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() { auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles); return attr; } ::llvm::ArrayRef getStaticInnerTiles(); }; } // namespace detail template class PackOpGenericAdaptor : public detail::PackOpGenericAdaptorBase { using ValueT = ::llvm::detail::ValueOfRange; using Base = detail::PackOpGenericAdaptorBase; static constexpr int odsIndex_source = 0; static constexpr int odsIndex_dest = 1; static constexpr int odsIndex_padding_value = 2; static constexpr int odsIndex_inner_tiles = 3; public: PackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, const Properties &properties, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} PackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::PropertyRef properties, ::mlir::RegionRange regions = {}) : PackOpGenericAdaptor(values, attrs, (properties ? *properties.as() : Properties{}), regions) {} PackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs) : PackOpGenericAdaptor(values, attrs, Properties{}, {}) {} PackOpGenericAdaptor(RangeT values, const PackOpGenericAdaptorBase &base) : Base(base), odsOperands(values) {} template >> PackOpGenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} std::pair getODSOperandIndexAndLength(unsigned index) { return Base::getODSOperandIndexAndLength(index, odsOperands.size()); } RangeT getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {std::next(odsOperands.begin(), valueRange.first), std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } ValueT getSource() { return (*getODSOperands(0).begin()); } ValueT getDest() { return (*getODSOperands(1).begin()); } ValueT getPaddingValue() { auto operands = getODSOperands(2); return operands.empty() ? ValueT{} : (*operands.begin()); } RangeT getInnerTiles() { return getODSOperands(3); } RangeT getOperands() { return odsOperands; } private: RangeT odsOperands; }; class PackOpAdaptor : public PackOpGenericAdaptor<::mlir::ValueRange> { public: using PackOpGenericAdaptor::PackOpGenericAdaptor; PackOpAdaptor(PackOp op); ::llvm::LogicalResult verify(::mlir::Location loc); }; class PackOp : public ::mlir::Op::Impl, ::mlir::OpTrait::AttrSizedOperandSegments, ::mlir::OpTrait::OpInvariants, ::mlir::BytecodeOpInterface::Trait, ::mlir::OpAsmOpInterface::Trait, ::mlir::DestinationStyleOpInterface::Trait, ::mlir::linalg::RelayoutOpInterface::Trait, ::mlir::ConditionallySpeculatable::Trait, ::mlir::MemoryEffectOpInterface::Trait, ::mlir::ReifyRankedShapedTypeOpInterface::Trait> { public: using Op::Op; using Op::print; using Adaptor = PackOpAdaptor; template using GenericAdaptor = PackOpGenericAdaptor; using FoldAdaptor = GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute>>; static constexpr int odsIndex_source = 0; static constexpr int odsIndex_dest = 1; static constexpr int odsIndex_padding_value = 2; static constexpr int odsIndex_inner_tiles = 3; using Properties = FoldAdaptor::Properties; using ::mlir::OpAsmOpInterface::Trait::getAsmBlockArgumentNames; using ::mlir::OpAsmOpInterface::Trait::getAsmBlockNames; using ::mlir::OpAsmOpInterface::Trait::getDefaultDialect; using ::mlir::ReifyRankedShapedTypeOpInterface::Trait::reifyShapeOfResult; using ::mlir::ReifyRankedShapedTypeOpInterface::Trait::reifyDimOfResult; static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { static ::llvm::StringRef attrNames[] = {::llvm::StringRef("inner_dims_pos"), ::llvm::StringRef("outer_dims_perm"), ::llvm::StringRef("static_inner_tiles"), ::llvm::StringRef("operandSegmentSizes")}; return ::llvm::ArrayRef(attrNames); } ::mlir::StringAttr getInnerDimsPosAttrName() { return getAttributeNameForIndex(0); } static ::mlir::StringAttr getInnerDimsPosAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 0); } ::mlir::StringAttr getOuterDimsPermAttrName() { return getAttributeNameForIndex(1); } static ::mlir::StringAttr getOuterDimsPermAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 1); } ::mlir::StringAttr getStaticInnerTilesAttrName() { return getAttributeNameForIndex(2); } static ::mlir::StringAttr getStaticInnerTilesAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 2); } ::mlir::StringAttr getOperandSegmentSizesAttrName() { return (*this)->getName().getAttributeNames().back(); } static ::mlir::StringAttr getOperandSegmentSizesAttrName(::mlir::OperationName name) { return name.getAttributeNames().back(); } static constexpr ::llvm::StringLiteral getOperationName() { return ::llvm::StringLiteral("linalg.pack"); } std::pair getODSOperandIndexAndLength(unsigned index); ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } ::mlir::TypedValue<::mlir::ShapedType> getSource() { return ::llvm::cast<::mlir::TypedValue<::mlir::ShapedType>>(*getODSOperands(0).begin()); } ::mlir::TypedValue<::mlir::ShapedType> getDest() { return ::llvm::cast<::mlir::TypedValue<::mlir::ShapedType>>(*getODSOperands(1).begin()); } ::mlir::TypedValue<::mlir::Type> getPaddingValue() { auto operands = getODSOperands(2); return operands.empty() ? ::mlir::TypedValue<::mlir::Type>{} : ::llvm::cast<::mlir::TypedValue<::mlir::Type>>(*operands.begin()); } ::mlir::Operation::operand_range getInnerTiles() { return getODSOperands(3); } ::mlir::OpOperand &getSourceMutable() { auto range = getODSOperandIndexAndLength(0); return getOperation()->getOpOperand(range.first); } ::mlir::OpOperand &getDestMutable() { auto range = getODSOperandIndexAndLength(1); return getOperation()->getOpOperand(range.first); } ::mlir::MutableOperandRange getPaddingValueMutable(); ::mlir::MutableOperandRange getInnerTilesMutable(); std::pair getODSResultIndexAndLength(unsigned index); ::mlir::Operation::result_range getODSResults(unsigned index) { auto valueRange = getODSResultIndexAndLength(index); return {std::next(getOperation()->result_begin(), valueRange.first), std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } ::mlir::TypedValue<::mlir::RankedTensorType> getResult() { auto results = getODSResults(0); return results.empty() ? ::mlir::TypedValue<::mlir::RankedTensorType>() : ::llvm::cast<::mlir::TypedValue<::mlir::RankedTensorType>>(*results.begin()); } static ::llvm::LogicalResult setPropertiesFromAttr(Properties &prop, ::mlir::Attribute attr, ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); static ::mlir::Attribute getPropertiesAsAttr(::mlir::MLIRContext *ctx, const Properties &prop); static llvm::hash_code computePropertiesHash(const Properties &prop); static std::optional getInherentAttr(::mlir::MLIRContext *ctx, const Properties &prop, llvm::StringRef name); static void setInherentAttr(Properties &prop, llvm::StringRef name, mlir::Attribute value); static void populateInherentAttrs(::mlir::MLIRContext *ctx, const Properties &prop, ::mlir::NamedAttrList &attrs); static ::llvm::LogicalResult verifyInherentAttrs(::mlir::OperationName opName, ::mlir::NamedAttrList &attrs, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); static ::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state); void writeProperties(::mlir::DialectBytecodeWriter &writer); ::mlir::DenseI64ArrayAttr getOuterDimsPermAttr() { return ::llvm::dyn_cast_or_null<::mlir::DenseI64ArrayAttr>(getProperties().outer_dims_perm); } ::llvm::ArrayRef getOuterDimsPerm(); ::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() { return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos); } ::llvm::ArrayRef getInnerDimsPos(); ::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() { return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles); } ::llvm::ArrayRef getStaticInnerTiles(); void setOuterDimsPermAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().outer_dims_perm = attr; } void setOuterDimsPerm(::std::optional<::llvm::ArrayRef> attrValue); void setInnerDimsPosAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().inner_dims_pos = attr; } void setInnerDimsPos(::llvm::ArrayRef attrValue); void setStaticInnerTilesAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().static_inner_tiles = attr; } void setStaticInnerTiles(::llvm::ArrayRef attrValue); ::mlir::Attribute removeOuterDimsPermAttr() { auto attr = getProperties().outer_dims_perm; getProperties().outer_dims_perm = {}; return attr; } static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, std::optional paddingValue = std::nullopt, ArrayRef outerDimsPerm = {}); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, std::optional paddingValue = std::nullopt, ArrayRef outerDimsPerm = {}); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, std::optional paddingValue = std::nullopt, ArrayRef outerDimsPerm = {}); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::Value padding_value, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static PackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); void print(::mlir::OpAsmPrinter &p); ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); ::llvm::LogicalResult verify(); static ::llvm::LogicalResult canonicalize(PackOp op, ::mlir::PatternRewriter &rewriter); static void getCanonicalizationPatterns(::mlir::RewritePatternSet &results, ::mlir::MLIRContext *context); ::llvm::LogicalResult fold(FoldAdaptor adaptor, ::llvm::SmallVectorImpl<::mlir::OpFoldResult> &results); void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn); void getEffects(::llvm::SmallVectorImpl<::mlir::SideEffects::EffectInstance<::mlir::MemoryEffects::Effect>> &effects); ::llvm::LogicalResult reifyResultShapes(::mlir::OpBuilder &builder, ::mlir::ReifiedRankedShapedTypeDims &reifiedReturnShapes); static ::llvm::LogicalResult setPropertiesFromParsedAttr(Properties &prop, ::mlir::Attribute attr, ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); private: ::mlir::StringAttr getAttributeNameForIndex(unsigned index) { return getAttributeNameForIndex((*this)->getName(), index); } static ::mlir::StringAttr getAttributeNameForIndex(::mlir::OperationName name, unsigned index) { assert(index < 3 && "invalid attribute index"); assert(name.getStringRef() == getOperationName() && "invalid operation name"); assert(name.isRegistered() && "Operation isn't registered, missing a " "dependent dialect loading?"); return name.getAttributeNames()[index]; } public: size_t getSourceRank() { return getSourceType().getRank(); }; size_t getDestRank() { return getDestType().getRank(); }; ShapedType getSourceType() { return ::llvm::cast(getSource().getType()); }; ShapedType getDestType() { return ::llvm::cast(getDest().getType()); }; MutableOperandRange getDpsInitsMutable() { return getDestMutable(); } /// Interface method for ConditionallySpeculatable. Speculation::Speculatability getSpeculatability(); /// Return a mapping from positions `inner_dims_pos` to their /// tile factors. DenseMap getDimAndTileMapping(); /// Return the tile sizes as OpFoldResult(s). Note, for Ops that simply /// define constants (e.g. `arith.constant`), this method returns /// Value/result of the Op (as opposed to the corresponding constant /// Attribute). E.g., for: /// %size = arith.constant 1 : i32 /// it will return %size, not 1. This is intended - replacing an SSA value /// with a constant attribute would require updating the corresponding dim /// from dynamic to static. SmallVector getMixedTiles(); /// Return the tile sizes as `int64_t`. If a tile size is dynamic /// a sentinel `kDynamic` is introduced at that position in /// the returned vector. SmallVector getStaticTiles(); /// Retrieve all outer dims for this Pack/UnPack Op, i.e. all the leading /// dims excluding the trailing dims corresponding to `innerTiles`. Note /// that this will include both tiled and non-tiled dimensions. The order /// of the output dimensions is consistent with the shape of the packed /// tensor. ArrayRef getAllOuterDims(); /// Similar to `getAllOuterDims`, but only retrieve the outer dims that /// have been tiled. Also, the order of the output dimensions is consistent /// with `inner_dims_pos` rather than the packed tensor. SmallVector getTiledOuterDims(); // Method to get the shape of the result as `SmallVector`. // This is a static method to allow getting the shape of the destination // expected while creating a `pack` op. static SmallVector getResultShape(OpBuilder &builder, Location loc, ArrayRef sourceDims, ArrayRef innerTileDims, ArrayRef innerDimsPos, ArrayRef outerDimsPerm = {}); // Method to get the `RankedTensorType` of the result based on the inner // tiles, position of the inner tiles (innerDimsPos) and interchange vector // of outer loops (outerDimsPerm). static RankedTensorType inferPackedTensorType(RankedTensorType sourceType, ArrayRef innerTileSizes, ArrayRef innerDimsPos, ArrayRef outerDimsPerm = {}); // Method to get the `MemRefType` of the result based on the inner // tiles, position of the inner tiles (innerDimsPos) and interchange vector // of outer loops (outerDimsPerm). static MemRefType inferPackedMemRefType(MemRefType sourceType, ArrayRef innerTileSizes, ArrayRef innerDimsPos, ArrayRef outerDimsPerm = {}); // Returns the shape of the packed type. It is a shared helper that helps // type inference methods in a way that ensures that they agree on which // dimensions are dynamic. static SmallVector inferPackedShape(ArrayRef inputShape, ArrayRef innerTileSizes, ArrayRef innerDimsPos, ArrayRef outerDimsPerm = {}); // Returns true if we have enough static information to catch undefined // behavior when the tile size does not divide perfectly the dimension of // the input tensor. Detecting UB requires that the input size and either // corresponding tile or output size are static. static bool requirePaddingValue(ArrayRef inputShape, ArrayRef innerDimsPos, ArrayRef outputShape, ArrayRef outerDimsPerm, ArrayRef innerTiles); // Same as above function but here dynamic dimensions are assumed // to require padding. static bool requirePaddingValueStrict(ArrayRef inputShape, ArrayRef innerDimsPos, ArrayRef outputShape, ArrayRef outerDimsPerm, ArrayRef innerTiles); static Value createDestinationTensor(OpBuilder &b, Location loc, Value source, ArrayRef innerTileSizes, ArrayRef innerDimsPos, ArrayRef outerDimsPerm); /// Build and return a new PackOp that is a clone of the current PackOp with /// (innerDimsPos, innerTiles) (resp. outerDimsPerm) are permuted by /// innerPermutation (resp. outerPermutation). /// A new `tensor.empty` of the proper shape is built in the process. /// Asserts that: /// - At least one of innerPermutation or outerPermutation is non-empty. /// - If not empty, innerPermutation is a valid permutation of size /// matching innerDimPos. /// - If not empty, outerPermutation is a valid permutation of size /// matching outerDimsPerm. PackOp createTransposedClone(OpBuilder &b, Location loc, ArrayRef innerPermutation, ArrayRef outerPermutation); /// Check if this PackOp is like a simple pad operation. /// In other words, this operation: /// 1. adds useless dimensions (dimension of size 1), /// 2. pads the other ones, and /// 3. doesn't shuffle the dimensions bool isLikePad(); }; } // namespace mlir::linalg MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::linalg::PackOp) MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::linalg::detail::PackOpGenericAdaptorBase::Properties) namespace mlir::linalg { //===----------------------------------------------------------------------===// // ::mlir::linalg::UnPackOp declarations //===----------------------------------------------------------------------===// namespace detail { class UnPackOpGenericAdaptorBase { public: struct Properties { using inner_dims_posTy = ::mlir::DenseI64ArrayAttr; inner_dims_posTy inner_dims_pos; auto getInnerDimsPos() const { auto &propStorage = this->inner_dims_pos; return ::llvm::cast<::mlir::DenseI64ArrayAttr>(propStorage); } void setInnerDimsPos(const ::mlir::DenseI64ArrayAttr &propValue) { this->inner_dims_pos = propValue; } using outer_dims_permTy = ::mlir::DenseI64ArrayAttr; outer_dims_permTy outer_dims_perm; auto getOuterDimsPerm() const { auto &propStorage = this->outer_dims_perm; return ::llvm::dyn_cast_or_null<::mlir::DenseI64ArrayAttr>(propStorage); } void setOuterDimsPerm(const ::mlir::DenseI64ArrayAttr &propValue) { this->outer_dims_perm = propValue; } using static_inner_tilesTy = ::mlir::DenseI64ArrayAttr; static_inner_tilesTy static_inner_tiles; auto getStaticInnerTiles() const { auto &propStorage = this->static_inner_tiles; return ::llvm::cast<::mlir::DenseI64ArrayAttr>(propStorage); } void setStaticInnerTiles(const ::mlir::DenseI64ArrayAttr &propValue) { this->static_inner_tiles = propValue; } bool operator==(const Properties &rhs) const { return rhs.inner_dims_pos == this->inner_dims_pos && rhs.outer_dims_perm == this->outer_dims_perm && rhs.static_inner_tiles == this->static_inner_tiles && true; } bool operator!=(const Properties &rhs) const { return !(*this == rhs); } }; protected: ::mlir::DictionaryAttr odsAttrs; ::std::optional<::mlir::OperationName> odsOpName; Properties properties; ::mlir::RegionRange odsRegions; public: UnPackOpGenericAdaptorBase(::mlir::DictionaryAttr attrs, const Properties &properties, ::mlir::RegionRange regions = {}) : odsAttrs(attrs), properties(properties), odsRegions(regions) { if (odsAttrs) odsOpName.emplace("linalg.unpack", odsAttrs.getContext()); } UnPackOpGenericAdaptorBase(UnPackOp op); std::pair getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize); const Properties &getProperties() { return properties; } ::mlir::DictionaryAttr getAttributes() { return odsAttrs; } ::mlir::DenseI64ArrayAttr getOuterDimsPermAttr(); ::llvm::ArrayRef getOuterDimsPerm(); ::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() { auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos); return attr; } ::llvm::ArrayRef getInnerDimsPos(); ::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() { auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles); return attr; } ::llvm::ArrayRef getStaticInnerTiles(); }; } // namespace detail template class UnPackOpGenericAdaptor : public detail::UnPackOpGenericAdaptorBase { using ValueT = ::llvm::detail::ValueOfRange; using Base = detail::UnPackOpGenericAdaptorBase; static constexpr int odsIndex_source = 0; static constexpr int odsIndex_dest = 1; static constexpr int odsIndex_inner_tiles = 2; public: UnPackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, const Properties &properties, ::mlir::RegionRange regions = {}) : Base(attrs, properties, regions), odsOperands(values) {} UnPackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs, ::mlir::PropertyRef properties, ::mlir::RegionRange regions = {}) : UnPackOpGenericAdaptor(values, attrs, (properties ? *properties.as() : Properties{}), regions) {} UnPackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = nullptr) : UnPackOpGenericAdaptor(values, attrs, Properties{}, {}) {} UnPackOpGenericAdaptor(RangeT values, const UnPackOpGenericAdaptorBase &base) : Base(base), odsOperands(values) {} template >> UnPackOpGenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {} std::pair getODSOperandIndexAndLength(unsigned index) { return Base::getODSOperandIndexAndLength(index, odsOperands.size()); } RangeT getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {std::next(odsOperands.begin(), valueRange.first), std::next(odsOperands.begin(), valueRange.first + valueRange.second)}; } ValueT getSource() { return (*getODSOperands(0).begin()); } ValueT getDest() { return (*getODSOperands(1).begin()); } RangeT getInnerTiles() { return getODSOperands(2); } RangeT getOperands() { return odsOperands; } private: RangeT odsOperands; }; class UnPackOpAdaptor : public UnPackOpGenericAdaptor<::mlir::ValueRange> { public: using UnPackOpGenericAdaptor::UnPackOpGenericAdaptor; UnPackOpAdaptor(UnPackOp op); ::llvm::LogicalResult verify(::mlir::Location loc); }; class UnPackOp : public ::mlir::Op::Impl, ::mlir::OpTrait::OpInvariants, ::mlir::BytecodeOpInterface::Trait, ::mlir::OpAsmOpInterface::Trait, ::mlir::DestinationStyleOpInterface::Trait, ::mlir::linalg::RelayoutOpInterface::Trait, ::mlir::ConditionallySpeculatable::Trait, ::mlir::MemoryEffectOpInterface::Trait, ::mlir::ReifyRankedShapedTypeOpInterface::Trait> { public: using Op::Op; using Op::print; using Adaptor = UnPackOpAdaptor; template using GenericAdaptor = UnPackOpGenericAdaptor; using FoldAdaptor = GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute>>; static constexpr int odsIndex_source = 0; static constexpr int odsIndex_dest = 1; static constexpr int odsIndex_inner_tiles = 2; using Properties = FoldAdaptor::Properties; using ::mlir::OpAsmOpInterface::Trait::getAsmBlockArgumentNames; using ::mlir::OpAsmOpInterface::Trait::getAsmBlockNames; using ::mlir::OpAsmOpInterface::Trait::getDefaultDialect; using ::mlir::ReifyRankedShapedTypeOpInterface::Trait::reifyShapeOfResult; using ::mlir::ReifyRankedShapedTypeOpInterface::Trait::reifyDimOfResult; static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { static ::llvm::StringRef attrNames[] = {::llvm::StringRef("inner_dims_pos"), ::llvm::StringRef("outer_dims_perm"), ::llvm::StringRef("static_inner_tiles")}; return ::llvm::ArrayRef(attrNames); } ::mlir::StringAttr getInnerDimsPosAttrName() { return getAttributeNameForIndex(0); } static ::mlir::StringAttr getInnerDimsPosAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 0); } ::mlir::StringAttr getOuterDimsPermAttrName() { return getAttributeNameForIndex(1); } static ::mlir::StringAttr getOuterDimsPermAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 1); } ::mlir::StringAttr getStaticInnerTilesAttrName() { return getAttributeNameForIndex(2); } static ::mlir::StringAttr getStaticInnerTilesAttrName(::mlir::OperationName name) { return getAttributeNameForIndex(name, 2); } static constexpr ::llvm::StringLiteral getOperationName() { return ::llvm::StringLiteral("linalg.unpack"); } std::pair getODSOperandIndexAndLength(unsigned index); ::mlir::Operation::operand_range getODSOperands(unsigned index) { auto valueRange = getODSOperandIndexAndLength(index); return {std::next(getOperation()->operand_begin(), valueRange.first), std::next(getOperation()->operand_begin(), valueRange.first + valueRange.second)}; } ::mlir::TypedValue<::mlir::ShapedType> getSource() { return ::llvm::cast<::mlir::TypedValue<::mlir::ShapedType>>(*getODSOperands(0).begin()); } ::mlir::TypedValue<::mlir::ShapedType> getDest() { return ::llvm::cast<::mlir::TypedValue<::mlir::ShapedType>>(*getODSOperands(1).begin()); } ::mlir::Operation::operand_range getInnerTiles() { return getODSOperands(2); } ::mlir::OpOperand &getSourceMutable() { auto range = getODSOperandIndexAndLength(0); return getOperation()->getOpOperand(range.first); } ::mlir::OpOperand &getDestMutable() { auto range = getODSOperandIndexAndLength(1); return getOperation()->getOpOperand(range.first); } ::mlir::MutableOperandRange getInnerTilesMutable(); std::pair getODSResultIndexAndLength(unsigned index); ::mlir::Operation::result_range getODSResults(unsigned index) { auto valueRange = getODSResultIndexAndLength(index); return {std::next(getOperation()->result_begin(), valueRange.first), std::next(getOperation()->result_begin(), valueRange.first + valueRange.second)}; } ::mlir::TypedValue<::mlir::RankedTensorType> getResult() { auto results = getODSResults(0); return results.empty() ? ::mlir::TypedValue<::mlir::RankedTensorType>() : ::llvm::cast<::mlir::TypedValue<::mlir::RankedTensorType>>(*results.begin()); } static ::llvm::LogicalResult setPropertiesFromAttr(Properties &prop, ::mlir::Attribute attr, ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); static ::mlir::Attribute getPropertiesAsAttr(::mlir::MLIRContext *ctx, const Properties &prop); static llvm::hash_code computePropertiesHash(const Properties &prop); static std::optional getInherentAttr(::mlir::MLIRContext *ctx, const Properties &prop, llvm::StringRef name); static void setInherentAttr(Properties &prop, llvm::StringRef name, mlir::Attribute value); static void populateInherentAttrs(::mlir::MLIRContext *ctx, const Properties &prop, ::mlir::NamedAttrList &attrs); static ::llvm::LogicalResult verifyInherentAttrs(::mlir::OperationName opName, ::mlir::NamedAttrList &attrs, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); static ::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state); void writeProperties(::mlir::DialectBytecodeWriter &writer); ::mlir::DenseI64ArrayAttr getOuterDimsPermAttr() { return ::llvm::dyn_cast_or_null<::mlir::DenseI64ArrayAttr>(getProperties().outer_dims_perm); } ::llvm::ArrayRef getOuterDimsPerm(); ::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() { return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos); } ::llvm::ArrayRef getInnerDimsPos(); ::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() { return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles); } ::llvm::ArrayRef getStaticInnerTiles(); void setOuterDimsPermAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().outer_dims_perm = attr; } void setOuterDimsPerm(::std::optional<::llvm::ArrayRef> attrValue); void setInnerDimsPosAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().inner_dims_pos = attr; } void setInnerDimsPos(::llvm::ArrayRef attrValue); void setStaticInnerTilesAttr(::mlir::DenseI64ArrayAttr attr) { getProperties().static_inner_tiles = attr; } void setStaticInnerTiles(::llvm::ArrayRef attrValue); ::mlir::Attribute removeOuterDimsPermAttr() { auto attr = getProperties().outer_dims_perm; getProperties().outer_dims_perm = {}; return attr; } static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, ArrayRef outerDimsPerm = {}); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, ArrayRef outerDimsPerm = {}); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, Value source, Value dest, ArrayRef innerDimsPos, ArrayRef innerTiles, ArrayRef outerDimsPerm = {}); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::mlir::DenseI64ArrayAttr outer_dims_perm, ::mlir::DenseI64ArrayAttr inner_dims_pos, ::mlir::ValueRange inner_tiles, ::mlir::DenseI64ArrayAttr static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef outer_dims_perm, ::llvm::ArrayRef inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef static_inner_tiles); static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); void print(::mlir::OpAsmPrinter &p); ::llvm::LogicalResult verifyInvariantsImpl(); ::llvm::LogicalResult verifyInvariants(); ::llvm::LogicalResult verify(); static ::llvm::LogicalResult canonicalize(UnPackOp op, ::mlir::PatternRewriter &rewriter); static void getCanonicalizationPatterns(::mlir::RewritePatternSet &results, ::mlir::MLIRContext *context); ::llvm::LogicalResult fold(FoldAdaptor adaptor, ::llvm::SmallVectorImpl<::mlir::OpFoldResult> &results); void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn); void getEffects(::llvm::SmallVectorImpl<::mlir::SideEffects::EffectInstance<::mlir::MemoryEffects::Effect>> &effects); ::llvm::LogicalResult reifyResultShapes(::mlir::OpBuilder &builder, ::mlir::ReifiedRankedShapedTypeDims &reifiedReturnShapes); static ::llvm::LogicalResult setPropertiesFromParsedAttr(Properties &prop, ::mlir::Attribute attr, ::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError); private: ::mlir::StringAttr getAttributeNameForIndex(unsigned index) { return getAttributeNameForIndex((*this)->getName(), index); } static ::mlir::StringAttr getAttributeNameForIndex(::mlir::OperationName name, unsigned index) { assert(index < 3 && "invalid attribute index"); assert(name.getStringRef() == getOperationName() && "invalid operation name"); assert(name.isRegistered() && "Operation isn't registered, missing a " "dependent dialect loading?"); return name.getAttributeNames()[index]; } public: size_t getSourceRank() { return getSourceType().getRank(); }; size_t getDestRank() { return getDestType().getRank(); }; ShapedType getSourceType() { return ::llvm::cast(getSource().getType()); }; ShapedType getDestType() { return ::llvm::cast(getDest().getType()); }; MutableOperandRange getDpsInitsMutable() { return getDestMutable(); } /// Interface method for ConditionallySpeculatable. Speculation::Speculatability getSpeculatability(); /// Return a mapping from positions `inner_dims_pos` to their /// tile factors. DenseMap getDimAndTileMapping(); /// Return the tile sizes as OpFoldResult(s). Note, for Ops that simply /// define constants (e.g. `arith.constant`), this method returns /// Value/result of the Op (as opposed to the corresponding constant /// Attribute). E.g., for: /// %size = arith.constant 1 : i32 /// it will return %size, not 1. This is intended - replacing an SSA value /// with a constant attribute would require updating the corresponding dim /// from dynamic to static. SmallVector getMixedTiles(); /// Return the tile sizes as `int64_t`. If a tile size is dynamic /// a sentinel `kDynamic` is introduced at that position in /// the returned vector. SmallVector getStaticTiles(); /// Retrieve all outer dims for this Pack/UnPack Op, i.e. all the leading /// dims excluding the trailing dims corresponding to `innerTiles`. Note /// that this will include both tiled and non-tiled dimensions. The order /// of the output dimensions is consistent with the shape of the packed /// tensor. ArrayRef getAllOuterDims(); /// Similar to `getAllOuterDims`, but only retrieve the outer dims that /// have been tiled. Also, the order of the output dimensions is consistent /// with `inner_dims_pos` rather than the packed tensor. SmallVector getTiledOuterDims(); static Value createDestinationTensor(OpBuilder &b, Location loc, Value source, ArrayRef innerTileSizes, ArrayRef innerDimsPos, ArrayRef outerDimsPerm); /// Build and return a new UnPackOp that is a clone of the current UnPackOp /// with (innerDimsPos, innerTiles) (resp. outerDimsPerm) are permuted by /// innerPermutation (resp. outerPermutation). /// Asserts that: /// - At least one of innerPermutation or outerPermutation is non-empty. /// - If not empty, innerPermutation is a valid permutation of size /// matching innerDimPos. /// - If not empty, outerPermutation is a valid permutation of size /// matching outerDimsPerm. UnPackOp createTransposedClone(OpBuilder &b, Location loc, Value transposedSource, ArrayRef innerPermutation, ArrayRef outerPermutation); /// Returns true if it is statically known that the `sliceOp` result shape /// is compatible with the `unPackOp`. I.e., it does not drop any tile. bool canFoldSliceOp(tensor::ExtractSliceOp sliceOp); /// Check if this UnPackOp is like a simple unpad operation. /// In other words, this operation: /// 1. drops useless dimensions (dimension of size 1), and /// 2. reduces dimensions in place (i.e., no transpose.) bool isLikeUnPad(); }; } // namespace mlir::linalg MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::linalg::UnPackOp) MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::linalg::detail::UnPackOpGenericAdaptorBase::Properties) #endif // GET_OP_CLASSES