/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Interface Definitions                                                      *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/


/// Method to generate a tensor initalized with the identity value of the
/// reduction operator. The tensor shape is equal to operation result
/// shape with new dimension for each non zero tile size.
::mlir::FailureOr<SmallVector<Value>> mlir::PartialReductionOpInterface::generateInitialTensorForPartialReduction(::mlir::OpBuilder & b, Location loc, ::mlir::ArrayRef<::mlir::OpFoldResult> tileSizes, const ::mlir::SetVector<unsigned> & reductionDims) {
      return getImpl()->generateInitialTensorForPartialReduction(getImpl(), getOperation(), b, loc, tileSizes, reductionDims);
  }

/// Method to generate a tiled version of the operation where the tiled
/// reduction dimension are converted to parallel dimensions with a size
/// less or equal to the tile size. This is meant to be used with
/// `mergeReductions` method which will combine the partial reductions.
/// The method receives the `offset` and `sizes` for all iteration space
/// dimensions, as well as the iteration number of the tiled reduction
/// dimensions (which is the induction variable of the inter-tile loop
/// for the reduction dimension divided by the step of the loop) in
/// `splitReductionIvs`.
::mlir::FailureOr<TilingResult> mlir::PartialReductionOpInterface::tileToPartialReduction(::mlir::OpBuilder & b, Location  loc, ::mlir::ReductionTilingStrategy tilingStrategy, ValueRange init, ::mlir::ArrayRef<::mlir::OpFoldResult> offsets, ::mlir::ArrayRef<::mlir::OpFoldResult> sizes, const ::llvm::SetVector<unsigned> & reductionDims, ::mlir::ArrayRef<::mlir::OpFoldResult> splitReductionIvs) {
      return getImpl()->tileToPartialReduction(getImpl(), getOperation(), b, loc, tilingStrategy, init, offsets, sizes, reductionDims, splitReductionIvs);
  }

/// Method to merge partial reductions for an operation that has been
/// tiled along the reduction dimensions. This will only apply the
/// reduction the operation.
::mlir::FailureOr<MergeResult> mlir::PartialReductionOpInterface::mergeReductions(::mlir::OpBuilder & b, Location  loc, ValueRange partialReduce, const ::mlir::SetVector<unsigned> & reductionDims) {
      return getImpl()->mergeReductions(getImpl(), getOperation(), b, loc, partialReduce, reductionDims);
  }

/// Method to return the position of the partial result tile computed by
/// the tiled operation. This is same as
/// TilingInterface:::getResultTilePosition, but determines the result
/// tile position for partial reduction.
/// The method receives the `offset` and `sizes` for all iteration space
/// dimensions, as well as the iteration number of the tiled reduction
/// dimensions (which is the induction variable of the inter-tile loop
/// for the reduction dimension divided by the tile size specified) in
/// `splitReductionIvs`.
::llvm::LogicalResult mlir::PartialReductionOpInterface::getPartialResultTilePosition(::mlir::OpBuilder & b, unsigned resultNumber, ReductionTilingStrategy tilingStrategy, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes, const ::mlir::SetVector<unsigned> & reductionDims, ::mlir::ArrayRef<::mlir::OpFoldResult> splitReductionIvs, ::mlir::SmallVector<::mlir::OpFoldResult> & resultOffsets, ::mlir::SmallVector<::mlir::OpFoldResult> & resultSizes) {
      return getImpl()->getPartialResultTilePosition(getImpl(), getOperation(), b, resultNumber, tilingStrategy, offsets, sizes, reductionDims, splitReductionIvs, resultOffsets, resultSizes);
  }

/// Returns a list of iterator types that describe the number of loops.
::mlir::SmallVector<::mlir::utils::IteratorType> mlir::PartialReductionOpInterface::getLoopIteratorTypes() {
      return getImpl()->implTilingInterface->getLoopIteratorTypes(getImpl()->implTilingInterface, getOperation());
  }

/// Returns a list of ranges that describe the loop bounds and
/// step for the loops of the operation.
::mlir::SmallVector<::mlir::Range> mlir::PartialReductionOpInterface::getIterationDomain(::mlir::OpBuilder & b) {
      return getImpl()->implTilingInterface->getIterationDomain(getImpl()->implTilingInterface, getOperation(), b);
  }

/// Method to generate the tiled implementation of an operation.
/// 
/// Given a tile of the iteration space (as returned by
/// `getIterationDomain`), generate in-place the code that represents
/// the computation corresponding to that tile of the iteration space.
/// It is the responsibility of the implementation of this method in
/// the operation to generate the slices of the operands needed for the
/// tiled implementation.
/// - `offsets` provides the offset of the tile in the coordinate system
///   of the original iteration space, i.e., if an iteration space
///   dimension had non-zero offset, it will be included in the offset
///   provided here (as opposed to zero-based offset "relative" to the
///   iteration space).
/// - `sizes` provides the size of the tile.
/// 
/// The returned `TilingResult` must return for each result of the
/// untiled operation, a `Value` that is the result of the tiled
/// operation.
::mlir::FailureOr<::mlir::TilingResult> mlir::PartialReductionOpInterface::getTiledImplementation(::mlir::OpBuilder & b, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes) {
      return getImpl()->implTilingInterface->getTiledImplementation(getImpl()->implTilingInterface, getOperation(), b, offsets, sizes);
  }

/// Method to return the position of the result tile computed by the
/// tiled operation.
/// 
/// For operations that return a value (typically a value of type
/// `RankedTensorType`), the generated tiled computation has to also
/// recompute a replacement for the results of the original operation.
/// The tiled implementation of the operation returns a tile of the
/// result(s). This methods returns information about what part of the
/// result tensor is computed by the tiled implementation. The manner in
/// which these tiles get put together to get the final result is upto
/// the surrounding loop construct. If an operation has no results, (for
/// example an operation that operates only on memrefs), then this method
/// need not be implemented by the operation.
/// - `resultNumber` is the result number of the original operation
///   being processed.
/// - `offsets` provides the offset of the tile in the coordinate system
///   of the original iteration space, i.e., if an iteration space
///   dimension had non-zero offset, it will be included in the offset
///   provided here (as opposed to zero-based offset "relative" to the
///   iteration space).
/// - `sizes` provides the size of the tile.
/// - `resultOffsets` is the offsets of the tile of the result generated
///   by the tiled implementation (returned by value).
/// - `resultSizes` is the size of the tile of the result generated
///   by the tiled implementation (returned by value).
/// 
/// Note: It is undefined behaviour if there is overlap between the
/// tiles of the result generated by the tiled implementation.
::llvm::LogicalResult mlir::PartialReductionOpInterface::getResultTilePosition(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes, ::mlir::SmallVector<::mlir::OpFoldResult> & resultOffsets, ::mlir::SmallVector<::mlir::OpFoldResult> & resultSizes) {
      return getImpl()->implTilingInterface->getResultTilePosition(getImpl()->implTilingInterface, getOperation(), b, resultNumber, offsets, sizes, resultOffsets, resultSizes);
  }

/// Method to generate the code that produces a tile of the result.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) consumer. Typically, for two operations with
/// producer -> consumer relation ship, to compute a tile of the
/// consumer a `slice` of the producer is needed. This method allows
/// computing that slice of the producer in-place, thereby "fusing"
/// the operations at tile-granularity. This method is different from
/// `getTiledImplementation`, which produces a tiled implementation
/// for a tile of the iteration space. This method produces a tiled
/// implementation based on the tile of producer required.
/// - `resultNumber` is the result of the producer used by the consumer.
/// - `offsets` is the offset of the slice of the producer result used by
///   the tiled implementation of the consumer.
/// - `sizes` is the size of the slice of the producer result used by the
///   consumer.
/// If fusion of the producer with the consumer is not legal for the
/// operation/result, this method should return failure.
/// 
/// Note: This method only deals with the mechanism of implementing the
/// fusion. In general the fusion might result in recomputation (based on
/// the way the result is produced by the producer and the access pattern
/// used in the consumer to access). This is upto the caller to handle
/// appropriately.
::mlir::FailureOr<::mlir::TilingResult> mlir::PartialReductionOpInterface::generateResultTileValue(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult> offsets, ::mlir::ArrayRef<::mlir::OpFoldResult> sizes) {
      return getImpl()->implTilingInterface->generateResultTileValue(getImpl()->implTilingInterface, getOperation(), b, resultNumber, offsets, sizes);
  }

/// Method to generate the tiled implementation of an operation that uses
/// the exact tiles of the given operands.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) producer. Given tiles of the producer, this
/// method generates the tile of the consumer that uses exactly these
/// produced tiles. In some sense it is the "reverse" of
/// `generateResultTileValue`.
/// - `operandNumbers` is the list of operands whose tiles are "producers".
/// - `allOffsets` is the offset of the slice of the producer used by the
///   tiled implementation of the consumer.
/// - `allSizes` is the size of the slice of the producer used by the
///   consumer.
/// If it is illegal to fuse with a producer along the given operand tiles for
/// an operation, the implementation should return a failure.
::mlir::FailureOr<::mlir::TilingResult> mlir::PartialReductionOpInterface::getTiledImplementationFromOperandTiles(::mlir::OpBuilder & b, ::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allSizes) {
      return getImpl()->implTilingInterface->getTiledImplementationFromOperandTiles(getImpl()->implTilingInterface, getOperation(), b, operandNumbers, allOffsets, allSizes);
  }

/// Method to return the tile of the iteration domain that uses a given
/// tile of the operand.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) producer. Given tiles of operands,
/// returns the tile of the iteration space that uses these tiles.
/// - `operandNumbers` is the list of operands whose tiles are "produced"
///   by the producer(s).
/// - `allOffsets` is the offset of the slice of the producers used by
///   the tiled implementation of the consumer.
/// - `allSizes` is the size of the slice of the producers used by the
///   consumer.
/// If it is illegal to fuse with the producer slices for an operation,
/// or if this mapping cannot be computed, the implementation should
/// return a failure.
/// 
/// Note that unlike the "tile consumer and fuse producer" case, the
/// "tile producer and fuse consumer" requires an additional method to get
/// the iteration tile space that encompasses all uses of the given operand
/// tile. The reason for this is, consider
/// ```mlir
/// %1 = scf.for...  {
///   %2 = <tiled_producer_op>
///   %3 = tensor.insert_slice %2 into ...
///   scf.yield %3
/// }
/// %4 = <consumer_op>)(... %1... )
/// ... <some_op>(... %4 ...)
/// ```
/// 
/// when fused this becomes
/// ```
/// %1 = scf.for...  {
///   %2 = <tiled_producer_op>
///   %3 = <tiled_consumer_op>(... %2...)
///   %4 = tensor.insert_slice %3 into ...
///   scf.yield %4
/// }
/// ... <some_op>(... %1 ...)
/// ```
/// 
/// i.e, when fusing the consumer, the replacement for the result of the
/// consumer needs to be returned to replace the uses of the consumer.
/// For the tile+fuse algorithm to do this it needs information about
/// which tile of the iteration space encompasses all uses of the tile
/// produced and use that to compute what are the results produced. Note
/// that this iteration space might be the entire iteration space of the
/// operation, or multiple operand tiles might map to intersecting
/// iteration spaces. It is upto the caller to make sure that it is still
/// fusable with producer in this scenario, or it must return a failure.
/// 
/// Note that this method is only used as a way to implement the
/// transformation. It does not provide guarantees on whether such a
/// transformation is profitable.
/// 
/// For most cases `getTiledImplementationFromOperandTiles` could be a
/// implemented using `getIterationDomainTileFromOperandTiles` +
/// `getTiledImplementation` methods.
::llvm::LogicalResult mlir::PartialReductionOpInterface::getIterationDomainTileFromOperandTiles(::mlir::OpBuilder & b, ::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>>  allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>>  allSizes, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainOffsets, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainSizes) {
      return getImpl()->implTilingInterface->getIterationDomainTileFromOperandTiles(getImpl()->implTilingInterface, getOperation(), b, operandNumbers, allOffsets, allSizes, iterDomainOffsets, iterDomainSizes);
  }

/// Method to return the tile of the iteration domain based
/// on the given tile of the certain result.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) consumer. Given a tile of an result,
/// returns the tile of the iteration space that uses this tile.
/// - `resultNumber` is the result of the producer used by the consumer.
/// - `offsets` is the offset of the slice of the producer result used by
///   the tiled implementation of the consumer.
/// - `sizes` is the size of the slice of the producer result used by the
///   consumer.
/// If fusion of the producer with the consumer is not legal for the
/// result, or if this mapping cannot be computed, the implementation
/// should return a failure.
/// 
/// For most cases `generateResultTileValue` could be a implemented using
/// `getIterationDomainTileFromResultTile` + `getTiledImplementation`
/// methods.
::llvm::LogicalResult mlir::PartialReductionOpInterface::getIterationDomainTileFromResultTile(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainOffsets, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainSizes) {
      return getImpl()->implTilingInterface->getIterationDomainTileFromResultTile(getImpl()->implTilingInterface, getOperation(), b, resultNumber, offsets, sizes, iterDomainOffsets, iterDomainSizes);
  }

/// Generates the scalar implementation of the operation.
/// 
/// Given the list `ivs` that represent points in the iteration space
/// (as specified by `getIterationDomain()`) returns the scalar operations
/// that represent the computation at that point in the iteration space.
/// This method is typically used as the "exit path", i.e. once all
/// transformations are done, this method can be used to lower to scalar
/// code that can then be lowered to LLVM or SPIR-V dialects.
::llvm::LogicalResult mlir::PartialReductionOpInterface::generateScalarImplementation(::mlir::OpBuilder & b, ::mlir::Location  loc, ::mlir::ValueRange  ivs) {
      return getImpl()->implTilingInterface->generateScalarImplementation(getImpl()->implTilingInterface, getOperation(), b, loc, ivs);
  }

/// Indicates whether it is possible to fuse this operation with the given
/// result slice. This method is not allowed to generate any IR.
bool mlir::PartialReductionOpInterface::isOpFusableWithConsumerSlice(unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult> offsets, ::mlir::ArrayRef<::mlir::OpFoldResult> sizes) {
      return getImpl()->implTilingInterface->isOpFusableWithConsumerSlice(getImpl()->implTilingInterface, getOperation(), resultNumber, offsets, sizes);
  }

/// Indicates whether it is possible to fuse this operation with the given
/// list of operand slices. This method is not allowed to generate any IR.
bool mlir::PartialReductionOpInterface::isOpFusableWithProducerSlices(::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allSizes) {
      return getImpl()->implTilingInterface->isOpFusableWithProducerSlices(getImpl()->implTilingInterface, getOperation(), operandNumbers, allOffsets, allSizes);
  }

/// Returns a list of iterator types that describe the number of loops.
::mlir::SmallVector<::mlir::utils::IteratorType> mlir::TilingInterface::getLoopIteratorTypes() {
      return getImpl()->getLoopIteratorTypes(getImpl(), getOperation());
  }

/// Returns a list of ranges that describe the loop bounds and
/// step for the loops of the operation.
::mlir::SmallVector<::mlir::Range> mlir::TilingInterface::getIterationDomain(::mlir::OpBuilder & b) {
      return getImpl()->getIterationDomain(getImpl(), getOperation(), b);
  }

/// Method to generate the tiled implementation of an operation.
/// 
/// Given a tile of the iteration space (as returned by
/// `getIterationDomain`), generate in-place the code that represents
/// the computation corresponding to that tile of the iteration space.
/// It is the responsibility of the implementation of this method in
/// the operation to generate the slices of the operands needed for the
/// tiled implementation.
/// - `offsets` provides the offset of the tile in the coordinate system
///   of the original iteration space, i.e., if an iteration space
///   dimension had non-zero offset, it will be included in the offset
///   provided here (as opposed to zero-based offset "relative" to the
///   iteration space).
/// - `sizes` provides the size of the tile.
/// 
/// The returned `TilingResult` must return for each result of the
/// untiled operation, a `Value` that is the result of the tiled
/// operation.
::mlir::FailureOr<::mlir::TilingResult> mlir::TilingInterface::getTiledImplementation(::mlir::OpBuilder & b, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes) {
      return getImpl()->getTiledImplementation(getImpl(), getOperation(), b, offsets, sizes);
  }

/// Method to return the position of the result tile computed by the
/// tiled operation.
/// 
/// For operations that return a value (typically a value of type
/// `RankedTensorType`), the generated tiled computation has to also
/// recompute a replacement for the results of the original operation.
/// The tiled implementation of the operation returns a tile of the
/// result(s). This methods returns information about what part of the
/// result tensor is computed by the tiled implementation. The manner in
/// which these tiles get put together to get the final result is upto
/// the surrounding loop construct. If an operation has no results, (for
/// example an operation that operates only on memrefs), then this method
/// need not be implemented by the operation.
/// - `resultNumber` is the result number of the original operation
///   being processed.
/// - `offsets` provides the offset of the tile in the coordinate system
///   of the original iteration space, i.e., if an iteration space
///   dimension had non-zero offset, it will be included in the offset
///   provided here (as opposed to zero-based offset "relative" to the
///   iteration space).
/// - `sizes` provides the size of the tile.
/// - `resultOffsets` is the offsets of the tile of the result generated
///   by the tiled implementation (returned by value).
/// - `resultSizes` is the size of the tile of the result generated
///   by the tiled implementation (returned by value).
/// 
/// Note: It is undefined behaviour if there is overlap between the
/// tiles of the result generated by the tiled implementation.
::llvm::LogicalResult mlir::TilingInterface::getResultTilePosition(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes, ::mlir::SmallVector<::mlir::OpFoldResult> & resultOffsets, ::mlir::SmallVector<::mlir::OpFoldResult> & resultSizes) {
      return getImpl()->getResultTilePosition(getImpl(), getOperation(), b, resultNumber, offsets, sizes, resultOffsets, resultSizes);
  }

/// Method to generate the code that produces a tile of the result.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) consumer. Typically, for two operations with
/// producer -> consumer relation ship, to compute a tile of the
/// consumer a `slice` of the producer is needed. This method allows
/// computing that slice of the producer in-place, thereby "fusing"
/// the operations at tile-granularity. This method is different from
/// `getTiledImplementation`, which produces a tiled implementation
/// for a tile of the iteration space. This method produces a tiled
/// implementation based on the tile of producer required.
/// - `resultNumber` is the result of the producer used by the consumer.
/// - `offsets` is the offset of the slice of the producer result used by
///   the tiled implementation of the consumer.
/// - `sizes` is the size of the slice of the producer result used by the
///   consumer.
/// If fusion of the producer with the consumer is not legal for the
/// operation/result, this method should return failure.
/// 
/// Note: This method only deals with the mechanism of implementing the
/// fusion. In general the fusion might result in recomputation (based on
/// the way the result is produced by the producer and the access pattern
/// used in the consumer to access). This is upto the caller to handle
/// appropriately.
::mlir::FailureOr<::mlir::TilingResult> mlir::TilingInterface::generateResultTileValue(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult> offsets, ::mlir::ArrayRef<::mlir::OpFoldResult> sizes) {
      return getImpl()->generateResultTileValue(getImpl(), getOperation(), b, resultNumber, offsets, sizes);
  }

/// Method to generate the tiled implementation of an operation that uses
/// the exact tiles of the given operands.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) producer. Given tiles of the producer, this
/// method generates the tile of the consumer that uses exactly these
/// produced tiles. In some sense it is the "reverse" of
/// `generateResultTileValue`.
/// - `operandNumbers` is the list of operands whose tiles are "producers".
/// - `allOffsets` is the offset of the slice of the producer used by the
///   tiled implementation of the consumer.
/// - `allSizes` is the size of the slice of the producer used by the
///   consumer.
/// If it is illegal to fuse with a producer along the given operand tiles for
/// an operation, the implementation should return a failure.
::mlir::FailureOr<::mlir::TilingResult> mlir::TilingInterface::getTiledImplementationFromOperandTiles(::mlir::OpBuilder & b, ::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allSizes) {
      return getImpl()->getTiledImplementationFromOperandTiles(getImpl(), getOperation(), b, operandNumbers, allOffsets, allSizes);
  }

/// Method to return the tile of the iteration domain that uses a given
/// tile of the operand.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) producer. Given tiles of operands,
/// returns the tile of the iteration space that uses these tiles.
/// - `operandNumbers` is the list of operands whose tiles are "produced"
///   by the producer(s).
/// - `allOffsets` is the offset of the slice of the producers used by
///   the tiled implementation of the consumer.
/// - `allSizes` is the size of the slice of the producers used by the
///   consumer.
/// If it is illegal to fuse with the producer slices for an operation,
/// or if this mapping cannot be computed, the implementation should
/// return a failure.
/// 
/// Note that unlike the "tile consumer and fuse producer" case, the
/// "tile producer and fuse consumer" requires an additional method to get
/// the iteration tile space that encompasses all uses of the given operand
/// tile. The reason for this is, consider
/// ```mlir
/// %1 = scf.for...  {
///   %2 = <tiled_producer_op>
///   %3 = tensor.insert_slice %2 into ...
///   scf.yield %3
/// }
/// %4 = <consumer_op>)(... %1... )
/// ... <some_op>(... %4 ...)
/// ```
/// 
/// when fused this becomes
/// ```
/// %1 = scf.for...  {
///   %2 = <tiled_producer_op>
///   %3 = <tiled_consumer_op>(... %2...)
///   %4 = tensor.insert_slice %3 into ...
///   scf.yield %4
/// }
/// ... <some_op>(... %1 ...)
/// ```
/// 
/// i.e, when fusing the consumer, the replacement for the result of the
/// consumer needs to be returned to replace the uses of the consumer.
/// For the tile+fuse algorithm to do this it needs information about
/// which tile of the iteration space encompasses all uses of the tile
/// produced and use that to compute what are the results produced. Note
/// that this iteration space might be the entire iteration space of the
/// operation, or multiple operand tiles might map to intersecting
/// iteration spaces. It is upto the caller to make sure that it is still
/// fusable with producer in this scenario, or it must return a failure.
/// 
/// Note that this method is only used as a way to implement the
/// transformation. It does not provide guarantees on whether such a
/// transformation is profitable.
/// 
/// For most cases `getTiledImplementationFromOperandTiles` could be a
/// implemented using `getIterationDomainTileFromOperandTiles` +
/// `getTiledImplementation` methods.
::llvm::LogicalResult mlir::TilingInterface::getIterationDomainTileFromOperandTiles(::mlir::OpBuilder & b, ::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>>  allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>>  allSizes, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainOffsets, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainSizes) {
      return getImpl()->getIterationDomainTileFromOperandTiles(getImpl(), getOperation(), b, operandNumbers, allOffsets, allSizes, iterDomainOffsets, iterDomainSizes);
  }

/// Method to return the tile of the iteration domain based
/// on the given tile of the certain result.
/// 
/// This method is required to allow operations to be "tiled and fused"
/// with an (already tiled) consumer. Given a tile of an result,
/// returns the tile of the iteration space that uses this tile.
/// - `resultNumber` is the result of the producer used by the consumer.
/// - `offsets` is the offset of the slice of the producer result used by
///   the tiled implementation of the consumer.
/// - `sizes` is the size of the slice of the producer result used by the
///   consumer.
/// If fusion of the producer with the consumer is not legal for the
/// result, or if this mapping cannot be computed, the implementation
/// should return a failure.
/// 
/// For most cases `generateResultTileValue` could be a implemented using
/// `getIterationDomainTileFromResultTile` + `getTiledImplementation`
/// methods.
::llvm::LogicalResult mlir::TilingInterface::getIterationDomainTileFromResultTile(::mlir::OpBuilder & b, unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult>  offsets, ::mlir::ArrayRef<::mlir::OpFoldResult>  sizes, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainOffsets, ::mlir::SmallVectorImpl<::mlir::OpFoldResult> & iterDomainSizes) {
      return getImpl()->getIterationDomainTileFromResultTile(getImpl(), getOperation(), b, resultNumber, offsets, sizes, iterDomainOffsets, iterDomainSizes);
  }

/// Generates the scalar implementation of the operation.
/// 
/// Given the list `ivs` that represent points in the iteration space
/// (as specified by `getIterationDomain()`) returns the scalar operations
/// that represent the computation at that point in the iteration space.
/// This method is typically used as the "exit path", i.e. once all
/// transformations are done, this method can be used to lower to scalar
/// code that can then be lowered to LLVM or SPIR-V dialects.
::llvm::LogicalResult mlir::TilingInterface::generateScalarImplementation(::mlir::OpBuilder & b, ::mlir::Location  loc, ::mlir::ValueRange  ivs) {
      return getImpl()->generateScalarImplementation(getImpl(), getOperation(), b, loc, ivs);
  }

/// Indicates whether it is possible to fuse this operation with the given
/// result slice. This method is not allowed to generate any IR.
bool mlir::TilingInterface::isOpFusableWithConsumerSlice(unsigned resultNumber, ::mlir::ArrayRef<::mlir::OpFoldResult> offsets, ::mlir::ArrayRef<::mlir::OpFoldResult> sizes) {
      return getImpl()->isOpFusableWithConsumerSlice(getImpl(), getOperation(), resultNumber, offsets, sizes);
  }

/// Indicates whether it is possible to fuse this operation with the given
/// list of operand slices. This method is not allowed to generate any IR.
bool mlir::TilingInterface::isOpFusableWithProducerSlices(::mlir::ArrayRef<unsigned> operandNumbers, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allOffsets, ::mlir::ArrayRef<::mlir::SmallVector<::mlir::OpFoldResult>> allSizes) {
      return getImpl()->isOpFusableWithProducerSlices(getImpl(), getOperation(), operandNumbers, allOffsets, allSizes);
  }
