This PR replaces the mixin `OpView` extension mechanism with the standard inheritance mechanism. Why? Firstly, mixins are not very pythonic (inheritance is usually used for this), a little convoluted, and too "tight" (can only be used in the immediately adjacent `_ext.py`). Secondly, it (mixins) are now blocking are correct implementation of "value builders" (see [here](https://github.com/llvm/llvm-project/pull/68764)) where the problem becomes how to choose the correct base class that the value builder should call. This PR looks big/complicated but appearances are deceiving; 4 things were needed to make this work: 1. Drop `skipDefaultBuilders` in `OpPythonBindingGen::emitDefaultOpBuilders` 2. Former mixin extension classes are converted to inherit from the generated `OpView` instead of being "mixins" a. extension classes that simply were calling into an already generated `super().__init__` continue to do so b. (almost all) extension classes that were calling `self.build_generic` because of a lack of default builder being generated can now also just call `super().__init__` 3. To handle the [lone single use-case](https://sourcegraph.com/search?q=context%3Aglobal+select_opview_mixin&patternType=standard&sm=1&groupBy=repo) of `select_opview_mixin`, namely [linalg](https://github.com/llvm/llvm-project/blob/main/mlir/python/mlir/dialects/_linalg_ops_ext.py#L38), only a small change was necessary in `opdsl/lang/emitter.py` (thanks to the emission/generation of default builders/`__init__`s) 4. since the `extend_opview_class` decorator is removed, we need a way to register extension classes as the desired `OpView` that `op.opview` conjures into existence; so we do the standard thing and just enable replacing the existing registered `OpView` i.e., `register_operation(_Dialect, replace=True)`. Note, the upgrade path for the common case is to change an extension to inherit from the generated builder and decorate it with `register_operation(_Dialect, replace=True)`. In the slightly more complicated case where `super().__init(self.build_generic(...))` is called in the extension's `__init__`, this needs to be updated to call `__init__` in `OpView`, i.e., the grandparent (see updated docs). Note, also `<DIALECT>_ext.py` files/modules will no longer be automatically loaded. Note, the PR has 3 base commits that look funny but this was done for the purpose of tracking the line history of moving the `<DIALECT>_ops_ext.py` class into `<DIALECT>.py` and updating (commit labeled "fix").
49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
# RUN: %PYTHON %s | FileCheck %s
|
|
|
|
from mlir.ir import *
|
|
import mlir.dialects.func as func
|
|
import mlir.dialects.arith as arith
|
|
|
|
|
|
def run(f):
|
|
print("\nTEST:", f.__name__)
|
|
f()
|
|
|
|
|
|
# CHECK-LABEL: TEST: testConstantOp
|
|
@run
|
|
def testConstantOps():
|
|
with Context() as ctx, Location.unknown():
|
|
module = Module.create()
|
|
with InsertionPoint(module.body):
|
|
arith.ConstantOp(value=42.42, result=F32Type.get())
|
|
# CHECK: %cst = arith.constant 4.242000e+01 : f32
|
|
print(module)
|
|
|
|
|
|
# CHECK-LABEL: TEST: testFastMathFlags
|
|
@run
|
|
def testFastMathFlags():
|
|
with Context() as ctx, Location.unknown():
|
|
module = Module.create()
|
|
with InsertionPoint(module.body):
|
|
a = arith.ConstantOp(value=42.42, result=F32Type.get())
|
|
r = arith.AddFOp(
|
|
a, a, fastmath=arith.FastMathFlags.nnan | arith.FastMathFlags.ninf
|
|
)
|
|
# CHECK: %0 = arith.addf %cst, %cst fastmath<nnan,ninf> : f32
|
|
print(r)
|
|
|
|
|
|
# CHECK-LABEL: TEST: testArithValueBuilder
|
|
@run
|
|
def testArithValueBuilder():
|
|
with Context() as ctx, Location.unknown():
|
|
module = Module.create()
|
|
f32_t = F32Type.get()
|
|
|
|
with InsertionPoint(module.body):
|
|
a = arith.constant(value=FloatAttr.get(f32_t, 42.42))
|
|
# CHECK: %cst = arith.constant 4.242000e+01 : f32
|
|
print(a)
|