未验证 提交 0b8664ea 编写于 作者: 0 0x45f 提交者: GitHub

[dy2stat_error] add revise suggestion for two error cases (#35648)

* dy2stat_error: add revise suggestion for two error cases

* fix test_error

* fix review
上级 bf983c2f
...@@ -143,6 +143,23 @@ class TraceBackFrameRange(OriginInfo): ...@@ -143,6 +143,23 @@ class TraceBackFrameRange(OriginInfo):
return msg + '\n'.join(self.source_code) + '\n' return msg + '\n'.join(self.source_code) + '\n'
class SuggestionDict(object):
def __init__(self):
# {(keywords): (suggestions)}
self.suggestion_dict = {
('is not initialized.', 'Hint:', 'IsInitialized'):
("Please ensure all your sublayers are inheritted from nn.Layer.",
"Please ensure there is no tensor created explicitly depended on external data, we suggest to register it as buffer tensor. See https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/04_dygraph_to_static/export_model/principle_cn.html#parameters-buffers for details"
)
}
def keys(self):
return self.suggestion_dict.keys()
def __getitem__(self, key):
return self.suggestion_dict[key]
class ErrorData(object): class ErrorData(object):
""" """
Error data attached to an exception which is raised in un-transformed code. Error data attached to an exception which is raised in un-transformed code.
...@@ -155,6 +172,7 @@ class ErrorData(object): ...@@ -155,6 +172,7 @@ class ErrorData(object):
self.origin_traceback = origin_traceback self.origin_traceback = origin_traceback
self.origin_info_map = origin_info_map self.origin_info_map = origin_info_map
self.in_runtime = False self.in_runtime = False
self.suggestion_dict = SuggestionDict()
def create_exception(self): def create_exception(self):
message = self.create_message() message = self.create_message()
...@@ -215,6 +233,22 @@ class ErrorData(object): ...@@ -215,6 +233,22 @@ class ErrorData(object):
return '\n'.join(message_lines) return '\n'.join(message_lines)
def _create_revise_suggestion(self, bottom_error_message):
revise_suggestions = [
'', ' ' * BLANK_COUNT_BEFORE_FILE_STR + 'Revise suggestion: '
]
for keywords in self.suggestion_dict.keys():
contain_keywords = [
True for i in keywords if i in ''.join(bottom_error_message)
]
if len(contain_keywords) == len(
keywords): # all keywords should be in bottom_error_message
for suggestion in self.suggestion_dict[keywords]:
suggestion_msg = ' ' * BLANK_COUNT_BEFORE_FILE_STR * 2 + '{}. {}'.format(
str(len(revise_suggestions) - 1), suggestion)
revise_suggestions.append(suggestion_msg)
return revise_suggestions if len(revise_suggestions) > 2 else []
def _simplify_error_value(self): def _simplify_error_value(self):
""" """
Simplifies error value to improve readability if error is raised in runtime. Simplifies error value to improve readability if error is raised in runtime.
...@@ -240,6 +274,7 @@ class ErrorData(object): ...@@ -240,6 +274,7 @@ class ErrorData(object):
# use empty line to locate the bottom_error_message # use empty line to locate the bottom_error_message
empty_line_idx = error_value_lines_strip.index('') empty_line_idx = error_value_lines_strip.index('')
bottom_error_message = error_value_lines[empty_line_idx + 1:] bottom_error_message = error_value_lines[empty_line_idx + 1:]
revise_suggestion = self._create_revise_suggestion(bottom_error_message)
filepath = '' filepath = ''
error_from_user_code = [] error_from_user_code = []
...@@ -269,6 +304,7 @@ class ErrorData(object): ...@@ -269,6 +304,7 @@ class ErrorData(object):
error_frame.insert(0, traceback_frame.formated_message()) error_frame.insert(0, traceback_frame.formated_message())
error_frame.extend(bottom_error_message) error_frame.extend(bottom_error_message)
error_frame.extend(revise_suggestion)
error_value_str = '\n'.join(error_frame) error_value_str = '\n'.join(error_frame)
self.error_value = self.error_type(error_value_str) self.error_value = self.error_type(error_value_str)
......
...@@ -474,11 +474,12 @@ class PartialProgramLayer: ...@@ -474,11 +474,12 @@ class PartialProgramLayer:
if isinstance(var, framework.Parameter): if isinstance(var, framework.Parameter):
if name not in param_and_buffer_names_set: if name not in param_and_buffer_names_set:
raise ValueError( raise ValueError(
"\n\tWe don't support to define layer with parameters in the function " "\n\tWe don't support to define layer with parameters in the function decorated by `@to_static`."
"decorated by `@declarative`.\n\tBecause that will re-defined parameters " "\n\tBut we found parameter(%s) was created in the decorated function."
"every time when you run the function.\n\t" "\n"
"But we found parameter(%s) was created in the decorated function.\n\t" "\n\tRevise suggestion: "
"Please define the layer with parameters in `__init__` function." "\n\t\t1. Please ensure all your sublayers are inheritted from nn.Layer."
"\n\t\t2. Please use nn.ParameterList and nn.LayerList as container instead of using a native Python container such as List"
% name) % name)
def _valid_vars(self, vars): def _valid_vars(self, vars):
......
...@@ -108,6 +108,31 @@ def func_error_in_runtime_with_empty_line(x): ...@@ -108,6 +108,31 @@ def func_error_in_runtime_with_empty_line(x):
return x return x
class SuggestionErrorTestNet(paddle.nn.Layer):
def __init__(self):
super(SuggestionErrorTestNet, self).__init__()
self.inner_net = SuggestionErrorTestNet2()
@paddle.jit.to_static
def forward(self, x):
return self.inner_net.forward(x)
class SuggestionErrorTestNet2():
def __init__(self):
super(SuggestionErrorTestNet2, self).__init__()
self.w = paddle.to_tensor([2.])
def forward(self, x):
out = paddle.matmul(self.w, x)
return out
def func_suggestion_error_in_runtime(x):
net = SuggestionErrorTestNet()
net(x)
class TestFlags(unittest.TestCase): class TestFlags(unittest.TestCase):
def setUp(self): def setUp(self):
self.reset_flags_to_default() self.reset_flags_to_default()
...@@ -385,5 +410,39 @@ class TestErrorInOther(unittest.TestCase): ...@@ -385,5 +410,39 @@ class TestErrorInOther(unittest.TestCase):
func_decorated_by_other_2() func_decorated_by_other_2()
class TestSuggestionErrorInRuntime(TestErrorBase):
def set_func(self):
self.func = func_suggestion_error_in_runtime
def set_input(self):
self.input = paddle.to_tensor([2.])
def set_exception_type(self):
self.exception_type = ValueError
def set_message(self):
self.expected_message = \
[
'File "{}", line 118, in forward'.format(self.filepath),
'return self.inner_net.forward(x)',
'File "{}", line 127, in forward'.format(self.filepath),
'def forward(self, x):',
'out = paddle.matmul(self.w, x)',
'<--- HERE',
'return out',
'Revise suggestion:',
'Please ensure all your sublayers are inheritted from nn.Layer.',
'Please ensure there is no tensor created explicitly depended on external data, we suggest to register it as buffer tensor. See'
]
def set_func_call(self):
# NOTE: self.func(self.input) is the StaticLayer().__call__(self.input)
self.func_call = lambda: self.func(self.input)
def test_error(self):
for disable_new_error in [0, 1]:
self._test_raise_new_exception(disable_new_error)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册