未验证 提交 aa10b11e 编写于 作者: 石晓伟 提交者: GitHub

refactor any.h, test=develop (#3736)

上级 9e361a4d
......@@ -76,8 +76,6 @@ class Context<TargetType::kHost> {
template <>
class Context<TargetType::kNPU> {
public:
Context() {}
explicit Context(const NPUContext& ctx);
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() {}
void CopySharedTo(NPUContext* ctx) {}
......@@ -101,8 +99,6 @@ class Context<TargetType::kNPU> {
template <>
class Context<TargetType::kAPU> {
public:
Context() {}
explicit Context(const APUContext& ctx);
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() {}
void CopySharedTo(APUContext* ctx) {}
......@@ -116,8 +112,6 @@ class Context<TargetType::kAPU> {
template <>
class Context<TargetType::kBM> {
public:
Context() {}
explicit Context(const BMContext& ctx);
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() { TargetWrapperBM::SetDevice(TargetWrapperBM::GetDevice()); }
void CopySharedTo(BMContext* ctx) {}
......@@ -131,8 +125,6 @@ class Context<TargetType::kBM> {
template <>
class Context<TargetType::kRKNPU> {
public:
Context() {}
explicit Context(const RKNPUContext& ctx);
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() {}
void CopySharedTo(RKNPUContext* ctx) {}
......@@ -146,9 +138,6 @@ class Context<TargetType::kRKNPU> {
template <>
class Context<TargetType::kXPU> {
public:
Context() {}
explicit Context(const XPUContext& ctx);
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() {}
......@@ -200,11 +189,6 @@ class Context<TargetType::kXPU> {
template <>
class Context<TargetType::kARM> {
public:
Context() {}
explicit Context(const ARMContext& ctx);
ARMContext& operator=(const ARMContext& ctx) {}
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() { DeviceInfo::Init(); }
......@@ -246,7 +230,6 @@ class Context<TargetType::kARM> {
template <>
class Context<TargetType::kFPGA> {
public:
Context() {}
void InitOnce() {}
FPGAContext& operator=(const FPGAContext& ctx) {}
......@@ -340,8 +323,6 @@ class Context<TargetType::kMLU> {
template <>
class Context<TargetType::kX86> {
public:
Context() {}
// NOTE: InitOnce should only be used by ContextScheduler
void InitOnce() {}
......
......@@ -115,7 +115,7 @@ class KernelBase {
}
template <typename T>
void SetParam(T param) {
param_.set<T>(param);
param_.set(param);
}
template <typename P>
P& Param() const {
......
......@@ -24,7 +24,7 @@ namespace cpp {
template <> \
void OpDesc::SetAttr<T>(const std::string& name, const T& v) { \
attr_types_[name] = AttrType::repr__; \
attrs_[name].set<T>(v); \
attrs_[name].set(v); \
}
SET_ATTR_IMPL(int32_t, INT);
......
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
// Copyright (c) 2020 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.
......@@ -13,11 +13,3 @@
// limitations under the License.
#include "lite/utils/any.h"
namespace paddle {
namespace lite {
size_t Any::kInvalidType{typeid(void).hash_code()};
} // namespace lite
} // namespace paddle
......@@ -13,8 +13,12 @@
// limitations under the License.
#pragma once
#include <functional>
#include <set>
#include <algorithm>
#include <cstring>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include "lite/utils/cp_logging.h"
namespace paddle {
......@@ -22,67 +26,273 @@ namespace lite {
class Any {
public:
Any() = default;
explicit Any(const Any& other) {
type_ = other.type_;
data_ = other.clone_data_(other.data_);
deleter_ = other.deleter_;
clone_data_ = other.clone_data_;
}
inline Any() = default;
inline explicit Any(Any&& other);
inline explicit Any(const Any& other);
template <typename T>
void set(const T& v) {
set<T>();
*get_mutable<T>() = v;
}
void set();
template <typename T>
void set() {
if (type_ != kInvalidType) {
CHECK(type_ == typeid(T).hash_code());
} else {
type_ = typeid(T).hash_code();
deleter_ = [&](void** data) {
delete static_cast<T*>(*data);
*data = nullptr;
void set(T&& other);
template <typename T>
const T& get() const;
template <typename T>
T* get_mutable();
template <typename T>
inline explicit Any(T&& other);
inline ~Any();
inline Any& operator=(Any&& other);
inline Any& operator=(const Any& other);
template <typename T>
inline Any& operator=(T&& other);
inline bool empty() const;
inline bool valid() const;
inline void clear();
inline void swap(Any& other);
inline const std::type_info& type() const;
template <typename T, typename... Args>
inline void construct(Args&&... args);
private:
template <typename T>
class TypeOnHeap;
template <typename T>
class TypeOnStack;
template <typename T>
class TypeInfo;
static const size_t kStack = sizeof(void*) * 3;
static const size_t kAlign = sizeof(void*);
union Data {
std::aligned_storage<kStack, kAlign>::type stack;
void* pheap;
};
clone_data_ = [&](void* data) {
T* res = new T;
CHECK(data) << "data pointer is nullptr";
*res = *static_cast<T*>(data);
return res;
struct Type {
void (*destroy)(Data* data);
void (*create_from_data)(Data* dst, const Data& src);
const std::type_info* ptype_info;
};
template <typename T>
struct data_on_stack {
static const bool value = ((alignof(T) <= kAlign) && (sizeof(T) <= kStack));
};
inline void construct(Any&& other);
inline void construct(const Any& other);
template <typename T>
inline void check_type() const;
template <typename T>
inline void check_type_by_name() const;
const Type* type_{nullptr};
Data data_;
};
template <typename T>
inline Any::Any(T&& other) {
typedef typename std::decay<T>::type DT;
if (std::is_same<DT, Any>::value) {
this->construct(std::forward<T>(other));
} else {
static_assert(std::is_copy_constructible<DT>::value,
"Any can only hold value that is copy constructable");
type_ = TypeInfo<DT>::get_type();
if (data_on_stack<DT>::value) {
#pragma GCC diagnostic push
#if 6 <= __GNUC__
#pragma GCC diagnostic ignored "-Wplacement-new"
#endif
new (&(data_.stack)) DT(std::forward<T>(other));
#pragma GCC diagnostic pop
} else {
data_.pheap = new DT(std::forward<T>(other));
}
data_ = new T;
}
}
template <typename T>
const T& get() const {
CHECK(data_);
CHECK(type_ == typeid(T).hash_code());
return *static_cast<T*>(data_);
inline Any::Any(Any&& other) { this->construct(std::move(other)); }
inline Any::Any(const Any& other) { this->construct(other); }
inline void Any::construct(Any&& other) {
type_ = other.type_;
data_ = other.data_;
other.type_ = nullptr;
}
inline void Any::construct(const Any& other) {
type_ = other.type_;
if (type_ != nullptr) {
type_->create_from_data(&data_, other.data_);
}
template <typename T>
T* get_mutable() {
CHECK(data_);
CHECK(type_ == typeid(T).hash_code());
return static_cast<T*>(data_);
}
template <typename T, typename... Args>
inline void Any::construct(Args&&... args) {
clear();
typedef typename std::decay<T>::type DT;
type_ = TypeInfo<DT>::get_type();
if (data_on_stack<DT>::value) {
#pragma GCC diagnostic push
#if 6 <= __GNUC__
#pragma GCC diagnostic ignored "-Wplacement-new"
#endif
new (&(data_.stack)) DT(std::forward<Args>(args)...);
#pragma GCC diagnostic pop
} else {
data_.pheap = new DT(std::forward<Args>(args)...);
}
}
template <typename T>
void Any::set() {
this->construct<T>();
}
template <typename T>
void Any::set(T&& other) {
this->construct<T>(std::forward<T>(other));
}
inline Any::~Any() { this->clear(); }
inline Any& Any::operator=(Any&& other) {
Any(std::move(other)).swap(*this);
return *this;
}
inline Any& Any::operator=(const Any& other) {
Any(other).swap(*this);
return *this;
}
template <typename T>
inline Any& Any::operator=(T&& other) {
Any(std::forward<T>(other)).swap(*this);
return *this;
}
inline void Any::swap(Any& other) {
std::swap(type_, other.type_);
std::swap(data_, other.data_);
}
inline void Any::clear() {
if (type_ != nullptr) {
if (type_->destroy != nullptr) {
type_->destroy(&data_);
}
type_ = nullptr;
}
}
inline bool Any::empty() const { return type_ == nullptr; }
inline bool Any::valid() const { return empty() == false; }
inline const std::type_info& Any::type() const {
if (type_ != nullptr) {
return *(type_->ptype_info);
} else {
return typeid(void);
}
}
template <typename T>
inline void Any::check_type() const {
CHECK_EQ((type_ == nullptr), false);
CHECK_EQ((*(type_->ptype_info) == typeid(T)), true);
}
template <typename T>
inline void Any::check_type_by_name() const {
CHECK_EQ((type_ == nullptr), false);
CHECK_EQ(strcmp(type_->ptype_info->name(), typeid(T).name()), 0);
}
bool valid() const { return (data_ != nullptr); }
template <typename T>
inline const T& Any::get() const {
this->check_type<T>();
return *Any::TypeInfo<T>::get_ptr(&(this->data_));
}
~Any() {
if (valid()) {
deleter_(&data_);
template <typename T>
T* Any::get_mutable() {
return Any::TypeInfo<T>::get_ptr(&(this->data_));
}
template <typename T>
class Any::TypeOnHeap {
public:
inline static T* get_ptr(Any::Data* data) {
return static_cast<T*>(data->pheap);
}
inline static const T* get_ptr(const Any::Data* data) {
return static_cast<const T*>(data->pheap);
}
inline static void create_from_data(Any::Data* dst, const Any::Data& data) {
dst->pheap = new T(*get_ptr(&data));
}
inline static void destroy(Data* data) {
delete static_cast<T*>(data->pheap);
}
};
template <typename T>
class Any::TypeOnStack {
public:
inline static T* get_ptr(Any::Data* data) {
return reinterpret_cast<T*>(&(data->stack));
}
inline static const T* get_ptr(const Any::Data* data) {
return reinterpret_cast<const T*>(&(data->stack));
}
inline static void create_from_data(Any::Data* dst, const Any::Data& data) {
new (&(dst->stack)) T(*get_ptr(&data));
}
inline static void destroy(Data* data) {
T* dptr = reinterpret_cast<T*>(&(data->stack));
dptr->~T();
}
};
template <typename T>
class Any::TypeInfo : public std::conditional<Any::data_on_stack<T>::value,
Any::TypeOnStack<T>,
Any::TypeOnHeap<T>>::type {
public:
inline static const Type* get_type() {
static TypeInfo<T> tp;
return &(tp.type_);
}
private:
static size_t kInvalidType;
size_t type_{kInvalidType};
void* data_{nullptr};
std::function<void(void**)> deleter_;
std::function<void*(void*)> clone_data_;
Type type_;
TypeInfo() {
if (std::is_pod<T>::value && data_on_stack<T>::value) {
type_.destroy = nullptr;
} else {
type_.destroy = TypeInfo<T>::destroy;
}
type_.create_from_data = TypeInfo<T>::create_from_data;
type_.ptype_info = &typeid(T);
}
};
} // namespace lite
......
......@@ -13,6 +13,7 @@
// limitations under the License.
#pragma once
#include <functional>
#include <iostream>
#include <list>
#include <map>
......
......@@ -103,7 +103,7 @@ static int gettimeofday(struct timeval* tp, void* tzp) {
#define _CHECK_BINARY(x, cmp, y) CHECK(x cmp y)
#else
#define CHECK(x) if (!(x)) paddle::lite::LogMessageFatal(__FILE__, __FUNCTION__, __LINE__).stream() << "Check failed: " #x << ": " // NOLINT(*)
#define _CHECK_BINARY(x, cmp, y) CHECK(x cmp y) << x << "!" #cmp << y << " "
#define _CHECK_BINARY(x, cmp, y) CHECK((x cmp y)) << (x) << "!" #cmp << (y) << " " // NOLINT(*)
#endif
// clang-format on
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册