19f3f6d7bSStella Laurenzo# RUN: %PYTHON %s | FileCheck %s
29f3f6d7bSStella Laurenzo
39f3f6d7bSStella Laurenzofrom mlir.ir import *
49f3f6d7bSStella Laurenzoimport mlir.dialects.python_test as test
59f3f6d7bSStella Laurenzo
69f3f6d7bSStella Laurenzodef run(f):
79f3f6d7bSStella Laurenzo  print("\nTEST:", f.__name__)
89f3f6d7bSStella Laurenzo  f()
914c92070SAlex Zinenko  return f
109f3f6d7bSStella Laurenzo
119f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testAttributes
1214c92070SAlex Zinenko@run
139f3f6d7bSStella Laurenzodef testAttributes():
140f9e6451SMehdi Amini  with Context() as ctx, Location.unknown():
150f9e6451SMehdi Amini    ctx.allow_unregistered_dialects = True
160f9e6451SMehdi Amini
179f3f6d7bSStella Laurenzo    #
189f3f6d7bSStella Laurenzo    # Check op construction with attributes.
199f3f6d7bSStella Laurenzo    #
209f3f6d7bSStella Laurenzo
219f3f6d7bSStella Laurenzo    i32 = IntegerType.get_signless(32)
229f3f6d7bSStella Laurenzo    one = IntegerAttr.get(i32, 1)
239f3f6d7bSStella Laurenzo    two = IntegerAttr.get(i32, 2)
249f3f6d7bSStella Laurenzo    unit = UnitAttr.get()
259f3f6d7bSStella Laurenzo
269f3f6d7bSStella Laurenzo    # CHECK: "python_test.attributed_op"() {
279f3f6d7bSStella Laurenzo    # CHECK-DAG: mandatory_i32 = 1 : i32
289f3f6d7bSStella Laurenzo    # CHECK-DAG: optional_i32 = 2 : i32
299f3f6d7bSStella Laurenzo    # CHECK-DAG: unit
309f3f6d7bSStella Laurenzo    # CHECK: }
31*9b79f50bSJeremy Furtek    op = test.AttributedOp(one, optional_i32=two, unit=unit)
329f3f6d7bSStella Laurenzo    print(f"{op}")
339f3f6d7bSStella Laurenzo
349f3f6d7bSStella Laurenzo    # CHECK: "python_test.attributed_op"() {
359f3f6d7bSStella Laurenzo    # CHECK: mandatory_i32 = 2 : i32
369f3f6d7bSStella Laurenzo    # CHECK: }
37*9b79f50bSJeremy Furtek    op2 = test.AttributedOp(two)
389f3f6d7bSStella Laurenzo    print(f"{op2}")
399f3f6d7bSStella Laurenzo
409f3f6d7bSStella Laurenzo    #
419f3f6d7bSStella Laurenzo    # Check generic "attributes" access and mutation.
429f3f6d7bSStella Laurenzo    #
439f3f6d7bSStella Laurenzo
449f3f6d7bSStella Laurenzo    assert "additional" not in op.attributes
459f3f6d7bSStella Laurenzo
469f3f6d7bSStella Laurenzo    # CHECK: "python_test.attributed_op"() {
479f3f6d7bSStella Laurenzo    # CHECK-DAG: additional = 1 : i32
489f3f6d7bSStella Laurenzo    # CHECK-DAG: mandatory_i32 = 2 : i32
499f3f6d7bSStella Laurenzo    # CHECK: }
509f3f6d7bSStella Laurenzo    op2.attributes["additional"] = one
519f3f6d7bSStella Laurenzo    print(f"{op2}")
529f3f6d7bSStella Laurenzo
539f3f6d7bSStella Laurenzo    # CHECK: "python_test.attributed_op"() {
549f3f6d7bSStella Laurenzo    # CHECK-DAG: additional = 2 : i32
559f3f6d7bSStella Laurenzo    # CHECK-DAG: mandatory_i32 = 2 : i32
569f3f6d7bSStella Laurenzo    # CHECK: }
579f3f6d7bSStella Laurenzo    op2.attributes["additional"] = two
589f3f6d7bSStella Laurenzo    print(f"{op2}")
599f3f6d7bSStella Laurenzo
609f3f6d7bSStella Laurenzo    # CHECK: "python_test.attributed_op"() {
619f3f6d7bSStella Laurenzo    # CHECK-NOT: additional = 2 : i32
629f3f6d7bSStella Laurenzo    # CHECK:     mandatory_i32 = 2 : i32
639f3f6d7bSStella Laurenzo    # CHECK: }
649f3f6d7bSStella Laurenzo    del op2.attributes["additional"]
659f3f6d7bSStella Laurenzo    print(f"{op2}")
669f3f6d7bSStella Laurenzo
679f3f6d7bSStella Laurenzo    try:
689f3f6d7bSStella Laurenzo      print(op.attributes["additional"])
699f3f6d7bSStella Laurenzo    except KeyError:
709f3f6d7bSStella Laurenzo      pass
719f3f6d7bSStella Laurenzo    else:
729f3f6d7bSStella Laurenzo      assert False, "expected KeyError on unknown attribute key"
739f3f6d7bSStella Laurenzo
749f3f6d7bSStella Laurenzo    #
759f3f6d7bSStella Laurenzo    # Check accessors to defined attributes.
769f3f6d7bSStella Laurenzo    #
779f3f6d7bSStella Laurenzo
789f3f6d7bSStella Laurenzo    # CHECK: Mandatory: 1
799f3f6d7bSStella Laurenzo    # CHECK: Optional: 2
809f3f6d7bSStella Laurenzo    # CHECK: Unit: True
819f3f6d7bSStella Laurenzo    print(f"Mandatory: {op.mandatory_i32.value}")
829f3f6d7bSStella Laurenzo    print(f"Optional: {op.optional_i32.value}")
839f3f6d7bSStella Laurenzo    print(f"Unit: {op.unit}")
849f3f6d7bSStella Laurenzo
859f3f6d7bSStella Laurenzo    # CHECK: Mandatory: 2
869f3f6d7bSStella Laurenzo    # CHECK: Optional: None
879f3f6d7bSStella Laurenzo    # CHECK: Unit: False
889f3f6d7bSStella Laurenzo    print(f"Mandatory: {op2.mandatory_i32.value}")
899f3f6d7bSStella Laurenzo    print(f"Optional: {op2.optional_i32}")
909f3f6d7bSStella Laurenzo    print(f"Unit: {op2.unit}")
919f3f6d7bSStella Laurenzo
929f3f6d7bSStella Laurenzo    # CHECK: Mandatory: 2
939f3f6d7bSStella Laurenzo    # CHECK: Optional: None
949f3f6d7bSStella Laurenzo    # CHECK: Unit: False
959f3f6d7bSStella Laurenzo    op.mandatory_i32 = two
969f3f6d7bSStella Laurenzo    op.optional_i32 = None
979f3f6d7bSStella Laurenzo    op.unit = False
989f3f6d7bSStella Laurenzo    print(f"Mandatory: {op.mandatory_i32.value}")
999f3f6d7bSStella Laurenzo    print(f"Optional: {op.optional_i32}")
1009f3f6d7bSStella Laurenzo    print(f"Unit: {op.unit}")
1019f3f6d7bSStella Laurenzo    assert "optional_i32" not in op.attributes
1029f3f6d7bSStella Laurenzo    assert "unit" not in op.attributes
1039f3f6d7bSStella Laurenzo
1049f3f6d7bSStella Laurenzo    try:
1059f3f6d7bSStella Laurenzo      op.mandatory_i32 = None
1069f3f6d7bSStella Laurenzo    except ValueError:
1079f3f6d7bSStella Laurenzo      pass
1089f3f6d7bSStella Laurenzo    else:
1099f3f6d7bSStella Laurenzo      assert False, "expected ValueError on setting a mandatory attribute to None"
1109f3f6d7bSStella Laurenzo
1119f3f6d7bSStella Laurenzo    # CHECK: Optional: 2
1129f3f6d7bSStella Laurenzo    op.optional_i32 = two
1139f3f6d7bSStella Laurenzo    print(f"Optional: {op.optional_i32.value}")
1149f3f6d7bSStella Laurenzo
1159f3f6d7bSStella Laurenzo    # CHECK: Optional: None
1169f3f6d7bSStella Laurenzo    del op.optional_i32
1179f3f6d7bSStella Laurenzo    print(f"Optional: {op.optional_i32}")
1189f3f6d7bSStella Laurenzo
1199f3f6d7bSStella Laurenzo    # CHECK: Unit: False
1209f3f6d7bSStella Laurenzo    op.unit = None
1219f3f6d7bSStella Laurenzo    print(f"Unit: {op.unit}")
1229f3f6d7bSStella Laurenzo    assert "unit" not in op.attributes
1239f3f6d7bSStella Laurenzo
1249f3f6d7bSStella Laurenzo    # CHECK: Unit: True
1259f3f6d7bSStella Laurenzo    op.unit = True
1269f3f6d7bSStella Laurenzo    print(f"Unit: {op.unit}")
1279f3f6d7bSStella Laurenzo
1289f3f6d7bSStella Laurenzo    # CHECK: Unit: False
1299f3f6d7bSStella Laurenzo    del op.unit
1309f3f6d7bSStella Laurenzo    print(f"Unit: {op.unit}")
1319f3f6d7bSStella Laurenzo
13214c92070SAlex Zinenko
13314c92070SAlex Zinenko# CHECK-LABEL: TEST: inferReturnTypes
13414c92070SAlex Zinenko@run
13514c92070SAlex Zinenkodef inferReturnTypes():
13614c92070SAlex Zinenko  with Context() as ctx, Location.unknown(ctx):
13714c92070SAlex Zinenko    test.register_python_test_dialect(ctx)
13814c92070SAlex Zinenko    module = Module.create()
13914c92070SAlex Zinenko    with InsertionPoint(module.body):
1402995d29bSAlex Zinenko      op = test.InferResultsOp()
14114c92070SAlex Zinenko      dummy = test.DummyOp()
14214c92070SAlex Zinenko
14314c92070SAlex Zinenko    # CHECK: [Type(i32), Type(i64)]
14414c92070SAlex Zinenko    iface = InferTypeOpInterface(op)
14514c92070SAlex Zinenko    print(iface.inferReturnTypes())
14614c92070SAlex Zinenko
14714c92070SAlex Zinenko    # CHECK: [Type(i32), Type(i64)]
14814c92070SAlex Zinenko    iface_static = InferTypeOpInterface(test.InferResultsOp)
14914c92070SAlex Zinenko    print(iface.inferReturnTypes())
15014c92070SAlex Zinenko
15114c92070SAlex Zinenko    assert isinstance(iface.opview, test.InferResultsOp)
15214c92070SAlex Zinenko    assert iface.opview == iface.operation.opview
15314c92070SAlex Zinenko
15414c92070SAlex Zinenko    try:
15514c92070SAlex Zinenko      iface_static.opview
15614c92070SAlex Zinenko    except TypeError:
15714c92070SAlex Zinenko      pass
15814c92070SAlex Zinenko    else:
15914c92070SAlex Zinenko      assert False, ("not expected to be able to obtain an opview from a static"
16014c92070SAlex Zinenko                     " interface")
16114c92070SAlex Zinenko
16214c92070SAlex Zinenko    try:
16314c92070SAlex Zinenko      InferTypeOpInterface(dummy)
16414c92070SAlex Zinenko    except ValueError:
16514c92070SAlex Zinenko      pass
16614c92070SAlex Zinenko    else:
16714c92070SAlex Zinenko      assert False, "not expected dummy op to implement the interface"
16814c92070SAlex Zinenko
16914c92070SAlex Zinenko    try:
17014c92070SAlex Zinenko      InferTypeOpInterface(test.DummyOp)
17114c92070SAlex Zinenko    except ValueError:
17214c92070SAlex Zinenko      pass
17314c92070SAlex Zinenko    else:
17414c92070SAlex Zinenko      assert False, "not expected dummy op class to implement the interface"
1752995d29bSAlex Zinenko
1762995d29bSAlex Zinenko
1772995d29bSAlex Zinenko# CHECK-LABEL: TEST: resultTypesDefinedByTraits
1782995d29bSAlex Zinenko@run
1792995d29bSAlex Zinenkodef resultTypesDefinedByTraits():
1802995d29bSAlex Zinenko  with Context() as ctx, Location.unknown(ctx):
1812995d29bSAlex Zinenko    test.register_python_test_dialect(ctx)
1822995d29bSAlex Zinenko    module = Module.create()
1832995d29bSAlex Zinenko    with InsertionPoint(module.body):
1842995d29bSAlex Zinenko      inferred = test.InferResultsOp()
1852995d29bSAlex Zinenko      same = test.SameOperandAndResultTypeOp([inferred.results[0]])
1862995d29bSAlex Zinenko      # CHECK-COUNT-2: i32
1872995d29bSAlex Zinenko      print(same.one.type)
1882995d29bSAlex Zinenko      print(same.two.type)
1892995d29bSAlex Zinenko
1902995d29bSAlex Zinenko      first_type_attr = test.FirstAttrDeriveTypeAttrOp(
1912995d29bSAlex Zinenko          inferred.results[1], TypeAttr.get(IndexType.get()))
1922995d29bSAlex Zinenko      # CHECK-COUNT-2: index
1932995d29bSAlex Zinenko      print(first_type_attr.one.type)
1942995d29bSAlex Zinenko      print(first_type_attr.two.type)
1952995d29bSAlex Zinenko
1962995d29bSAlex Zinenko      first_attr = test.FirstAttrDeriveAttrOp(
1972995d29bSAlex Zinenko          FloatAttr.get(F32Type.get(), 3.14))
1982995d29bSAlex Zinenko      # CHECK-COUNT-3: f32
1992995d29bSAlex Zinenko      print(first_attr.one.type)
2002995d29bSAlex Zinenko      print(first_attr.two.type)
2012995d29bSAlex Zinenko      print(first_attr.three.type)
2022995d29bSAlex Zinenko
2032995d29bSAlex Zinenko      implied = test.InferResultsImpliedOp()
2042995d29bSAlex Zinenko      # CHECK: i32
2052995d29bSAlex Zinenko      print(implied.integer.type)
2062995d29bSAlex Zinenko      # CHECK: f64
2072995d29bSAlex Zinenko      print(implied.flt.type)
2082995d29bSAlex Zinenko      # CHECK: index
2092995d29bSAlex Zinenko      print(implied.index.type)
21054c99842SMichal Terepeta
21154c99842SMichal Terepeta
21254c99842SMichal Terepeta# CHECK-LABEL: TEST: testOptionalOperandOp
21354c99842SMichal Terepeta@run
21454c99842SMichal Terepetadef testOptionalOperandOp():
21554c99842SMichal Terepeta  with Context() as ctx, Location.unknown():
21654c99842SMichal Terepeta    test.register_python_test_dialect(ctx)
21754c99842SMichal Terepeta
21854c99842SMichal Terepeta    module = Module.create()
21954c99842SMichal Terepeta    with InsertionPoint(module.body):
22054c99842SMichal Terepeta
221*9b79f50bSJeremy Furtek      op1 = test.OptionalOperandOp()
22254c99842SMichal Terepeta      # CHECK: op1.input is None: True
22354c99842SMichal Terepeta      print(f"op1.input is None: {op1.input is None}")
22454c99842SMichal Terepeta
225*9b79f50bSJeremy Furtek      op2 = test.OptionalOperandOp(input=op1)
22654c99842SMichal Terepeta      # CHECK: op2.input is None: False
22754c99842SMichal Terepeta      print(f"op2.input is None: {op2.input is None}")
22889a92fb3SAlex Zinenko
22989a92fb3SAlex Zinenko
23089a92fb3SAlex Zinenko# CHECK-LABEL: TEST: testCustomAttribute
23189a92fb3SAlex Zinenko@run
23289a92fb3SAlex Zinenkodef testCustomAttribute():
23389a92fb3SAlex Zinenko  with Context() as ctx:
23489a92fb3SAlex Zinenko    test.register_python_test_dialect(ctx)
23589a92fb3SAlex Zinenko    a = test.TestAttr.get()
23689a92fb3SAlex Zinenko    # CHECK: #python_test.test_attr
23789a92fb3SAlex Zinenko    print(a)
23889a92fb3SAlex Zinenko
23989a92fb3SAlex Zinenko    # The following cast must not assert.
24089a92fb3SAlex Zinenko    b = test.TestAttr(a)
24189a92fb3SAlex Zinenko
24289a92fb3SAlex Zinenko    unit = UnitAttr.get()
24389a92fb3SAlex Zinenko    try:
24489a92fb3SAlex Zinenko      test.TestAttr(unit)
24589a92fb3SAlex Zinenko    except ValueError as e:
24689a92fb3SAlex Zinenko      assert "Cannot cast attribute to TestAttr" in str(e)
24789a92fb3SAlex Zinenko    else:
24889a92fb3SAlex Zinenko      raise
24989a92fb3SAlex Zinenko
25022fea18eSAlex Zinenko    # The following must trigger a TypeError from our adaptors and must not
25122fea18eSAlex Zinenko    # crash.
25222fea18eSAlex Zinenko    try:
25322fea18eSAlex Zinenko      test.TestAttr(42)
25422fea18eSAlex Zinenko    except TypeError as e:
25522fea18eSAlex Zinenko      assert "Expected an MLIR object" in str(e)
25622fea18eSAlex Zinenko    else:
25722fea18eSAlex Zinenko      raise
25822fea18eSAlex Zinenko
25989a92fb3SAlex Zinenko    # The following must trigger a TypeError from pybind (therefore, not
26089a92fb3SAlex Zinenko    # checking its message) and must not crash.
26189a92fb3SAlex Zinenko    try:
26289a92fb3SAlex Zinenko      test.TestAttr(42, 56)
26389a92fb3SAlex Zinenko    except TypeError:
26489a92fb3SAlex Zinenko      pass
26589a92fb3SAlex Zinenko    else:
26689a92fb3SAlex Zinenko      raise
26789a92fb3SAlex Zinenko
26889a92fb3SAlex Zinenko
26989a92fb3SAlex Zinenko@run
27089a92fb3SAlex Zinenkodef testCustomType():
27189a92fb3SAlex Zinenko  with Context() as ctx:
27289a92fb3SAlex Zinenko    test.register_python_test_dialect(ctx)
27389a92fb3SAlex Zinenko    a = test.TestType.get()
27489a92fb3SAlex Zinenko    # CHECK: !python_test.test_type
27589a92fb3SAlex Zinenko    print(a)
27689a92fb3SAlex Zinenko
27789a92fb3SAlex Zinenko    # The following cast must not assert.
27889a92fb3SAlex Zinenko    b = test.TestType(a)
27989a92fb3SAlex Zinenko
28089a92fb3SAlex Zinenko    i8 = IntegerType.get_signless(8)
28189a92fb3SAlex Zinenko    try:
28289a92fb3SAlex Zinenko      test.TestType(i8)
28389a92fb3SAlex Zinenko    except ValueError as e:
28489a92fb3SAlex Zinenko      assert "Cannot cast type to TestType" in str(e)
28589a92fb3SAlex Zinenko    else:
28689a92fb3SAlex Zinenko      raise
28789a92fb3SAlex Zinenko
28822fea18eSAlex Zinenko    # The following must trigger a TypeError from our adaptors and must not
28922fea18eSAlex Zinenko    # crash.
29022fea18eSAlex Zinenko    try:
29122fea18eSAlex Zinenko      test.TestType(42)
29222fea18eSAlex Zinenko    except TypeError as e:
29322fea18eSAlex Zinenko      assert "Expected an MLIR object" in str(e)
29422fea18eSAlex Zinenko    else:
29522fea18eSAlex Zinenko      raise
29622fea18eSAlex Zinenko
29789a92fb3SAlex Zinenko    # The following must trigger a TypeError from pybind (therefore, not
29889a92fb3SAlex Zinenko    # checking its message) and must not crash.
29989a92fb3SAlex Zinenko    try:
30089a92fb3SAlex Zinenko      test.TestType(42, 56)
30189a92fb3SAlex Zinenko    except TypeError:
30289a92fb3SAlex Zinenko      pass
30389a92fb3SAlex Zinenko    else:
30489a92fb3SAlex Zinenko      raise
305