1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
# RUN: %PYTHON %s | FileCheck %s
import gc
from mlir.ir import *
def run(f):
print("\nTEST:", f.__name__)
f()
gc.collect()
assert Context._get_live_count() == 0
return f
@run
def testLifecycleContextDestroy():
ctx = Context()
def callback(foo): ...
handler = ctx.attach_diagnostic_handler(callback)
assert handler.attached
# If context is destroyed before the handler, it should auto-detach.
ctx = None
gc.collect()
assert not handler.attached
# And finally collecting the handler should be fine.
handler = None
gc.collect()
@run
def testLifecycleExplicitDetach():
ctx = Context()
def callback(foo): ...
handler = ctx.attach_diagnostic_handler(callback)
assert handler.attached
handler.detach()
assert not handler.attached
@run
def testLifecycleWith():
ctx = Context()
def callback(foo): ...
with ctx.attach_diagnostic_handler(callback) as handler:
assert handler.attached
assert not handler.attached
@run
def testLifecycleWithAndExplicitDetach():
ctx = Context()
def callback(foo): ...
with ctx.attach_diagnostic_handler(callback) as handler:
assert handler.attached
handler.detach()
assert not handler.attached
# CHECK-LABEL: TEST: testDiagnosticCallback
@run
def testDiagnosticCallback():
ctx = Context()
def callback(d):
# CHECK: DIAGNOSTIC: message='foobar', severity=DiagnosticSeverity.ERROR, loc=loc(unknown)
print(f"DIAGNOSTIC: message='{d.message}', severity={d.severity}, loc={d.location}")
return True
handler = ctx.attach_diagnostic_handler(callback)
loc = Location.unknown(ctx)
loc.emit_error("foobar")
assert not handler.had_error
# CHECK-LABEL: TEST: testDiagnosticEmptyNotes
# TODO: Come up with a way to inject a diagnostic with notes from this API.
@run
def testDiagnosticEmptyNotes():
ctx = Context()
def callback(d):
# CHECK: DIAGNOSTIC: notes=()
print(f"DIAGNOSTIC: notes={d.notes}")
return True
handler = ctx.attach_diagnostic_handler(callback)
loc = Location.unknown(ctx)
loc.emit_error("foobar")
assert not handler.had_error
# CHECK-LABEL: TEST: testDiagnosticNonEmptyNotes
@run
def testDiagnosticNonEmptyNotes():
ctx = Context()
def callback(d):
# CHECK: DIAGNOSTIC:
# CHECK: message='arith.addi' op requires one result
# CHECK: notes=['see current operation: "arith.addi"() : () -> ()']
print(f"DIAGNOSTIC:")
print(f" message={d.message}")
print(f" notes={list(map(str, d.notes))}")
return True
handler = ctx.attach_diagnostic_handler(callback)
loc = Location.unknown(ctx)
Operation.create('arith.addi', loc=loc).verify()
assert not handler.had_error
# CHECK-LABEL: TEST: testDiagnosticCallbackException
@run
def testDiagnosticCallbackException():
ctx = Context()
def callback(d):
raise ValueError("Error in handler")
handler = ctx.attach_diagnostic_handler(callback)
loc = Location.unknown(ctx)
loc.emit_error("foobar")
assert handler.had_error
# CHECK-LABEL: TEST: testEscapingDiagnostic
@run
def testEscapingDiagnostic():
ctx = Context()
diags = []
def callback(d):
diags.append(d)
return True
handler = ctx.attach_diagnostic_handler(callback)
loc = Location.unknown(ctx)
loc.emit_error("foobar")
assert not handler.had_error
# CHECK: DIAGNOSTIC: <Invalid Diagnostic>
print(f"DIAGNOSTIC: {str(diags[0])}")
try:
diags[0].severity
raise RuntimeError("expected exception")
except ValueError:
pass
try:
diags[0].location
raise RuntimeError("expected exception")
except ValueError:
pass
try:
diags[0].message
raise RuntimeError("expected exception")
except ValueError:
pass
try:
diags[0].notes
raise RuntimeError("expected exception")
except ValueError:
pass
# CHECK-LABEL: TEST: testDiagnosticReturnTrueHandles
@run
def testDiagnosticReturnTrueHandles():
ctx = Context()
def callback1(d):
print(f"CALLBACK1: {d}")
return True
def callback2(d):
print(f"CALLBACK2: {d}")
return True
ctx.attach_diagnostic_handler(callback1)
ctx.attach_diagnostic_handler(callback2)
loc = Location.unknown(ctx)
# CHECK-NOT: CALLBACK1
# CHECK: CALLBACK2: foobar
# CHECK-NOT: CALLBACK1
loc.emit_error("foobar")
# CHECK-LABEL: TEST: testDiagnosticReturnFalseDoesNotHandle
@run
def testDiagnosticReturnFalseDoesNotHandle():
ctx = Context()
def callback1(d):
print(f"CALLBACK1: {d}")
return True
def callback2(d):
print(f"CALLBACK2: {d}")
return False
ctx.attach_diagnostic_handler(callback1)
ctx.attach_diagnostic_handler(callback2)
loc = Location.unknown(ctx)
# CHECK: CALLBACK2: foobar
# CHECK: CALLBACK1: foobar
loc.emit_error("foobar")
|