Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions python/paddle/fluid/dygraph/dygraph_to_static/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,23 @@ def formated_message(self):
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):
"""
Error data attached to an exception which is raised in un-transformed code.
Expand All @@ -155,6 +172,7 @@ def __init__(self, error_type, error_value, origin_traceback,
self.origin_traceback = origin_traceback
self.origin_info_map = origin_info_map
self.in_runtime = False
self.suggestion_dict = SuggestionDict()

def create_exception(self):
message = self.create_message()
Expand Down Expand Up @@ -215,6 +233,22 @@ def create_message(self):

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):
"""
Simplifies error value to improve readability if error is raised in runtime.
Expand All @@ -240,6 +274,7 @@ def _simplify_error_value(self):
# use empty line to locate the bottom_error_message
empty_line_idx = error_value_lines_strip.index('')
bottom_error_message = error_value_lines[empty_line_idx + 1:]
revise_suggestion = self._create_revise_suggestion(bottom_error_message)

filepath = ''
error_from_user_code = []
Expand Down Expand Up @@ -269,6 +304,7 @@ def _simplify_error_value(self):
error_frame.insert(0, traceback_frame.formated_message())

error_frame.extend(bottom_error_message)
error_frame.extend(revise_suggestion)
error_value_str = '\n'.join(error_frame)
self.error_value = self.error_type(error_value_str)

Expand Down
11 changes: 6 additions & 5 deletions python/paddle/fluid/dygraph/dygraph_to_static/partial_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,12 @@ def _check_params_all_inited(self, main_program):
if isinstance(var, framework.Parameter):
if name not in param_and_buffer_names_set:
raise ValueError(
"\n\tWe don't support to define layer with parameters in the function "
"decorated by `@declarative`.\n\tBecause that will re-defined parameters "
"every time when you run the function.\n\t"
"But we found parameter(%s) was created in the decorated function.\n\t"
"Please define the layer with parameters in `__init__` function."
"\n\tWe don't support to define layer with parameters in the function decorated by `@to_static`."
"\n\tBut we found parameter(%s) was created in the decorated function."
"\n"
"\n\tRevise suggestion: "
"\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)

def _valid_vars(self, vars):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,31 @@ def func_error_in_runtime_with_empty_line(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):
def setUp(self):
self.reset_flags_to_default()
Expand Down Expand Up @@ -385,5 +410,39 @@ def test(self):
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__':
unittest.main()