chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
/* Copyright (c) 2022 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 <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
|
||||
#include "paddle/phi/common/data_type.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
|
||||
#ifdef PADDLE_WITH_FLAGCX
|
||||
#include <flagcx.h>
|
||||
#endif
|
||||
namespace phi {
|
||||
|
||||
#define _PhiForEachDataTypeHelper_(callback, cpp_type, data_type) \
|
||||
callback(cpp_type, data_type);
|
||||
|
||||
#define _PhiForEachDataType_(callback) \
|
||||
_PhiForEachDataTypeHelper_(callback, float, DataType::FLOAT32); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::float16, DataType::FLOAT16); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::bfloat16, DataType::BFLOAT16); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::float8_e4m3fn, DataType::FLOAT8_E4M3FN); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::float8_e5m2, DataType::FLOAT8_E5M2); \
|
||||
_PhiForEachDataTypeHelper_(callback, double, DataType::FLOAT64); \
|
||||
_PhiForEachDataTypeHelper_(callback, int, DataType::INT32); \
|
||||
_PhiForEachDataTypeHelper_(callback, int64_t, DataType::INT64); \
|
||||
_PhiForEachDataTypeHelper_(callback, bool, DataType::BOOL); \
|
||||
_PhiForEachDataTypeHelper_(callback, uint8_t, DataType::UINT8); \
|
||||
_PhiForEachDataTypeHelper_(callback, int16_t, DataType::INT16); \
|
||||
_PhiForEachDataTypeHelper_(callback, int8_t, DataType::INT8); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::complex<float>, DataType::COMPLEX64); \
|
||||
_PhiForEachDataTypeHelper_( \
|
||||
callback, ::phi::dtype::complex<double>, DataType::COMPLEX128);
|
||||
|
||||
#define _PhiForEachDataTypeTiny_(callback) \
|
||||
_PhiForEachDataTypeHelper_(callback, int, DataType::INT32); \
|
||||
_PhiForEachDataTypeHelper_(callback, int64_t, DataType::INT64);
|
||||
|
||||
template <typename Visitor>
|
||||
inline void VisitDataType(DataType type, Visitor visitor) {
|
||||
#define PhiVisitDataTypeCallback(cpp_type, data_type) \
|
||||
do { \
|
||||
if (type == data_type) { \
|
||||
visitor.template apply<cpp_type>(); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
_PhiForEachDataType_(PhiVisitDataTypeCallback);
|
||||
#undef PhiVisitDataTypeCallback
|
||||
PADDLE_THROW(common::errors::Unimplemented(
|
||||
"Not supported DataType(%d) as data type.", static_cast<int>(type)));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
inline void VisitDataTypeTiny(DataType type, Visitor visitor) {
|
||||
#define PhiVisitDataTypeCallbackTiny(cpp_type, data_type) \
|
||||
do { \
|
||||
if (type == data_type) { \
|
||||
visitor.template apply<cpp_type>(); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
_PhiForEachDataTypeTiny_(PhiVisitDataTypeCallbackTiny);
|
||||
#undef PhiVisitDataTypeCallbackTiny
|
||||
PADDLE_THROW(common::errors::Unimplemented(
|
||||
"Not supported DataType(%d) as data type.", static_cast<int>(type)));
|
||||
}
|
||||
|
||||
inline bool IsComplexType(const DataType& type) {
|
||||
return (type == DataType::COMPLEX64 || type == DataType::COMPLEX128);
|
||||
}
|
||||
|
||||
inline DataType ToComplexType(const DataType& type) {
|
||||
switch (type) {
|
||||
case DataType::FLOAT32:
|
||||
return DataType::COMPLEX64;
|
||||
case DataType::FLOAT64:
|
||||
return DataType::COMPLEX128;
|
||||
default:
|
||||
PADDLE_THROW(errors::Unimplemented(
|
||||
"Can not transform data type (%s) to complex type, now only support "
|
||||
"float32 and float64 real value.",
|
||||
type));
|
||||
}
|
||||
}
|
||||
|
||||
inline DataType ToRealType(const DataType& type) {
|
||||
switch (type) {
|
||||
case DataType::COMPLEX64:
|
||||
return DataType::FLOAT32;
|
||||
case DataType::COMPLEX128:
|
||||
return DataType::FLOAT64;
|
||||
default:
|
||||
PADDLE_THROW(errors::Unimplemented(
|
||||
"Can not transform data type (%s) to real type, now only support "
|
||||
"complex64 and complex128 value.",
|
||||
type));
|
||||
}
|
||||
}
|
||||
|
||||
// In some cases we need to use the conversion between DataType and
|
||||
// fluid proto::VarType::Type, but can't depend on the proto::VarType::Type.
|
||||
// So here we defined an enum type ProtoDataType which corresponds to
|
||||
// proto::VarType::Type in fluid, but keeps only the data types we need.
|
||||
// Note: The ProtoDataType (defined here) and proto::VarType::Type (defined
|
||||
// in framework.pb.h) need to be modified simultaneously.
|
||||
enum ProtoDataType {
|
||||
BOOL = 0,
|
||||
INT16 = 1,
|
||||
INT32 = 2,
|
||||
INT64 = 3,
|
||||
FP16 = 4,
|
||||
FP32 = 5,
|
||||
FP64 = 6,
|
||||
RAW = 17,
|
||||
UINT8 = 20,
|
||||
INT8 = 21,
|
||||
BF16 = 22,
|
||||
COMPLEX64 = 23,
|
||||
COMPLEX128 = 24,
|
||||
PSTRING = 29,
|
||||
FP8_E4M3FN = 32,
|
||||
FP8_E5M2 = 33,
|
||||
UINT16 = 36,
|
||||
UINT32 = 37,
|
||||
UINT64 = 38,
|
||||
};
|
||||
|
||||
inline DataType TransToPhiDataType(const int& dtype) {
|
||||
// Set the order of case branches according to the frequency with
|
||||
// the data type is used
|
||||
switch (dtype) {
|
||||
case ProtoDataType::FP32:
|
||||
return DataType::FLOAT32;
|
||||
case ProtoDataType::FP64:
|
||||
return DataType::FLOAT64;
|
||||
case ProtoDataType::INT64:
|
||||
return DataType::INT64;
|
||||
case ProtoDataType::INT32:
|
||||
return DataType::INT32;
|
||||
case ProtoDataType::INT8:
|
||||
return DataType::INT8;
|
||||
case ProtoDataType::UINT8:
|
||||
return DataType::UINT8;
|
||||
case ProtoDataType::INT16:
|
||||
return DataType::INT16;
|
||||
case ProtoDataType::COMPLEX64:
|
||||
return DataType::COMPLEX64;
|
||||
case ProtoDataType::COMPLEX128:
|
||||
return DataType::COMPLEX128;
|
||||
case ProtoDataType::FP8_E4M3FN:
|
||||
return DataType::FLOAT8_E4M3FN;
|
||||
case ProtoDataType::FP8_E5M2:
|
||||
return DataType::FLOAT8_E5M2;
|
||||
case ProtoDataType::FP16:
|
||||
return DataType::FLOAT16;
|
||||
case ProtoDataType::BF16:
|
||||
return DataType::BFLOAT16;
|
||||
case ProtoDataType::BOOL:
|
||||
return DataType::BOOL;
|
||||
case ProtoDataType::PSTRING:
|
||||
return DataType::PSTRING;
|
||||
case ProtoDataType::RAW:
|
||||
return DataType::ALL_DTYPE;
|
||||
default:
|
||||
return DataType::UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
inline int TransToProtoVarType(const DataType& dtype) {
|
||||
// Set the order of case branches according to the frequency with
|
||||
// the data type is used
|
||||
switch (dtype) {
|
||||
case DataType::FLOAT32:
|
||||
return ProtoDataType::FP32;
|
||||
case DataType::FLOAT64:
|
||||
return ProtoDataType::FP64;
|
||||
case DataType::INT64:
|
||||
return ProtoDataType::INT64;
|
||||
case DataType::INT32:
|
||||
return ProtoDataType::INT32;
|
||||
case DataType::INT8:
|
||||
return ProtoDataType::INT8;
|
||||
case DataType::UINT8:
|
||||
return ProtoDataType::UINT8;
|
||||
case DataType::UINT16:
|
||||
return ProtoDataType::UINT16;
|
||||
case DataType::UINT32:
|
||||
return ProtoDataType::UINT32;
|
||||
case DataType::UINT64:
|
||||
return ProtoDataType::UINT64;
|
||||
case DataType::INT16:
|
||||
return ProtoDataType::INT16;
|
||||
case DataType::COMPLEX64:
|
||||
return ProtoDataType::COMPLEX64;
|
||||
case DataType::COMPLEX128:
|
||||
return ProtoDataType::COMPLEX128;
|
||||
case DataType::FLOAT8_E4M3FN:
|
||||
return ProtoDataType::FP8_E4M3FN;
|
||||
case DataType::FLOAT8_E5M2:
|
||||
return ProtoDataType::FP8_E5M2;
|
||||
case DataType::FLOAT16:
|
||||
return ProtoDataType::FP16;
|
||||
case DataType::BFLOAT16:
|
||||
return ProtoDataType::BF16;
|
||||
case DataType::BOOL:
|
||||
return ProtoDataType::BOOL;
|
||||
case DataType::PSTRING:
|
||||
return ProtoDataType::PSTRING;
|
||||
case DataType::UNDEFINED:
|
||||
return ProtoDataType::RAW;
|
||||
default:
|
||||
PADDLE_THROW(common::errors::Unimplemented(
|
||||
"Unsupported data type `%s` when casting it into "
|
||||
"paddle data type.",
|
||||
dtype));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PADDLE_WITH_NCCL) || defined(PADDLE_WITH_RCCL)
|
||||
inline ncclDataType_t ToNCCLDataType(DataType type) {
|
||||
if (type == DataType::FLOAT32) {
|
||||
return ncclFloat;
|
||||
} else if (type == DataType::FLOAT64) {
|
||||
return ncclDouble;
|
||||
} else if (type == DataType::INT32) {
|
||||
return ncclInt;
|
||||
} else if (type == DataType::INT64) {
|
||||
return ncclInt64;
|
||||
} else if (type == DataType::FLOAT16) {
|
||||
return ncclFloat16;
|
||||
} else if (type == DataType::UINT8) {
|
||||
return ncclUint8;
|
||||
} else if (type == DataType::INT8) {
|
||||
return ncclInt8;
|
||||
} else if (type == DataType::BOOL || type == DataType::FLOAT8_E4M3FN ||
|
||||
type == DataType::FLOAT8_E5M2) {
|
||||
return ncclUint8;
|
||||
#if (NCCL_VERSION_CODE >= 21000 && CUDA_VERSION >= 11000) || \
|
||||
defined(PADDLE_WITH_HIP)
|
||||
} else if (type == DataType::BFLOAT16) {
|
||||
return ncclBfloat16;
|
||||
#endif
|
||||
} else {
|
||||
PADDLE_THROW(
|
||||
errors::Unimplemented("This datatype in nccl is not supported."));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(PADDLE_WITH_XPU_BKCL)
|
||||
inline BKCLDataType ToBKCLDataType(DataType type) {
|
||||
if (type == DataType::FLOAT32) {
|
||||
return BKCL_FLOAT;
|
||||
} else if (type == DataType::FLOAT64) {
|
||||
return BKCL_FLOAT64;
|
||||
} else if (type == DataType::INT8) {
|
||||
return BKCL_UINT8;
|
||||
} else if (type == DataType::INT32) {
|
||||
return BKCL_INT32;
|
||||
} else if (type == DataType::INT64) {
|
||||
return BKCL_INT64;
|
||||
} else if (type == DataType::FLOAT16) {
|
||||
return BKCL_FLOAT16;
|
||||
} else if (type == DataType::UINT8) {
|
||||
return BKCL_UINT8;
|
||||
} else if (type == DataType::BOOL) {
|
||||
return BKCL_UINT8;
|
||||
} else if (type == DataType::BFLOAT16) {
|
||||
return BKCL_BFLOAT16;
|
||||
} else {
|
||||
PADDLE_THROW(
|
||||
errors::Unimplemented("This datatype in bkcl is not supported."));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(PADDLE_WITH_FLAGCX)
|
||||
inline flagcxDataType_t ToFlagcxDataType(DataType type) {
|
||||
if (type == DataType::FLOAT32) {
|
||||
return flagcxFloat;
|
||||
} else if (type == DataType::FLOAT64) {
|
||||
return flagcxDouble;
|
||||
} else if (type == DataType::INT32) {
|
||||
return flagcxInt;
|
||||
} else if (type == DataType::INT64) {
|
||||
return flagcxInt64;
|
||||
} else if (type == DataType::FLOAT16) {
|
||||
return flagcxFloat16;
|
||||
} else if (type == DataType::UINT8) {
|
||||
return flagcxUint8;
|
||||
} else if (type == DataType::INT8) {
|
||||
return flagcxInt8;
|
||||
} else if (type == DataType::BOOL) {
|
||||
return flagcxUint8;
|
||||
} else if (type == DataType::BFLOAT16) {
|
||||
return flagcxBfloat16;
|
||||
} else {
|
||||
PADDLE_THROW(
|
||||
errors::Unimplemented("This datatype in flagcx is not supported."));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,164 @@
|
||||
/* Copyright (c) 2021 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 <utility>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
template <typename T>
|
||||
class intrusive_ptr {
|
||||
public:
|
||||
using this_type = intrusive_ptr;
|
||||
constexpr intrusive_ptr() noexcept = default;
|
||||
|
||||
~intrusive_ptr() {
|
||||
if (px) {
|
||||
intrusive_ptr_release(px);
|
||||
}
|
||||
}
|
||||
|
||||
intrusive_ptr(intrusive_ptr&& rhs) noexcept : px(rhs.px) { rhs.px = nullptr; }
|
||||
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
|
||||
intrusive_ptr(intrusive_ptr<U>&& rhs) noexcept : px(rhs.get()) {
|
||||
rhs.reset();
|
||||
}
|
||||
|
||||
intrusive_ptr& operator=(intrusive_ptr&& rhs) {
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() { this_type().swap(*this); }
|
||||
|
||||
void reset(T* rhs) { this_type(rhs).swap(*this); }
|
||||
|
||||
void reset(T* rhs, bool add_ref) { this_type(rhs, add_ref).swap(*this); }
|
||||
|
||||
T* get() const noexcept { return px; }
|
||||
|
||||
T* detach() noexcept {
|
||||
T* ret = px;
|
||||
px = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
PADDLE_ENFORCE_NOT_NULL(
|
||||
px,
|
||||
common::errors::PreconditionNotMet(
|
||||
"The pointer must be non-null before the dereference operation."));
|
||||
return *px;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
PADDLE_ENFORCE_NOT_NULL(
|
||||
px,
|
||||
common::errors::PreconditionNotMet(
|
||||
"The pointer must be non-null before the dereference operation."));
|
||||
return px;
|
||||
}
|
||||
|
||||
void swap(intrusive_ptr& rhs) noexcept {
|
||||
T* tmp = px;
|
||||
px = rhs.px;
|
||||
rhs.px = tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
|
||||
explicit intrusive_ptr(U* p, bool add_ref = true) : px(p) {
|
||||
if (px && add_ref) {
|
||||
intrusive_ptr_add_ref(px);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename R, typename... Args>
|
||||
friend intrusive_ptr<R> make_intrusive(Args&&...);
|
||||
template <typename R>
|
||||
friend intrusive_ptr<R> copy_intrusive(const intrusive_ptr<R>&);
|
||||
|
||||
T* px{nullptr};
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator==(const intrusive_ptr<T>& a,
|
||||
const intrusive_ptr<U>& b) noexcept {
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator!=(const intrusive_ptr<T>& a,
|
||||
const intrusive_ptr<U>& b) noexcept {
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator==(const intrusive_ptr<T>& a, U* b) noexcept {
|
||||
return a.get() == b;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator!=(const intrusive_ptr<T>& a, U* b) noexcept {
|
||||
return a.get() != b;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator==(T* a, const intrusive_ptr<U>& b) noexcept {
|
||||
return a == b.get();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator!=(T* a, const intrusive_ptr<U>& b) noexcept {
|
||||
return a != b.get();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(const intrusive_ptr<T>& p, std::nullptr_t) noexcept {
|
||||
return p.get() == nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(std::nullptr_t, const intrusive_ptr<T>& p) noexcept {
|
||||
return p.get() == nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator!=(const intrusive_ptr<T>& p, std::nullptr_t) noexcept {
|
||||
return p.get() != nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator!=(std::nullptr_t, const intrusive_ptr<T>& p) noexcept {
|
||||
return p.get() != nullptr;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline intrusive_ptr<T> make_intrusive(Args&&... args) {
|
||||
return intrusive_ptr<T>(new T(std::forward<Args>(args)...), false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline intrusive_ptr<T> copy_intrusive(const intrusive_ptr<T>& rhs) {
|
||||
return intrusive_ptr<T>(rhs.get(), true);
|
||||
}
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 2021 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 <atomic>
|
||||
|
||||
namespace phi {
|
||||
|
||||
template <typename DerivedT>
|
||||
class intrusive_ref_counter;
|
||||
template <typename DerivedT>
|
||||
void intrusive_ptr_add_ref(const intrusive_ref_counter<DerivedT>* p) noexcept;
|
||||
template <typename DerivedT>
|
||||
void intrusive_ptr_release(const intrusive_ref_counter<DerivedT>* p) noexcept;
|
||||
|
||||
template <typename DerivedT>
|
||||
class intrusive_ref_counter {
|
||||
public:
|
||||
constexpr intrusive_ref_counter() noexcept : ref_(1) {}
|
||||
virtual ~intrusive_ref_counter() = default;
|
||||
|
||||
unsigned int use_count() const noexcept { return ref_.load(); }
|
||||
|
||||
protected:
|
||||
intrusive_ref_counter(const intrusive_ref_counter&) = delete;
|
||||
intrusive_ref_counter& operator=(const intrusive_ref_counter&) = delete;
|
||||
|
||||
friend void intrusive_ptr_add_ref<DerivedT>(
|
||||
const intrusive_ref_counter<DerivedT>* p) noexcept;
|
||||
friend void intrusive_ptr_release<DerivedT>(
|
||||
const intrusive_ref_counter<DerivedT>* p) noexcept;
|
||||
|
||||
private:
|
||||
mutable std::atomic_int_fast32_t ref_;
|
||||
};
|
||||
|
||||
template <typename DerivedT>
|
||||
inline void intrusive_ptr_add_ref(
|
||||
const intrusive_ref_counter<DerivedT>* p) noexcept {
|
||||
p->ref_.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
template <typename DerivedT>
|
||||
inline void intrusive_ptr_release(
|
||||
const intrusive_ref_counter<DerivedT>* p) noexcept {
|
||||
if (p->ref_.load(std::memory_order_acquire) == 0 ||
|
||||
p->ref_.fetch_sub(1) == 0) {
|
||||
delete static_cast<const DerivedT*>(p); // NOLINT
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,104 @@
|
||||
/* Copyright (c) 2022 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
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <mutex> // NOLINT
|
||||
#endif // !_WIN32
|
||||
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
#if !defined(_WIN32)
|
||||
struct RWLock {
|
||||
RWLock() { pthread_rwlock_init(&lock_, nullptr); }
|
||||
|
||||
~RWLock() { pthread_rwlock_destroy(&lock_); }
|
||||
|
||||
inline void RDLock() {
|
||||
PADDLE_ENFORCE_EQ(
|
||||
pthread_rwlock_rdlock(&lock_),
|
||||
0,
|
||||
common::errors::External("The pthread failed to acquire read lock."));
|
||||
}
|
||||
|
||||
inline void WRLock() {
|
||||
PADDLE_ENFORCE_EQ(
|
||||
pthread_rwlock_wrlock(&lock_),
|
||||
0,
|
||||
common::errors::External("The pthread failed to acquire write lock."));
|
||||
}
|
||||
|
||||
inline void UNLock() {
|
||||
PADDLE_ENFORCE_EQ(
|
||||
pthread_rwlock_unlock(&lock_),
|
||||
0,
|
||||
common::errors::External("The pthread failed to unlock."));
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_rwlock_t lock_;
|
||||
};
|
||||
// TODO(paddle-dev): Support RWLock for WIN32 for correctness.
|
||||
#else
|
||||
// https://stackoverflow.com/questions/7125250/making-pthread-rwlock-wrlock-recursive
|
||||
// In windows, rw_lock seems like a hack. Use empty object and do nothing.
|
||||
struct RWLock {
|
||||
// FIXME(minqiyang): use mutex here to do fake lock
|
||||
inline void RDLock() { mutex_.lock(); }
|
||||
|
||||
inline void WRLock() { mutex_.lock(); }
|
||||
|
||||
inline void UNLock() { mutex_.unlock(); }
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
};
|
||||
#endif
|
||||
|
||||
class AutoWRLock {
|
||||
public:
|
||||
explicit AutoWRLock(RWLock* rw_lock) : lock_(rw_lock) { Lock(); }
|
||||
|
||||
~AutoWRLock() { UnLock(); }
|
||||
|
||||
private:
|
||||
inline void Lock() { lock_->WRLock(); }
|
||||
|
||||
inline void UnLock() { lock_->UNLock(); }
|
||||
|
||||
private:
|
||||
RWLock* lock_;
|
||||
};
|
||||
|
||||
class AutoRDLock {
|
||||
public:
|
||||
explicit AutoRDLock(RWLock* rw_lock) : lock_(rw_lock) { Lock(); }
|
||||
|
||||
~AutoRDLock() { UnLock(); }
|
||||
|
||||
private:
|
||||
inline void Lock() { lock_->RDLock(); }
|
||||
|
||||
inline void UnLock() { lock_->UNLock(); }
|
||||
|
||||
private:
|
||||
RWLock* lock_;
|
||||
};
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2021 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 <string>
|
||||
|
||||
#include "paddle/phi/backends/cpu/cpu_context.h"
|
||||
#include "paddle/phi/backends/custom/custom_context.h"
|
||||
#include "paddle/phi/backends/gpu/gpu_context.h"
|
||||
#include "paddle/phi/backends/xpu/xpu_context.h"
|
||||
#include "paddle/phi/core/distributed/auto_parallel/dist_tensor.h"
|
||||
#include "paddle/phi/core/framework/feed_fetch_type.h"
|
||||
#include "paddle/phi/core/raw_tensor.h"
|
||||
#include "paddle/phi/core/selected_rows.h"
|
||||
#include "paddle/phi/core/sparse_coo_tensor.h"
|
||||
#include "paddle/phi/core/sparse_csr_tensor.h"
|
||||
#include "paddle/phi/core/storage_properties.h"
|
||||
#include "paddle/phi/core/string_tensor.h"
|
||||
#include "paddle/phi/core/tensor_array.h"
|
||||
#include "paddle/phi/core/utils/type_info.h"
|
||||
#include "paddle/phi/core/vocab/string_array.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
template <typename BaseT, typename DerivedT>
|
||||
TypeInfoTraits<BaseT, DerivedT>::TypeInfoTraits() {
|
||||
static_cast<BaseT*>(static_cast<DerivedT*>(this))->type_info_ = kType;
|
||||
}
|
||||
|
||||
template <typename BaseT, typename DerivedT>
|
||||
bool TypeInfoTraits<BaseT, DerivedT>::classof(const BaseT* obj) {
|
||||
return obj->type_info() == kType;
|
||||
}
|
||||
|
||||
template <typename BaseT, typename DerivedT>
|
||||
const TypeInfo<BaseT> TypeInfoTraits<BaseT, DerivedT>::kType =
|
||||
RegisterStaticType<BaseT>(DerivedT::name());
|
||||
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, DenseTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, SelectedRows>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, SparseCooTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, SparseCsrTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, StringTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, TensorArray>;
|
||||
template class PADDLE_API
|
||||
TypeInfoTraits<phi::TensorBase, phi::distributed::DistTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, Vocab>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, Strings>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, RawTensor>;
|
||||
template class PADDLE_API TypeInfoTraits<phi::TensorBase, FeedList>;
|
||||
|
||||
template class PADDLE_API TypeInfoTraits<phi::DeviceContext, CPUContext>;
|
||||
#ifdef PADDLE_WITH_CUSTOM_DEVICE
|
||||
template class PADDLE_API TypeInfoTraits<phi::DeviceContext, CustomContext>;
|
||||
#endif
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) || \
|
||||
defined(PADDLE_WITH_XPU_KP)
|
||||
template class PADDLE_API TypeInfoTraits<phi::DeviceContext, GPUContext>;
|
||||
#endif
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
template class PADDLE_API TypeInfoTraits<phi::DeviceContext, GPUPinnedContext>;
|
||||
#endif
|
||||
|
||||
#ifdef PADDLE_WITH_XPU
|
||||
template class TypeInfoTraits<phi::DeviceContext, XPUContext>;
|
||||
template class TypeInfoTraits<phi::DeviceContext, XPUPinnedContext>;
|
||||
#endif
|
||||
|
||||
#ifdef PADDLE_WITH_DNNL
|
||||
template class TypeInfoTraits<phi::StorageProperties, OneDNNStorageProperties>;
|
||||
#endif
|
||||
|
||||
#ifdef PADDLE_WITH_XPU
|
||||
template class TypeInfoTraits<phi::StorageProperties, XPUStorageProperties>;
|
||||
#endif
|
||||
|
||||
template class TypeInfoTraits<phi::StorageProperties, NPUStorageProperties>;
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Copyright (c) 2021 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 <string>
|
||||
#include "paddle/utils/test_macros.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
template <typename BaseT>
|
||||
class TypeRegistry;
|
||||
|
||||
template <typename BaseT>
|
||||
class TypeInfo {
|
||||
public:
|
||||
const std::string& name() const;
|
||||
|
||||
int8_t id() const { return id_; }
|
||||
|
||||
bool operator==(TypeInfo other) const { return id_ == other.id(); }
|
||||
bool operator!=(TypeInfo other) const { return id_ != other.id(); }
|
||||
|
||||
static const TypeInfo kUnknownType;
|
||||
|
||||
private:
|
||||
friend class TypeRegistry<BaseT>;
|
||||
explicit TypeInfo(int8_t id) : id_(id) {}
|
||||
int8_t id_;
|
||||
};
|
||||
|
||||
template <typename BaseT, typename DerivedT>
|
||||
class TypeInfoTraits {
|
||||
public:
|
||||
static const TypeInfo<BaseT> kType;
|
||||
TypeInfoTraits();
|
||||
static bool classof(const BaseT* obj);
|
||||
};
|
||||
|
||||
template <typename BaseT>
|
||||
TypeInfo<BaseT> RegisterStaticType(const std::string& type);
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 2021 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 <cassert>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "paddle/phi/core/utils/type_info.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
template <typename BaseT>
|
||||
class TypeRegistry {
|
||||
public:
|
||||
TypeRegistry(const TypeRegistry&) = delete;
|
||||
TypeRegistry& operator=(const TypeRegistry&) = delete;
|
||||
|
||||
static TypeRegistry& GetInstance();
|
||||
|
||||
TypeInfo<BaseT> RegisterType(const std::string& type);
|
||||
const std::string& GetTypeName(TypeInfo<BaseT> info) const;
|
||||
|
||||
private:
|
||||
TypeRegistry() = default;
|
||||
mutable std::mutex mutex_;
|
||||
std::vector<std::string> names_;
|
||||
std::map<std::string, int8_t> name_to_id_;
|
||||
};
|
||||
|
||||
template <typename BaseT>
|
||||
TypeRegistry<BaseT>& TypeRegistry<BaseT>::GetInstance() {
|
||||
static TypeRegistry<BaseT> registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
TypeInfo<BaseT> TypeRegistry<BaseT>::RegisterType(const std::string& type) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
assert(name_to_id_.find(type) == name_to_id_.end());
|
||||
assert(names_.size() < static_cast<decltype(names_.size())>(
|
||||
std::numeric_limits<int8_t>::max()));
|
||||
int8_t id = static_cast<int8_t>(names_.size());
|
||||
names_.emplace_back(type);
|
||||
name_to_id_[type] = id;
|
||||
return TypeInfo<BaseT>(id);
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
const std::string& TypeRegistry<BaseT>::GetTypeName(
|
||||
TypeInfo<BaseT> info) const {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
int8_t id = info.id();
|
||||
assert(id >= 0);
|
||||
assert(static_cast<size_t>(id) < names_.size());
|
||||
return names_[id];
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
TypeInfo<BaseT> RegisterStaticType(const std::string& type) {
|
||||
return TypeRegistry<BaseT>::GetInstance().RegisterType(type);
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
const std::string& TypeInfo<BaseT>::name() const {
|
||||
return TypeRegistry<BaseT>::GetInstance().GetTypeName(*this);
|
||||
}
|
||||
|
||||
template <typename BaseT>
|
||||
const TypeInfo<BaseT> TypeInfo<BaseT>::kUnknownType =
|
||||
RegisterStaticType<BaseT>("Unknown");
|
||||
|
||||
} // namespace phi
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) 2023 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 "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
|
||||
namespace phi {
|
||||
|
||||
// need add dependency to phi_place when use phi::VisitPlace
|
||||
template <typename Visitor>
|
||||
typename Visitor::result_type VisitPlace(const Place& place,
|
||||
const Visitor& visitor) {
|
||||
switch (place.GetType()) {
|
||||
case AllocationType::GPU: {
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
phi::GPUPlace p(place.GetDeviceId());
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with CUDA. Cannot visit cuda_pinned")));
|
||||
return typename Visitor::result_type();
|
||||
#endif
|
||||
}
|
||||
case AllocationType::GPUPINNED: {
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
phi::GPUPinnedPlace p;
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with CUDA. Cannot visit cuda_pinned")));
|
||||
return typename Visitor::result_type();
|
||||
#endif
|
||||
}
|
||||
case AllocationType::XPU: {
|
||||
#ifdef PADDLE_WITH_XPU
|
||||
phi::XPUPlace p(place.GetDeviceId());
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with XPU. Cannot visit xpu device")));
|
||||
return typename Visitor::result_type();
|
||||
#endif
|
||||
}
|
||||
case AllocationType::XPUPINNED: {
|
||||
#if defined(PADDLE_WITH_XPU)
|
||||
phi::XPUPinnedPlace p;
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with XPU. Cannot visit xpu device")));
|
||||
return typename Visitor::result_type();
|
||||
#endif
|
||||
}
|
||||
case AllocationType::IPU: {
|
||||
#ifdef PADDLE_WITH_IPU
|
||||
IPUPlace p(place.GetDeviceId());
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with IPU. Cannot visit ipu device")));
|
||||
return typename Visitor::result_type();
|
||||
#endif
|
||||
}
|
||||
case AllocationType::CUSTOM: {
|
||||
#ifdef PADDLE_WITH_CUSTOM_DEVICE
|
||||
CustomPlace p(place.GetDeviceType(), place.GetDeviceId());
|
||||
return visitor(p);
|
||||
#else
|
||||
PADDLE_THROW(common::errors::Unavailable(
|
||||
("Paddle is not compiled with CUSTOM. Cannot visit custom device")));
|
||||
#endif
|
||||
}
|
||||
default: {
|
||||
phi::CPUPlace p;
|
||||
return visitor(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace phi
|
||||
Reference in New Issue
Block a user