diff --git a/gtestsuite/testinghelpers/inc/common/data_generators.h b/gtestsuite/testinghelpers/inc/common/data_generators.h index 600f36eb4..8daa4b616 100644 --- a/gtestsuite/testinghelpers/inc/common/data_generators.h +++ b/gtestsuite/testinghelpers/inc/common/data_generators.h @@ -33,6 +33,7 @@ */ #include +#include #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 @@ -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 @@ -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 +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::real_type; + std::vector exponent(12); + + if (std::is_same::value) + { + exponent = {23, 203, 18, 180, 123, 130, 185, 178, 108, 158, 185, 220}; + } + else if (std::is_same::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::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::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 diff --git a/gtestsuite/testsuite/level3/gemm/dgemm_ovr_undr.cpp b/gtestsuite/testsuite/level3/gemm/dgemm_ovr_undr.cpp new file mode 100644 index 000000000..e01bab102 --- /dev/null +++ b/gtestsuite/testsuite/level3/gemm/dgemm_ovr_undr.cpp @@ -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 +#include "test_gemm.h" + + +class DGEMMOvrUndr : + public ::testing::TestWithParam> {}; + +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(); + + //---------------------------------------------------------- + // Call test body using these parameters + //---------------------------------------------------------- + test_gemm( 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> 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() + ); \ No newline at end of file diff --git a/gtestsuite/testsuite/level3/gemm/test_gemm.h b/gtestsuite/testsuite/level3/gemm/test_gemm.h index 147bcdab5..3c4e21ee4 100644 --- a/gtestsuite/testsuite/level3/gemm/test_gemm.h +++ b/gtestsuite/testsuite/level3/gemm/test_gemm.h @@ -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 #include +#include template 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( storage, m, n, c.data(), c_ref.data(), ldc, thresh, true ); } + +// Test body used for overflow and underflow checks +template +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 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( 5.5, 10.5, storage, trnsa, m, k, lda, + testinghelpers::datagenerators::ElementType::FP ); + b = testinghelpers::get_random_matrix( 3.2, 5.6, storage, trnsb, k, n, ldb, + testinghelpers::datagenerators::ElementType::FP ); + c = testinghelpers::get_random_matrix( -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 c_ref(c); + + // Create a copy of c so that we can check reference results. + //---------------------------------------------------------- + // Call BLIS function + //---------------------------------------------------------- + gemm( storage, trnsa, trnsb, m, n, k, &alpha, a.data(), lda, + b.data(), ldb, &beta, c.data(), ldc ); + + //---------------------------------------------------------- + // Call reference implementation. + //---------------------------------------------------------- + testinghelpers::ref_gemm( storage, trnsa, trnsb, m, n, k, alpha, + a.data(), lda, b.data(), ldb, beta, c_ref.data(), ldc ); + + //---------------------------------------------------------- + // check component-wise error. + //---------------------------------------------------------- + computediff( storage, m, n, c.data(), c_ref.data(), ldc, thresh, true ); +}