mirror of
https://github.com/amd/blis.git
synced 2026-05-25 02:44:31 +00:00
Gtestsuite: Added overflow and underflow tests for dgemm
- Added overflow and underflow tests for dgemm These tests cause floating point overflow and underflow by feeding values close to DBL_MAX and DBL_MIN values to matrices DBL_MAX = 1.7976931348623158e+308 DBL_MIN = 2.2250738585072014e-308 When computations result in values beyond the range [DBL_MIN, DBL_MAX], it leads to an overflow or underflow condition Two new arguments are added to test_gemm routine - over_under and input_range over_under = 0 indicates overflow over_under = 1 indicates underflow input_range = -1 indicates values within overflow or underflow limits input_range = 0 indicates values very close to DBL_MIN or DBL_MAX input_range = 1 indicates values beyond DBL_MIN or DBL_MAX - New file: dgemm_ovr_undr.cpp Overflow and underflow tests are called from this file dgemm_overflow and dgemm_underflow. This file uses cfloat header file for DBL_MIN and DBL_MAX values Signed-off-by: Nimmy Krishnan <nimmy.krishnan@amd.com> AMD-Internal: [CPUPL-4492] Change-Id: I4bbd519abacc56f322c73d6c0187ed6e1abbbf2b
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <random>
|
||||
#include <type_traits>
|
||||
#include "common/testing_helpers.h"
|
||||
|
||||
namespace testinghelpers {
|
||||
@@ -114,7 +115,7 @@ void getfp(T2 from, T3 to, gtint_t n, gtint_t incx, T1* x)
|
||||
* with elements that follow a uniform distribution in the range [from, to].
|
||||
* @param[in] storage storage type of matrix A, row or column major
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in] lda leading dimension of matrix A
|
||||
*/
|
||||
template<typename T1, typename T2, typename T3>
|
||||
@@ -177,7 +178,7 @@ void getfp(T2 from, T3 to, char storage, gtint_t m, gtint_t n, T1* a, gtint_t ld
|
||||
* @brief Returns a random fp vector (float, double, scomplex, dcomplex)
|
||||
* with elements that follow a uniform distribution in the range [from, to].
|
||||
* @param[in] storage storage type of matrix A, row or column major
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in] trans transposition of matrix A
|
||||
* @param[in] lda leading dimension of matrix A
|
||||
@@ -254,7 +255,7 @@ void getint(int from, int to, gtint_t n, gtint_t incx, T* x)
|
||||
* with elements that are integers and follow a uniform distribution in the range [from, to].
|
||||
* @param[in] storage storage type of matrix A, row or column major
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in] lda leading dimension of matrix A
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -318,7 +319,7 @@ void getint(int from, int to, char storage, gtint_t m, gtint_t n, T* a, gtint_t
|
||||
* @brief Returns a random fp matrix (float, double, scomplex, dcomplex)
|
||||
* with elements that are integers and follow a uniform distribution in the range [from, to].
|
||||
* @param[in] storage storage type of matrix A, row or column major
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in] m, n dimentions of matrix A
|
||||
* @param[in, out] a the random fp matrix A
|
||||
* @param[in] trans transposition of matrix A
|
||||
* @param[in] lda leading dimension of matrix A
|
||||
@@ -531,4 +532,96 @@ void set_ev_mat( char storage, char trns, gtint_t ld, gtint_t i, gtint_t j, T ex
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function to set few values of a matrix to values relative to DBL_MAX/DBL_MIN
|
||||
These values are used to create overflow and underflow scenarios
|
||||
*/
|
||||
template<typename T>
|
||||
void set_overflow_underflow_mat(char storage, char trns, gtint_t ld, gtint_t i, gtint_t j, T* a, gtint_t mode, gtint_t input_range)
|
||||
{
|
||||
/* Calculate index where overflow/underflow values need to be inserted */
|
||||
gtint_t indexA = 0;
|
||||
|
||||
if ( storage == 'c' || storage == 'C' )
|
||||
{
|
||||
if ( trns == 'n' || trns == 'N' )
|
||||
{
|
||||
indexA = i + j*ld;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexA = j + i*ld;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( trns == 'n' || trns == 'N' )
|
||||
{
|
||||
indexA = i*ld + j;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexA = j*ld + i;
|
||||
}
|
||||
}
|
||||
|
||||
using RT = typename testinghelpers::type_info<T>::real_type;
|
||||
std::vector<int> exponent(12);
|
||||
|
||||
if (std::is_same<RT, double>::value)
|
||||
{
|
||||
exponent = {23, 203, 18, 180, 123, 130, 185, 178, 108, 158, 185, 220};
|
||||
}
|
||||
else if (std::is_same<RT, float>::value)
|
||||
{
|
||||
exponent = {3, 20, 8, 2, 30, 28, 8, 10, 33, 24, 8, 22};
|
||||
}
|
||||
|
||||
T limits_val;
|
||||
|
||||
/* When mode is set to 0, values relative to DBL_MAX are inserted into the input matrices */
|
||||
if(mode == 0)
|
||||
{
|
||||
limits_val = (std::numeric_limits<RT>::max)();
|
||||
switch(input_range)
|
||||
{
|
||||
case -1:
|
||||
a[0] = limits_val/ pow(10, exponent[0]);
|
||||
a[indexA] = limits_val/ pow(10, exponent[1]);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
a[0] = -(limits_val/ pow(10, exponent[4]));
|
||||
a[indexA] = -(limits_val/ pow(10, exponent[5]));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
a[0] = limits_val/ pow(10, exponent[8]);
|
||||
a[indexA] = limits_val/ pow(10, exponent[9]);
|
||||
}
|
||||
}
|
||||
/* When mode is set to 1, values relative to DBL_MIN are inserted into the input matrices*/
|
||||
else
|
||||
{
|
||||
limits_val = (std::numeric_limits<RT>::min)();
|
||||
switch(input_range)
|
||||
{
|
||||
case -1:
|
||||
a[0] = limits_val * pow(10, exponent[0]);
|
||||
a[indexA] = limits_val * pow(10, exponent[1]);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
a[0] = -(limits_val * pow(10, exponent[4]));
|
||||
a[indexA] = -(limits_val * pow(10, exponent[5]));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
a[0] = limits_val * pow(10, exponent[8]);
|
||||
a[indexA] = limits_val * pow(10, exponent[9]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} //end of namespace testinghelpers
|
||||
|
||||
479
gtestsuite/testsuite/level3/gemm/dgemm_ovr_undr.cpp
Normal file
479
gtestsuite/testsuite/level3/gemm/dgemm_ovr_undr.cpp
Normal file
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
|
||||
BLIS
|
||||
An object-based framework for developing high-performance BLAS-like
|
||||
libraries.
|
||||
|
||||
Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name(s) of the copyright holder(s) nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "test_gemm.h"
|
||||
|
||||
|
||||
class DGEMMOvrUndr :
|
||||
public ::testing::TestWithParam<std::tuple<char, // storage format
|
||||
char, // transa
|
||||
char, // transb
|
||||
gtint_t, // over_under
|
||||
gtint_t, // input_range
|
||||
gtint_t, // m
|
||||
gtint_t, // n
|
||||
gtint_t, // k
|
||||
double, // alpha
|
||||
double, // beta
|
||||
gtint_t, // lda_inc
|
||||
gtint_t, // ldb_inc
|
||||
gtint_t, // ldc_inc
|
||||
gtint_t, // ai
|
||||
gtint_t, // aj
|
||||
gtint_t, // bi
|
||||
gtint_t // bj
|
||||
>> {};
|
||||
|
||||
TEST_P(DGEMMOvrUndr, OverflowUnderflow)
|
||||
{
|
||||
using T = double;
|
||||
//----------------------------------------------------------
|
||||
// Initialize values from the parameters passed through
|
||||
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
|
||||
//----------------------------------------------------------
|
||||
// matrix storage format(row major, column major)
|
||||
char storage = std::get<0>(GetParam());
|
||||
// denotes whether matrix a is n,t
|
||||
char transa = std::get<1>(GetParam());
|
||||
// denotes whether matrix b is n,t
|
||||
char transb = std::get<2>(GetParam());
|
||||
// over_under denotes whether overflow or underflow is to be tested
|
||||
gtint_t over_under = std::get<3>(GetParam());
|
||||
// input_range denotes the range of values that would be used to populate the matrices
|
||||
gtint_t input_range = std::get<4>(GetParam());
|
||||
// matrix size m
|
||||
gtint_t m = std::get<5>(GetParam());
|
||||
// matrix size n
|
||||
gtint_t n = std::get<6>(GetParam());
|
||||
// matrix size k
|
||||
gtint_t k = std::get<7>(GetParam());
|
||||
// specifies alpha value
|
||||
T alpha = std::get<8>(GetParam());
|
||||
// specifies beta value
|
||||
T beta = std::get<9>(GetParam());
|
||||
// lda, ldb, ldc increments.
|
||||
// If increments are zero, then the array size matches the matrix size.
|
||||
// If increments are nonnegative, the array size is bigger than the matrix size.
|
||||
gtint_t lda_inc = std::get<10>(GetParam());
|
||||
gtint_t ldb_inc = std::get<11>(GetParam());
|
||||
gtint_t ldc_inc = std::get<12>(GetParam());
|
||||
|
||||
// ai, aj, bi, bj are the indices where overflow/underflow values need to be inserted
|
||||
gtint_t ai = std::get<13>(GetParam());
|
||||
gtint_t aj = std::get<14>(GetParam());
|
||||
gtint_t bi = std::get<15>(GetParam());
|
||||
gtint_t bj = std::get<16>(GetParam());
|
||||
|
||||
// Set the threshold for the errors:
|
||||
double thresh = 10*m*n*testinghelpers::getEpsilon<T>();
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Call test body using these parameters
|
||||
//----------------------------------------------------------
|
||||
test_gemm<T>( storage, transa, transb, over_under, input_range, m, n, k, lda_inc, ldb_inc, ldc_inc, ai, aj, bi, bj, alpha, beta, thresh );
|
||||
|
||||
}
|
||||
|
||||
class DGEMMOUTestPrint {
|
||||
public:
|
||||
std::string operator()(
|
||||
testing::TestParamInfo<std::tuple<char, char, char, gtint_t, gtint_t, gtint_t, gtint_t, gtint_t, double, double, gtint_t, gtint_t, gtint_t, gtint_t, gtint_t, gtint_t, gtint_t>> str) const {
|
||||
char sfm = std::get<0>(str.param);
|
||||
char tsa = std::get<1>(str.param);
|
||||
char tsb = std::get<2>(str.param);
|
||||
gtint_t over_under = std::get<3>(str.param);
|
||||
gtint_t input_range = std::get<4>(str.param);
|
||||
gtint_t m = std::get<5>(str.param);
|
||||
gtint_t n = std::get<6>(str.param);
|
||||
gtint_t k = std::get<7>(str.param);
|
||||
double alpha = std::get<8>(str.param);
|
||||
double beta = std::get<9>(str.param);
|
||||
gtint_t lda_inc = std::get<10>(str.param);
|
||||
gtint_t ldb_inc = std::get<11>(str.param);
|
||||
gtint_t ldc_inc = std::get<12>(str.param);
|
||||
gtint_t ai = std::get<13>(str.param);
|
||||
gtint_t aj = std::get<14>(str.param);
|
||||
gtint_t bi = std::get<15>(str.param);
|
||||
gtint_t bj = std::get<16>(str.param);
|
||||
|
||||
gtint_t lda = testinghelpers::get_leading_dimension( sfm, tsa, m, k, lda_inc );
|
||||
gtint_t ldb = testinghelpers::get_leading_dimension( sfm, tsb, k, n, ldb_inc );
|
||||
gtint_t ldc = testinghelpers::get_leading_dimension( sfm, 'n', m, n, ldc_inc );
|
||||
|
||||
#ifdef TEST_BLAS
|
||||
std::string str_name = "blas_";
|
||||
#elif TEST_CBLAS
|
||||
std::string str_name = "cblas_";
|
||||
#else //#elif TEST_BLIS_TYPED
|
||||
std::string str_name = "bli_";
|
||||
#endif
|
||||
str_name = str_name + "StorageOfCMatrix_" + sfm;
|
||||
str_name = str_name + "_transa_" + tsa + "_transb_"+ tsb;
|
||||
std::string over_under_str = ( over_under > 0) ? "underflow": "overflow";
|
||||
str_name = str_name + "_" + over_under_str;
|
||||
std::string input_range_str = (input_range < 0) ? "within_limit": (input_range > 0) ? "beyond_limit" : "close_to_limit";
|
||||
str_name = str_name + "_" + input_range_str;
|
||||
str_name = str_name + "_m_" + std::to_string(m);
|
||||
str_name = str_name + "_n_" + std::to_string(n);
|
||||
str_name = str_name + "_k_" + std::to_string(k);
|
||||
str_name = str_name + "_A_" + std::to_string(ai) + "_" + std::to_string(aj);
|
||||
str_name = str_name + "_B_" + std::to_string(bi) + "_" + std::to_string(bj);
|
||||
std::string alpha_str = ( alpha > 0) ? std::to_string(int(alpha)) : "m" + std::to_string(int(std::abs(alpha)));
|
||||
str_name = str_name + "_alpha_" + alpha_str;
|
||||
std::string beta_str = ( beta > 0) ? std::to_string(int(beta)) : "m" + std::to_string(int(std::abs(beta)));
|
||||
str_name = str_name + "_beta_" + beta_str;
|
||||
str_name = str_name + "_lda_" + std::to_string(lda);
|
||||
str_name = str_name + "_ldb_" + std::to_string(ldb);
|
||||
str_name = str_name + "_ldc_" + std::to_string(ldc);
|
||||
return str_name;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Tests for Overflow
|
||||
|
||||
An Overflow condition occurs when the result of an operation or computation is larger than the
|
||||
maximum representable floating point value. For double precision floating points, the largest
|
||||
representable number is
|
||||
DBL_MAX = 1.7976931348623158e+308
|
||||
|
||||
This test populates matrices with values close to DBL_MAX so that the subsequent operations lead
|
||||
to values larger than DBL_MAX and hence causes a floating point overflow.
|
||||
|
||||
The argument over_under is used to indicate whether the test is an overflow or an underflow test.
|
||||
over_under = 0 indicates an overflow test
|
||||
|
||||
The argument input_range is used to choose the range of values used to populate input matrices
|
||||
input_range = -1 for values < DBL_MAX
|
||||
input_range = 0 for values close to DBL_MAX
|
||||
input_range = 1 for values > DBL_MAX
|
||||
*/
|
||||
|
||||
/* Overflow test for values much less than DBL_MAX */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
overflow_within_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(0), // over_under = 0 for overflow
|
||||
::testing::Values(-1), // input_range = -1 to test values less than DBL_MAX
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values( -1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(3), // increment to the leading dim of a
|
||||
::testing::Values(3), // increment to the leading dim of b
|
||||
::testing::Values(3), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(100), // ai
|
||||
::testing::Values(120), // aj
|
||||
::testing::Values(140), // bi
|
||||
::testing::Values(110) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
/* Overflow test for values close to DBL_MAX */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
overflow_close_to_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(0), // over_under = 0 for overflow
|
||||
::testing::Values(0), // input_range = 0 to test values close to DBL_MAX
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values( -1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(0), // increment to the leading dim of a
|
||||
::testing::Values(0), // increment to the leading dim of b
|
||||
::testing::Values(0), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(110), // ai
|
||||
::testing::Values(130), // aj
|
||||
::testing::Values(140), // bi
|
||||
::testing::Values(120) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
|
||||
/* Overflow test for values close to DBL_MAX and aplha = 0*/
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
overflow_close_to_limit_alpha0,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(0), // over_under = 0 for overflow
|
||||
::testing::Values(0), // input_range = 0 to test values close to DBL_MAX
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values(0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(5), // increment to the leading dim of a
|
||||
::testing::Values(5), // increment to the leading dim of b
|
||||
::testing::Values(5), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(108), // ai
|
||||
::testing::Values(122), // aj
|
||||
::testing::Values(145), // bi
|
||||
::testing::Values(108) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
/* Overflow test for values larger than DBL_MAX */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
overflow_beyond_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(0), // over_under = 0 for overflow
|
||||
::testing::Values(1), // input_range = 1 to test values larger than DBL_MAX
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values( -1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(0), // increment to the leading dim of a
|
||||
::testing::Values(0), // increment to the leading dim of b
|
||||
::testing::Values(0), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(110), // ai
|
||||
::testing::Values(140), // aj
|
||||
::testing::Values(130), // bi
|
||||
::testing::Values(100) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
Tests for Underflow
|
||||
|
||||
An underflow occurs when the result of an operation or a computation is smaller than the
|
||||
smallest representable floating point number. For double-precision floating points,
|
||||
the smallest representable number is
|
||||
DBL_MIN = 2.2250738585072014e-308
|
||||
|
||||
This test populates matrices with values close to DBL_MIN so that the subsequent operations
|
||||
lead to values smaller than DBL_MIN and hence results in a floating point underflow.
|
||||
|
||||
The argument over_under is used to indicate whether a test is an overflow or an underflow test.
|
||||
over_under=1 indicates an underflow test
|
||||
|
||||
The argument input_range is used to choose the range of values used to populate input matrices
|
||||
input_range = -1 for values > DBL_MIN
|
||||
input_range = 0 for values close to DBL_MIN
|
||||
input_range = 1 for values < DBL_MIN
|
||||
|
||||
*/
|
||||
|
||||
/* Underflow test for values larger than DBL_MIN */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
underflow_within_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(1), // over_under = 1 for underflow
|
||||
::testing::Values(-1), // input_range = -1 to test values larger than DBL_MIN
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values( -1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(3), // increment to the leading dim of a
|
||||
::testing::Values(3), // increment to the leading dim of b
|
||||
::testing::Values(3), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(100), // ai
|
||||
::testing::Values(120), // aj
|
||||
::testing::Values(140), // bi
|
||||
::testing::Values(110) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
/* Underflow test for values close to DBL_MIN */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
underflow_close_to_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(1), // over_under = 1 for underflow
|
||||
::testing::Values(0), // input_range = 0 to test values close to DBL_MIN
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values( -1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(5), // increment to the leading dim of a
|
||||
::testing::Values(5), // increment to the leading dim of b
|
||||
::testing::Values(5), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(101), // ai
|
||||
::testing::Values(118), // aj
|
||||
::testing::Values(132), // bi
|
||||
::testing::Values(110) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
/* Underflow test for values close to DBL_MIN and alpha = 0 */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
underflow_close_to_limit_alpha0,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(1), // over_under = 1 for underflow
|
||||
::testing::Values(0), // input_range = 0 to test values close to DBL_MIN
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values(0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(0), // increment to the leading dim of a
|
||||
::testing::Values(0), // increment to the leading dim of b
|
||||
::testing::Values(0), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(117), // ai
|
||||
::testing::Values(122), // aj
|
||||
::testing::Values(88), // bi
|
||||
::testing::Values(42) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* Underflow test for values smaller than DBL_MIN */
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
underflow_beyond_limit,
|
||||
DGEMMOvrUndr,
|
||||
::testing::Combine(
|
||||
// No condition based on storage scheme of matrices
|
||||
::testing::Values('c'), // storage format
|
||||
// No conditions based on trans of matrices
|
||||
::testing::Values('n', 't'), // transa
|
||||
::testing::Values('n', 't'), // transb
|
||||
|
||||
::testing::Values(1), // over_under = 1 for underflow
|
||||
::testing::Values(1), // input_range = 1 to test values smaller than DBL_MIN
|
||||
::testing::Values(120, 256, 512), // m
|
||||
|
||||
::testing::Values(144, 237, 680), // n
|
||||
|
||||
::testing::Values(128, 557, 680), // k
|
||||
// No condition based on alpha
|
||||
::testing::Values(-1.0), // alpha
|
||||
// No condition based on beta
|
||||
::testing::Values(-1.0), // beta
|
||||
::testing::Values(3), // increment to the leading dim of a
|
||||
::testing::Values(3), // increment to the leading dim of b
|
||||
::testing::Values(3), // increment to the leading dim of c
|
||||
|
||||
::testing::Values(44), // ai
|
||||
::testing::Values(135), // aj
|
||||
::testing::Values(100), // bi
|
||||
::testing::Values(105) // bj
|
||||
),
|
||||
::DGEMMOUTestPrint()
|
||||
);
|
||||
@@ -4,7 +4,7 @@
|
||||
An object-based framework for developing high-performance BLAS-like
|
||||
libraries.
|
||||
|
||||
Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (C) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "inc/check_error.h"
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <cfloat>
|
||||
|
||||
template<typename T>
|
||||
void test_gemm( char storage, char trnsa, char trnsb, gtint_t m, gtint_t n,
|
||||
@@ -136,3 +137,110 @@ void test_gemm( char storage, char trnsa, char trnsb, gtint_t m, gtint_t n,
|
||||
//----------------------------------------------------------
|
||||
computediff<T>( storage, m, n, c.data(), c_ref.data(), ldc, thresh, true );
|
||||
}
|
||||
|
||||
// Test body used for overflow and underflow checks
|
||||
template<typename T>
|
||||
void test_gemm( char storage, char trnsa, char trnsb, gtint_t over_under, gtint_t input_range,
|
||||
gtint_t m, gtint_t n, gtint_t k, gtint_t lda_inc, gtint_t ldb_inc,
|
||||
gtint_t ldc_inc, gtint_t ai, gtint_t aj, gtint_t bi, gtint_t bj, T alpha,
|
||||
T beta, double thresh )
|
||||
{
|
||||
// Compute the leading dimensions of a, b, and c.
|
||||
gtint_t lda = testinghelpers::get_leading_dimension( storage, trnsa, m, k, lda_inc );
|
||||
gtint_t ldb = testinghelpers::get_leading_dimension( storage, trnsb, k, n, ldb_inc );
|
||||
gtint_t ldc = testinghelpers::get_leading_dimension( storage, 'n', m, n, ldc_inc );
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Initialize matrices with random numbers
|
||||
//----------------------------------------------------------
|
||||
std::vector<T> a,b,c;
|
||||
|
||||
/*
|
||||
Testing for Overflow
|
||||
======================
|
||||
For double-precision floating point, the maximum representable number is
|
||||
DBL_MAX = 1.7976931348623158e+308
|
||||
|
||||
Any value higher than DBL_MAX is considered to be an overflow.
|
||||
|
||||
over_under=0 indicates Overflow testing
|
||||
The input matrices are populated with 3 different value ranges based on input_range
|
||||
|
||||
|****************************************************************|
|
||||
| input_range | Expected Input | Expected Output |
|
||||
|*************|*************************|************************|
|
||||
| -1 | Values much less than | Exact floating point |
|
||||
| | DBL_MAX | values |
|
||||
|*************|*************************|************************|
|
||||
| 0 | Values close to | Exact floating point |
|
||||
| | DBL_MAX | values upto DBL_MAX |
|
||||
| | | |
|
||||
| | | +/-INF for values |
|
||||
| | | higher than +/-DBL_MAX |
|
||||
|*************|*************************|************************|
|
||||
| 1 | Values much higher than | +/-INF for values |
|
||||
| | DBL_MAX | higher than +/-DBL_MAX |
|
||||
| | | |
|
||||
******************************************************************
|
||||
|
||||
Testing for Underflow
|
||||
========================
|
||||
For double-precision floating point, the minimum representable number is
|
||||
DBL_MIN = 2.2250738585072014e-308
|
||||
|
||||
Any value lower than DBL_MIN is considered to be an underflow
|
||||
|
||||
over_under=1 indicates Underflow testing
|
||||
The input matrices are populated with 3 different value ranges based on input_range
|
||||
|
||||
|******************************************************************|
|
||||
| input_range | Expected Input | Expected Output |
|
||||
|*************|**************************|*************************|
|
||||
| -1 | Values much larger | Exact floating point |
|
||||
| | than DBL_MIN | values |
|
||||
|*************|**************************|*************************|
|
||||
| 0 | Values close to | Exact floating point |
|
||||
| | DBL_MIN | values upto DBL_MIN |
|
||||
| | | |
|
||||
| | | +0 for values |
|
||||
| | | lower than DBL_MIN |
|
||||
|*************|**************************|*************************|
|
||||
| 1 | Values much smaller than | +0 for values |
|
||||
| | DBL_MIN | smaller than +/-DBL_MIN |
|
||||
| | | |
|
||||
********************************************************************
|
||||
|
||||
*/
|
||||
a = testinghelpers::get_random_matrix<T>( 5.5, 10.5, storage, trnsa, m, k, lda,
|
||||
testinghelpers::datagenerators::ElementType::FP );
|
||||
b = testinghelpers::get_random_matrix<T>( 3.2, 5.6, storage, trnsb, k, n, ldb,
|
||||
testinghelpers::datagenerators::ElementType::FP );
|
||||
c = testinghelpers::get_random_matrix<T>( -5, -2, storage, 'n', m, n, ldc,
|
||||
testinghelpers::datagenerators::ElementType::FP );
|
||||
/*
|
||||
Based on the value of over_under, overflow/underflow values are inserted to the input matrices
|
||||
at the indices passed as arguments.
|
||||
*/
|
||||
testinghelpers::set_overflow_underflow_mat( storage, trnsa, lda, ai, aj, a.data(), over_under, input_range);
|
||||
testinghelpers::set_overflow_underflow_mat( storage, trnsb, lda, bi, bj, b.data(), over_under, input_range);
|
||||
|
||||
std::vector<T> c_ref(c);
|
||||
|
||||
// Create a copy of c so that we can check reference results.
|
||||
//----------------------------------------------------------
|
||||
// Call BLIS function
|
||||
//----------------------------------------------------------
|
||||
gemm<T>( storage, trnsa, trnsb, m, n, k, &alpha, a.data(), lda,
|
||||
b.data(), ldb, &beta, c.data(), ldc );
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Call reference implementation.
|
||||
//----------------------------------------------------------
|
||||
testinghelpers::ref_gemm<T>( storage, trnsa, trnsb, m, n, k, alpha,
|
||||
a.data(), lda, b.data(), ldb, beta, c_ref.data(), ldc );
|
||||
|
||||
//----------------------------------------------------------
|
||||
// check component-wise error.
|
||||
//----------------------------------------------------------
|
||||
computediff<T>( storage, m, n, c.data(), c_ref.data(), ldc, thresh, true );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user