MLIR 24.0.0git
ShardOps.h
Go to the documentation of this file.
1//===- ShardOps.h - Shard Dialect Operations --------------------*- C++ -*-===//
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
9#ifndef MLIR_DIALECT_SHARD_IR_SHARDOPS_H
10#define MLIR_DIALECT_SHARD_IR_SHARDOPS_H
11
14#include "mlir/IR/Diagnostics.h"
17#include "mlir/IR/SymbolTable.h"
18#include "llvm/Support/MathExtras.h"
19
20namespace mlir {
21namespace shard {
22
23using GridAxis = int16_t;
27
28} // namespace shard
29} // namespace mlir
30
31#include "mlir/Dialect/Shard/IR/ShardEnums.h.inc"
32
33#define GET_ATTRDEF_CLASSES
34#include "mlir/Dialect/Shard/IR/ShardAttributes.h.inc"
35
36namespace mlir {
37namespace shard {
38
39class Sharding {
40private:
43 SmallVector<int64_t> static_halo_sizes;
44 SmallVector<int64_t> static_sharded_dims_offsets;
45 SmallVector<Value> dynamic_halo_sizes;
46 SmallVector<Value> dynamic_sharded_dims_offsets;
47
48public:
49 Sharding(::mlir::FlatSymbolRefAttr grid_ = nullptr);
50 Sharding(Value rhs);
52 ArrayRef<GridAxesAttr> split_axes_,
53 ArrayRef<int64_t> static_halo_sizes_ = {},
54 ArrayRef<int64_t> static_sharded_dims_offsets_ = {},
55 ArrayRef<Value> dynamic_halo_sizes_ = {},
56 ArrayRef<Value> dynamic_sharded_dims_offsets_ = {});
57 ::mlir::FlatSymbolRefAttr getGridAttr() const { return grid; }
58 ::llvm::StringRef getGrid() const { return grid ? grid.getValue() : ""; }
59 ArrayRef<GridAxesAttr> getSplitAxes() const { return split_axes; }
60 ArrayRef<int64_t> getStaticHaloSizes() const { return static_halo_sizes; }
62 return static_sharded_dims_offsets;
63 }
64 ArrayRef<Value> getDynamicHaloSizes() const { return dynamic_halo_sizes; }
66 return dynamic_sharded_dims_offsets;
67 }
68 operator bool() const { return (!grid) == false; }
69 bool operator==(Value rhs) const;
70 bool operator!=(Value rhs) const;
71 bool operator==(const Sharding &rhs) const;
72 bool operator!=(const Sharding &rhs) const;
73 bool equalSplitAxes(const Sharding &rhs) const;
74 bool equalHaloAndShardSizes(const Sharding &rhs) const;
75 bool equalHaloSizes(const Sharding &rhs) const;
76 bool equalShardSizes(const Sharding &rhs) const;
77};
78
79llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Sharding &sharding);
80
81inline Diagnostic &operator<<(Diagnostic &diag, const Sharding &sharding) {
82 std::string str;
83 llvm::raw_string_ostream os(str);
84 os << sharding;
85 return diag << os.str();
86}
87
88} // namespace shard
89} // namespace mlir
90
91#define GET_TYPEDEF_CLASSES
92#include "mlir/Dialect/Shard/IR/ShardTypes.h.inc"
93
94#define GET_OP_CLASSES
95#include "mlir/Dialect/Shard/IR/ShardOps.h.inc"
96
97namespace mlir {
98namespace shard {
99
100inline bool isReductionLoop(utils::IteratorType iType) {
101 return iType == utils::IteratorType::reduction;
102}
103
104// Remove empty subarrays of `array` until a minimum lengh of one is reached.
105template <typename T>
107 while (array.size() > 1 && array.back().empty())
108 array.pop_back();
109}
110
111// Is the same tensor replicated on all processes.
112inline bool isFullReplication(Sharding sharding) {
113 return llvm::all_of(sharding.getSplitAxes(), [](GridAxesAttr axes) {
114 return axes.asArrayRef().empty();
115 });
116}
117
118inline shard::GridOp
120 SymbolTableCollection &symbolTableCollection) {
121 if (!gridSymbol)
122 return nullptr;
123 return symbolTableCollection.lookupNearestSymbolFrom<shard::GridOp>(
124 op, gridSymbol);
125}
126
127inline shard::GridOp getGrid(Operation *op, FlatSymbolRefAttr gridSymbol,
128 SymbolTableCollection &symbolTableCollection) {
129 shard::GridOp gridOp = getGridOrNull(op, gridSymbol, symbolTableCollection);
130 assert(gridOp);
131 return gridOp;
132}
133
134// Get the corresponding grid op using the standard attribute nomenclature.
135template <typename Op>
136shard::GridOp getGrid(Op op, SymbolTableCollection &symbolTableCollection) {
137 return getGrid(op.getOperation(), op.getGridAttr(), symbolTableCollection);
138}
139
140template <>
141inline shard::GridOp
142getGrid<ShardOp>(ShardOp op, SymbolTableCollection &symbolTableCollection) {
143 return getGrid(
144 op.getOperation(),
145 cast<ShardingOp>(op.getSharding().getDefiningOp()).getGridAttr(),
146 symbolTableCollection);
147}
148
149// Get the number of processes that participate in each group
150// induced by `gridAxes`.
151template <typename GridAxesRange, typename GridShapeRange>
152int64_t collectiveProcessGroupSize(GridAxesRange &&gridAxes,
153 GridShapeRange &&gridShape) {
154 int64_t res = 1;
155
156 for (GridAxis axis : gridAxes) {
157 auto axisSize = *(std::begin(gridShape) + axis);
158 if (ShapedType::isDynamic(axisSize)) {
159 return ShapedType::kDynamic;
160 }
161 res *= axisSize;
162 }
163
164 return res;
165}
166
167template <typename GridAxesRange>
168int64_t collectiveProcessGroupSize(GridAxesRange &&gridAxes, GridOp grid) {
169 return collectiveProcessGroupSize(std::forward<GridAxesRange>(gridAxes),
170 grid.getShape());
171}
172
173// Get the size of a sharded dimension.
174inline int64_t shardDimension(int64_t dimSize, int64_t shardCount) {
175 if (ShapedType::isDynamic(dimSize) || ShapedType::isDynamic(shardCount))
176 return ShapedType::kDynamic;
177
178 assert(dimSize % shardCount == 0);
179 return dimSize / shardCount;
180}
181
182// Get the size of an unsharded dimension.
183inline int64_t gatherDimension(int64_t dimSize, int64_t shardCount) {
184 if (ShapedType::isDynamic(dimSize) || ShapedType::isDynamic(shardCount))
185 return ShapedType::kDynamic;
186
187 return dimSize * shardCount;
188}
189
190// Return the per-device sharded type for `shape` based on `sharding`.
191// This is the tensor shape on each grid partition.
192// Example:
193// On a 2x4x? grid with split axes = [[0], [1], [2]] the shape ?x5x1 would
194// result in a shape for each shard of ?x2x?.
195ShapedType shardShapedType(ShapedType shape, GridOp grid, Sharding sharding);
196
197// If ranked tensor type return its sharded counterpart.
198//
199// If not ranked tensor type return `type`.
200// `sharding` in that case must be null.
201Type shardType(Type type, GridOp grid, Sharding sharding);
202
203// Insert shard op if there is not one that already has the same sharding.
204// Use newShardOp if it is not null. Otherwise create a new one.
205// May insert resharding if required.
206// Potentially updates newShardOp.
208 OpBuilder &builder);
209void maybeInsertSourceShardingAnnotation(Sharding sharding, OpOperand &operand,
210 OpBuilder &builder);
211
212/// Converts a vector of OpFoldResults (ints) into vector of Values of the
213/// provided type.
216 ValueRange dynamics, Type type = Type());
217} // namespace shard
218} // namespace mlir
219
220#endif // MLIR_DIALECT_SHARD_IR_SHARDOPS_H
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine.
A symbol reference with a reference path containing a single element.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
This class helps build Operations.
Definition Builders.h:210
This class represents an operand of an operation.
Definition Value.h:256
This is a value defined by a result of an operation.
Definition Value.h:456
This provides public APIs that all operations should have.
Operation * getOperation()
Inherit getOperation from OpState.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
This class represents a collection of SymbolTables.
virtual Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:392
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
ArrayRef< Value > getDynamicShardedDimsOffsets() const
Definition ShardOps.h:65
bool operator!=(Value rhs) const
Definition ShardOps.cpp:746
bool equalShardSizes(const Sharding &rhs) const
Definition ShardOps.cpp:714
Sharding(::mlir::FlatSymbolRefAttr grid_=nullptr)
Definition ShardOps.cpp:777
static Sharding get(::mlir::FlatSymbolRefAttr grid_, ArrayRef< GridAxesAttr > split_axes_, ArrayRef< int64_t > static_halo_sizes_={}, ArrayRef< int64_t > static_sharded_dims_offsets_={}, ArrayRef< Value > dynamic_halo_sizes_={}, ArrayRef< Value > dynamic_sharded_dims_offsets_={})
Definition ShardOps.cpp:795
bool equalSplitAxes(const Sharding &rhs) const
Definition ShardOps.cpp:691
ArrayRef< int64_t > getStaticHaloSizes() const
Definition ShardOps.h:60
::mlir::FlatSymbolRefAttr getGridAttr() const
Definition ShardOps.h:57
::llvm::StringRef getGrid() const
Definition ShardOps.h:58
bool equalHaloAndShardSizes(const Sharding &rhs) const
Definition ShardOps.cpp:710
bool operator==(Value rhs) const
Definition ShardOps.cpp:742
ArrayRef< Value > getDynamicHaloSizes() const
Definition ShardOps.h:64
ArrayRef< int64_t > getStaticShardedDimsOffsets() const
Definition ShardOps.h:61
ArrayRef< GridAxesAttr > getSplitAxes() const
Definition ShardOps.h:59
bool equalHaloSizes(const Sharding &rhs) const
Definition ShardOps.cpp:730
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const Sharding &sharding)
Definition ShardOps.cpp:754
ShapedType shardShapedType(ShapedType shape, GridOp grid, Sharding sharding)
Definition ShardOps.cpp:279
shard::GridOp getGrid< ShardOp >(ShardOp op, SymbolTableCollection &symbolTableCollection)
Definition ShardOps.h:142
void maybeInsertTargetShardingAnnotation(Sharding sharding, OpResult result, OpBuilder &builder)
Definition ShardOps.cpp:336
DenseI16ArrayAttr GridAxesAttr
Definition ShardOps.h:24
void removeTrailingEmptySubArray(SmallVector< SmallVector< T > > &array)
Definition ShardOps.h:106
shard::GridOp getGridOrNull(Operation *op, FlatSymbolRefAttr gridSymbol, SymbolTableCollection &symbolTableCollection)
Definition ShardOps.h:119
bool isFullReplication(Sharding sharding)
Definition ShardOps.h:112
int16_t GridAxis
Definition ShardOps.h:23
DenseI64ArrayAttr HaloSizePairAttr
Definition ShardOps.h:26
void maybeInsertSourceShardingAnnotation(Sharding sharding, OpOperand &operand, OpBuilder &builder)
Definition ShardOps.cpp:350
bool isReductionLoop(utils::IteratorType iType)
Definition ShardOps.h:100
DenseI64ArrayAttr ShardShapeAttr
Definition ShardOps.h:25
int64_t shardDimension(int64_t dimSize, int64_t shardCount)
Definition ShardOps.h:174
Type shardType(Type type, GridOp grid, Sharding sharding)
Definition ShardOps.cpp:289
SmallVector< Value > getMixedAsValues(OpBuilder b, const Location &loc, llvm::ArrayRef< int64_t > statics, ValueRange dynamics, Type type=Type())
Converts a vector of OpFoldResults (ints) into vector of Values of the provided type.
Definition ShardOps.cpp:75
int64_t collectiveProcessGroupSize(GridAxesRange &&gridAxes, GridShapeRange &&gridShape)
Definition ShardOps.h:152
shard::GridOp getGrid(Operation *op, FlatSymbolRefAttr gridSymbol, SymbolTableCollection &symbolTableCollection)
Definition ShardOps.h:127
int64_t gatherDimension(int64_t dimSize, int64_t shardCount)
Definition ShardOps.h:183
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
detail::DenseArrayAttrImpl< int16_t > DenseI16ArrayAttr