Skip to content

Commit

Permalink
[HIP] fix host min/max in header (#82956)
Browse files Browse the repository at this point in the history
CUDA defines min/max functions for host in global namespace.
HIP header needs to define them too to be compatible.
Currently only min/max(int, int) is defined. This causes
wrong result for arguments that are out of range for int.
This patch defines host min/max functions to be compatible
with CUDA.

Also allows users to define
`__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__` to disable
host max/min in global namespace.

min/max functions with mixed signed/unsigned integer
parameters are not defined unless
`__HIP_DEFINE_MIXED_HOST_MIN_MAX__` is defined.

Fixes: SWDEV-446564
  • Loading branch information
yxsamliu authored Feb 27, 2024
1 parent 822142f commit 55783bd
Showing 1 changed file with 66 additions and 6 deletions.
72 changes: 66 additions & 6 deletions clang/lib/Headers/__clang_hip_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -1306,15 +1306,75 @@ float min(float __x, float __y) { return __builtin_fminf(__x, __y); }
__DEVICE__
double min(double __x, double __y) { return __builtin_fmin(__x, __y); }

#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
__host__ inline static int min(int __arg1, int __arg2) {
return __arg1 < __arg2 ? __arg1 : __arg2;
// Define host min/max functions.
#if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) && \
!defined(__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__)

#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
#define DEFINE_MIN_MAX_FUNCTIONS(ret_type, type1, type2) \
inline ret_type min(const type1 __a, const type2 __b) { \
return (__a < __b) ? __a : __b; \
} \
inline ret_type max(const type1 __a, const type2 __b) { \
return (__a > __b) ? __a : __b; \
}

// Define min and max functions for same type comparisons
DEFINE_MIN_MAX_FUNCTIONS(int, int, int)
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, unsigned int)
DEFINE_MIN_MAX_FUNCTIONS(long, long, long)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, unsigned long)
DEFINE_MIN_MAX_FUNCTIONS(long long, long long, long long)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long,
unsigned long long)

// The host min/max functions below accept mixed signed/unsigned integer
// parameters and perform unsigned comparisons, which may produce unexpected
// results if a signed integer was passed unintentionally. To avoid this
// happening silently, these overloaded functions are not defined by default.
// However, for compatibility with CUDA, they will be defined if users define
// __HIP_DEFINE_MIXED_HOST_MIN_MAX__.
#ifdef __HIP_DEFINE_MIXED_HOST_MIN_MAX__
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, int, unsigned int)
DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, int)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, long, unsigned long)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, long)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, long long, unsigned long long)
DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long, long long)
#endif // ifdef __HIP_DEFINE_MIXED_HOST_MIN_MAX__

// Floating-point comparisons using built-in functions
inline float min(float const __a, float const __b) {
return __builtin_fminf(__a, __b);
}
inline double min(double const __a, double const __b) {
return __builtin_fmin(__a, __b);
}
inline double min(float const __a, double const __b) {
return __builtin_fmin(__a, __b);
}
inline double min(double const __a, float const __b) {
return __builtin_fmin(__a, __b);
}

__host__ inline static int max(int __arg1, int __arg2) {
return __arg1 > __arg2 ? __arg1 : __arg2;
inline float max(float const __a, float const __b) {
return __builtin_fmaxf(__a, __b);
}
inline double max(double const __a, double const __b) {
return __builtin_fmax(__a, __b);
}
inline double max(float const __a, double const __b) {
return __builtin_fmax(__a, __b);
}
#endif // !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
inline double max(double const __a, float const __b) {
return __builtin_fmax(__a, __b);
}

#pragma pop_macro("DEFINE_MIN_MAX_FUNCTIONS")

#endif // !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__) &&
// !defined(__HIP_NO_HOST_MIN_MAX_IN_GLOBAL_NAMESPACE__)
#endif

#pragma pop_macro("__DEVICE__")
Expand Down

0 comments on commit 55783bd

Please sign in to comment.