Files
TheRock/rocm-systems/projects/hip-tests/catch/unit/deviceLib/fp6_ocp.cc
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

307 lines
9.0 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include <hip/hip_fp6.h>
#include <hip_test_common.hh>
#include <bitset>
#include <type_traits>
#include <vector>
std::vector<__hip_fp6_storage_t> get_all_fp6_ocp_nums() {
std::vector<__hip_fp6_storage_t> ret;
constexpr unsigned short max_fp6_num = 0b0011'1111;
ret.reserve(max_fp6_num + 1);
for (unsigned short i = 0; i <= max_fp6_num; i++) {
ret.push_back(static_cast<__hip_fp6_storage_t>(i));
}
return ret;
}
template <bool is_e2m3, typename T>
__global__ void Type_to_fp6(T* f, __hip_fp6_storage_t* res, size_t size) {
auto i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < size) {
if constexpr (is_e2m3) {
__hip_fp6_e2m3 tmp(f[i]);
res[i] = tmp.__x;
} else {
__hip_fp6_e3m2 tmp(f[i]);
res[i] = tmp.__x;
}
}
}
/**
* Test Description
* ------------------------
* - Basic test to convert given interger values to FP6 type in the host
* with E2M3 and E3M2 formats.
* Test source
* ------------------------
* - /unit/deviceLib/fp6_ocp.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.5
*/
HIP_TEMPLATE_TEST_CASE(Unit_all_fp6_ocp_vector_cvt_interger_data, int, long int, long long int,
short int) {
SECTION("Fp6 with e2m3") {
std::vector<TestType> input = {0, 1, 2, 3, 4, 5, 6, 7, -0, -1, -2, -3, -4, -5, -6, -7};
for (const auto val : input) {
__hip_fp6_e2m3 fp6(val);
float ret = fp6;
INFO("In: " << val);
INFO("Out: " << ret);
REQUIRE(ret == val);
}
}
SECTION("Fp6 with e3m2 ") {
std::vector<TestType> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12,
14, 16, 20, 24, 28, -0, -1, -2, -3, -4, -5,
-6, -7, -8, -10, -12, -14, -16, -20, -24, -28};
for (const auto val : input) {
__hip_fp6_e3m2 fp6(val);
float ret = fp6;
INFO("In: " << val);
INFO("Out: " << ret);
REQUIRE(ret == val);
}
}
}
/**
* Test Description
* ------------------------
* - Basic test to convert given unsigned interger values to FP6 type in the host
* with E2M3 and E3M2 formats.
* Test source
* ------------------------
* - /unit/deviceLib/fp6_ocp.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.5
*/
HIP_TEMPLATE_TEST_CASE(Unit_all_fp6_ocp_vector_cvt_unsigned_interger_data, int, long int,
long long int, short int) {
SECTION("Fp6 with e2m3") {
std::vector<TestType> input = {0, 1, 2, 3, 4, 5, 6, 7};
for (const auto val : input) {
__hip_fp6_e2m3 fp6(val);
float ret = fp6;
INFO("In: " << val);
INFO("Out: " << ret);
REQUIRE(ret == val);
}
}
SECTION("Fp6 with e3m2 ") {
std::vector<TestType> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28};
for (const auto val : input) {
__hip_fp6_e3m2 fp6(val);
float ret = fp6;
INFO("In: " << val);
INFO("Out: " << ret);
REQUIRE(ret == val);
}
}
}
/**
* Test Description
* ------------------------
* - Basic test to convert given unsigned interger values to FP6 type in the device
* with E2M3 and E3M2 formats.
* Test source
* ------------------------
* - /unit/deviceLib/fp6_ocp.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.5
*/
HIP_TEMPLATE_TEST_CASE(Unit_all_fp6_ocp_vector_cvt_unsigned_integer_device, unsigned int,
unsigned long int, unsigned long long int, unsigned short int) {
bool is_e2m3 = GENERATE(true, false);
std::vector<TestType> f_vals;
std::vector<__hip_fp6_storage_t> all_vals;
constexpr TestType lhs = 0;
constexpr TestType rhs = 64;
constexpr TestType step = 1;
f_vals.reserve(500);
all_vals.reserve(500);
for (TestType fval = lhs; fval <= rhs; fval += step) {
if (is_e2m3) {
__hip_fp6_e2m3 tmp(fval);
all_vals.push_back(tmp.__x);
} else {
__hip_fp6_e3m2 tmp(fval);
all_vals.push_back(tmp.__x);
}
f_vals.push_back(fval);
}
TestType* d_f_vals;
__hip_fp6_storage_t* d_res;
HIP_CHECK(hipMalloc(&d_f_vals, sizeof(TestType) * f_vals.size()));
HIP_CHECK(hipMalloc(&d_res, sizeof(__hip_fp6_storage_t) * f_vals.size()));
HIP_CHECK(
hipMemcpy(d_f_vals, f_vals.data(), sizeof(TestType) * f_vals.size(), hipMemcpyHostToDevice));
auto fp6_kernel = is_e2m3 ? Type_to_fp6<true, TestType> : Type_to_fp6<false, TestType>;
fp6_kernel<<<(f_vals.size() / 64) + 1, 64>>>(d_f_vals, d_res, f_vals.size());
std::vector<__hip_fp6_storage_t> final_res(f_vals.size(), static_cast<__hip_fp6_storage_t>(0));
HIP_CHECK(hipMemcpy(final_res.data(), d_res, sizeof(__hip_fp6_storage_t) * final_res.size(),
hipMemcpyDeviceToHost));
for (size_t i = 0; i < final_res.size(); i++) {
INFO("Checking: " << f_vals[i] << " for: " << (is_e2m3 ? "e2m3" : "e3m2")
<< " original: " << (int)all_vals[i] << " convert back: " << (int)final_res[i]
<< " Idx : " << i);
TestType gpu_cvt_res = 0, cpu_cvt_res = 0;
float gpu_cvt_res_ = 0.0, cpu_cvt_res_ = 0.0;
if (is_e2m3) {
__hip_fp6_e2m3 gtmp;
gtmp.__x = final_res[i];
gpu_cvt_res_ = gtmp;
gpu_cvt_res = gpu_cvt_res_;
__hip_fp6_e2m3 ctmp;
ctmp.__x = all_vals[i];
cpu_cvt_res_ = ctmp;
cpu_cvt_res = cpu_cvt_res_;
} else {
__hip_fp6_e3m2 gtmp;
gtmp.__x = final_res[i];
gpu_cvt_res_ = gtmp;
gpu_cvt_res = gpu_cvt_res_;
__hip_fp6_e3m2 ctmp;
ctmp.__x = all_vals[i];
cpu_cvt_res_ = ctmp;
cpu_cvt_res = cpu_cvt_res_;
}
INFO("cpu cvt val: " << cpu_cvt_res << " gpu cvt val: " << gpu_cvt_res);
REQUIRE(cpu_cvt_res == gpu_cvt_res);
}
HIP_CHECK(hipFree(d_f_vals));
HIP_CHECK(hipFree(d_res));
}
/**
* Test Description
* ------------------------
* - Basic test to convert given interger values to FP6 type in device with
* E2M3 and E3M2 formats.
* Test source
* ------------------------
* - /unit/deviceLib/fp6_ocp.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.5
*/
HIP_TEMPLATE_TEST_CASE(Unit_all_fp6_ocp_vector_cvt_interger_data_device, int, long int,
long long int, short int) {
bool is_e2m3 = GENERATE(true, false);
std::vector<TestType> f_vals;
std::vector<__hip_fp6_storage_t> all_vals;
SECTION("all representable numbers") {
all_vals = get_all_fp6_ocp_nums();
f_vals.reserve(all_vals.size());
for (const auto& fp6 : all_vals) {
TestType f = 0;
float f_ = 0.0;
if (is_e2m3) {
__hip_fp6_e2m3 tmp;
tmp.__x = fp6;
f_ = tmp;
f = f_;
} else {
__hip_fp6_e3m2 tmp;
tmp.__x = fp6;
f_ = tmp;
f = f_;
}
f_vals.push_back(f);
}
}
SECTION("Range stepped numbers") {
constexpr TestType lhs = -30;
constexpr TestType rhs = 30;
constexpr TestType step = 1;
f_vals.reserve(500);
all_vals.reserve(500);
for (TestType fval = lhs; fval <= rhs; fval += step) {
if (is_e2m3) {
__hip_fp6_e2m3 tmp(fval);
all_vals.push_back(tmp.__x);
} else {
__hip_fp6_e3m2 tmp(fval);
all_vals.push_back(tmp.__x);
}
f_vals.push_back(fval);
}
}
TestType* d_f_vals;
__hip_fp6_storage_t* d_res;
HIP_CHECK(hipMalloc(&d_f_vals, sizeof(TestType) * f_vals.size()));
HIP_CHECK(hipMalloc(&d_res, sizeof(__hip_fp6_storage_t) * f_vals.size()));
HIP_CHECK(
hipMemcpy(d_f_vals, f_vals.data(), sizeof(TestType) * f_vals.size(), hipMemcpyHostToDevice));
auto fp6_kernel = is_e2m3 ? Type_to_fp6<true, TestType> : Type_to_fp6<false, TestType>;
fp6_kernel<<<(f_vals.size() / 64) + 1, 64>>>(d_f_vals, d_res, f_vals.size());
std::vector<__hip_fp6_storage_t> final_res(f_vals.size(), static_cast<__hip_fp6_storage_t>(0));
HIP_CHECK(hipMemcpy(final_res.data(), d_res, sizeof(__hip_fp6_storage_t) * final_res.size(),
hipMemcpyDeviceToHost));
for (size_t i = 0; i < final_res.size(); i++) {
INFO("Checking: " << f_vals[i] << " for: " << (is_e2m3 ? "e2m3" : "e3m2")
<< " original: " << (int)all_vals[i] << " convert back: " << (int)final_res[i]
<< " Idx : " << i);
TestType gpu_cvt_res = 0.0f, cpu_cvt_res = 0.0f;
float gpu_cvt_res_ = 0.0, cpu_cvt_res_ = 0.0;
if (is_e2m3) {
__hip_fp6_e2m3 gtmp;
gtmp.__x = final_res[i];
gpu_cvt_res_ = gtmp;
gpu_cvt_res = gpu_cvt_res_;
__hip_fp6_e2m3 ctmp;
ctmp.__x = all_vals[i];
cpu_cvt_res_ = ctmp;
cpu_cvt_res = cpu_cvt_res_;
} else {
__hip_fp6_e3m2 gtmp;
gtmp.__x = final_res[i];
gpu_cvt_res_ = gtmp;
gpu_cvt_res = gpu_cvt_res_;
__hip_fp6_e3m2 ctmp;
ctmp.__x = all_vals[i];
cpu_cvt_res_ = ctmp;
cpu_cvt_res = cpu_cvt_res_;
}
INFO("cpu cvt val: " << cpu_cvt_res << " gpu cvt val: " << gpu_cvt_res);
REQUIRE(cpu_cvt_res == gpu_cvt_res);
}
HIP_CHECK(hipFree(d_f_vals));
HIP_CHECK(hipFree(d_res));
}