|
|
@ -31,6 +31,8 @@ limitations under the License. */
|
|
|
|
#include <sstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
|
|
#include "glog/logging.h"
|
|
|
|
#include "glog/logging.h"
|
|
|
|
#include "paddle/fluid/platform/macros.h"
|
|
|
|
#include "paddle/fluid/platform/macros.h"
|
|
|
@ -280,16 +282,62 @@ inline void throw_on_error(ncclResult_t stat, const std::string& msg) {
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
#define __PADDLE_BINARY_COMPARE(__VAL0, __VAL1, __CMP, __INV_CMP, ...) \
|
|
|
|
namespace details {
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
|
|
|
inline constexpr bool IsArithmetic() {
|
|
|
|
|
|
|
|
return std::is_arithmetic<T>::value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T1, typename T2, bool kIsArithmetic /* = true */>
|
|
|
|
|
|
|
|
struct TypeConverterImpl {
|
|
|
|
|
|
|
|
using Type1 = typename std::common_type<T1, T2>::type;
|
|
|
|
|
|
|
|
using Type2 = Type1;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
|
|
|
|
struct TypeConverterImpl<T1, T2, false> {
|
|
|
|
|
|
|
|
using Type1 = T1;
|
|
|
|
|
|
|
|
using Type2 = T2;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
|
|
|
|
struct TypeConverter {
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
static constexpr bool kIsArithmetic =
|
|
|
|
|
|
|
|
IsArithmetic<T1>() && IsArithmetic<T2>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
using Type1 = typename TypeConverterImpl<T1, T2, kIsArithmetic>::Type1;
|
|
|
|
|
|
|
|
using Type2 = typename TypeConverterImpl<T1, T2, kIsArithmetic>::Type2;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
|
|
|
|
using CommonType1 = typename std::add_lvalue_reference<
|
|
|
|
|
|
|
|
typename std::add_const<typename TypeConverter<T1, T2>::Type1>::type>::type;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
|
|
|
|
using CommonType2 = typename std::add_lvalue_reference<
|
|
|
|
|
|
|
|
typename std::add_const<typename TypeConverter<T1, T2>::Type2>::type>::type;
|
|
|
|
|
|
|
|
} // namespace details
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define __PADDLE_BINARY_COMPARE(__VAL1, __VAL2, __CMP, __INV_CMP, ...) \
|
|
|
|
do { \
|
|
|
|
do { \
|
|
|
|
auto __cond1__ = (__VAL0); \
|
|
|
|
auto __val1 = (__VAL1); \
|
|
|
|
auto __cond2__ = (__VAL1); \
|
|
|
|
auto __val2 = (__VAL2); \
|
|
|
|
if (UNLIKELY(!((__cond1__)__CMP(__cond2__)))) { \
|
|
|
|
using __TYPE1__ = decltype(__val1); \
|
|
|
|
|
|
|
|
using __TYPE2__ = decltype(__val2); \
|
|
|
|
|
|
|
|
using __COMMON_TYPE1__ = \
|
|
|
|
|
|
|
|
::paddle::platform::details::CommonType1<__TYPE1__, __TYPE2__>; \
|
|
|
|
|
|
|
|
using __COMMON_TYPE2__ = \
|
|
|
|
|
|
|
|
::paddle::platform::details::CommonType2<__TYPE1__, __TYPE2__>; \
|
|
|
|
|
|
|
|
bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1))__CMP( \
|
|
|
|
|
|
|
|
static_cast<__COMMON_TYPE2__>(__val2)); \
|
|
|
|
|
|
|
|
if (UNLIKELY(!__is_not_error)) { \
|
|
|
|
PADDLE_THROW("Enforce failed. Expected %s " #__CMP \
|
|
|
|
PADDLE_THROW("Enforce failed. Expected %s " #__CMP \
|
|
|
|
" %s, but received %s:%s " #__INV_CMP " %s:%s.\n%s", \
|
|
|
|
" %s, but received %s:%s " #__INV_CMP " %s:%s.\n%s", \
|
|
|
|
#__VAL0, #__VAL1, #__VAL0, \
|
|
|
|
#__VAL1, #__VAL2, #__VAL1, \
|
|
|
|
::paddle::string::to_string(__cond1__), #__VAL1, \
|
|
|
|
::paddle::string::to_string(__val1), #__VAL2, \
|
|
|
|
::paddle::string::to_string(__cond2__), \
|
|
|
|
::paddle::string::to_string(__val2), \
|
|
|
|
::paddle::string::Sprintf(__VA_ARGS__)); \
|
|
|
|
::paddle::string::Sprintf(__VA_ARGS__)); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
} while (0)
|
|
|
|