Skip to content

Commit 6583762

Browse files
authored
[Codegen] Remove depreciated vector distribution transform codegen path (#19233)
Removes iree_vector_ext.layout attribute for VectorExt and other related passes which were required for the vector distribution transform dialect path. This path is now depreciated.
1 parent e1ce3fa commit 6583762

28 files changed

+209
-3589
lines changed

compiler/src/iree/compiler/Codegen/Common/GPU/GPUDistributionPatterns.cpp

Lines changed: 0 additions & 808 deletions
Large diffs are not rendered by default.

compiler/src/iree/compiler/Codegen/Common/GPU/GPUPatterns.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ void populateDropSharedMemoryDeallocOpPatterns(RewritePatternSet &patterns);
3131

3232
void populateGPUDistributionPatterns(RewritePatternSet &patterns);
3333

34-
void populateGPUDistributionLayoutAttrPatterns(Value laneId,
35-
RewritePatternSet &patterns);
36-
37-
void populateGPUReductionDistributionPatterns(RewritePatternSet &patterns,
38-
int64_t maxBitsPerShuffle = 32);
39-
4034
void populateGPUDistributeNestedLayoutAttrPatterns(
4135
RewritePatternSet &patterns, Value threadId, int64_t subgroupSize,
4236
int64_t maxBitsPerShuffle = 32);
@@ -46,9 +40,6 @@ void populateGPUDistributeNestedLayoutAttrPatterns(
4640
void populateGPUDistributeNestedLayoutContractAMDGPUPatterns(
4741
RewritePatternSet &patterns);
4842

49-
void populateGPULayoutResolutionDistributionPatterns(
50-
RewritePatternSet &patterns);
51-
5243
} // namespace mlir::iree_compiler
5344

5445
#endif // IREE_COMPILER_CODEGEN_COMMON_GPUPATTERNS_H_

compiler/src/iree/compiler/Codegen/Common/GPU/test/gpu_vector_distribution.mlir

Lines changed: 18 additions & 680 deletions
Large diffs are not rendered by default.

compiler/src/iree/compiler/Codegen/Common/TransformExtensions/CommonExtensions.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,14 +1120,10 @@ transform_dialect::TestGpuVectorDistribution::applyToOne(
11201120
rewriter.create<gpu::ThreadIdOp>(target.getLoc(), gpu::Dimension::x);
11211121

11221122
populateGPUDistributionPatterns(patterns);
1123-
populateGPUDistributionLayoutAttrPatterns(laneId, patterns);
1124-
populateGPUReductionDistributionPatterns(patterns);
11251123
// For testing we use subgroup size = 64.
11261124
populateGPUDistributeNestedLayoutAttrPatterns(patterns, laneId,
11271125
/*subgroupSize=*/64);
11281126
populateGPUDistributeNestedLayoutContractAMDGPUPatterns(patterns);
1129-
if (getExperimental())
1130-
populateGPULayoutResolutionDistributionPatterns(patterns);
11311127
if (failed(distributeVectorOps(target, patterns, options))) {
11321128
return emitDefaultDefiniteFailure(target);
11331129
}

compiler/src/iree/compiler/Codegen/Common/test/vector_layout_analysis.mlir

Lines changed: 180 additions & 61 deletions
Large diffs are not rendered by default.

compiler/src/iree/compiler/Codegen/Dialect/VectorExt/IR/VectorExtAttrs.cpp

Lines changed: 0 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -25,219 +25,6 @@ namespace mlir::iree_compiler::IREE::VectorExt {
2525

2626
using VectorValue = TypedValue<VectorType>;
2727

28-
bool PerDimLayoutAttr::contains(const LayoutDimension &dim) {
29-
for (LayoutDimensionAttr label : getLabels()) {
30-
if (label.getValue() == dim)
31-
return true;
32-
}
33-
return false;
34-
}
35-
36-
std::optional<int64_t> PerDimLayoutAttr::getShape(const LayoutDimension &dim) {
37-
for (auto value : llvm::zip(getLabels(), getShapes())) {
38-
if (dim == std::get<0>(value).getValue())
39-
return std::get<1>(value);
40-
}
41-
return std::nullopt;
42-
}
43-
44-
std::optional<int64_t> LayoutAttr::getShape(const LayoutDimension &dim) const {
45-
for (PerDimLayoutAttr layout : getLayouts()) {
46-
std::optional<int64_t> maybeShape = layout.getShape(dim);
47-
if (maybeShape)
48-
return maybeShape.value();
49-
}
50-
return std::nullopt;
51-
}
52-
53-
// Get the SIMT Vector shape in the order specified by dims. If no dims are
54-
// specified, then return an empty vector.
55-
LogicalResult LayoutAttr::isValidLayout(ShapedType shapeTy,
56-
Location loc) const {
57-
ArrayRef<int64_t> shape = shapeTy.getShape();
58-
if (shape.size() != getRank()) {
59-
return emitError(loc, "Rank of vector (")
60-
<< shape.size() << ") does not match rank of layout (" << getRank()
61-
<< ").";
62-
}
63-
for (auto [idx, layout] : llvm::enumerate(getLayouts())) {
64-
ArrayRef<int64_t> layoutShape = layout.getShapes();
65-
int64_t expectedShape =
66-
std::reduce(layoutShape.begin(), layoutShape.end(),
67-
static_cast<int64_t>(1), std::multiplies<int64_t>());
68-
if (expectedShape != shape[idx]) {
69-
std::string shapeStr;
70-
llvm::raw_string_ostream shapeOs(shapeStr);
71-
llvm::interleaveComma(shape, shapeOs);
72-
std::string layoutStr;
73-
llvm::raw_string_ostream layoutOs(layoutStr);
74-
printStripped(layoutOs);
75-
return emitError(loc, "Vector shape: [")
76-
<< shapeStr << "] does not match the layout (" << layoutStr
77-
<< ") at dim " << idx
78-
<< ". Dimension expected by layout: " << expectedShape
79-
<< " actual: " << shape[idx];
80-
}
81-
}
82-
return success();
83-
}
84-
85-
// Project out the layout for the specified dimensions
86-
// resulting in the layout for a lower dimensional vector.
87-
VectorLayoutInterface LayoutAttr::project(ArrayRef<bool> droppedDims) const {
88-
assert(droppedDims.size() == getRank() &&
89-
"droppedDims size must match layout size");
90-
91-
ArrayRef<PerDimLayoutAttr> layouts = getLayouts();
92-
SmallVector<PerDimLayoutAttr> newLayouts;
93-
for (auto pair : llvm::zip(droppedDims, layouts)) {
94-
if (!std::get<0>(pair))
95-
newLayouts.push_back(std::get<1>(pair));
96-
}
97-
return LayoutAttr::get(getContext(), newLayouts);
98-
}
99-
100-
// Permute the layout according to the provided permutation
101-
// vector. The dimensionality of the layout remains the same.
102-
VectorLayoutInterface LayoutAttr::permute(ArrayRef<int64_t> permutation) const {
103-
assert(permutation.size() == getRank() &&
104-
"permutation size must match layout rank");
105-
106-
ArrayRef<PerDimLayoutAttr> layouts = getLayouts();
107-
SmallVector<PerDimLayoutAttr> newLayouts;
108-
for (unsigned index : permutation) {
109-
assert(index >= 0 && index < getRank());
110-
newLayouts.push_back(layouts[index]);
111-
}
112-
return LayoutAttr::get(getContext(), newLayouts);
113-
}
114-
115-
// This function returns the distributed shape of the SIMT
116-
// vector and evaluates it in the following order:
117-
// BATCHX, BATCHY, VECTORY, VECTORX
118-
// The vector dimensions are combined into a single SIMT
119-
// vector dimension.
120-
SmallVector<int64_t> LayoutAttr::getDistributedShape() const {
121-
SmallVector<LayoutDimension> labels{
122-
LayoutDimension::BATCHX, LayoutDimension::BATCHY,
123-
LayoutDimension::VECTORY, LayoutDimension::VECTORX};
124-
SmallVector<int64_t> simtVectorShape;
125-
std::optional<int64_t> vectorShape;
126-
for (LayoutDimension dim : labels) {
127-
ArrayRef<PerDimLayoutAttr> layouts = getLayouts();
128-
for (PerDimLayoutAttr layout : layouts) {
129-
if (!layout.contains(dim))
130-
continue;
131-
int64_t shape = layout.getShape(dim).value();
132-
if (isVectorDimension(dim)) {
133-
vectorShape = shape * vectorShape.value_or(1);
134-
continue;
135-
}
136-
simtVectorShape.push_back(shape);
137-
}
138-
}
139-
if (vectorShape)
140-
simtVectorShape.push_back(vectorShape.value());
141-
return simtVectorShape;
142-
}
143-
144-
PerDimLayoutAttr LayoutAttr::getDimLayout(int64_t dim) const {
145-
assert(dim >= 0 && dim < getRank());
146-
return getLayouts()[dim];
147-
}
148-
149-
std::optional<int64_t> LayoutAttr::getBatchDim(int64_t dim) {
150-
assert(dim < getRank());
151-
PerDimLayoutAttr layout = getDimLayout(dim);
152-
for (auto [name, shape] :
153-
llvm::zip_equal(layout.getLabels(), layout.getShapes())) {
154-
if (isBatchDimension(name.getValue()))
155-
return shape;
156-
}
157-
return std::nullopt;
158-
}
159-
160-
std::optional<int64_t> LayoutAttr::getLaneDim(int64_t dim) {
161-
assert(dim < getRank());
162-
PerDimLayoutAttr layout = getDimLayout(dim);
163-
for (auto [name, shape] :
164-
llvm::zip_equal(layout.getLabels(), layout.getShapes())) {
165-
if (isLaneDimension(name.getValue()))
166-
return shape;
167-
}
168-
return std::nullopt;
169-
}
170-
171-
std::optional<LayoutDimension> LayoutAttr::getLane(int64_t dim) {
172-
assert(dim < getRank());
173-
PerDimLayoutAttr layout = getDimLayout(dim);
174-
for (auto [name, shape] :
175-
llvm::zip_equal(layout.getLabels(), layout.getShapes())) {
176-
if (isLaneDimension(name.getValue()))
177-
return name.getValue();
178-
}
179-
return std::nullopt;
180-
}
181-
182-
int64_t LayoutAttr::getRank() const { return getLayouts().size(); }
183-
184-
std::tuple<int64_t, int64_t, int64_t> LayoutAttr::getLaneGrid() {
185-
int64_t laneX = 1;
186-
int64_t laneY = 1;
187-
int64_t laneZ = 1;
188-
for (PerDimLayoutAttr dimLayout : getLayouts()) {
189-
// Note that valid layouts only include at most one instance of each
190-
// dimension type, so this is simply doing assignment on the first instance
191-
// of each lane index, not an accumulative product.
192-
auto maybeXShape = dimLayout.getShape(LayoutDimension::LANEX);
193-
laneX *= maybeXShape.value_or(1);
194-
auto maybeYShape = dimLayout.getShape(LayoutDimension::LANEY);
195-
laneY *= maybeYShape.value_or(1);
196-
auto maybeZShape = dimLayout.getShape(LayoutDimension::LANEZ);
197-
laneZ *= maybeZShape.value_or(1);
198-
}
199-
return std::make_tuple(laneX, laneY, laneZ);
200-
}
201-
202-
uint64_t LayoutAttr::getShuffleOffset(int64_t reductionDim) {
203-
uint64_t offset = 0;
204-
std::optional<LayoutDimension> laneDim = getLane(reductionDim);
205-
if (!laneDim)
206-
return offset;
207-
switch (laneDim.value()) {
208-
case LayoutDimension::LANEX:
209-
offset = 1;
210-
break;
211-
case LayoutDimension::LANEY:
212-
offset = getShape(LayoutDimension::LANEX).value_or(0);
213-
break;
214-
case LayoutDimension::LANEZ:
215-
offset = getShape(LayoutDimension::LANEX).value_or(0) *
216-
getShape(LayoutDimension::LANEY).value_or(0);
217-
break;
218-
default:
219-
assert(false && "Invalid dimension! Expected lane dimension");
220-
break;
221-
}
222-
return offset;
223-
}
224-
225-
bool LayoutAttr::hasLaneConflictWith(const LayoutAttr &other) {
226-
SmallVector<LayoutDimension> laneDims{
227-
LayoutDimension::LANEX, LayoutDimension::LANEY, LayoutDimension::LANEZ};
228-
for (LayoutDimension dim : laneDims) {
229-
std::optional<int64_t> shape = getShape(dim);
230-
std::optional<int64_t> otherShape = other.getShape(dim);
231-
if ((shape && !otherShape) || (!shape && otherShape))
232-
return true;
233-
if (shape && otherShape) {
234-
if (shape.value() != otherShape.value())
235-
return true;
236-
}
237-
}
238-
return false;
239-
}
240-
24128
// Project the nested layout. This take a mask on the dimensions of the vector
24229
// associated with this layout and projects out those dimensions. This reduces
24330
// the rank of the layout in the process.

compiler/src/iree/compiler/Codegen/Dialect/VectorExt/IR/VectorExtAttrs.td

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -13,98 +13,6 @@ include "iree/compiler/Codegen/Dialect/VectorExt/IR/VectorExtBase.td"
1313
// Vector layout attributes
1414
//===---------------------------------------------------------------------===//
1515

16-
// Defines the batch dimensions for the original SIMD tensor.
17-
// By convention, X is along rows and Y along columns.
18-
def BATCHX : I32EnumAttrCase<"BATCHX", 0>;
19-
def BATCHY : I32EnumAttrCase<"BATCHY", 1>;
20-
// Defines the vector dimension.
21-
def VECTORX : I32EnumAttrCase<"VECTORX", 2>;
22-
def VECTORY : I32EnumAttrCase<"VECTORY", 3>;
23-
def VECTORZ : I32EnumAttrCase<"VECTORZ", 4>;
24-
// Defines the lane dimensions.
25-
def LANEX : I32EnumAttrCase<"LANEX", 5>;
26-
def LANEY : I32EnumAttrCase<"LANEY", 6>;
27-
def LANEZ : I32EnumAttrCase<"LANEZ", 7>;
28-
29-
def LayoutDimension : IREEVectorExt_I32EnumAttr<"LayoutDimension",
30-
"Describes the dimension of the high-dimensional layout", [
31-
BATCHX,
32-
BATCHY,
33-
VECTORX,
34-
VECTORY,
35-
VECTORZ,
36-
LANEX,
37-
LANEY,
38-
LANEZ,
39-
]>;
40-
41-
def LayoutDimensionAttr : IREEVectorExt_EnumAttr<LayoutDimension, "dimension">;
42-
43-
def PerDimLayoutAttr : IREEVectorExt_Attr<"PerDimLayout"> {
44-
let mnemonic = "per_dim_layout";
45-
let summary = [{high-dimensional vector register layout for a given vector dimension}];
46-
let description = [{
47-
This attribute describes the per dimension register layout for a given vector
48-
that could be prescribed by an operator such as matrix multiplication.
49-
This is a way to explicitly represent the layout in the IR
50-
when it is in the SIMD form prior to converting to the SIMT form so that
51-
we can reason about layouts, propagating layouts and layout conflicts.
52-
}];
53-
let parameters = (ins
54-
ArrayRefParameter<"LayoutDimensionAttr", "labels for the high dimensional layout dims">:$labels,
55-
ArrayRefParameter<"int64_t", "shapes for the high dimensional layout dims">:$shapes
56-
);
57-
let assemblyFormat = "`<``[` $labels `]``,` `[` $shapes `]``>`";
58-
let genVerifyDecl = 0;
59-
let extraClassDeclaration = [{
60-
std::optional<int64_t> getShape(const LayoutDimension &dim);
61-
bool contains(const LayoutDimension &dim);
62-
}];
63-
}
64-
65-
def LayoutAttr : IREEVectorExt_Attr<"Layout",
66-
[ DeclareAttrInterfaceMethods<VectorLayoutInterface> ]> {
67-
let mnemonic = "layout";
68-
let summary = [{high-dimensional vector register layout for a given vector}];
69-
let description = [{
70-
This contains a complete specification of the layout for a given vector,
71-
whereas the attribute above only specifies the per dimension layout.
72-
}];
73-
let parameters = (ins
74-
ArrayRefParameter<"PerDimLayoutAttr", "layout for each dimension of the vector">:$layouts
75-
);
76-
let assemblyFormat = "`<`$layouts`>`";
77-
let genVerifyDecl = 0;
78-
let extraClassDeclaration = [{
79-
// Get the shape for a given layout dimension.
80-
std::optional<int64_t> getShape(const LayoutDimension &dim) const;
81-
std::optional<int64_t> getBatchDim(int64_t dim);
82-
// Get the lane dimension shape for a provided simd tensor dim.
83-
std::optional<int64_t> getLaneDim(int64_t dim);
84-
// Get the lane dimension for a provided simd tensor dim.
85-
std::optional<LayoutDimension> getLane(int64_t dim);
86-
87-
// Returns the grid of lane ids. Assumes a valid layout.
88-
::std::tuple<int64_t, int64_t, int64_t> getLaneGrid();
89-
PerDimLayoutAttr getDimLayout(int64_t dim) const;
90-
91-
// Given the reduction dim, computes the shuffle offset
92-
// based on the shapes of the lane dimensions. The shuffle
93-
// offset is used during the thread global reduction
94-
// when emitting a gpu::ShuffleOp and follows
95-
// the semantics of the offset operand defined there,
96-
// which is that for lane k, the shuffle op returns the
97-
// value from lane k ^ offset.
98-
uint64_t getShuffleOffset(int64_t reductionDim);
99-
100-
// Determines whether the other layout has a lane
101-
// dimension that the current layout does not have OR whether
102-
// the shape of the two layouts for a common lane dimension
103-
// is not the same.
104-
bool hasLaneConflictWith(const LayoutAttr &other);
105-
}];
106-
}
107-
10816
def NestedLayoutAttr : IREEVectorExt_Attr<"NestedLayout",
10917
[ DeclareAttrInterfaceMethods<VectorLayoutInterface> ]> {
11018
let mnemonic = "nested_layout";

compiler/src/iree/compiler/Codegen/Dialect/VectorExt/IR/VectorExtDialect.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ namespace mlir::iree_compiler::IREE::VectorExt {
2323
struct IREEVectorExtDialectOpAsmInterface : public OpAsmDialectInterface {
2424
using OpAsmDialectInterface::OpAsmDialectInterface;
2525
AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
26-
if (llvm::isa<LayoutAttr>(attr)) {
27-
os << "layout";
28-
return AliasResult::OverridableAlias;
29-
}
3026
if (llvm::isa<NestedLayoutAttr>(attr)) {
3127
os << "nested";
3228
return AliasResult::OverridableAlias;

0 commit comments

Comments
 (0)