Skip to content

Commit

Permalink
Add HIP test host-min-max
Browse files Browse the repository at this point in the history
  • Loading branch information
yxsamliu committed Feb 27, 2024
1 parent e597556 commit 6c0b6af
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 0 deletions.
3 changes: 3 additions & 0 deletions External/HIP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ macro(create_local_hip_tests VariantSuffix)
# Set per-source compilation/link options
set_source_files_properties(with-fopenmp.hip PROPERTIES
COMPILE_FLAGS -fopenmp)
set_source_files_properties(host-min-max.hip PROPERTIES
COMPILE_FLAGS -D__HIP_DEFINE_MIXED_HOST_MIN_MAX__)
# Add HIP tests to be added to hip-tests-simple
list(APPEND HIP_LOCAL_TESTS empty)
list(APPEND HIP_LOCAL_TESTS with-fopenmp)
list(APPEND HIP_LOCAL_TESTS saxpy)
list(APPEND HIP_LOCAL_TESTS host-min-max)
list(APPEND HIP_LOCAL_TESTS InOneWeekend)
list(APPEND HIP_LOCAL_TESTS TheNextWeek)

Expand Down
96 changes: 96 additions & 0 deletions External/HIP/host-min-max.hip
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include <algorithm>
#include <cstdlib>t
#include <hip/hip_runtime.h>
#include <iostream>
#include <map>
#include <string>
#include <type_traits>
#include <typeinfo>

// Convert typeid name to C++ type name
std::string demangle(const char *name) {
static const std::map<char, std::string> demangleMap = {
{'i', "int"}, {'f', "float"},
{'d', "double"}, {'j', "unsigned int"},
{'l', "long"}, {'m', "unsigned long"},
{'x', "long long"}, {'y', "unsigned long long"}};

auto it = demangleMap.find(name[0]);
if (it != demangleMap.end()) {
return it->second;
} else {
return std::string(name);
}
}

void checkHipCall(hipError_t status, const char *msg) {
if (status != hipSuccess) {
std::cerr << "HIP Error: " << msg << " - " << hipGetErrorString(status)
<< std::endl;
std::abort();
}
}

template <typename T1, typename T2>
void compareResults(T1 hipResult, T2 stdResult, const std::string &testName) {
using CommonType = typename std::common_type<T1, T2>::type;
if (static_cast<CommonType>(hipResult) !=
static_cast<CommonType>(stdResult)) {
std::cerr << testName << " mismatch: HIP result " << hipResult << " ("
<< demangle(typeid(hipResult).name()) << "), std result "
<< stdResult << " (" << demangle(typeid(stdResult).name()) << ")"
<< std::endl;
std::abort();
}
}

template <typename T1, typename T2> void runTest(T1 a, T2 b) {
std::cout << "\nTesting with values: " << a << " ("
<< demangle(typeid(a).name()) << ") and " << b << " ("
<< demangle(typeid(b).name()) << ")" << std::endl;

// Using std::min and std::max as reference
// The two arguments are converted to std::common_type first then passed
// to std::min/max. This assumes compatiblity with CUDA.
using CommonType = typename std::common_type<T1, T2>::type;
CommonType stdMinResult = std::min<CommonType>(a, b);
CommonType stdMaxResult = std::max<CommonType>(a, b);
std::cout << "Host std::min result: " << stdMinResult
<< " (Type: " << demangle(typeid(stdMinResult).name()) << ")"
<< std::endl;
std::cout << "Host std::max result: " << stdMaxResult
<< " (Type: " << demangle(typeid(stdMaxResult).name()) << ")"
<< std::endl;

// Using HIP's global min/max functions
CommonType hipMinResult = min(a, b);
CommonType hipMaxResult = max(a, b);
std::cout << "Host HIP min result: " << hipMinResult
<< " (Type: " << demangle(typeid(hipMinResult).name()) << ")"
<< std::endl;
std::cout << "Host HIP max result: " << hipMaxResult
<< " (Type: " << demangle(typeid(hipMaxResult).name()) << ")"
<< std::endl;

// Ensure the host HIP and std results match
compareResults(hipMinResult, stdMinResult, "HIP vs std min");
compareResults(hipMaxResult, stdMaxResult, "HIP vs std max");
}

int main() {
checkHipCall(hipSetDevice(0), "hipSetDevice failed");

// For mixed signed/unsigned integer arguments, assuming CUDA compatibility,
// i.e. the signed integer is implicitly converted to unsigned type and then
// compared.
runTest(10uLL, -5LL); // Testing with unsigned int and long long
runTest(-15, 20u); // Testing with int and unsigned int
runTest(2147483647, 2147483648u); // Testing with int and unsigned int
runTest(
-922337203685477580LL,
922337203685477580uLL); // Testing with long long and unsigned long long
runTest(2.5f, 3.14159); // Testing with float and double

std::cout << "\nPass\n";
return 0;
}
32 changes: 32 additions & 0 deletions External/HIP/host-min-max.reference_output
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

Testing with values: 10 (unsigned long long) and -5 (long long)
Host std::min result: 10 (Type: unsigned long long)
Host std::max result: 18446744073709551611 (Type: unsigned long long)
Host HIP min result: 10 (Type: unsigned long long)
Host HIP max result: 18446744073709551611 (Type: unsigned long long)

Testing with values: -15 (int) and 20 (unsigned int)
Host std::min result: 20 (Type: unsigned int)
Host std::max result: 4294967281 (Type: unsigned int)
Host HIP min result: 20 (Type: unsigned int)
Host HIP max result: 4294967281 (Type: unsigned int)

Testing with values: 2147483647 (int) and 2147483648 (unsigned int)
Host std::min result: 2147483647 (Type: unsigned int)
Host std::max result: 2147483648 (Type: unsigned int)
Host HIP min result: 2147483647 (Type: unsigned int)
Host HIP max result: 2147483648 (Type: unsigned int)

Testing with values: -922337203685477580 (long long) and 922337203685477580 (unsigned long long)
Host std::min result: 922337203685477580 (Type: unsigned long long)
Host std::max result: 17524406870024074036 (Type: unsigned long long)
Host HIP min result: 922337203685477580 (Type: unsigned long long)
Host HIP max result: 17524406870024074036 (Type: unsigned long long)

Testing with values: 2.5 (float) and 3.14159 (double)
Host std::min result: 2.5 (Type: double)
Host std::max result: 3.14159 (Type: double)
Host HIP min result: 2.5 (Type: double)
Host HIP max result: 3.14159 (Type: double)

Pass

0 comments on commit 6c0b6af

Please sign in to comment.