-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[mlir][xegpu] Add definitons of MatrixDescType and related ops. #153273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 13 commits
cce8aba
76ccc39
e62da97
cb0a195
98871cc
06eec6e
6df4291
e11c88d
23380a9
9e3aa8d
af2c25f
0531abf
0385088
f6862fa
552c871
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1101,4 +1101,150 @@ def XeGPU_ConvertLayoutOp: XeGPU_Op<"convert_layout", [Pure, AllTypesMatch<["sou | |
let hasCanonicalizer = 1; | ||
} | ||
|
||
def isSharedPred : CPred<"isSharedMemory(llvm::cast<mlir::MemRefType>($_self))">; | ||
class StaticShared1DMemRefOf<list<Type> allowedTypes> : | ||
ConfinedType<MemRefRankOf<allowedTypes, [1]>, [HasStaticShapePred, isSharedPred], | ||
"statically shaped " # MemRefOf<allowedTypes>.summary # " for shared memory", | ||
"mlir::MemRefType">; | ||
|
||
class SizeInBits<string name> : | ||
StrFunc<"llvm::cast<mlir::ShapedType>($" # name # ".getType()).getNumElements()" | ||
"*llvm::cast<mlir::ShapedType>($" # name # ".getType()).getElementTypeBitWidth()">; | ||
class AllMemSizesMatch<list<string> names> : | ||
AllMatchSameOperatorTrait<names, SizeInBits<"_self">.result, | ||
"size in bits">; | ||
|
||
def XeGPU_CreateMatrixDescOp: XeGPU_Op<"create_matrix_desc", [Pure, | ||
AllMemSizesMatch<["source", "matrix_desc"]>]> { | ||
let summary = "Create a matrix descriptor."; | ||
let description = [{ | ||
Creates a matrix descriptor from a shared local memory (SLM) buffer. | ||
The resulting matrix descriptor has to have the same size as the underlying | ||
shared local memory. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shared local memory => memory. The memory descriptor itself doesn't have to associated with share local memory. |
||
|
||
Arguments: | ||
- `source` : a 1D statically shaped memref with element type i8, representing the raw SLM buffer. | ||
Results: | ||
- `matrix_desc` : the matrix descriptor. | ||
}]; | ||
let arguments = (ins StaticShared1DMemRefOf<[I8]>:$source); | ||
let results = (outs XeGPU_MatrixDesc:$matrix_desc); | ||
let assemblyFormat = "$source prop-dict attr-dict `` `:` type($source) `->` qualified(type($matrix_desc))"; | ||
} | ||
|
||
def XeGPU_LoadMatrixOp: XeGPU_Op<"load_matrix", [MemoryEffects<[MemRead]>, | ||
AllElementTypesMatch<["matrix_desc", "res"]>, | ||
AllRanksMatch<["matrix_desc", "res"]>]> { | ||
let arguments = (ins XeGPU_MatrixDesc:$matrix_desc, | ||
Variadic<Index>: $offsets, | ||
DenseI64ArrayAttr: $const_offsets, | ||
OptionalAttr<LayoutTrait>:$layout | ||
); | ||
let results = (outs XeGPU_ValueType:$res); | ||
let assemblyFormat = [{ | ||
$matrix_desc `` custom<DynamicIndexList>($offsets, $const_offsets) | ||
prop-dict attr-dict `` `:` type(operands) `->` type(results) | ||
}]; | ||
|
||
let description = [{ | ||
This operation reads a block of data from shared local memory (SLM) | ||
using the provided matrix descriptor. | ||
|
||
Arguments: | ||
- `matrix_desc`: the matrix descriptor identifying the SLM region. | ||
- `offsets`: the coordinates within the matrix to read from. | ||
- `layout`: [optional] An attribute for guiding distributions among | ||
subgroups and/or work-items. It currently can accept either | ||
LayoutAttr or SliceAttr. | ||
Results: | ||
- `res`: the matrix elements loaded from SLM. | ||
}]; | ||
|
||
let builders = [ | ||
OpBuilder<(ins "Type":$res, "TypedValue<MatrixDescType>": $matrix_desc, | ||
"llvm::ArrayRef<OpFoldResult>": $offsets, "LayoutTrait": $layout)>, | ||
]; | ||
let extraClassDeclaration = [{ | ||
SmallVector<OpFoldResult> getMixedOffsets() { | ||
return getMixedValues(getConstOffsets(), getOffsets(), getContext()); | ||
} | ||
}]; | ||
|
||
let hasVerifier = 1; | ||
} | ||
|
||
def XeGPU_StoreMatrixOp: XeGPU_Op<"store_matrix", [MemoryEffects<[MemWrite]>, | ||
AllElementTypesMatch<["matrix_desc", "data"]>, | ||
AllRanksMatch<["matrix_desc", "data"]>]> { | ||
let arguments = (ins | ||
XeGPU_ValueType:$data, | ||
XeGPU_MatrixDesc:$matrix_desc, | ||
Variadic<Index>: $offsets, | ||
DenseI64ArrayAttr: $const_offsets, | ||
OptionalAttr<LayoutTrait>:$layout | ||
); | ||
let assemblyFormat = [{ $data `,` $matrix_desc `` custom<DynamicIndexList>($offsets, $const_offsets) | ||
prop-dict attr-dict `` `:` type(operands)}]; | ||
let description = [{ | ||
This operation writes the `data` fragment into the shared local memory region | ||
identified by `matrix_desc`. | ||
|
||
Arguments: | ||
- `matrix_desc`: the matrix descriptor specifying the SLM region. | ||
- `offsets`: the coordinates within the matrix where the data will be written. | ||
- `data`: the values to be stored in the matrix. | ||
- `layout`: [optional] An attribute for guiding distributions among | ||
subgroups and/or work-items. It currently can accept either | ||
LayoutAttr or SliceAttr. | ||
}]; | ||
let builders = [ | ||
OpBuilder<(ins "Value" : $data, "TypedValue<MatrixDescType>": $matrix_desc, | ||
"llvm::ArrayRef<OpFoldResult>": $offsets, "LayoutTrait": $layout)>, | ||
]; | ||
let extraClassDeclaration = [{ | ||
SmallVector<OpFoldResult> getMixedOffsets() { | ||
return getMixedValues(getConstOffsets(), getOffsets(), getContext()); | ||
} | ||
}]; | ||
|
||
let hasVerifier = 1; | ||
} | ||
|
||
def XeGPU_MatrixDescSubviewOp: XeGPU_Op<"matrix_desc_subview", | ||
[Pure, ViewLikeOpInterface, AllElementTypesMatch<["src", "res"]>]> { | ||
let description = [{ | ||
Creates a subview of a matrix descriptor. The resulting matrix descriptor can have | ||
a lower rank than the source; in this case, the result dimensions correspond to the | ||
higher-order dimensions of the source matrix descriptor. | ||
|
||
Arguments: | ||
- `src` : a matrix descriptor. | ||
- `offsets` : the coordinates within the matrix the subview will be created from. | ||
|
||
Results: | ||
- `res` : a matrix descriptor with smaller size. | ||
|
||
}]; | ||
let arguments = (ins XeGPU_MatrixDesc:$src, | ||
Variadic<Index>:$offsets, | ||
DenseI64ArrayAttr:$const_offsets); | ||
let results = (outs XeGPU_MatrixDesc:$res); | ||
let assemblyFormat = [{$src `` custom<DynamicIndexList>($offsets, $const_offsets) prop-dict | ||
attr-dict `` `:` qualified(type($src)) `->` qualified(type($res))}]; | ||
let builders = [ | ||
OpBuilder<(ins "Type": $res, "Value":$src, "llvm::ArrayRef<OpFoldResult>": $offsets)> | ||
]; | ||
|
||
let extraClassDeclaration = [{ | ||
mlir::Value getViewSource() { return getSrc(); } | ||
|
||
SmallVector<OpFoldResult> getMixedOffsets() { | ||
return getMixedValues(getConstOffsets(), getOffsets(), getContext()); | ||
} | ||
}]; | ||
|
||
let hasVerifier = 1; | ||
} | ||
|
||
|
||
#endif // MLIR_DIALECT_XEGPU_IR_XEGPUOPS_TD |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -201,4 +201,53 @@ def XeGPU_Nbarrier: XeGPUTypeDef<"Nbarrier", "nbarrier", [], "mlir::Type"> { | |
}]; | ||
} | ||
|
||
def XeGPU_MatrixDesc: XeGPUTypeDef<"MatrixDesc", "matrix_desc", [ShapedTypeInterface], "mlir::Type"> { | ||
let summary = "MatrixDesc describing the data in SLM"; | ||
let description = [{ | ||
MatrixDesc represents a block of data stored in shared local memory. | ||
By default, unless a layout attribute is provided, the data is stored | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this layout? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the tests, there is usage like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please refer to intel/mlir-extensions#1092 for the motivation and explanation of the slm memory layout of matrix descriptor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to the questions here. It just reads as a MemRef layout which is fine but could use explicit clarification as Could you add more description here? Or at least an example snippet. |
||
contiguously in row-major order within the region. | ||
|
||
Examples: | ||
```mlir | ||
// A matrix of data stored in column-major order. | ||
!xegpu.matrix_desc<128x128xf16, #xegpu.mem_layout<stride = [1, 128]>> | ||
|
||
// A matrix of data stored in a blocked layout. Elements within the same block | ||
// are stored contiguously in memory. Blocks are stored in row-major order. | ||
!xegpu.matrix_desc<128x128xf16, #xegpu.mem_layout<block = [8, 8]>> | ||
|
||
// A matrix of data stored in column-major order with blocked layout. | ||
!xegpu.matrix_desc<128x128xf16, #xegpu.mem_layout<stride = [1, 128], block = [8, 8]>> | ||
``` | ||
}]; | ||
let parameters = (ins ArrayRefParameter<"int64_t">: $shape, | ||
"mlir::Type": $elementType, | ||
OptionalParameter<"MemLayoutAttr">: $mem_layout); | ||
|
||
let extraClassDeclaration = [{ | ||
bool hasRank() const { return true; } | ||
|
||
MatrixDescType cloneWith(std::optional<llvm::ArrayRef<int64_t>> shape, Type elementType) const { | ||
return MatrixDescType::get(getContext(), shape.value_or(getShape()), elementType, getMemLayout()); | ||
} | ||
|
||
ArrayAttr getStrides() { | ||
auto layout = getMemLayout(); | ||
if (layout && layout.hasAttr("stride")) { | ||
return layout.getStrides(); | ||
} | ||
|
||
// derive and return default strides | ||
SmallVector<int64_t> defaultStrides; | ||
llvm::append_range(defaultStrides, getShape().drop_front()); | ||
llvm::append_values(defaultStrides, 1); | ||
Builder builder(getContext()); | ||
return builder.getI64ArrayAttr(defaultStrides); | ||
} | ||
}]; | ||
|
||
let hasCustomAssemblyFormat = true; | ||
} | ||
|
||
#endif // MLIR_DIALECT_XEGPU_IR_XEGPUTYPES_TD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove extra line