-
Notifications
You must be signed in to change notification settings - Fork 154
Expand file tree
/
Copy pathtest_error_traceback.py
More file actions
240 lines (185 loc) · 9.4 KB
/
Copy pathtest_error_traceback.py
File metadata and controls
240 lines (185 loc) · 9.4 KB
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# SPDX-FileCopyrightText: Copyright (c) <2026> NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
import inspect
import re
import sys
from itertools import zip_longest
import pytest
import cuda.tile as ct
import torch
from cuda.tile._execution import static_def
def raising_helper():
raise ValueError("你好,世界")
sourceless_helper = eval("lambda: raising_helper()")
def expr_helper():
print(sourceless_helper())
def indented_helper(use_static_eval: bool):
if ct.ensure_constant(use_static_eval):
ct.static_eval(expr_helper())
else:
ct.static_assert(False, "Boom")
@ct.kernel
def kernel_1(use_static_eval: ct.Constant[bool]):
indented_helper(use_static_eval)
def test_traceback_formatting():
kernel_1_line = _source_line_no(kernel_1._annotated_function.pyfunc, "indented_helper")
indented_helper_line = _source_line_no(indented_helper, "ct.static_assert(False,")
expected = f"""Static assertion failed: Boom
"WHATEVERtest_error_traceback.py", line {kernel_1_line}, col 5-36, in kernel_1:
indented_helper(use_static_eval)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"WHATEVERtest_error_traceback.py", line {indented_helper_line}, col 9-39, in indented_helper:
ct.static_assert(False, "Boom")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"""
with pytest.raises(ct.TileStaticAssertionError) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel_1, (False,))
_check_message(str(e.value), expected)
def test_traceback_formatting_static_eval():
kernel_1_line = _source_line_no(kernel_1._annotated_function.pyfunc, "indented_helper")
indented_helper_line = _source_line_no(indented_helper, "ct.static_eval(expr_helper())")
expr_helper_line = _source_line_no(expr_helper, "print")
raising_helper_line = _source_line_no(raising_helper, "raise")
expected = f"""Exception was raised inside static_eval() (ValueError: 你好,世界)
"WHATEVERtest_error_traceback.py", line {kernel_1_line}, col 5-36, in kernel_1:
indented_helper(use_static_eval)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"WHATEVERtest_error_traceback.py", line {indented_helper_line}, col 9-37, in indented_helper:
ct.static_eval(expr_helper())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Entering compile-time evaluation inside static_eval()]
"WHATEVERtest_error_traceback.py", line {indented_helper_line}, col 24-36, in indented_helper [inside static_eval()]:
ct.static_eval(expr_helper())
^^^^^^^^^^^^^
"WHATEVERtest_error_traceback.py", line {expr_helper_line}, col 11-29, in expr_helper [inside static_eval()]:
print(sourceless_helper())
^^^^^^^^^^^^^^^^^^^
"<string>", line 1, in <lambda> [inside static_eval()]
"WHATEVERtest_error_traceback.py", line {raising_helper_line}, col 5-34, in raising_helper [inside static_eval()]:
raise ValueError("你好,世界")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^""" # noqa
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel_1, (True,))
_check_message(str(e.value), expected)
def test_traceback_formatting_static_exception():
@ct.kernel
def kernel():
raise ct.static_exception(TypeError("12345"))
kernel_line = _source_line_no(kernel._annotated_function.pyfunc, "raise")
expected = f"""Exception was raised at compile time (TypeError: 12345)
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 9-53, in kernel:
raise ct.static_exception(TypeError("12345"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"""
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel, ())
_check_message(str(e.value), expected)
def test_traceback_formatting_static_def():
@static_def
def static_def_helper(x, y):
return x // y
@ct.kernel
def kernel():
static_def_helper(1, 0)
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel, ())
kernel_line = _source_line_no(kernel._annotated_function.pyfunc, "static_def_helper(1, 0)")
helper_line = _source_line_no(static_def_helper, "return x // y")
expected = f"""Exception was raised inside @static_def function (ZeroDivisionError: WHATEVER)
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 9-31, in kernel:
static_def_helper(1, 0)
^^^^^^^^^^^^^^^^^^^^^^^
[Entering compile-time evaluation inside @static_def]
"WHATEVERtest_error_traceback.py", line {helper_line}, col 16-21, in static_def_helper [inside @static_def]:
return x // y
^^^^^^""" # noqa
_check_message(str(e.value), expected)
def test_traceback_formatting_enter_static_eval_inside_lambda():
def foo():
raise TypeError("hi")
@ct.kernel
def kernel():
lamb = lambda: ct.static_eval(foo()) # noqa
lamb()
kernel_lambda_line = _source_line_no(kernel._annotated_function.pyfunc, "lambda:")
kernel_call_line = _source_line_no(kernel._annotated_function.pyfunc, "lamb()")
foo_helper_line = _source_line_no(foo, "raise TypeError")
expected = f"""Exception was raised inside static_eval() (TypeError: hi)
"WHATEVERtest_error_traceback.py", line {kernel_call_line}, col 9-14, in kernel:
lamb()
^^^^^^
"WHATEVERtest_error_traceback.py", line {kernel_lambda_line}, col 24-44, in <lambda>:
lamb = lambda: ct.static_eval(foo()) # noqa
^^^^^^^^^^^^^^^^^^^^^
[Entering compile-time evaluation inside static_eval()]
"WHATEVERtest_error_traceback.py", line {kernel_lambda_line}, col 39-43, in <lambda> [inside static_eval()]:
lamb = lambda: ct.static_eval(foo()) # noqa
^^^^^
"WHATEVERtest_error_traceback.py", line {foo_helper_line}, col 9-29, in foo [inside static_eval()]:
raise TypeError("hi")
^^^^^^^^^^^^^^^^^^^^^""" # noqa
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel, ())
_check_message(str(e.value), expected)
def test_traceback_formatting_error_inside_static_assert_expr():
@ct.kernel
def kernel():
ct.static_assert(1 // 0)
kernel_line = _source_line_no(kernel._annotated_function.pyfunc, "ct.static_assert(1 // 0)")
expected = f"""Exception was raised inside static_assert() condition (ZeroDivisionError: WHATEVER)
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 9-32, in kernel:
ct.static_assert(1 // 0)
^^^^^^^^^^^^^^^^^^^^^^^^
[Entering compile-time evaluation inside static_assert() condition]
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 26-31, in kernel [inside static_assert() condition]:
ct.static_assert(1 // 0)
^^^^^^""" # noqa
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel, ())
_check_message(str(e.value), expected)
def test_traceback_formatting_error_inside_static_assert_message():
@ct.kernel
def kernel():
ct.static_assert(False, 1 // 0)
kernel_line = _source_line_no(kernel._annotated_function.pyfunc, "ct.static_assert(")
expected = f"""Exception was raised inside static_assert() message (ZeroDivisionError: WHATEVER)
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 9-39, in kernel:
ct.static_assert(False, 1 // 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Entering compile-time evaluation inside static_assert() message]
"WHATEVERtest_error_traceback.py", line {kernel_line}, col 33-38, in kernel [inside static_assert() message]:
ct.static_assert(False, 1 // 0)
^^^^^^""" # noqa
with pytest.raises(ct.StaticException) as e:
ct.launch(torch.cuda.current_stream(), (1,), kernel, ())
_check_message(str(e.value), expected)
def _source_line_no(func, substring: str) -> int:
lines, first_line_no = inspect.getsourcelines(func)
for i, s in enumerate(lines):
if substring in s:
return i + first_line_no
assert False, f"Line containing '{substring}' not found in function's source"
def _check_message(actual: str, expected_template: str):
expected_lines = expected_template.splitlines()
# Prior to Python 3.11, code objects have no column-level info.
# Need to strip column information from the expected message.
if (sys.version_info.major, sys.version_info.minor) < (3, 11):
filtered_lines = []
static_eval_frame = False
for line in expected_lines:
if static_eval_frame:
# Skip caret underlines (^^^^^^^^^^^^^^^)
if re.fullmatch(" *\\^+", line):
continue
filtered_lines.append(re.sub("col [^,]*, ", "", line))
else:
filtered_lines.append(line)
if re.search("Entering compile-time", line):
static_eval_frame = True
expected_lines = filtered_lines
print("\n".join(expected_lines))
actual_lines = actual.splitlines()
for expected, actual in zip_longest(expected_lines, actual_lines):
assert expected is not None
assert actual is not None
pat = re.escape(expected).replace("WHATEVER", ".*")
assert re.fullmatch(pat, actual), f"Mismatch!\nActual: {actual}\nExpected: {expected}\n"