#pragma once #include "mlir/Dialect/Tensor/IR/Tensor.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Value.h" #include "mlir/IR/ValueRange.h" #include "mlir/Transforms/DialectConversion.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include #include #include #include #include namespace onnx_mlir { using HSliceId = size_t; using CoreId = size_t; template > constexpr C ceilIntegerDivide(A a, B b) { static_assert(std::is_integral_v, "A must be an integer type"); static_assert(std::is_integral_v, "B must be an integer type"); C ac = static_cast(a); C bc = static_cast(b); return 1 + (ac - 1) / bc; } template > constexpr std::pair ceilIntegerDivideWithRemainder(A a, B b) { static_assert(std::is_integral_v, "A must be an integer type"); static_assert(std::is_integral_v, "B must be an integer type"); C ac = static_cast(a); C bc = static_cast(b); return {ceilIntegerDivide(ac, bc), ac % bc}; } template bool isVectorShape(mlir::ArrayRef shape) { return shape.size() == 2 && (shape[0] == 1 || shape[1] == 1); } template bool isMatrixShape(mlir::ArrayRef shape) { return shape.size() == 2; } template bool isHVectorShape(mlir::ArrayRef shape) { return shape.size() == 2 && shape[0] == 1; } inline auto getTensorShape(mlir::Value tensor) { return mlir::cast(tensor.getType()).getShape(); } inline bool haveSameStaticShape(mlir::Value lhs, mlir::Value rhs) { auto lhsType = mlir::dyn_cast(lhs.getType()); auto rhsType = mlir::dyn_cast(rhs.getType()); return lhsType && rhsType && lhsType.hasStaticShape() && rhsType.hasStaticShape() && lhsType.getShape() == rhsType.getShape(); } bool hasStaticPositiveShape(mlir::ArrayRef shape); bool hasStaticPositiveShape(mlir::RankedTensorType type); int64_t getStaticShapeElementCount(mlir::ArrayRef shape); llvm::SmallVector permuteShape(mlir::ArrayRef shape, mlir::ArrayRef permutation); llvm::SmallVector invertPermutation(mlir::ArrayRef permutation); mlir::FailureOr> getTransposePermutationChecked(std::optional permAttr, int64_t rank); mlir::Value transposeMaybeInCompute(mlir::Value value, mlir::RankedTensorType resultType, mlir::ArrayRef permutation, mlir::PatternRewriter& rewriter, mlir::Location loc); llvm::SmallVector getUnitStrides(mlir::PatternRewriter& rewriter, int64_t rank); llvm::SmallVector getZeroOffsets(mlir::PatternRewriter& rewriter, int64_t rank); llvm::SmallVector getStaticSizes(mlir::PatternRewriter& rewriter, mlir::ArrayRef shape); /// Slices a statically shaped tensor along one axis into contiguous pieces of /// at most `sliceSize` elements. llvm::SmallVector sliceTensor(const mlir::Value& tensorToSlice, size_t axis, int64_t sliceSize, mlir::ConversionPatternRewriter& rewriter, mlir::Location loc); llvm::SmallVector sliceVector(const mlir::Value& vectorToSlice, int64_t sliceSize, mlir::ConversionPatternRewriter& rewriter, mlir::Location loc); /// Partitions one logical vector into per-core crossbar-sized slices using the /// current PIM target geometry. llvm::DenseMap> sliceVectorPerCrossbarPerCore( const mlir::Value& vectorToSlice, mlir::ConversionPatternRewriter& rewriter, mlir::Location loc); mlir::Value extractAxisSlice( mlir::PatternRewriter& rewriter, mlir::Location loc, mlir::Value source, int64_t axis, int64_t offset, int64_t size); mlir::Value insertStaticSlice(mlir::PatternRewriter& rewriter, mlir::Location loc, mlir::Value source, mlir::Value dest, llvm::ArrayRef offsets); } // namespace onnx_mlir