Skip to content

Commit 777a403

Browse files
committed
add utils
1 parent f687ed9 commit 777a403

File tree

3 files changed

+64
-18
lines changed

3 files changed

+64
-18
lines changed

mlir/include/mlir/Dialect/XeGPU/Utils/XeGPUUtils.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
namespace mlir {
1414

1515
class VectorType;
16+
class OpOperand;
17+
class OpResult;
18+
1619
namespace xegpu {
1720
class LayoutAttr;
1821
class TensorDescType;
@@ -50,6 +53,18 @@ FailureOr<VectorType> getDistributedVectorType(xegpu::TensorDescType tdescTy);
5053
FailureOr<VectorType> getDistributedVectorType(VectorType originalType,
5154
LayoutAttr layout);
5255

56+
/// Retrieves the LayoutAttr associated with a given Value. For TensorDescType
57+
/// values, the LayoutAttr is extracted from the TensorDescType itself. For
58+
/// other values, it is obtained from the attributes of the defining operation.
59+
/// Returns nullptr if no LayoutAttr is found.
60+
LayoutAttr getLayoutAttr(Value value);
61+
62+
/// Retrieves the name for the LayoutAttr associated with a given OpOperand.
63+
std::string getLayoutName(OpOperand &opr);
64+
65+
/// Retrieves the name for the LayoutAttr associated with a given OpResult.
66+
std::string getLayoutName(OpResult res);
67+
5368
} // namespace xegpu
5469

5570
} // namespace mlir

mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ constexpr unsigned packedSizeInBitsForDefault =
6262
16; // Minimum packing size per register for DPAS A.
6363
constexpr unsigned packedSizeInBitsForDpasB =
6464
32; // Minimum packing size per register for DPAS B.
65-
static const char *const operandLayoutNamePrefix = "layout_operand_";
66-
static const char *const resultLayoutNamePrefix = "layout_result_";
6765

6866
namespace {
6967

@@ -728,10 +726,7 @@ class LayoutAttrAssignment {
728726
void LayoutAttrAssignment::assignToUsers(Value v, xegpu::LayoutAttr layout) {
729727
for (OpOperand &user : v.getUses()) {
730728
Operation *owner = user.getOwner();
731-
unsigned operandNumber = user.getOperandNumber();
732-
// Use a generic name for ease of querying the layout attribute later.
733-
std::string attrName =
734-
operandLayoutNamePrefix + std::to_string(operandNumber);
729+
std::string attrName = xegpu::getLayoutName(user);
735730
owner->setAttr(attrName, layout);
736731
}
737732
}
@@ -805,10 +800,10 @@ LogicalResult LayoutAttrAssignment::assign(Operation *op) {
805800
return success();
806801
}
807802
// Otherwise simply attach the layout to the op itself.
808-
for (auto [i, r] : llvm::enumerate(op->getResults())) {
803+
for (auto r : op->getOpResults()) {
809804
xegpu::LayoutAttr layoutInfo = getLayoutAttrForValue(r);
810805
if (layoutInfo) {
811-
std::string attrName = resultLayoutNamePrefix + std::to_string(i);
806+
std::string attrName = xegpu::getLayoutName(r);
812807
op->setAttr(attrName, layoutInfo);
813808
// Attach the layout attribute to the users of the result.
814809
assignToUsers(r, layoutInfo);
@@ -928,11 +923,8 @@ static SmallVector<NamedAttribute>
928923
removeTemporaryLayoutAttributes(ArrayRef<NamedAttribute> attrs) {
929924
SmallVector<NamedAttribute> newAttrs;
930925
for (NamedAttribute attr : attrs) {
931-
if (attr.getName().strref().contains(operandLayoutNamePrefix) ||
932-
attr.getName().strref().contains(resultLayoutNamePrefix)) {
933-
continue;
934-
}
935-
newAttrs.push_back(attr);
926+
if (!isa<xegpu::LayoutAttr>(attr.getValue()))
927+
newAttrs.push_back(attr);
936928
}
937929
return newAttrs;
938930
}
@@ -1335,11 +1327,10 @@ struct DpasDistribution final : public gpu::WarpDistributionPattern {
13351327

13361328
auto dpasOp = operand->get().getDefiningOp<xegpu::DpasOp>();
13371329
unsigned operandIdx = operand->getOperandNumber();
1338-
std::string layoutAName =
1339-
llvm::formatv("{0}{1}", operandLayoutNamePrefix, 0).str();
1340-
std::string layoutBName =
1341-
llvm::formatv("{0}{1}", operandLayoutNamePrefix, 1).str();
1342-
auto layoutCName = llvm::formatv("{0}{1}", resultLayoutNamePrefix, 0).str();
1330+
std::string layoutAName = xegpu::getLayoutName(dpasOp->getOpOperand(0));
1331+
std::string layoutBName = xegpu::getLayoutName(dpasOp->getOpOperand(1));
1332+
std::string layoutCName = xegpu::getLayoutName(dpasOp->getOpResult(0));
1333+
13431334
xegpu::LayoutAttr layoutA =
13441335
dpasOp->getAttrOfType<xegpu::LayoutAttr>(layoutAName);
13451336
xegpu::LayoutAttr layoutB =

mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "mlir/Dialect/XeGPU/Utils/XeGPUUtils.h"
1414
#include "mlir/Dialect/XeGPU/IR/XeGPU.h"
15+
#include "mlir/IR/Operation.h"
16+
#include "llvm/Support/FormatVariadic.h"
1517
#include <cstdint>
1618
#include <numeric>
1719

@@ -83,3 +85,41 @@ mlir::xegpu::getDistributedVectorType(VectorType originalType,
8385
/*memory_space=*/xegpu::MemorySpace::Global, layout);
8486
return xegpu::getDistributedVectorType(helperTdescTy);
8587
}
88+
89+
xegpu::LayoutAttr xegpu::getLayoutAttr(Value value) {
90+
if (!value)
91+
return LayoutAttr();
92+
93+
if (auto tdescTy = dyn_cast<xegpu::TensorDescType>(value.getType()))
94+
return tdescTy.getLayoutAttr();
95+
96+
if (auto result = dyn_cast<OpResult>(value)) {
97+
Operation *defOp = result.getDefiningOp();
98+
assert(defOp && "result must have a defining op");
99+
std::string layoutName = getLayoutName(result);
100+
if (defOp->hasAttr(layoutName))
101+
return defOp->getAttrOfType<xegpu::LayoutAttr>(layoutName);
102+
}
103+
104+
if (auto arg = dyn_cast<BlockArgument>(value)) {
105+
auto parentOp = arg.getOwner()->getParentOp();
106+
if (auto funcOp = dyn_cast<FuncOp>(parentOp)) {
107+
std::string layoutName = getLayoutName(arg);
108+
if (funcOp->hasAttr(layoutName))
109+
return funcOp->getAttrOfType<xegpu::LayoutAttr>(layoutName);
110+
}
111+
}
112+
113+
return nullptr;
114+
}
115+
116+
std::string xegpu::getLayoutName(OpOperand &opr) {
117+
const StringRef prefix("layout_operand_");
118+
return llvm::formatv("{0}{1}", prefix, opr.getOperandNumber()).str();
119+
}
120+
121+
std::string xegpu::getLayoutName(OpResult res) {
122+
const StringRef prefix = "layout_result_";
123+
return llvm::formatv("{0}{1}", prefix, res.getResultNumber()).str();
124+
}
125+

0 commit comments

Comments
 (0)