mirror of
https://github.com/amd/blis.git
synced 2026-05-25 19:04:32 +00:00
GTestSuite: Added Tests for DGEMMT
- Added API tests for DGEMMT.
- Added Extreme Value Test cases (EVT) for DGEMMT.
- Tests for various combinations of INFs
and NANs for A and B matrix are added.
- Added Invalid input test cases (IIT).
- Added memory testing for DGEMMT API.
AMD-Internal: [CPUPL-4724]
Change-Id: Ib40802ea49417b4a4883831c2d971e59a2e093e5
This commit is contained in:
297
gtestsuite/testsuite/level3/gemmt/IIT_ERS_test.cpp
Normal file
297
gtestsuite/testsuite/level3/gemmt/IIT_ERS_test.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
|
||||
BLIS
|
||||
An object-based framework for developing high-performance BLAS-like
|
||||
libraries.
|
||||
|
||||
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
|
||||
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 "common/testing_helpers.h"
|
||||
#include "gemmt.h"
|
||||
#include "inc/check_error.h"
|
||||
#include "common/wrong_inputs_helpers.h"
|
||||
|
||||
template <typename T>
|
||||
class GEMMT_IIT_ERS : public ::testing::Test {};
|
||||
typedef ::testing::Types<float, double, scomplex, dcomplex> TypeParam; // The supported datatypes from BLAS calls for GEMMT
|
||||
TYPED_TEST_SUITE(GEMMT_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support.
|
||||
|
||||
// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h.
|
||||
using namespace testinghelpers::IIT;
|
||||
|
||||
#if defined(TEST_BLAS) || defined(TEST_CBLAS)
|
||||
|
||||
/*
|
||||
Incorrect Input Testing(IIT)
|
||||
|
||||
BLAS exceptions get triggered in the following cases(for GEMM):
|
||||
1. When UPLO != 'L' || UPLO != 'U' (info = 1)
|
||||
2. When TRANSA != 'N' || TRANSA != 'T' || TRANSA != 'C' (info = 2)
|
||||
3. When TRANSB != 'N' || TRANSB != 'T' || TRANSB != 'C' (info = 3)
|
||||
4. When n < 0 (info = 4)
|
||||
5. When k < 0 (info = 5)
|
||||
6. When lda < max(1, thresh) (info = 8), thresh set based on TRANSA value
|
||||
7. When ldb < max(1, thresh) (info = 10), thresh set based on TRANSB value
|
||||
8. When ldc < max(1, n) (info = 13)
|
||||
|
||||
*/
|
||||
|
||||
// When info == 1
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_uploa)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, 'A', TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 2
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_transa)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, 'A', TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 3
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_transb)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, 'A', N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 4
|
||||
TYPED_TEST(GEMMT_IIT_ERS, n_lt_zero)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, -1, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 5
|
||||
TYPED_TEST(GEMMT_IIT_ERS, k_lt_zero)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 8
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_lda)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA-1, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 10
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_ldb)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB-1, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When info == 13
|
||||
TYPED_TEST(GEMMT_IIT_ERS, invalid_ldc)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC-1 );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
/*
|
||||
Early Return Scenarios(ERS) :
|
||||
|
||||
The GEMMt API is expected to return early in the following cases:
|
||||
|
||||
1. When n == 0.
|
||||
2. When (alpha == 0 or k == 0) and beta == 1.
|
||||
|
||||
*/
|
||||
|
||||
// When n is 0
|
||||
TYPED_TEST(GEMMT_IIT_ERS, n_eq_zero)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, 0, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When alpha is 0 and beta is 1
|
||||
TYPED_TEST(GEMMT_IIT_ERS, alpha_zero_beta_one)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
// When k is 0 and beta is 1
|
||||
TYPED_TEST(GEMMT_IIT_ERS, k_zero_beta_one)
|
||||
{
|
||||
using T = TypeParam;
|
||||
|
||||
// Defining the C matrix with values for debugging purposes
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, N, LDC);
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', N, K, LDA);
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>(-10, 10, STORAGE, 'N', K, N, LDB);
|
||||
// Copy so that we check that the elements of C are not modified.
|
||||
std::vector<T> c_ref(c);
|
||||
T alpha, beta;
|
||||
|
||||
testinghelpers::initone<T>( alpha );
|
||||
testinghelpers::initone<T>( beta );
|
||||
|
||||
gemmt<T>( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC );
|
||||
computediff<T>( STORAGE, N, N, c.data(), c_ref.data(), LDC );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
175
gtestsuite/testsuite/level3/gemmt/dgemmt_evt_testing.cpp
Normal file
175
gtestsuite/testsuite/level3/gemmt/dgemmt_evt_testing.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
|
||||
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_gemmt.h"
|
||||
|
||||
class dgemmtEVT :
|
||||
public ::testing::TestWithParam<std::tuple<char, // storage format
|
||||
char, // uplo
|
||||
char, // transa
|
||||
char, // transb
|
||||
gtint_t, // n
|
||||
gtint_t, // k
|
||||
double, // alpha
|
||||
double, // beta
|
||||
gtint_t, // lda_inc
|
||||
gtint_t, // ldb_inc
|
||||
gtint_t, // ldc_inc
|
||||
double, // exception value for A matrix
|
||||
double, // exception value for B matrix
|
||||
double>> {}; // exception value for C matrix
|
||||
|
||||
TEST_P( dgemmtEVT, NaNInfCheck )
|
||||
{
|
||||
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());
|
||||
// specifies if the upper or lower triangular part of C is used
|
||||
char uplo = std::get<1>(GetParam());
|
||||
// denotes whether matrix a is n,c,t,h
|
||||
char transa = std::get<2>(GetParam());
|
||||
// denotes whether matrix b is n,c,t,h
|
||||
char transb = std::get<3>(GetParam());
|
||||
// matrix size n
|
||||
gtint_t n = std::get<4>(GetParam());
|
||||
// matrix size k
|
||||
gtint_t k = std::get<5>(GetParam());
|
||||
// specifies alpha value
|
||||
T alpha = std::get<6>(GetParam());
|
||||
// specifies beta value
|
||||
T beta = std::get<7>(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<8>(GetParam());
|
||||
gtint_t ldb_inc = std::get<9>(GetParam());
|
||||
gtint_t ldc_inc = std::get<10>(GetParam());
|
||||
T aexval = std::get<11>(GetParam());
|
||||
T bexval = std::get<12>(GetParam());
|
||||
T cexval = std::get<13>(GetParam());
|
||||
|
||||
// Set the threshold for the errors:
|
||||
double thresh = 10*n*k*testinghelpers::getEpsilon<T>();
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Call test body using these parameters
|
||||
//----------------------------------------------------------
|
||||
test_gemmt<T>( storage, uplo, transa, transb, n, k, lda_inc, ldb_inc, ldc_inc,
|
||||
alpha, beta, thresh, false, true, aexval, bexval, cexval );
|
||||
}
|
||||
|
||||
class dgemmtEVTPrint
|
||||
{
|
||||
public:
|
||||
std::string operator()(
|
||||
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,gtint_t,double,double,gtint_t,gtint_t,gtint_t,double,double,double>> str) const {
|
||||
char sfm = std::get<0>(str.param);
|
||||
char uplo = std::get<1>(str.param);
|
||||
char tsa = std::get<2>(str.param);
|
||||
char tsb = std::get<3>(str.param);
|
||||
gtint_t n = std::get<4>(str.param);
|
||||
gtint_t k = std::get<5>(str.param);
|
||||
double alpha = std::get<6>(str.param);
|
||||
double beta = std::get<7>(str.param);
|
||||
gtint_t lda_inc = std::get<8>(str.param);
|
||||
gtint_t ldb_inc = std::get<9>(str.param);
|
||||
gtint_t ldc_inc = std::get<10>(str.param);
|
||||
double aexval = std::get<11>(str.param);
|
||||
double bexval = std::get<12>(str.param);
|
||||
double cexval = std::get<13>(str.param);
|
||||
#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 + "_storage_" + sfm;
|
||||
str_name = str_name + "_transa_" + tsa;
|
||||
str_name = str_name + "_transb_" + tsb;
|
||||
str_name = str_name + "_uploa_" + uplo;
|
||||
str_name = str_name + "_n_" + std::to_string(n);
|
||||
str_name = str_name + "_k_" + std::to_string(k);
|
||||
std::string alpha_str = testinghelpers::get_value_string(alpha);
|
||||
str_name = str_name + "_alpha_" + alpha_str;
|
||||
std::string beta_str = testinghelpers::get_value_string(beta);
|
||||
str_name = str_name + "_beta_" + beta_str;
|
||||
gtint_t lda = testinghelpers::get_leading_dimension( sfm, tsa, n, 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', n, n, ldc_inc );
|
||||
str_name = str_name + "_ex_a_" + testinghelpers::get_value_string(aexval);
|
||||
str_name = str_name + "_ex_b_" + testinghelpers::get_value_string(bexval);
|
||||
str_name = str_name + "_ex_c_" + testinghelpers::get_value_string(cexval);
|
||||
str_name = str_name + "_ldb_" + 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;
|
||||
}
|
||||
};
|
||||
|
||||
static double AOCL_NAN = std::numeric_limits<double>::quiet_NaN();
|
||||
static double AOCL_INF = std::numeric_limits<double>::infinity();
|
||||
|
||||
#ifndef TEST_BLIS_TYPED
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Native,
|
||||
dgemmtEVT,
|
||||
::testing::Combine(
|
||||
::testing::Values('c'
|
||||
#ifndef TEST_BLAS
|
||||
,'r'
|
||||
#endif
|
||||
), // storage format
|
||||
::testing::Values('u','l'), // uplo u:upper, l:lower
|
||||
::testing::Values('n','t'), // transa
|
||||
::testing::Values('n','t'), // transb
|
||||
::testing::Values(7, 800), // n
|
||||
::testing::Values(7, 800), // k
|
||||
::testing::Values(2.4, AOCL_NAN/*, AOCL_INF, -AOCL_INF*/), // alpha //commented values fail
|
||||
::testing::Values(2.4/*, AOCL_NAN*/, AOCL_INF, -AOCL_INF), // beta //commented values fail
|
||||
::testing::Values(gtint_t(0)), // increment to the leading dim of a
|
||||
::testing::Values(gtint_t(0)), // increment to the leading dim of b
|
||||
::testing::Values(gtint_t(0)), // increment to the leading dim of c
|
||||
::testing::Values(0.0, AOCL_NAN, AOCL_INF, -AOCL_INF), // extreme value for A matrix
|
||||
::testing::Values(0.0, AOCL_NAN, AOCL_INF, -AOCL_INF), // extreme value for B matrix
|
||||
::testing::Values(0.0, AOCL_NAN, AOCL_INF, -AOCL_INF) // extreme value for B matrix
|
||||
),
|
||||
::dgemmtEVTPrint()
|
||||
);
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -35,22 +35,23 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "test_gemmt.h"
|
||||
|
||||
class dgemmtTest :
|
||||
public ::testing::TestWithParam<std::tuple<char,
|
||||
char,
|
||||
char,
|
||||
char,
|
||||
gtint_t,
|
||||
gtint_t,
|
||||
double,
|
||||
double,
|
||||
gtint_t,
|
||||
gtint_t,
|
||||
gtint_t>> {};
|
||||
class dgemmtAPI :
|
||||
public ::testing::TestWithParam<std::tuple<char, // storage
|
||||
char, // uplo
|
||||
char, // transa
|
||||
char, // transb
|
||||
gtint_t, // n
|
||||
gtint_t, // k
|
||||
double, // alpha
|
||||
double, // beta
|
||||
gtint_t, // lda_inc
|
||||
gtint_t, // ldb_inc
|
||||
gtint_t, // ldc_inc
|
||||
bool>> {}; // is memory test
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(dgemmtTest);
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(dgemmtAPI);
|
||||
|
||||
TEST_P(dgemmtTest, RandomData)
|
||||
TEST_P(dgemmtAPI, FunctionalTest)
|
||||
{
|
||||
using T = double;
|
||||
//----------------------------------------------------------
|
||||
@@ -79,6 +80,7 @@ TEST_P(dgemmtTest, RandomData)
|
||||
gtint_t lda_inc = std::get<8>(GetParam());
|
||||
gtint_t ldb_inc = std::get<9>(GetParam());
|
||||
gtint_t ldc_inc = std::get<10>(GetParam());
|
||||
bool is_mem_test = std::get<11>(GetParam());
|
||||
|
||||
// Set the threshold for the errors:
|
||||
double thresh = 10*n*k*testinghelpers::getEpsilon<T>();
|
||||
@@ -86,17 +88,17 @@ TEST_P(dgemmtTest, RandomData)
|
||||
//----------------------------------------------------------
|
||||
// Call test body using these parameters
|
||||
//----------------------------------------------------------
|
||||
test_gemmt<T>( storage, uplo, transa, transb, n, k, lda_inc, ldb_inc, ldc_inc, alpha, beta, thresh );
|
||||
test_gemmt<T>( storage, uplo, transa, transb, n, k, lda_inc, ldb_inc, ldc_inc, alpha, beta, thresh, is_mem_test );
|
||||
}
|
||||
|
||||
class dgemmtTestPrint {
|
||||
class dgemmtPrint {
|
||||
public:
|
||||
std::string operator()(
|
||||
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,gtint_t,double,double,gtint_t,gtint_t,gtint_t>> str) const {
|
||||
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,gtint_t,double,double,gtint_t,gtint_t,gtint_t,bool>> str) const {
|
||||
char sfm = std::get<0>(str.param);
|
||||
char tsa = std::get<1>(str.param);
|
||||
char tsb = std::get<2>(str.param);
|
||||
char uplo = std::get<3>(str.param);
|
||||
char uplo = std::get<1>(str.param);
|
||||
char tsa = std::get<2>(str.param);
|
||||
char tsb = std::get<3>(str.param);
|
||||
gtint_t n = std::get<4>(str.param);
|
||||
gtint_t k = std::get<5>(str.param);
|
||||
double alpha = std::get<6>(str.param);
|
||||
@@ -104,51 +106,105 @@ public:
|
||||
gtint_t lda_inc = std::get<8>(str.param);
|
||||
gtint_t ldb_inc = std::get<9>(str.param);
|
||||
gtint_t ldc_inc = std::get<10>(str.param);
|
||||
bool is_mem_test = std::get<11>(str.param);
|
||||
#ifdef TEST_BLAS
|
||||
std::string str_name = "dgemmt_";
|
||||
std::string str_name = "blas_";
|
||||
#elif TEST_CBLAS
|
||||
std::string str_name = "cblas_dgemmt";
|
||||
std::string str_name = "cblas_";
|
||||
#else //#elif TEST_BLIS_TYPED
|
||||
std::string str_name = "bli_dgemmt";
|
||||
std::string str_name = "bli_";
|
||||
#endif
|
||||
str_name = str_name + "_" + sfm+sfm+sfm;
|
||||
str_name = str_name + "_" + tsa + tsb;
|
||||
str_name = str_name + "_" + uplo;
|
||||
str_name = str_name + "_" + std::to_string(n);
|
||||
str_name = str_name + "_" + std::to_string(k);
|
||||
std::string alpha_str = ( alpha > 0) ? std::to_string(int(alpha)) : "m" + std::to_string(int(std::abs(alpha)));
|
||||
str_name = str_name + "_a" + 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 + "_b" + beta_str;
|
||||
str_name = str_name + "_" + std::to_string(lda_inc);
|
||||
str_name = str_name + "_" + std::to_string(ldb_inc);
|
||||
str_name = str_name + "_" + std::to_string(ldc_inc);
|
||||
str_name = str_name + "_storage_" + sfm;
|
||||
str_name = str_name + "_transa_" + tsa;
|
||||
str_name = str_name + "_transb_" + tsb;
|
||||
str_name = str_name + "_uploa_" + uplo;
|
||||
str_name = str_name + "_n_" + std::to_string(n);
|
||||
str_name = str_name + "_k_" + std::to_string(k);
|
||||
std::string alpha_str = testinghelpers::get_value_string(alpha);
|
||||
str_name = str_name + "_alpha_" + alpha_str;
|
||||
std::string beta_str = testinghelpers::get_value_string(beta);
|
||||
str_name = str_name + "_beta_" + beta_str;
|
||||
gtint_t lda = testinghelpers::get_leading_dimension( sfm, tsa, n, 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', n, n, ldc_inc );
|
||||
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);
|
||||
str_name = str_name + (is_mem_test ? "_mem_test_enabled" : "_mem_test_disabled");
|
||||
return str_name;
|
||||
}
|
||||
};
|
||||
// Disable tests for BLIS_TYPED case due to compiler errors.
|
||||
|
||||
#ifndef TEST_BLIS_TYPED
|
||||
// Black box testing.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Blackbox,
|
||||
dgemmtTest,
|
||||
skinny_fringe_cases,
|
||||
dgemmtAPI,
|
||||
::testing::Combine(
|
||||
::testing::Values('c'
|
||||
#ifndef TEST_BLAS
|
||||
,'r'
|
||||
,'r'
|
||||
#endif
|
||||
), // storage format
|
||||
::testing::Values('u','l'), // uplo u:upper, l:lower
|
||||
::testing::Values('n','c','t'), // transa
|
||||
::testing::Values('n','c','t'), // transb
|
||||
::testing::Range(gtint_t(10), gtint_t(31), 10), // n
|
||||
::testing::Range(gtint_t(10), gtint_t(31), 10), // k
|
||||
::testing::Values(2.0), // alpha
|
||||
::testing::Values(3.0), // beta
|
||||
::testing::Values(gtint_t(0), gtint_t(4)), // increment to the leading dim of a
|
||||
::testing::Values(gtint_t(0), gtint_t(1)), // increment to the leading dim of b
|
||||
::testing::Values(gtint_t(0), gtint_t(2)) // increment to the leading dim of c
|
||||
::testing::Values('n','t'), // transa
|
||||
::testing::Values('n','t'), // transb
|
||||
::testing::Range(gtint_t(1), gtint_t(30), 1), // n
|
||||
::testing::Range(gtint_t(1), gtint_t(30), 1), // k
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // alpha
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // beta
|
||||
::testing::Values(gtint_t(0), gtint_t(153)), // increment to the leading dim of a
|
||||
::testing::Values(gtint_t(0), gtint_t(122)), // increment to the leading dim of b
|
||||
::testing::Values(gtint_t(0), gtint_t(195)), // increment to the leading dim of c
|
||||
::testing::Values(true, false) // is memory test
|
||||
),
|
||||
::dgemmtTestPrint()
|
||||
::dgemmtPrint()
|
||||
);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
skinny,
|
||||
dgemmtAPI,
|
||||
::testing::Combine(
|
||||
::testing::Values('c'
|
||||
#ifndef TEST_BLAS
|
||||
,'r'
|
||||
#endif
|
||||
), // storage format
|
||||
::testing::Values('u','l'), // uplo u:upper, l:lower
|
||||
::testing::Values('n','t'), // transa
|
||||
::testing::Values('n','t'), // transb
|
||||
::testing::Values(35, 537, 799), // n
|
||||
::testing::Values(35, 537, 799), // k
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // alpha
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // beta
|
||||
::testing::Values(gtint_t(0), gtint_t(153)), // increment to the leading dim of a
|
||||
::testing::Values(gtint_t(0), gtint_t(122)), // increment to the leading dim of b
|
||||
::testing::Values(gtint_t(0), gtint_t(195)), // increment to the leading dim of c
|
||||
::testing::Values(true, false) // is memory test
|
||||
),
|
||||
::dgemmtPrint()
|
||||
);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
large,
|
||||
dgemmtAPI,
|
||||
::testing::Combine(
|
||||
::testing::Values('c'
|
||||
#ifndef TEST_BLAS
|
||||
,'r'
|
||||
#endif
|
||||
), // storage format
|
||||
::testing::Values('u','l'), // uplo u:upper, l:lower
|
||||
::testing::Values('n','t'), // transa
|
||||
::testing::Values('n','t'), // transb
|
||||
::testing::Values(800, 1500), // n
|
||||
::testing::Values(800, 1500), // k
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // alpha
|
||||
::testing::Values(1.0, 0.0, -2.4, 3.1), // beta
|
||||
::testing::Values(gtint_t(0), gtint_t(153)), // increment to the leading dim of a
|
||||
::testing::Values(gtint_t(0), gtint_t(122)), // increment to the leading dim of b
|
||||
::testing::Values(gtint_t(0), gtint_t(195)), // increment to the leading dim of c
|
||||
::testing::Values(true, false) // is memory test
|
||||
),
|
||||
::dgemmtPrint()
|
||||
);
|
||||
#endif
|
||||
|
||||
@@ -39,11 +39,13 @@
|
||||
#include "inc/check_error.h"
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include "common/testing_helpers.h"
|
||||
|
||||
template<typename T>
|
||||
void test_gemmt( char storage, char uplo, char trnsa, char trnsb, gtint_t n,
|
||||
gtint_t k, gtint_t lda_inc, gtint_t ldb_inc, gtint_t ldc_inc, T alpha,
|
||||
T beta, double thresh )
|
||||
T beta, double thresh, bool is_mem_test=false, bool is_evt_test=false,
|
||||
T evt_a=T{0.0}, T evt_b=T{0.0}, T evt_c=T{0.0} )
|
||||
{
|
||||
// Compute the leading dimensions of a, b, and c.
|
||||
gtint_t lda = testinghelpers::get_leading_dimension( storage, trnsa, n, k, lda_inc );
|
||||
@@ -53,27 +55,86 @@ void test_gemmt( char storage, char uplo, char trnsa, char trnsb, gtint_t n,
|
||||
//----------------------------------------------------------
|
||||
// Initialize matrics with random numbers
|
||||
//----------------------------------------------------------
|
||||
std::vector<T> a = testinghelpers::get_random_matrix<T>( -2, 8, storage, trnsa, n, k, lda );
|
||||
std::vector<T> b = testinghelpers::get_random_matrix<T>( -5, 2, storage, trnsb, k, n, ldb );
|
||||
std::vector<T> c = testinghelpers::get_random_matrix<T>( -3, 5, storage, 'n', n, n, ldc );
|
||||
T *a_ptr, *b_ptr, *c_ptr;
|
||||
dim_t size_a = testinghelpers::matsize(storage, trnsa, n, k, lda) * sizeof(T);
|
||||
testinghelpers::ProtectedBuffer a(size_a, false, is_mem_test );
|
||||
a_ptr = (T*)a.greenzone_1;
|
||||
testinghelpers::datagenerators::randomgenerators<T>( -2, 8, storage, n, k, a_ptr, trnsa, lda);
|
||||
|
||||
dim_t size_b = testinghelpers::matsize(storage, trnsb, k, n, ldb) * sizeof(T);
|
||||
testinghelpers::ProtectedBuffer b(size_b, false, is_mem_test );
|
||||
b_ptr = (T*)b.greenzone_1;
|
||||
testinghelpers::datagenerators::randomgenerators<T>( -5, 2, storage, k, n, b_ptr, trnsb, ldb);
|
||||
|
||||
dim_t size_c = testinghelpers::matsize(storage, 'n', n, n, ldc) * sizeof(T);
|
||||
testinghelpers::ProtectedBuffer c(size_c, false, is_mem_test );
|
||||
c_ptr = (T*)c.greenzone_1;
|
||||
testinghelpers::datagenerators::randomgenerators<T>( -3, 5, storage, n, n, c_ptr, 'n', ldc);
|
||||
|
||||
if ( is_evt_test )
|
||||
{
|
||||
dim_t n_rand = rand() % std::min(n, k);
|
||||
dim_t k_rand = rand() % std::min(n, k);
|
||||
a_ptr[n_rand + k_rand * lda] = evt_a;
|
||||
}
|
||||
|
||||
if ( is_evt_test )
|
||||
{
|
||||
dim_t n_rand = rand() % std::min(n, k);
|
||||
dim_t k_rand = rand() % std::min(n, k);
|
||||
b_ptr[n_rand + k_rand * lda] = evt_a;
|
||||
}
|
||||
|
||||
if ( is_evt_test )
|
||||
{
|
||||
dim_t n_rand = rand() % std::min(n, k);
|
||||
dim_t k_rand = rand() % std::min(n, k);
|
||||
b_ptr[n_rand + k_rand * lda] = evt_a;
|
||||
}
|
||||
|
||||
// Create a copy of c so that we can check reference results.
|
||||
std::vector<T> c_ref(c);
|
||||
std::vector<T> c_ref(testinghelpers::matsize(storage, 'n', n, n, ldc));
|
||||
memcpy(c_ref.data(), c_ptr, size_c);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Call BLIS function
|
||||
//----------------------------------------------------------
|
||||
gemmt<T>( storage, uplo, trnsa, trnsb, n, k, &alpha, a.data(), lda,
|
||||
b.data(), ldb, &beta, c.data(), ldc );
|
||||
// add signal handler for segmentation fault
|
||||
testinghelpers::ProtectedBuffer::start_signal_handler();
|
||||
try
|
||||
{
|
||||
//----------------------------------------------------------
|
||||
// Call BLIS function
|
||||
//----------------------------------------------------------
|
||||
gemmt<T>( storage, uplo, trnsa, trnsb, n, k, &alpha, a_ptr, lda,
|
||||
b_ptr, ldb, &beta, c_ptr, ldc );
|
||||
if (is_mem_test)
|
||||
{
|
||||
memcpy(a.greenzone_2, a.greenzone_1, size_a);
|
||||
memcpy(b.greenzone_2, b.greenzone_1, size_b);
|
||||
memcpy(c.greenzone_2, c_ref.data(), size_c);
|
||||
|
||||
gemmt<T>( storage, uplo, trnsa, trnsb, n, k, &alpha, (T*)a.greenzone_2, lda,
|
||||
(T*)b.greenzone_2, ldb, &beta, (T*)c.greenzone_2, ldc );
|
||||
}
|
||||
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
// reset to default signal handler
|
||||
testinghelpers::ProtectedBuffer::stop_signal_handler();
|
||||
|
||||
// show failure in case seg fault was detected
|
||||
FAIL() << "Memory Test Failed";
|
||||
}
|
||||
// reset to default signal handler
|
||||
testinghelpers::ProtectedBuffer::stop_signal_handler();
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Call reference implementation.
|
||||
//----------------------------------------------------------
|
||||
testinghelpers::ref_gemmt<T>( storage, uplo, trnsa, trnsb, n, k, alpha,
|
||||
a.data(), lda, b.data(), ldb, beta, c_ref.data(), ldc );
|
||||
a_ptr, lda, b_ptr, ldb, beta, c_ref.data(), ldc );
|
||||
|
||||
//----------------------------------------------------------
|
||||
// check component-wise error.
|
||||
//----------------------------------------------------------
|
||||
computediff<T>( storage, n, n, c.data(), c_ref.data(), ldc, thresh );
|
||||
computediff<T>( storage, n, n, c_ptr, c_ref.data(), ldc, thresh, is_evt_test );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user