import gc
from mlir.ir import *
from mlir.dialects import func
def run(f):
print("\nTEST:", f.__name__)
f()
gc.collect()
assert Context._get_live_count() == 0
return f
@run
def testCapsuleConversions():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
value = Operation.create("custom.op1", results=[i32]).result
value_capsule = value._CAPIPtr
assert '"mlir.ir.Value._CAPIPtr"' in repr(value_capsule)
value2 = Value._CAPICreate(value_capsule)
assert value2 == value
@run
def testOpResultOwner():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
op = Operation.create("custom.op1", results=[i32])
assert op.result.owner == op
@run
def testBlockArgOwner():
ctx = Context()
ctx.allow_unregistered_dialects = True
module = Module.parse(
r"""
func.func @foo(%arg0: f32) {
return
}""",
ctx,
)
func = module.body.operations[0]
block = func.regions[0].blocks[0]
assert block.arguments[0].owner == block
@run
def testValueIsInstance():
ctx = Context()
ctx.allow_unregistered_dialects = True
module = Module.parse(
r"""
func.func @foo(%arg0: f32) {
%0 = "some_dialect.some_op"() : () -> f64
return
}""",
ctx,
)
func = module.body.operations[0]
assert BlockArgument.isinstance(func.regions[0].blocks[0].arguments[0])
assert not OpResult.isinstance(func.regions[0].blocks[0].arguments[0])
op = func.regions[0].blocks[0].operations[0]
assert not BlockArgument.isinstance(op.results[0])
assert OpResult.isinstance(op.results[0])
@run
def testValueHash():
ctx = Context()
ctx.allow_unregistered_dialects = True
module = Module.parse(
r"""
func.func @foo(%arg0: f32) -> f32 {
%0 = "some_dialect.some_op"(%arg0) : (f32) -> f32
return %0 : f32
}""",
ctx,
)
[func] = module.body.operations
block = func.entry_block
op, ret = block.operations
assert hash(block.arguments[0]) == hash(op.operands[0])
assert hash(op.result) == hash(ret.operands[0])
@run
def testValueUses():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
op1 = Operation.create("custom.op2", operands=[value])
op2 = Operation.create("custom.op2", operands=[value])
for use in value.uses:
assert use.owner in [op1, op2]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
@run
def testValueReplaceAllUsesWith():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
op1 = Operation.create("custom.op2", operands=[value])
op2 = Operation.create("custom.op2", operands=[value])
value2 = Operation.create("custom.op3", results=[i32]).results[0]
value.replace_all_uses_with(value2)
assert len(list(value.uses)) == 0
for use in value2.uses:
assert use.owner in [op1, op2]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
@run
def testValueReplaceAllUsesWithExcept():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
op1 = Operation.create("custom.op1", operands=[value])
op2 = Operation.create("custom.op2", operands=[value])
value2 = Operation.create("custom.op3", results=[i32]).results[0]
value.replace_all_uses_except(value2, op1)
assert len(list(value.uses)) == 1
for use in value2.uses:
assert use.owner in [op2]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
for use in value.uses:
assert use.owner in [op1]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
@run
def testValueReplaceAllUsesWithMultipleExceptions():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
op1 = Operation.create("custom.op1", operands=[value])
op2 = Operation.create("custom.op2", operands=[value])
op3 = Operation.create("custom.op3", operands=[value])
value2 = Operation.create("custom.op4", results=[i32]).results[0]
value.replace_all_uses_except(value2, [op1, op2])
assert len(list(value.uses)) == 2
assert len(list(value2.uses)) == 1
for use in value2.uses:
assert use.owner in [op3]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
for use in value.uses:
assert use.owner in [op1, op2]
print(f"Use owner: {use.owner}")
print(f"Use operand_number: {use.operand_number}")
@run
def testValuePrintAsOperand():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
print(value)
value2 = Operation.create("custom.op2", results=[i32]).results[0]
print(value2)
topFn = func.FuncOp("test", ([i32, i32], []))
entry_block = Block.create_at_start(topFn.operation.regions[0], [i32, i32])
with InsertionPoint(entry_block):
value3 = Operation.create("custom.op3", results=[i32]).results[0]
print(value3)
value4 = Operation.create("custom.op4", results=[i32]).results[0]
print(value4)
func.ReturnOp([])
print(value.get_name())
print(value2.get_name())
print(value3.get_name())
print(value4.get_name())
print("With AsmState")
state = AsmState(topFn.operation, use_local_scope=True)
print(value3.get_name(state=state))
print(value4.get_name(state=state))
print("With use_local_scope")
print(value3.get_name(use_local_scope=True))
print(value4.get_name(use_local_scope=True))
print(entry_block.arguments[0].get_name())
print(entry_block.arguments[1].get_name())
print(module)
value2.owner.detach_from_parent()
print(value2.get_name())
@run
def testValuePrintAsOperandNamedLocPrefix():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
named_value = Operation.create(
"custom.op5", results=[i32], loc=Location.name("apple")
).results[0]
print(named_value)
print("With use_name_loc_as_prefix")
print(named_value.get_name(use_name_loc_as_prefix=True))
@run
def testValueSetType():
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
i64 = IntegerType.get_signless(64)
module = Module.create()
with InsertionPoint(module.body):
value = Operation.create("custom.op1", results=[i32]).results[0]
print(value)
value.set_type(i64)
print(value)
print(value.owner)
@run
def testValueCasters():
class NOPResult(OpResult):
def __init__(self, v):
super().__init__(v)
def __str__(self):
return super().__str__().replace(Value.__name__, NOPResult.__name__)
class NOPValue(Value):
def __init__(self, v):
super().__init__(v)
def __str__(self):
return super().__str__().replace(Value.__name__, NOPValue.__name__)
class NOPBlockArg(BlockArgument):
def __init__(self, v):
super().__init__(v)
def __str__(self):
return super().__str__().replace(Value.__name__, NOPBlockArg.__name__)
@register_value_caster(IntegerType.static_typeid)
def cast_int(v) -> Value:
print("in caster", v.__class__.__name__)
if isinstance(v, OpResult):
return NOPResult(v)
if isinstance(v, BlockArgument):
return NOPBlockArg(v)
elif isinstance(v, Value):
return NOPValue(v)
ctx = Context()
ctx.allow_unregistered_dialects = True
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
values = Operation.create("custom.op1", results=[i32, i32]).results
print("result", values[0].result_number, values[0])
print("result", values[1].result_number, values[1])
print("results slice", values[:1][0].result_number, values[:1][0])
value0, value1 = values
print("result", value0.result_number, values[0])
print("result", value1.result_number, values[1])
op1 = Operation.create("custom.op2", operands=[value0, value1])
print(op1)
print("operand 0", op1.operands[0])
print("operand 1", op1.operands[1])
@func.FuncOp.from_py_func(i32, i32)
def reduction(arg0, arg1):
print("as func arg", arg0.arg_number, arg0.__class__.__name__)
print("as func arg", arg1.arg_number, arg1.__class__.__name__)
print(
"args slice",
reduction.func_op.arguments[:1][0].arg_number,
reduction.func_op.arguments[:1][0],
)
try:
@register_value_caster(IntegerType.static_typeid)
def dont_cast_int_shouldnt_register(v):
...
except RuntimeError as e:
print(e)
@register_value_caster(IntegerType.static_typeid, replace=True)
def dont_cast_int(v) -> OpResult:
assert isinstance(v, OpResult)
print("don't cast", v.result_number, v)
return v
with Location.unknown(ctx):
i32 = IntegerType.get_signless(32)
module = Module.create()
with InsertionPoint(module.body):
new_value = Operation.create("custom.op1", results=[i32]).result
print("result", new_value.result_number, new_value)
new_value = Operation.create("custom.op2", results=[i32]).results[0]
print("result", new_value.result_number, new_value)