You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
boost::get is not a completely safe interface, although it will not go wrong in most cases, but in extreme case, if may fail and directly throw a boost::bad_get exception without any stack information. This kind of problem is difficult to debug.
Use this macro instead of boost :: get, when something goes wrong, we can get richer error information . Including the error file, line number, expected value type and actual value type, this can help users to locate the cause of the error easily.
difficulty
The boost :: get has 4 types of return value, include T, const T, T&, const T&, so here need some tricks to cover these 4 scenarios with only one macro. With the help of @sneaxiy, under the gcc5.4 environment, we solved this problem with only one macro, see the commit 11bbbb2.
But CI now using gcc4.8, the writing above cannot be compiled under gcc4.8, this is a gcc4.8’s bug, gcc official recommends to use a higher version to solve. So I had to write three macros here to solve this problem, as follows:
- BOOST_GET (e.g. return int& or int*)
- BOOST_GET_CONST(e.g. return const int& or const int*)
- BOOST_GET_MUTABLE (e.g. return int or int*)
Examples:
Case 1: Place Get Error
1. original boost::get
this is a C++ exception, but using boost::get directly cannot throw C++ error info.
code piece
boost::get<platform::CPUPlace>(self); # self is CUDAPlace(0)
error result
Traceback (most recent call last):
File "boost_get_err.py", line 6, in <module>
new_place = fluid.CUDAPlace(p.gpu_device_id())
RuntimeError: boost::bad_get: failed value get using boost::get
2. new macro BOOST_GET
code piece
BOOST_GET_CONST(platform::CPUPlace, self); # self is CUDAPlace(0)
error result
Traceback (most recent call last):
File "boost_get_err.py", line 6, in <module>
new_place = fluid.CUDAPlace(p.gpu_device_id())
paddle.fluid.core_avx.EnforceNotMet:
--------------------------------------------
C++ Call Stacks (More useful to developers):
--------------------------------------------
0 std::string paddle::platform::GetTraceBackString<std::string>(std::string&&, char const*, int)
1 paddle::platform::EnforceNotMet::EnforceNotMet(paddle::platform::ErrorSummary const&, char const*, int)
2 std::conditional<std::is_pointer<paddle::platform::Place>::value, paddle::platform::CPUPlace const*, paddle::platform::CPUPlace const&>::type paddle::platform::details::SafeBoostGetConst<paddle::platform::CPUPlace, paddle::platform::Place>(paddle::platform::Place const&, char const*, char const*, int)
----------------------
Error Message Summary:
----------------------
InvalidArgumentError: boost::get failed, cannot get value (self) by type paddle::platform::CPUPlace, its type is paddle::platform::CUDAPlace. at (/work/paddle/paddle/fluid/pybind/pybind.cc:1365)
Case 2: Attr Get Error
1. original boost::get
Traceback (most recent call last):
File "boost_get_err2.py", line 12, in <module>
conv = conv2d(data)
File "/usr/local/lib/python3.5/dist-packages/paddle/fluid/dygraph/layers.py", line 460, in __call__
outputs = self.forward(*inputs, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/paddle/fluid/dygraph/nn.py", line 234, in forward
self._act)
File "</usr/local/lib/python3.5/dist-packages/decorator.py:decorator-gen-22>", line 2, in _append_activation_in_dygraph
File "/usr/local/lib/python3.5/dist-packages/paddle/fluid/wrapped_decorator.py", line 25, in __impl__
return wrapped_func(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/paddle/fluid/framework.py", line 216, in __impl__
return func(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/paddle/fluid/dygraph_utils.py", line 40, in _append_activation_in_dygraph
return act_op(input, *attrs)
RuntimeError: boost::bad_get: failed value get using boost::get
In order to avoid the direct use of boost :: get, I added a new rule to CI to limit the use of boost :: get. If found, it will remind developer to use the macro BOOST_GET(_**) series macros.
chenwhql
changed the title
Add macro BOOST_GET_SAFELY to enrich the error information of boost :: get
Add macro BOOST_GET to enrich the error information of boost :: get
May 9, 2020
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
boost::get
is not a completely safe interface, although it will not go wrong in most cases, but in extreme case, if may fail and directly throw aboost::bad_get
exception without any stack information. This kind of problem is difficult to debug.Related issues:
Now there are nearly 600
boost :: get
in paddle without catch exception when used.In this PR, I add new series macros
BOOST_GET{***}
, It encapsulatesboost :: get
as follows:Use this macro instead of
boost :: get
, when something goes wrong, we can get richer error information . Including the error file, line number, expected value type and actual value type, this can help users to locate the cause of the error easily.difficulty
The
boost :: get
has 4 types of return value, includeT, const T, T&, const T&
, so here need some tricks to cover these 4 scenarios with only one macro. With the help of @sneaxiy, under the gcc5.4 environment, we solved this problem with only one macro, see the commit 11bbbb2.But CI now using gcc4.8, the writing above cannot be compiled under gcc4.8, this is a gcc4.8’s bug, gcc official recommends to use a higher version to solve. So I had to write three macros here to solve this problem, as follows:
Examples:
Case 1: Place Get Error
1. original
boost::get
this is a C++ exception, but using
boost::get
directly cannot throw C++ error info.code piece
2. new macro
BOOST_GET
Case 2: Attr Get Error
1. original
boost::get
2. new macro
BOOST_GET
CI check
In order to avoid the direct use of
boost :: get
, I added a new rule to CI to limit the use ofboost :: get
. If found, it will remind developer to use the macroBOOST_GET(_**) series macros
.