Skip to content

Commit 0fb4a20

Browse files
committed
[mlir] fix shared-lib build fallout of e231070
The patch in question broke the build with shared libraries due to missing dependencies, one of which would have been circular between MLIRStandard and MLIRMemRef if added. Fix this by moving more code around and swapping the dependency direction. MLIRMemRef now depends on MLIRStandard, but MLIRStandard does _not_ depend on MLIRMemRef. Arguably, this is the right direction anyway since numerous libraries depend on MLIRStandard and don't necessarily need to depend on MLIRMemref. Other otable changes include: - some EDSC code is moved inline to MemRef/EDSC/Intrinsics.h because it creates MemRef dialect operations; - a utility function related to shape moved to BuiltinTypes.h/cpp because it only realtes to shaped types and not any particular dialect (standard dialect is erroneously believed to contain MemRefType); - a Python test for the standard dialect is disabled completely because the ops it tests moved to the new MemRef dialect, but it is not exposed to Python bindings, and the change for that is non-trivial.
1 parent d09ae93 commit 0fb4a20

File tree

14 files changed

+138
-117
lines changed

14 files changed

+138
-117
lines changed

mlir/include/mlir/Dialect/MemRef/EDSC/Intrinsics.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
#define MLIR_DIALECT_MEMREF_EDSC_INTRINSICS_H_
1010

1111
#include "mlir/Dialect/MemRef/IR/MemRef.h"
12+
#include "mlir/Dialect/StandardOps/EDSC/Builders.h"
13+
#include "mlir/Dialect/StandardOps/EDSC/Intrinsics.h"
1214
#include "mlir/EDSC/Builders.h"
1315

16+
#include "llvm/ADT/SmallVector.h"
17+
1418
namespace mlir {
1519
namespace edsc {
1620
namespace intrinsics {
@@ -34,4 +38,52 @@ using MemRefIndexedValue =
3438
} // namespace edsc
3539
} // namespace mlir
3640

41+
static inline ::llvm::SmallVector<mlir::Value, 8>
42+
getMemRefSizes(mlir::Value memRef) {
43+
using namespace mlir;
44+
using namespace mlir::edsc;
45+
using namespace mlir::edsc::intrinsics;
46+
mlir::MemRefType memRefType = memRef.getType().cast<mlir::MemRefType>();
47+
assert(isStrided(memRefType) && "Expected strided MemRef type");
48+
49+
SmallVector<mlir::Value, 8> res;
50+
res.reserve(memRefType.getShape().size());
51+
const auto &shape = memRefType.getShape();
52+
for (unsigned idx = 0, n = shape.size(); idx < n; ++idx) {
53+
if (shape[idx] == -1)
54+
res.push_back(memref_dim(memRef, idx));
55+
else
56+
res.push_back(std_constant_index(shape[idx]));
57+
}
58+
return res;
59+
}
60+
61+
namespace mlir {
62+
namespace edsc {
63+
64+
/// A MemRefBoundsCapture represents the information required to step through a
65+
/// MemRef. It has placeholders for non-contiguous tensors that fit within the
66+
/// Fortran subarray model.
67+
/// At the moment it can only capture a MemRef with an identity layout map.
68+
// TODO: Support MemRefs with layoutMaps.
69+
class MemRefBoundsCapture : public BoundsCapture {
70+
public:
71+
explicit MemRefBoundsCapture(Value v) {
72+
auto memrefSizeValues = getMemRefSizes(v);
73+
for (auto s : memrefSizeValues) {
74+
lbs.push_back(intrinsics::std_constant_index(0));
75+
ubs.push_back(s);
76+
steps.push_back(1);
77+
}
78+
}
79+
80+
unsigned fastestVarying() const { return rank() - 1; }
81+
82+
private:
83+
Value base;
84+
};
85+
86+
} // namespace edsc
87+
} // namespace mlir
88+
3789
#endif // MLIR_DIALECT_MEMREF_EDSC_INTRINSICS_H_

mlir/include/mlir/Dialect/MemRef/IR/MemRef.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
#include "mlir/Interfaces/ViewLikeInterface.h"
1717

1818
namespace mlir {
19+
20+
class Location;
21+
class OpBuilder;
22+
1923
raw_ostream &operator<<(raw_ostream &os, Range &range);
2024

2125
/// Return the list of Range (i.e. offset, size, stride). Each Range
2226
/// entry contains either the dynamic value or a ConstantIndexOp constructed
2327
/// with `b` at location `loc`.
2428
SmallVector<Range, 8> getOrCreateRanges(OffsetSizeAndStrideOpInterface op,
2529
OpBuilder &b, Location loc);
30+
31+
/// Given an operation, retrieves the value of each dynamic dimension through
32+
/// constructing the necessary DimOp operators.
33+
SmallVector<Value, 4> getDynOperands(Location loc, Value val, OpBuilder &b);
2634
} // namespace mlir
2735

2836
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/StandardOps/EDSC/Builders.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,6 @@ class BoundsCapture {
4444
SmallVector<int64_t, 8> steps;
4545
};
4646

47-
/// A MemRefBoundsCapture represents the information required to step through a
48-
/// MemRef. It has placeholders for non-contiguous tensors that fit within the
49-
/// Fortran subarray model.
50-
/// At the moment it can only capture a MemRef with an identity layout map.
51-
// TODO: Support MemRefs with layoutMaps.
52-
class MemRefBoundsCapture : public BoundsCapture {
53-
public:
54-
explicit MemRefBoundsCapture(Value v);
55-
56-
unsigned fastestVarying() const { return rank() - 1; }
57-
58-
private:
59-
Value base;
60-
};
61-
6247
/// A VectorBoundsCapture represents the information required to step through a
6348
/// Vector accessing each scalar element at a time. It is the counterpart of
6449
/// a MemRefBoundsCapture but for vectors. This exists purely for boilerplate

mlir/include/mlir/Dialect/StandardOps/IR/Ops.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,6 @@ class ConstantIndexOp : public ConstantOp {
108108
static bool classof(Operation *op);
109109
};
110110

111-
/// Given an `originalShape` and a `reducedShape` assumed to be a subset of
112-
/// `originalShape` with some `1` entries erased, return the set of indices
113-
/// that specifies which of the entries of `originalShape` are dropped to obtain
114-
/// `reducedShape`. The returned mask can be applied as a projection to
115-
/// `originalShape` to obtain the `reducedShape`. This mask is useful to track
116-
/// which dimensions must be kept when e.g. compute MemRef strides under
117-
/// rank-reducing operations. Return None if reducedShape cannot be obtained
118-
/// by dropping only `1` entries in `originalShape`.
119-
llvm::Optional<llvm::SmallDenseSet<unsigned>>
120-
computeRankReductionMask(ArrayRef<int64_t> originalShape,
121-
ArrayRef<int64_t> reducedShape);
122-
123111
/// Compute `lhs` `pred` `rhs`, where `pred` is one of the known integer
124112
/// comparison predicates.
125113
bool applyCmpPredicate(CmpIPredicate predicate, const APInt &lhs,

mlir/include/mlir/Dialect/StandardOps/Utils/Utils.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,6 @@
2323

2424
namespace mlir {
2525

26-
class Location;
27-
class OpBuilder;
28-
29-
/// Given an operation, retrieves the value of each dynamic dimension through
30-
/// constructing the necessary DimOp operators.
31-
SmallVector<Value, 4> getDynOperands(Location loc, Value val, OpBuilder &b);
32-
3326
/// Matches a ConstantIndexOp.
3427
detail::op_matcher<ConstantIndexOp> matchConstantIndex();
3528

mlir/include/mlir/IR/BuiltinTypes.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,18 @@ class MemRefType::Builder {
245245
Attribute memorySpace;
246246
};
247247

248+
/// Given an `originalShape` and a `reducedShape` assumed to be a subset of
249+
/// `originalShape` with some `1` entries erased, return the set of indices
250+
/// that specifies which of the entries of `originalShape` are dropped to obtain
251+
/// `reducedShape`. The returned mask can be applied as a projection to
252+
/// `originalShape` to obtain the `reducedShape`. This mask is useful to track
253+
/// which dimensions must be kept when e.g. compute MemRef strides under
254+
/// rank-reducing operations. Return None if reducedShape cannot be obtained
255+
/// by dropping only `1` entries in `originalShape`.
256+
llvm::Optional<llvm::SmallDenseSet<unsigned>>
257+
computeRankReductionMask(ArrayRef<int64_t> originalShape,
258+
ArrayRef<int64_t> reducedShape);
259+
248260
//===----------------------------------------------------------------------===//
249261
// Deferred Method Definitions
250262
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/MemRef/IR/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_mlir_dialect_library(MLIRMemRef
66
${PROJECT_SOURCE_DIR}/inlude/mlir/Dialect/MemRefDialect
77

88
DEPENDS
9+
MLIRStandardOpsIncGen
910
MLIRMemRefOpsIncGen
1011

1112
LINK_COMPONENTS
@@ -14,4 +15,7 @@ add_mlir_dialect_library(MLIRMemRef
1415
LINK_LIBS PUBLIC
1516
MLIRDialect
1617
MLIRIR
18+
MLIRStandard
19+
MLIRTensor
20+
MLIRViewLikeInterface
1721
)

mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ struct MemRefInlinerInterface : public DialectInlinerInterface {
3030
};
3131
} // end anonymous namespace
3232

33+
SmallVector<Value, 4> mlir::getDynOperands(Location loc, Value val,
34+
OpBuilder &b) {
35+
SmallVector<Value, 4> dynOperands;
36+
auto shapedType = val.getType().cast<ShapedType>();
37+
for (auto dim : llvm::enumerate(shapedType.getShape())) {
38+
if (dim.value() == MemRefType::kDynamicSize)
39+
dynOperands.push_back(b.create<memref::DimOp>(loc, val, dim.index()));
40+
}
41+
return dynOperands;
42+
}
43+
3344
void mlir::memref::MemRefDialect::initialize() {
3445
addOperations<DmaStartOp, DmaWaitOp,
3546
#define GET_OP_LIST

mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,40 +1560,6 @@ void SubViewOp::build(OpBuilder &b, OperationState &result, Value source,
15601560
/// For ViewLikeOpInterface.
15611561
Value SubViewOp::getViewSource() { return source(); }
15621562

1563-
/// Given an `originalShape` and a `reducedShape` assumed to be a subset of
1564-
/// `originalShape` with some `1` entries erased, return the set of indices
1565-
/// that specifies which of the entries of `originalShape` are dropped to obtain
1566-
/// `reducedShape`. The returned mask can be applied as a projection to
1567-
/// `originalShape` to obtain the `reducedShape`. This mask is useful to track
1568-
/// which dimensions must be kept when e.g. compute MemRef strides under
1569-
/// rank-reducing operations. Return None if reducedShape cannot be obtained
1570-
/// by dropping only `1` entries in `originalShape`.
1571-
llvm::Optional<llvm::SmallDenseSet<unsigned>>
1572-
mlir::computeRankReductionMask(ArrayRef<int64_t> originalShape,
1573-
ArrayRef<int64_t> reducedShape) {
1574-
size_t originalRank = originalShape.size(), reducedRank = reducedShape.size();
1575-
llvm::SmallDenseSet<unsigned> unusedDims;
1576-
unsigned reducedIdx = 0;
1577-
for (unsigned originalIdx = 0; originalIdx < originalRank; ++originalIdx) {
1578-
// Greedily insert `originalIdx` if no match.
1579-
if (reducedIdx < reducedRank &&
1580-
originalShape[originalIdx] == reducedShape[reducedIdx]) {
1581-
reducedIdx++;
1582-
continue;
1583-
}
1584-
1585-
unusedDims.insert(originalIdx);
1586-
// If no match on `originalIdx`, the `originalShape` at this dimension
1587-
// must be 1, otherwise we bail.
1588-
if (originalShape[originalIdx] != 1)
1589-
return llvm::None;
1590-
}
1591-
// The whole reducedShape must be scanned, otherwise we bail.
1592-
if (reducedIdx != reducedRank)
1593-
return llvm::None;
1594-
return unusedDims;
1595-
}
1596-
15971563
enum SubViewVerificationResult {
15981564
Success,
15991565
RankTooLarge,

mlir/lib/Dialect/StandardOps/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ add_mlir_dialect_library(MLIRStandard
1616
MLIRControlFlowInterfaces
1717
MLIREDSC
1818
MLIRIR
19-
MLIRMemRef
2019
MLIRSideEffectInterfaces
2120
MLIRTensor
2221
MLIRVectorInterfaces

mlir/lib/Dialect/StandardOps/EDSC/Builders.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "mlir/Dialect/MemRef/EDSC/Intrinsics.h"
109
#include "mlir/Dialect/StandardOps/EDSC/Intrinsics.h"
1110
#include "mlir/IR/AffineExpr.h"
1211
#include "mlir/IR/AffineMap.h"
@@ -15,31 +14,6 @@ using namespace mlir;
1514
using namespace mlir::edsc;
1615
using namespace mlir::edsc::intrinsics;
1716

18-
static SmallVector<Value, 8> getMemRefSizes(Value memRef) {
19-
MemRefType memRefType = memRef.getType().cast<MemRefType>();
20-
assert(isStrided(memRefType) && "Expected strided MemRef type");
21-
22-
SmallVector<Value, 8> res;
23-
res.reserve(memRefType.getShape().size());
24-
const auto &shape = memRefType.getShape();
25-
for (unsigned idx = 0, n = shape.size(); idx < n; ++idx) {
26-
if (shape[idx] == -1)
27-
res.push_back(memref_dim(memRef, idx));
28-
else
29-
res.push_back(std_constant_index(shape[idx]));
30-
}
31-
return res;
32-
}
33-
34-
mlir::edsc::MemRefBoundsCapture::MemRefBoundsCapture(Value v) {
35-
auto memrefSizeValues = getMemRefSizes(v);
36-
for (auto s : memrefSizeValues) {
37-
lbs.push_back(std_constant_index(0));
38-
ubs.push_back(s);
39-
steps.push_back(1);
40-
}
41-
}
42-
4317
mlir::edsc::VectorBoundsCapture::VectorBoundsCapture(VectorType t) {
4418
for (auto s : t.getShape()) {
4519
lbs.push_back(std_constant_index(0));

mlir/lib/Dialect/StandardOps/Utils/Utils.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,10 @@
1212

1313
#include "mlir/Dialect/StandardOps/Utils/Utils.h"
1414

15-
#include "mlir/Dialect/MemRef/IR/MemRef.h"
1615
#include "mlir/Dialect/StandardOps/IR/Ops.h"
1716

1817
using namespace mlir;
1918

20-
SmallVector<Value, 4> mlir::getDynOperands(Location loc, Value val,
21-
OpBuilder &b) {
22-
SmallVector<Value, 4> dynOperands;
23-
auto shapedType = val.getType().cast<ShapedType>();
24-
for (auto dim : llvm::enumerate(shapedType.getShape())) {
25-
if (dim.value() == MemRefType::kDynamicSize)
26-
dynOperands.push_back(b.create<memref::DimOp>(loc, val, dim.index()));
27-
}
28-
return dynOperands;
29-
}
30-
3119
/// Matches a ConstantIndexOp.
3220
/// TODO: This should probably just be a general matcher that uses matchConstant
3321
/// and checks the operation for an index type.

mlir/lib/IR/BuiltinTypes.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,40 @@ unsigned BaseMemRefType::getMemorySpaceAsInt() const {
465465
// MemRefType
466466
//===----------------------------------------------------------------------===//
467467

468+
/// Given an `originalShape` and a `reducedShape` assumed to be a subset of
469+
/// `originalShape` with some `1` entries erased, return the set of indices
470+
/// that specifies which of the entries of `originalShape` are dropped to obtain
471+
/// `reducedShape`. The returned mask can be applied as a projection to
472+
/// `originalShape` to obtain the `reducedShape`. This mask is useful to track
473+
/// which dimensions must be kept when e.g. compute MemRef strides under
474+
/// rank-reducing operations. Return None if reducedShape cannot be obtained
475+
/// by dropping only `1` entries in `originalShape`.
476+
llvm::Optional<llvm::SmallDenseSet<unsigned>>
477+
mlir::computeRankReductionMask(ArrayRef<int64_t> originalShape,
478+
ArrayRef<int64_t> reducedShape) {
479+
size_t originalRank = originalShape.size(), reducedRank = reducedShape.size();
480+
llvm::SmallDenseSet<unsigned> unusedDims;
481+
unsigned reducedIdx = 0;
482+
for (unsigned originalIdx = 0; originalIdx < originalRank; ++originalIdx) {
483+
// Greedily insert `originalIdx` if no match.
484+
if (reducedIdx < reducedRank &&
485+
originalShape[originalIdx] == reducedShape[reducedIdx]) {
486+
reducedIdx++;
487+
continue;
488+
}
489+
490+
unusedDims.insert(originalIdx);
491+
// If no match on `originalIdx`, the `originalShape` at this dimension
492+
// must be 1, otherwise we bail.
493+
if (originalShape[originalIdx] != 1)
494+
return llvm::None;
495+
}
496+
// The whole reducedShape must be scanned, otherwise we bail.
497+
if (reducedIdx != reducedRank)
498+
return llvm::None;
499+
return unusedDims;
500+
}
501+
468502
bool mlir::detail::isSupportedMemorySpace(Attribute memorySpace) {
469503
// Empty attribute is allowed as default memory space.
470504
if (!memorySpace)

0 commit comments

Comments
 (0)