1072 lines
57 KiB
C++
1072 lines
57 KiB
C++
/*===- 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<int32_t, 4>;
|
|
operandSegmentSizesTy operandSegmentSizes;
|
|
::llvm::ArrayRef<int32_t> getOperandSegmentSizes() const {
|
|
auto &propStorage = this->operandSegmentSizes;
|
|
return propStorage;
|
|
}
|
|
void setOperandSegmentSizes(::llvm::ArrayRef<int32_t> 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<unsigned, unsigned> getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize);
|
|
const Properties &getProperties() {
|
|
return properties;
|
|
}
|
|
|
|
::mlir::DictionaryAttr getAttributes() {
|
|
return odsAttrs;
|
|
}
|
|
|
|
::mlir::DenseI64ArrayAttr getOuterDimsPermAttr();
|
|
::llvm::ArrayRef<int64_t> getOuterDimsPerm();
|
|
::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() {
|
|
auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos);
|
|
return attr;
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getInnerDimsPos();
|
|
::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() {
|
|
auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles);
|
|
return attr;
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getStaticInnerTiles();
|
|
};
|
|
|
|
} // namespace detail
|
|
template <typename RangeT>
|
|
class PackOpGenericAdaptor : public detail::PackOpGenericAdaptorBase {
|
|
using ValueT = ::llvm::detail::ValueOfRange<RangeT>;
|
|
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 *>() : Properties{}), regions) {}
|
|
|
|
PackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs) : PackOpGenericAdaptor(values, attrs, Properties{}, {}) {}
|
|
|
|
PackOpGenericAdaptor(RangeT values, const PackOpGenericAdaptorBase &base) : Base(base), odsOperands(values) {}
|
|
|
|
template <typename LateInst = PackOp, typename = std::enable_if_t<std::is_same_v<LateInst, PackOp>>>
|
|
PackOpGenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {}
|
|
|
|
std::pair<unsigned, unsigned> 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<PackOp, ::mlir::OpTrait::ZeroRegions, ::mlir::OpTrait::VariadicResults, ::mlir::OpTrait::ZeroSuccessors, ::mlir::OpTrait::AtLeastNOperands<2>::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 <typename RangeT>
|
|
using GenericAdaptor = PackOpGenericAdaptor<RangeT>;
|
|
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<PackOp>::getAsmBlockArgumentNames;
|
|
using ::mlir::OpAsmOpInterface::Trait<PackOp>::getAsmBlockNames;
|
|
using ::mlir::OpAsmOpInterface::Trait<PackOp>::getDefaultDialect;
|
|
using ::mlir::ReifyRankedShapedTypeOpInterface::Trait<PackOp>::reifyShapeOfResult;
|
|
using ::mlir::ReifyRankedShapedTypeOpInterface::Trait<PackOp>::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<unsigned, unsigned> 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<unsigned, unsigned> 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<mlir::Attribute> 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<int64_t> getOuterDimsPerm();
|
|
::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() {
|
|
return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos);
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getInnerDimsPos();
|
|
::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() {
|
|
return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles);
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getStaticInnerTiles();
|
|
void setOuterDimsPermAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().outer_dims_perm = attr;
|
|
}
|
|
|
|
void setOuterDimsPerm(::std::optional<::llvm::ArrayRef<int64_t>> attrValue);
|
|
void setInnerDimsPosAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().inner_dims_pos = attr;
|
|
}
|
|
|
|
void setInnerDimsPos(::llvm::ArrayRef<int64_t> attrValue);
|
|
void setStaticInnerTilesAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().static_inner_tiles = attr;
|
|
}
|
|
|
|
void setStaticInnerTiles(::llvm::ArrayRef<int64_t> 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<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, std::optional<Value> paddingValue = std::nullopt, ArrayRef<int64_t> outerDimsPerm = {});
|
|
static PackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, Value source, Value dest, ArrayRef<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, std::optional<Value> paddingValue = std::nullopt, ArrayRef<int64_t> outerDimsPerm = {});
|
|
static PackOp create(::mlir::ImplicitLocOpBuilder &builder, Value source, Value dest, ArrayRef<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, std::optional<Value> paddingValue = std::nullopt, ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<ShapedType>(getSource().getType()); };
|
|
ShapedType getDestType() {
|
|
return ::llvm::cast<ShapedType>(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<int64_t, OpFoldResult> 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<OpFoldResult> 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<int64_t> 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<int64_t> 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<int64_t> getTiledOuterDims();
|
|
|
|
// Method to get the shape of the result as `SmallVector<OpFoldResult>`.
|
|
// This is a static method to allow getting the shape of the destination
|
|
// expected while creating a `pack` op.
|
|
static SmallVector<OpFoldResult> getResultShape(OpBuilder &builder,
|
|
Location loc, ArrayRef<OpFoldResult> sourceDims,
|
|
ArrayRef<OpFoldResult> innerTileDims, ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> 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<int64_t> innerTileSizes, ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> 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<int64_t> innerTileSizes, ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> 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<int64_t> inferPackedShape(ArrayRef<int64_t> inputShape,
|
|
ArrayRef<int64_t> innerTileSizes, ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> 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<int64_t> inputShape,
|
|
ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> outputShape,
|
|
ArrayRef<int64_t> outerDimsPerm,
|
|
ArrayRef<OpFoldResult> innerTiles);
|
|
|
|
// Same as above function but here dynamic dimensions are assumed
|
|
// to require padding.
|
|
static bool requirePaddingValueStrict(ArrayRef<int64_t> inputShape,
|
|
ArrayRef<int64_t> innerDimsPos,
|
|
ArrayRef<int64_t> outputShape,
|
|
ArrayRef<int64_t> outerDimsPerm,
|
|
ArrayRef<OpFoldResult> innerTiles);
|
|
|
|
static Value createDestinationTensor(OpBuilder &b, Location loc,
|
|
Value source, ArrayRef<OpFoldResult> innerTileSizes,
|
|
ArrayRef<int64_t> innerDimsPos, ArrayRef<int64_t> 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<int64_t> innerPermutation,
|
|
ArrayRef<int64_t> 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<unsigned, unsigned> getODSOperandIndexAndLength(unsigned index, unsigned odsOperandsSize);
|
|
const Properties &getProperties() {
|
|
return properties;
|
|
}
|
|
|
|
::mlir::DictionaryAttr getAttributes() {
|
|
return odsAttrs;
|
|
}
|
|
|
|
::mlir::DenseI64ArrayAttr getOuterDimsPermAttr();
|
|
::llvm::ArrayRef<int64_t> getOuterDimsPerm();
|
|
::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() {
|
|
auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos);
|
|
return attr;
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getInnerDimsPos();
|
|
::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() {
|
|
auto attr = ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles);
|
|
return attr;
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getStaticInnerTiles();
|
|
};
|
|
|
|
} // namespace detail
|
|
template <typename RangeT>
|
|
class UnPackOpGenericAdaptor : public detail::UnPackOpGenericAdaptorBase {
|
|
using ValueT = ::llvm::detail::ValueOfRange<RangeT>;
|
|
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 *>() : Properties{}), regions) {}
|
|
|
|
UnPackOpGenericAdaptor(RangeT values, ::mlir::DictionaryAttr attrs = nullptr) : UnPackOpGenericAdaptor(values, attrs, Properties{}, {}) {}
|
|
|
|
UnPackOpGenericAdaptor(RangeT values, const UnPackOpGenericAdaptorBase &base) : Base(base), odsOperands(values) {}
|
|
|
|
template <typename LateInst = UnPackOp, typename = std::enable_if_t<std::is_same_v<LateInst, UnPackOp>>>
|
|
UnPackOpGenericAdaptor(RangeT values, LateInst op) : Base(op), odsOperands(values) {}
|
|
|
|
std::pair<unsigned, unsigned> 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<UnPackOp, ::mlir::OpTrait::ZeroRegions, ::mlir::OpTrait::VariadicResults, ::mlir::OpTrait::ZeroSuccessors, ::mlir::OpTrait::AtLeastNOperands<2>::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 <typename RangeT>
|
|
using GenericAdaptor = UnPackOpGenericAdaptor<RangeT>;
|
|
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<UnPackOp>::getAsmBlockArgumentNames;
|
|
using ::mlir::OpAsmOpInterface::Trait<UnPackOp>::getAsmBlockNames;
|
|
using ::mlir::OpAsmOpInterface::Trait<UnPackOp>::getDefaultDialect;
|
|
using ::mlir::ReifyRankedShapedTypeOpInterface::Trait<UnPackOp>::reifyShapeOfResult;
|
|
using ::mlir::ReifyRankedShapedTypeOpInterface::Trait<UnPackOp>::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<unsigned, unsigned> 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<unsigned, unsigned> 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<mlir::Attribute> 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<int64_t> getOuterDimsPerm();
|
|
::mlir::DenseI64ArrayAttr getInnerDimsPosAttr() {
|
|
return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().inner_dims_pos);
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getInnerDimsPos();
|
|
::mlir::DenseI64ArrayAttr getStaticInnerTilesAttr() {
|
|
return ::llvm::cast<::mlir::DenseI64ArrayAttr>(getProperties().static_inner_tiles);
|
|
}
|
|
|
|
::llvm::ArrayRef<int64_t> getStaticInnerTiles();
|
|
void setOuterDimsPermAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().outer_dims_perm = attr;
|
|
}
|
|
|
|
void setOuterDimsPerm(::std::optional<::llvm::ArrayRef<int64_t>> attrValue);
|
|
void setInnerDimsPosAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().inner_dims_pos = attr;
|
|
}
|
|
|
|
void setInnerDimsPos(::llvm::ArrayRef<int64_t> attrValue);
|
|
void setStaticInnerTilesAttr(::mlir::DenseI64ArrayAttr attr) {
|
|
getProperties().static_inner_tiles = attr;
|
|
}
|
|
|
|
void setStaticInnerTiles(::llvm::ArrayRef<int64_t> 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<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, ArrayRef<int64_t> outerDimsPerm = {});
|
|
static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, Value source, Value dest, ArrayRef<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, ArrayRef<int64_t> outerDimsPerm = {});
|
|
static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, Value source, Value dest, ArrayRef<int64_t> innerDimsPos, ArrayRef<OpFoldResult> innerTiles, ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> static_inner_tiles);
|
|
static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type result, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> static_inner_tiles);
|
|
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> static_inner_tiles);
|
|
static UnPackOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> static_inner_tiles);
|
|
static UnPackOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value source, ::mlir::Value dest, /*optional*/::llvm::ArrayRef<int64_t> outer_dims_perm, ::llvm::ArrayRef<int64_t> inner_dims_pos, ::mlir::ValueRange inner_tiles, ::llvm::ArrayRef<int64_t> 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<ShapedType>(getSource().getType()); };
|
|
ShapedType getDestType() {
|
|
return ::llvm::cast<ShapedType>(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<int64_t, OpFoldResult> 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<OpFoldResult> 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<int64_t> 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<int64_t> 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<int64_t> getTiledOuterDims();
|
|
|
|
static Value createDestinationTensor(OpBuilder &b, Location loc,
|
|
Value source, ArrayRef<OpFoldResult> innerTileSizes,
|
|
ArrayRef<int64_t> innerDimsPos, ArrayRef<int64_t> 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<int64_t> innerPermutation,
|
|
ArrayRef<int64_t> 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
|
|
|