19f3f6d7bSStella Laurenzo# RUN: %PYTHON %s | FileCheck %s
29f3f6d7bSStella Laurenzo
39f3f6d7bSStella Laurenzoimport gc
49f3f6d7bSStella Laurenzofrom mlir.ir import *
59f3f6d7bSStella Laurenzo
69f3f6d7bSStella Laurenzodef run(f):
79f3f6d7bSStella Laurenzo  print("\nTEST:", f.__name__)
89f3f6d7bSStella Laurenzo  f()
99f3f6d7bSStella Laurenzo  gc.collect()
109f3f6d7bSStella Laurenzo  assert Context._get_live_count() == 0
11ace1d0adSStella Laurenzo  return f
129f3f6d7bSStella Laurenzo
139f3f6d7bSStella Laurenzo
149f3f6d7bSStella Laurenzo# Verify successful parse.
159f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testParseSuccess
169f3f6d7bSStella Laurenzo# CHECK: module @successfulParse
17ace1d0adSStella Laurenzo@run
189f3f6d7bSStella Laurenzodef testParseSuccess():
199f3f6d7bSStella Laurenzo  ctx = Context()
209f3f6d7bSStella Laurenzo  module = Module.parse(r"""module @successfulParse {}""", ctx)
219f3f6d7bSStella Laurenzo  assert module.context is ctx
229f3f6d7bSStella Laurenzo  print("CLEAR CONTEXT")
239f3f6d7bSStella Laurenzo  ctx = None  # Ensure that module captures the context.
249f3f6d7bSStella Laurenzo  gc.collect()
259f3f6d7bSStella Laurenzo  module.dump()  # Just outputs to stderr. Verifies that it functions.
269f3f6d7bSStella Laurenzo  print(str(module))
279f3f6d7bSStella Laurenzo
289f3f6d7bSStella Laurenzo
299f3f6d7bSStella Laurenzo# Verify parse error.
309f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testParseError
319f3f6d7bSStella Laurenzo# CHECK: testParseError: Unable to parse module assembly (see diagnostics)
32ace1d0adSStella Laurenzo@run
339f3f6d7bSStella Laurenzodef testParseError():
349f3f6d7bSStella Laurenzo  ctx = Context()
359f3f6d7bSStella Laurenzo  try:
369f3f6d7bSStella Laurenzo    module = Module.parse(r"""}SYNTAX ERROR{""", ctx)
379f3f6d7bSStella Laurenzo  except ValueError as e:
389f3f6d7bSStella Laurenzo    print("testParseError:", e)
399f3f6d7bSStella Laurenzo  else:
409f3f6d7bSStella Laurenzo    print("Exception not produced")
419f3f6d7bSStella Laurenzo
429f3f6d7bSStella Laurenzo
439f3f6d7bSStella Laurenzo# Verify successful parse.
449f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testCreateEmpty
459f3f6d7bSStella Laurenzo# CHECK: module {
46ace1d0adSStella Laurenzo@run
479f3f6d7bSStella Laurenzodef testCreateEmpty():
489f3f6d7bSStella Laurenzo  ctx = Context()
499f3f6d7bSStella Laurenzo  loc = Location.unknown(ctx)
509f3f6d7bSStella Laurenzo  module = Module.create(loc)
519f3f6d7bSStella Laurenzo  print("CLEAR CONTEXT")
529f3f6d7bSStella Laurenzo  ctx = None  # Ensure that module captures the context.
539f3f6d7bSStella Laurenzo  gc.collect()
549f3f6d7bSStella Laurenzo  print(str(module))
559f3f6d7bSStella Laurenzo
569f3f6d7bSStella Laurenzo
579f3f6d7bSStella Laurenzo# Verify round-trip of ASM that contains unicode.
589f3f6d7bSStella Laurenzo# Note that this does not test that the print path converts unicode properly
599f3f6d7bSStella Laurenzo# because MLIR asm always normalizes it to the hex encoding.
609f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testRoundtripUnicode
619f3f6d7bSStella Laurenzo# CHECK: func private @roundtripUnicode()
629f3f6d7bSStella Laurenzo# CHECK: foo = "\F0\9F\98\8A"
63ace1d0adSStella Laurenzo@run
649f3f6d7bSStella Laurenzodef testRoundtripUnicode():
659f3f6d7bSStella Laurenzo  ctx = Context()
669f3f6d7bSStella Laurenzo  module = Module.parse(r"""
67*2310ced8SRiver Riddle    func.func private @roundtripUnicode() attributes { foo = "��" }
689f3f6d7bSStella Laurenzo  """, ctx)
699f3f6d7bSStella Laurenzo  print(str(module))
709f3f6d7bSStella Laurenzo
71ace1d0adSStella Laurenzo
72ace1d0adSStella Laurenzo# Verify round-trip of ASM that contains unicode.
73ace1d0adSStella Laurenzo# Note that this does not test that the print path converts unicode properly
74ace1d0adSStella Laurenzo# because MLIR asm always normalizes it to the hex encoding.
75ace1d0adSStella Laurenzo# CHECK-LABEL: TEST: testRoundtripBinary
76ace1d0adSStella Laurenzo# CHECK: func private @roundtripUnicode()
77ace1d0adSStella Laurenzo# CHECK: foo = "\F0\9F\98\8A"
78ace1d0adSStella Laurenzo@run
79ace1d0adSStella Laurenzodef testRoundtripBinary():
80ace1d0adSStella Laurenzo  with Context():
81ace1d0adSStella Laurenzo    module = Module.parse(r"""
82*2310ced8SRiver Riddle      func.func private @roundtripUnicode() attributes { foo = "��" }
83ace1d0adSStella Laurenzo    """)
84ace1d0adSStella Laurenzo    binary_asm = module.operation.get_asm(binary=True)
85ace1d0adSStella Laurenzo    assert isinstance(binary_asm, bytes)
86ace1d0adSStella Laurenzo    module = Module.parse(binary_asm)
87ace1d0adSStella Laurenzo    print(module)
889f3f6d7bSStella Laurenzo
899f3f6d7bSStella Laurenzo
909f3f6d7bSStella Laurenzo# Tests that module.operation works and correctly interns instances.
919f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testModuleOperation
92ace1d0adSStella Laurenzo@run
939f3f6d7bSStella Laurenzodef testModuleOperation():
949f3f6d7bSStella Laurenzo  ctx = Context()
959f3f6d7bSStella Laurenzo  module = Module.parse(r"""module @successfulParse {}""", ctx)
969f3f6d7bSStella Laurenzo  assert ctx._get_live_module_count() == 1
979f3f6d7bSStella Laurenzo  op1 = module.operation
989f3f6d7bSStella Laurenzo  assert ctx._get_live_operation_count() == 1
999f3f6d7bSStella Laurenzo  # CHECK: module @successfulParse
1009f3f6d7bSStella Laurenzo  print(op1)
1019f3f6d7bSStella Laurenzo
1029f3f6d7bSStella Laurenzo  # Ensure that operations are the same on multiple calls.
1039f3f6d7bSStella Laurenzo  op2 = module.operation
1049f3f6d7bSStella Laurenzo  assert ctx._get_live_operation_count() == 1
1059f3f6d7bSStella Laurenzo  assert op1 is op2
1069f3f6d7bSStella Laurenzo
1076b0bed7eSJohn Demme  # Test live operation clearing.
1086b0bed7eSJohn Demme  op1 = module.operation
1096b0bed7eSJohn Demme  assert ctx._get_live_operation_count() == 1
1106b0bed7eSJohn Demme  num_invalidated = ctx._clear_live_operations()
1116b0bed7eSJohn Demme  assert num_invalidated == 1
1126b0bed7eSJohn Demme  assert ctx._get_live_operation_count() == 0
1136b0bed7eSJohn Demme  op1 = None
1146b0bed7eSJohn Demme  gc.collect()
1156b0bed7eSJohn Demme  op1 = module.operation
1166b0bed7eSJohn Demme
1179f3f6d7bSStella Laurenzo  # Ensure that if module is de-referenced, the operations are still valid.
1189f3f6d7bSStella Laurenzo  module = None
1199f3f6d7bSStella Laurenzo  gc.collect()
1209f3f6d7bSStella Laurenzo  print(op1)
1219f3f6d7bSStella Laurenzo
1229f3f6d7bSStella Laurenzo  # Collect and verify lifetime.
1239f3f6d7bSStella Laurenzo  op1 = None
1249f3f6d7bSStella Laurenzo  op2 = None
1259f3f6d7bSStella Laurenzo  gc.collect()
1269f3f6d7bSStella Laurenzo  print("LIVE OPERATIONS:", ctx._get_live_operation_count())
1279f3f6d7bSStella Laurenzo  assert ctx._get_live_operation_count() == 0
1289f3f6d7bSStella Laurenzo  assert ctx._get_live_module_count() == 0
1299f3f6d7bSStella Laurenzo
1309f3f6d7bSStella Laurenzo
1319f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testModuleCapsule
132ace1d0adSStella Laurenzo@run
1339f3f6d7bSStella Laurenzodef testModuleCapsule():
1349f3f6d7bSStella Laurenzo  ctx = Context()
1359f3f6d7bSStella Laurenzo  module = Module.parse(r"""module @successfulParse {}""", ctx)
1369f3f6d7bSStella Laurenzo  assert ctx._get_live_module_count() == 1
1379f3f6d7bSStella Laurenzo  # CHECK: "mlir.ir.Module._CAPIPtr"
1389f3f6d7bSStella Laurenzo  module_capsule = module._CAPIPtr
1399f3f6d7bSStella Laurenzo  print(module_capsule)
1409f3f6d7bSStella Laurenzo  module_dup = Module._CAPICreate(module_capsule)
1419f3f6d7bSStella Laurenzo  assert module is module_dup
1429f3f6d7bSStella Laurenzo  assert module_dup.context is ctx
1439f3f6d7bSStella Laurenzo  # Gc and verify destructed.
1449f3f6d7bSStella Laurenzo  module = None
1459f3f6d7bSStella Laurenzo  module_capsule = None
1469f3f6d7bSStella Laurenzo  module_dup = None
1479f3f6d7bSStella Laurenzo  gc.collect()
1489f3f6d7bSStella Laurenzo  assert ctx._get_live_module_count() == 0
1499f3f6d7bSStella Laurenzo
150