Skip to content

Commit 380a694

Browse files
Improve documentation, add launch param attrs
1 parent 67e32af commit 380a694

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-9
lines changed

mlir/python/mlir/dialects/gpu/__init__.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .._gpu_ops_gen import _Dialect
77
from .._gpu_enum_gen import *
88
from ..._mlir_libs._mlirDialectsGPU import *
9-
from typing import Callable, Sequence, Union, Optional
9+
from typing import Callable, Sequence, Union, Optional, List
1010

1111
try:
1212
from ...ir import (
@@ -20,6 +20,7 @@
2020
Type,
2121
DictAttr,
2222
Attribute,
23+
DenseI32ArrayAttr,
2324
)
2425
from .._ods_common import (
2526
get_default_loc_context as _get_default_loc_context,
@@ -29,26 +30,44 @@
2930
raise RuntimeError("Error loading imports from extension module") from e
3031

3132

32-
FUNCTION_TYPE_ATTRIBUTE_NAME = "function_type"
3333
KERNEL_ATTRIBUTE_NAME = "gpu.kernel"
34+
KNOWN_BLOCK_SIZE_ATTRIBUTE_NAME = "gpu.known_block_size"
35+
KNOWN_GRID_SIZE_ATTRIBUTE_NAME = "gpu.known_grid_size"
36+
37+
FUNCTION_TYPE_ATTRIBUTE_NAME = "function_type"
3438
SYM_NAME_ATTRIBUTE_NAME = "sym_name"
3539
ARGUMENT_ATTRIBUTE_NAME = "arg_attrs"
3640
RESULT_ATTRIBUTE_NAME = "res_attrs"
3741

38-
3942
@_ods_cext.register_operation(_Dialect, replace=True)
4043
class GPUFuncOp(GPUFuncOp):
44+
__doc__ = GPUFuncOp.__doc__
45+
4146
def __init__(
4247
self,
4348
function_type: Union[FunctionType, TypeAttr],
4449
sym_name: Optional[Union[str, StringAttr]] = None,
4550
kernel: Optional[bool] = None,
4651
body_builder: Optional[Callable[[GPUFuncOp], None]] = None,
52+
known_block_size: Optional[Union[List[int], DenseI32ArrayAttr]] = None,
53+
known_grid_size: Optional[Union[List[int], DenseI32ArrayAttr]] = None,
4754
*args,
4855
loc=None,
4956
ip=None,
5057
**kwargs,
5158
):
59+
"""
60+
Create a GPUFuncOp with the provided `function_type`, `sym_name`, `kernel`, `body_builder`, `known_block_size`, and `known_grid_size`.
61+
- `function_type` is a FunctionType or a TypeAttr.
62+
- `sym_name` is a string or a StringAttr representing the function name.
63+
- `kernel` is a boolean representing whether the function is a kernel.
64+
- `body_builder` is an optional callback. When provided, a new entry block
65+
is created and the callback is invoked with the new op as argument within
66+
an InsertionPoint context already set for the block. The callback is
67+
expected to insert a terminator in the block.
68+
- `known_block_size` is an optional list of integers or a DenseI32ArrayAttr representing the known block size.
69+
- `known_grid_size` is an optional list of integers or a DenseI32ArrayAttr representing the known grid size.
70+
"""
5271
function_type = (
5372
TypeAttr.get(function_type)
5473
if not isinstance(function_type, TypeAttr)
@@ -62,6 +81,20 @@ def __init__(
6281
if body_builder is not None:
6382
with InsertionPoint(self.add_entry_block()):
6483
body_builder(self)
84+
if known_block_size is not None:
85+
if isinstance(known_block_size, list):
86+
self.attributes[KNOWN_BLOCK_SIZE_ATTRIBUTE_NAME] = (
87+
DenseI32ArrayAttr.get(known_block_size)
88+
)
89+
else:
90+
self.attributes[KNOWN_BLOCK_SIZE_ATTRIBUTE_NAME] = known_block_size
91+
if known_grid_size is not None:
92+
if isinstance(known_grid_size, list):
93+
self.attributes[KNOWN_GRID_SIZE_ATTRIBUTE_NAME] = (
94+
DenseI32ArrayAttr.get(known_grid_size)
95+
)
96+
else:
97+
self.attributes[KNOWN_GRID_SIZE_ATTRIBUTE_NAME] = known_grid_size
6598

6699
@property
67100
def type(self) -> FunctionType:
@@ -77,6 +110,18 @@ def name(self) -> StringAttr:
77110
def is_kernel(self) -> bool:
78111
return KERNEL_ATTRIBUTE_NAME in self.attributes
79112

113+
@property
114+
def known_block_size(self) -> Optional[DenseI32ArrayAttr]:
115+
if KNOWN_BLOCK_SIZE_ATTRIBUTE_NAME not in self.attributes:
116+
return None
117+
return self.attributes[KNOWN_BLOCK_SIZE_ATTRIBUTE_NAME]
118+
119+
@property
120+
def known_grid_size(self) -> Optional[DenseI32ArrayAttr]:
121+
if KNOWN_GRID_SIZE_ATTRIBUTE_NAME not in self.attributes:
122+
return None
123+
return self.attributes[KNOWN_GRID_SIZE_ATTRIBUTE_NAME]
124+
80125
def add_entry_block(self) -> Block:
81126
function_type = self.type
82127
return self.body.blocks.append(

mlir/test/python/dialects/gpu/dialect.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# RUN: %PYTHON %s | FileCheck %s
22

33
from mlir.ir import *
4+
import mlir.ir as ir
45
import mlir.dialects.gpu as gpu
56
import mlir.dialects.gpu.passes
67
from mlir.passmanager import *
7-
import mlir.ir as ir
88

99

1010
def run(f):
@@ -70,15 +70,16 @@ def testObjectAttr():
7070
# CHECK-LABEL: testGPUFuncOp
7171
@run
7272
def testGPUFuncOp():
73+
assert gpu.GPUFuncOp.__doc__ is not None
7374
module = Module.create()
7475
with InsertionPoint(module.body):
7576
gpu_module_name = StringAttr.get("gpu_module")
7677
gpumodule = gpu.GPUModuleOp(gpu_module_name)
7778
block = gpumodule.bodyRegion.blocks.append()
7879

7980
def builder(func: gpu.GPUFuncOp) -> None:
80-
_ = gpu.GlobalIdOp(gpu.Dimension.x)
81-
_ = gpu.ReturnOp([])
81+
gpu.GlobalIdOp(gpu.Dimension.x)
82+
gpu.ReturnOp([])
8283

8384
with InsertionPoint(block):
8485
name = StringAttr.get("kernel0")
@@ -96,6 +97,8 @@ def builder(func: gpu.GPUFuncOp) -> None:
9697
sym_name="kernel1",
9798
kernel=True,
9899
body_builder=builder,
100+
known_block_size=[1, 2, 3],
101+
known_grid_size=DenseI32ArrayAttr.get([4, 5, 6]),
99102
)
100103

101104
assert func.name.value == "kernel1"
@@ -104,13 +107,17 @@ def builder(func: gpu.GPUFuncOp) -> None:
104107
assert func.arguments == []
105108
assert func.entry_block == func.body.blocks[0]
106109
assert func.is_kernel
110+
assert func.known_block_size == DenseI32ArrayAttr.get([1, 2, 3])
111+
assert func.known_grid_size == DenseI32ArrayAttr.get([4, 5, 6])
107112

108-
non_kernel_func = gpu.GPUFuncOp(
113+
func = gpu.GPUFuncOp(
109114
func_type,
110115
sym_name="non_kernel_func",
111116
body_builder=builder,
112117
)
113-
assert not non_kernel_func.is_kernel
118+
assert not func.is_kernel
119+
assert func.known_block_size is None
120+
assert func.known_grid_size is None
114121

115122
print(module)
116123

@@ -119,7 +126,9 @@ def builder(func: gpu.GPUFuncOp) -> None:
119126
# CHECK: %[[VAL_0:.*]] = gpu.global_id x
120127
# CHECK: gpu.return
121128
# CHECK: }
122-
# CHECK: gpu.func @kernel1() kernel {
129+
# CHECK: gpu.func @kernel1() kernel attributes
130+
# CHECK-SAME: gpu.known_block_size = array<i32: 1, 2, 3>
131+
# CHECK-SAME: gpu.known_grid_size = array<i32: 4, 5, 6>
123132
# CHECK: %[[VAL_0:.*]] = gpu.global_id x
124133
# CHECK: gpu.return
125134
# CHECK: }

0 commit comments

Comments
 (0)