diff --git a/paddle/fluid/framework/CMakeLists.txt b/paddle/fluid/framework/CMakeLists.txt index 6440607dbe4666ff3ff91dc526465706b3b9c1f0..b3fe2d97a8a1e2bb3ce62879503f548bfacef6dc 100644 --- a/paddle/fluid/framework/CMakeLists.txt +++ b/paddle/fluid/framework/CMakeLists.txt @@ -115,6 +115,8 @@ cc_test(cow_ptr_tests SRCS details/cow_ptr_test.cc) # cc_test(channel_test SRCS channel_test.cc) cc_test(tuple_test SRCS tuple_test.cc ) +cc_test(attribute_type_test SRCS attribute_type_test.cc) + # disable test temporarily. # TODO https://github.com/PaddlePaddle/Paddle/issues/11971 # cc_test(concurrency_test SRCS concurrency_test.cc DEPS go_op channel_close_op channel_create_op diff --git a/paddle/fluid/framework/attribute.h b/paddle/fluid/framework/attribute.h index 8428bf8e3392f68c9d1e2553f4d017cb620bb9f3..2b0552825752e927e13463dd60a0944edf0503a4 100644 --- a/paddle/fluid/framework/attribute.h +++ b/paddle/fluid/framework/attribute.h @@ -20,6 +20,7 @@ limitations under the License. */ #include #include +#include "paddle/fluid/framework/attribute_type.h" #include "paddle/fluid/framework/framework.pb.h" #include "paddle/fluid/framework/type_defs.h" #include "paddle/fluid/platform/enforce.h" @@ -128,7 +129,8 @@ struct ExtractAttribute { attr_value = &boost::get(attr); } catch (boost::bad_get& bad_get) { PADDLE_THROW("Cannot get attribute %s by type %s, its type is %s", - attr_name_, typeid(T).name(), attr.type().name()); + attr_name_, paddle::framework::demangle(typeid(T).name()), + paddle::framework::demangle(attr.type().name())); } return attr_value; } @@ -160,7 +162,7 @@ struct ExtractAttribute { attr_value = &boost::get(attr); } catch (boost::bad_get& bad_get) { PADDLE_THROW("Cannot get attribute %s by type bool, its type is %s", - attr_name_, attr.type().name()); + attr_name_, paddle::framework::demangle(attr.type().name())); } return attr_value; } @@ -186,7 +188,7 @@ struct ExtractAttribute { attr_value = &boost::get(attr); } catch (boost::bad_get& bad_get) { PADDLE_THROW("Cannot get attribute %s by type int64_t, its type is %s", - attr_name_, attr.type().name()); + attr_name_, paddle::framework::demangle(attr.type().name())); } return attr_value; } diff --git a/paddle/fluid/framework/attribute_type.h b/paddle/fluid/framework/attribute_type.h new file mode 100644 index 0000000000000000000000000000000000000000..337dcde77559785e249af39620e5ccab33be7127 --- /dev/null +++ b/paddle/fluid/framework/attribute_type.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include + +// __has_include is currently supported by GCC and Clang. However GCC 4.9 may +// have issues and +// returns 1 for 'defined( __has_include )', while '__has_include' is actually +// not supported: +#if defined(__has_include) && (!defined(BOOST_GCC) || (__GNUC__ + 0) >= 5) +#if __has_include() +#define PADDLE_FRAMEWORK_HAS_CXXABI_H +#endif +#elif defined(__GLIBCXX__) || defined(__GLIBCPP__) +#define PADDLE_FRAMEWORK_HAS_CXXABI_H +#endif + +#if defined(PADDLE_FRAMEWORK_HAS_CXXABI_H) +#include +// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is +// implemented by gabi++ library +// which does not implement abi::__cxa_demangle(). We detect this implementation +// by checking the include guard here. +#if defined(__GABIXX_CXXABI_H__) +#undef PADDLE_FRAMEWORK_HAS_CXXABI_H +#else +#include +#include +#endif +#endif + +namespace paddle { +namespace framework { + +inline char const* demangle_alloc(char const* name); +inline void demangle_free(char const* name); + +class scoped_demangled_name { + private: + char const* m_p; + + public: + explicit scoped_demangled_name(char const* name) + : m_p(demangle_alloc(name)) {} + + ~scoped_demangled_name() { demangle_free(m_p); } + + char const* get() const { return m_p; } + + scoped_demangled_name(scoped_demangled_name const&) = delete; + scoped_demangled_name& operator=(scoped_demangled_name const&) = delete; +}; + +#if defined(PADDLE_FRAMEWORK_HAS_CXXABI_H) + +inline char const* demangle_alloc(char const* name) { + int status = 0; + std::size_t size = 0; + return abi::__cxa_demangle(name, NULL, &size, &status); +} + +inline void demangle_free(char const* name) { + std::free(const_cast(name)); +} + +inline std::string demangle(char const* name) { + scoped_demangled_name demangled_name(name); + char const* p = demangled_name.get(); + if (!p) p = name; + return p; +} + +#else + +inline char const* demangle_alloc(char const* name) { return name; } + +inline void demangle_free(char const*) {} + +inline std::string demangle(char const* name) { return name; } + +#endif + +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/attribute_type_test.cc b/paddle/fluid/framework/attribute_type_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..82537b8a0f1207da2ad9ec95390f9ae9daf2f92f --- /dev/null +++ b/paddle/fluid/framework/attribute_type_test.cc @@ -0,0 +1,46 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include +#include + +#include "gtest/gtest.h" +#include "paddle/fluid/framework/attribute_type.h" + +TEST(Attribute, TypeName) { + bool boolean; + int integer; + float ft; + std::string str; + std::vector booleans; + std::vector integers; + std::vector strings; + + EXPECT_EQ("bool", paddle::framework::demangle(typeid(boolean).name())); + EXPECT_EQ("int", paddle::framework::demangle(typeid(integer).name())); + EXPECT_EQ("float", paddle::framework::demangle(typeid(ft).name())); + EXPECT_EQ( + "std::__cxx11::basic_string, " + "std::allocator >", + paddle::framework::demangle(typeid(str).name())); + EXPECT_EQ("std::vector >", + paddle::framework::demangle(typeid(booleans).name())); + EXPECT_EQ("std::vector >", + paddle::framework::demangle(typeid(integers).name())); + EXPECT_EQ( + "std::vector, " + "std::allocator >, std::allocator, std::allocator > > >", + paddle::framework::demangle(typeid(strings).name())); +}