25struct GpuIdOpInterface
26 :
public ValueBoundsOpInterface::ExternalModel<GpuIdOpInterface<Op>, Op> {
27 void populateBoundsForIndexValue(Operation *op, Value value,
28 ValueBoundsConstraintSet &cstr)
const {
29 auto inferrable = cast<InferIntRangeInterface>(op);
31 "inferring for value that isn't the GPU op's result");
32 auto translateConstraint = [&](Value v,
const ConstantIntRanges &range) {
34 "GPU ID op inferring values for something that's not its result");
35 cstr.
bound(v) >= range.smin().getSExtValue();
36 cstr.
bound(v) <= range.smax().getSExtValue();
38 assert(inferrable->getNumOperands() == 0 &&
"ID ops have no operands");
39 inferrable.inferResultRanges({}, translateConstraint);
47struct SubgroupBroadcastOpInterface
48 :
public ValueBoundsOpInterface::ExternalModel<SubgroupBroadcastOpInterface,
49 SubgroupBroadcastOp> {
50 void populateBoundsForIndexValue(Operation *op, Value value,
51 ValueBoundsConstraintSet &cstr)
const {
52 auto broadcastOp = cast<SubgroupBroadcastOp>(op);
53 assert(value == broadcastOp.getResult() &&
"invalid value");
57 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
58 ValueBoundsConstraintSet &cstr)
const {
59 auto broadcastOp = cast<SubgroupBroadcastOp>(op);
60 assert(value == broadcastOp.getResult() &&
"invalid value");
61 cstr.
bound(value)[dim] == cstr.
getExpr(broadcastOp.getSrc(), dim);
65struct GpuLaunchOpInterface
66 :
public ValueBoundsOpInterface::ExternalModel<GpuLaunchOpInterface,
68 void populateBoundsForIndexValue(Operation *op, Value value,
69 ValueBoundsConstraintSet &cstr)
const {
70 auto launchOp = cast<LaunchOp>(op);
72 Value sizeArg =
nullptr;
74 KernelDim3 gridSizeArgs = launchOp.getGridSizeOperandValues();
75 KernelDim3 blockSizeArgs = launchOp.getBlockSizeOperandValues();
77 auto match = [&](KernelDim3 bodyArgs, KernelDim3 externalArgs,
79 if (value == bodyArgs.
x) {
80 sizeArg = externalArgs.x;
83 if (value == bodyArgs.
y) {
84 sizeArg = externalArgs.y;
87 if (value == bodyArgs.
z) {
88 sizeArg = externalArgs.z;
92 match(launchOp.getThreadIds(), blockSizeArgs,
false);
93 match(launchOp.getBlockSize(), blockSizeArgs,
true);
94 match(launchOp.getBlockIds(), gridSizeArgs,
false);
95 match(launchOp.getGridSize(), gridSizeArgs,
true);
96 if (launchOp.hasClusterSize()) {
97 KernelDim3 clusterSizeArgs = *launchOp.getClusterSizeOperandValues();
98 match(*launchOp.getClusterIds(), clusterSizeArgs,
false);
99 match(*launchOp.getClusterSize(), clusterSizeArgs,
true);
106 cstr.
bound(value) >= 1;
109 cstr.
bound(value) >= 0;
118#define REGISTER(X) X::attachInterface<GpuIdOpInterface<X>>(*ctx);
134 LaunchOp::attachInterface<GpuLaunchOpInterface>(*ctx);
135 SubgroupBroadcastOp::attachInterface<SubgroupBroadcastOpInterface>(*ctx);
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.
MLIRContext is the top-level object for a collection of MLIR operations.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
AffineExpr getExpr(Value value, std::optional< int64_t > dim=std::nullopt)
Return an expression that represents the given index-typed value or shaped value dimension.
BoundBuilder bound(Value value)
Add a bound for the given index-typed value or shaped value.
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.