MLIR 24.0.0git
ShardingInterfaceImpl.cpp
Go to the documentation of this file.
1//===- ShardingInterfaceImpl.cpp - Arith sharding models ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
14
15using namespace mlir;
16using namespace mlir::arith;
17using namespace mlir::shard;
18
19namespace {
20// Sharding of arith.constant
21// RankedTensor constants can be sharded like any other tensor.
22// %cst = arith.constant dense<0.000000e+00> : tensor<1024x1024xf32>
23// %sharding = shard.sharding @grid4x4 split_axes = [[0]] : !shard.sharding
24// Scalar constants are always replicated and need no sharding annotation.
25
26struct ConstantShardingInterface
27 : public ShardingInterface::ExternalModel<ConstantShardingInterface,
28 ConstantOp> {
29 SmallVector<utils::IteratorType> getLoopIteratorTypes(Operation *op) const {
30 auto ndims = 0;
31 if (auto type = dyn_cast<RankedTensorType>(op->getResult(0).getType())) {
32 ndims = type.getRank();
33 }
34 return SmallVector<utils::IteratorType>(ndims,
35 utils::IteratorType::parallel);
36 }
37
38 SmallVector<AffineMap> getIndexingMaps(Operation *op) const {
39 if (auto type = dyn_cast<RankedTensorType>(op->getResult(0).getType())) {
40 return SmallVector<AffineMap>(1, {AffineMap::getMultiDimIdentityMap(
41 type.getRank(), op->getContext())});
42 }
43 return {};
44 }
45
46 // Indicate failure if no result sharding exists.
47 // Otherwise mirror result sharding if it is a tensor constant.
48 // Otherwise return replication option.
49 FailureOr<ShardingOption>
50 getShardingOption(Operation *op, ArrayRef<Sharding> operandShardings,
51 ArrayRef<Sharding> resultShardings) const {
52 assert(resultShardings.size() == 1 &&
53 "Expecting exactly one result sharding for arith.constant");
54 const auto &resultSharding = resultShardings[0];
55 if (!resultSharding) {
56 return failure();
57 }
58 if (auto type = dyn_cast<RankedTensorType>(op->getResult(0).getType())) {
59 ShardingArray axesArray(resultSharding.getSplitAxes().size());
60 for (auto [i, axes] : llvm::enumerate(resultSharding.getSplitAxes())) {
61 axesArray[i].append(axes.asArrayRef().begin(), axes.asArrayRef().end());
62 }
63 return ShardingOption(axesArray, resultSharding.getGridAttr());
64 }
65 return ShardingOption({}, resultSharding.getGridAttr());
66 }
67
68 LogicalResult partition(Operation *op, ArrayRef<Value> partitiondOperands,
69 ArrayRef<Sharding> operandShardings,
70 ArrayRef<Sharding> resultShardings,
71 IRMapping &partitionMap,
72 SymbolTableCollection &symbolTable,
73 OpBuilder &builder) const {
74 auto cOp = cast<ConstantOp>(op);
75 if (auto value = dyn_cast<DenseTypedElementsAttr>(cOp.getValue())) {
76 if (!value.isSplat() || !resultShardings[0]) {
77 // Currently non-splat constants are not supported.
78 return failure();
79 }
80 const auto &sharding = resultShardings[0];
81 auto newType = cast<RankedTensorType>(shardType(
82 cOp.getType(), getGrid(op, sharding.getGridAttr(), symbolTable),
83 sharding));
84 auto newValue = value.resizeSplat(newType);
85 auto newOp = ConstantOp::create(builder, op->getLoc(), newType, newValue);
86 partitionMap.map(op->getResult(0), newOp.getResult());
87 partitionMap.map(op, newOp.getOperation());
88 } else {
89 // `clone` will populate the mapping of old to new results.
90 (void)builder.clone(*op, partitionMap);
91 }
92 return success();
93 }
94};
95} // namespace
96
98 DialectRegistry &registry) {
99
100 registry.addExtension(+[](MLIRContext *ctx, ArithDialect *dialect) {
101 ConstantOp::template attachInterface<ConstantShardingInterface>(*ctx);
102 });
103}
return success()
static AffineMap getMultiDimIdentityMap(unsigned numDims, MLIRContext *context)
Returns an AffineMap with 'numDims' identity result dim exprs.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
Definition IRMapping.h:30
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:71
Operation * clone(Operation &op, IRMapping &mapper)
Creates a deep copy of the specified operation, remapping any operands that use values outside of the...
Definition Builders.cpp:581
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition Operation.h:434
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:240
MLIRContext * getContext()
Return the context this operation is associated with.
Definition Operation.h:233
Type getType() const
Return the type of this value.
Definition Value.h:105
void registerShardingInterfaceExternalModels(DialectRegistry &registry)
Type shardType(Type type, GridOp grid, Sharding sharding)
Definition ShardOps.cpp:289
shard::GridOp getGrid(Operation *op, FlatSymbolRefAttr gridSymbol, SymbolTableCollection &symbolTableCollection)
Definition ShardOps.h:127
SmallVector< SmallVector< GridAxis > > ShardingArray
Include the generated interface declarations.