GTestSuite: Added Tests for DTRSV

- Added API tests for DTRSV.
  - Added Extreme Value Test cases (EVT) for DTRSV.
    - Tests for various combinations of INFs
       and NANs for X vector and B matrix are added.
  - Added Invalid input test cases (IIT).
  - Added memory testing for DTRSV
    kernels.
  - Fixed a bug in alphax function where scaling
    of a vector with a scalar was not handled
    correctly when incx was negative.

AMD-Internal: [CPUPL-4715]
Change-Id: I84c873e98f845e05b11860e7ef6083d1184489b4
This commit is contained in:
Shubham Sharma
2024-03-11 14:36:17 +05:30
parent e14da6f73d
commit 9c40473a96
5 changed files with 516 additions and 59 deletions

View File

@@ -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
@@ -173,7 +173,9 @@ static void alphax( gtint_t n, T alpha, T *xp, gtint_t incx )
gtint_t ix = 0;
for(i = 0 ; i < n ; i++) {
xp[ix] = (alpha * xp[ix]);
ix = ix + incx;
// use absolute value of incx to ensure
// correctness when incx < 0
ix = ix + std::abs(incx);
}
}

View File

@@ -0,0 +1,190 @@
/*
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 "trsv.h"
#include "inc/check_error.h"
#include "common/testing_helpers.h"
#include "common/wrong_inputs_helpers.h"
#include <stdexcept>
#include <algorithm>
#include <gtest/gtest.h>
template <typename T>
class TRSV_IIT_ERS_Test : public ::testing::Test {};
typedef ::testing::Types<float, double, scomplex, dcomplex> TypeParam;
TYPED_TEST_SUITE(TRSV_IIT_ERS_Test, TypeParam);
#ifdef TEST_BLAS
using namespace testinghelpers::IIT;
/*
Incorrect Input Testing(IIT)
BLAS exceptions get triggered in the following cases(for TRSV):
1. When UPLO != 'L' || UPLO != 'U' (info = 1)
2. When TRANS != 'N' || TRANS != 'T' || TRANS != 'C' (info = 2)
3. When DIAG != 'U' || DIAG != 'N' (info = 3)
4. When n < 0 (info = 4)
5. When lda < N (info = 6)
6. When incx == 0 (info = 8)
*/
/**
* @brief Test TRSV when UPLO argument is incorrect
* when info == 1
*
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_UPLO)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, 'A', TRANS, DIAG, N, &alpha, nullptr, LDA, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/**
* @brief Test TRSV when TRANS argument is incorrect
* when info == 2
*
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_TRANS)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, 'A', DIAG, N, &alpha, nullptr, LDA, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/**
* @brief Test TRSV when DIAG argument is incorrect
* when info == 3
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_DIAG)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, TRANS, 'A', N, &alpha, nullptr, LDA, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/**
* @brief Test TRSV when N is negative
* when info == 4
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_n)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, TRANS, DIAG, -1, &alpha, nullptr, LDA, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/**
* @brief Test TRSV when lda < max(1, N)
* when info == 6
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_lda)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, TRANS, DIAG, N, &alpha, nullptr, LDA - 1, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/**
* @brief Test TRSV when INCX == 0
* when info == 8
*/
TYPED_TEST(TRSV_IIT_ERS_Test, invalid_incx)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, TRANS, DIAG, N, &alpha, nullptr, LDA, x.data(), 0);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
/*
Early Return Scenarios(ERS) :
The TRSV API is expected to return early in the following cases:
1. When n == 0.
*/
/**
* @brief Test TRSV when N is zero
*/
TYPED_TEST(TRSV_IIT_ERS_Test, n_eq_zero)
{
using T = TypeParam;
T alpha = T{1};
std::vector<T> x = testinghelpers::get_random_vector<T>(0, 1, N, INC);
std::vector<T> x_ref(x);
trsv<T>( STORAGE, UPLO, TRANS, DIAG, 0, &alpha, nullptr, LDA, x.data(), INC);
computediff<T>( N, x.data(), x_ref.data(), INC );
}
#endif

View File

@@ -0,0 +1,171 @@
/*
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_trsv.h"
class dtrsvEVT :
public ::testing::TestWithParam<std::tuple<char, // storage format
char, // uplo
char, // trans
char, // diag
gtint_t, // n
double, // alpha
gtint_t, // incx
double, // exception value for X
double, // excepton value for Y
gtint_t>> {}; // ld_inc
TEST_P( dtrsvEVT, 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());
// denotes whether matrix a is u,l
char uploa = std::get<1>(GetParam());
// denotes whether matrix a is n,c,t,h
char transa = std::get<2>(GetParam());
// denotes whether matrix diag is u,n
char diaga = std::get<3>(GetParam());
// matrix size n
gtint_t n = std::get<4>(GetParam());
// specifies alpha value
T alpha = std::get<5>(GetParam());
// stride size for x:
gtint_t incx = std::get<6>(GetParam());
// extreme value for x
double xexval = std::get<7>(GetParam());
// extreme value for A
double aexval = std::get<8>(GetParam());
// lda increment.
// If increment is zero, then the array size matches the matrix size.
// If increment are nonnegative, the array size is bigger than the matrix size.
gtint_t lda_inc = std::get<9>(GetParam());
// Set the threshold for the errors:
// Check gtestsuite trsv.h or netlib source code for reminder of the
// functionality from which we estimate operation count per element
// of output, and hence the multipler for epsilon.
double thresh;
if (n == 0)
thresh = 0.0;
else
thresh = 2*n*testinghelpers::getEpsilon<T>();
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_trsv<T>( storage, uploa, transa, diaga, n, alpha, lda_inc, incx, thresh, false, true, xexval, aexval);
}
class dtrsvEVTPrint
{
public:
std::string operator()(
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,double,gtint_t,double,double,gtint_t>> str) const {
char sfm = std::get<0>(str.param);
char uploa = std::get<1>(str.param);
char transa = std::get<2>(str.param);
char diaga = std::get<3>(str.param);
gtint_t n = std::get<4>(str.param);
double alpha = std::get<5>(str.param);
gtint_t incx = std::get<6>(str.param);
double xexval = std::get<7>(str.param);
double aexval = std::get<8>(str.param);
gtint_t ld_inc = std::get<9>(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 + "stor_" + sfm;
str_name = str_name + "_uplo_" + uploa;
str_name = str_name + "_transa_" + transa;
str_name = str_name + "_diaga_" + diaga;
str_name = str_name + "_n_" + std::to_string(n);
std::string alpha_str = testinghelpers::get_value_string(alpha);
str_name = str_name + "_alpha_" + alpha_str;
std::string incx_str = ( incx > 0) ? std::to_string(incx) : "m" + std::to_string(std::abs(incx));
str_name = str_name + "_incx_" + incx_str;
str_name = str_name + "_ex_x_" + testinghelpers::get_value_string(xexval);
str_name = str_name + "_ex_a_" + testinghelpers::get_value_string(aexval);
str_name = str_name + "_lda_" + std::to_string(
testinghelpers::get_leading_dimension( sfm, transa, n, n, ld_inc )
);
return str_name;
}
};
static double AOCL_NAN = std::numeric_limits<double>::quiet_NaN();
static double AOCL_INF = std::numeric_limits<double>::infinity();
INSTANTIATE_TEST_SUITE_P(
Native,
dtrsvEVT,
::testing::Combine(
::testing::Values('c'
#ifndef TEST_BLAS
,'r'
#endif
), // storage format
::testing::Values('u','l'), // uploa
::testing::Values('n','t'), // transa
::testing::Values('n','u'), // diaga , n=NONUNIT_DIAG u=UNIT_DIAG
::testing::Values(gtint_t(32),
gtint_t(24),
gtint_t(8),
gtint_t(4),
gtint_t(2),
gtint_t(1),
gtint_t(15)
), // n (random values)
::testing::Values( 1.0
#ifdef TEST_BLIS_TYPED
, -2.2, 5.4, -1.0, 0.0
#endif
), // alpha
::testing::Values(gtint_t(-2), gtint_t(-1),
gtint_t( 1), gtint_t( 2)), // stride size for x
::testing::Values(AOCL_NAN, -AOCL_INF, AOCL_INF, 1 /*,0 <-fail*/),// exception value for x
::testing::Values(AOCL_NAN, -AOCL_INF, AOCL_INF 0), // exception value for A
::testing::Values(gtint_t(0), gtint_t(10)) // increment to the leading dim of a
),
::dtrsvEVTPrint()
);

View File

@@ -35,17 +35,18 @@
#include <gtest/gtest.h>
#include "test_trsv.h"
class dtrsvTest :
public ::testing::TestWithParam<std::tuple<char,
char,
char,
char,
gtint_t,
double,
gtint_t,
gtint_t>> {};
class dtrsvAPI :
public ::testing::TestWithParam<std::tuple<char, // storage format
char, // uplo
char, // trans
char, // diag
gtint_t, // n
double, // alpha
gtint_t, // incx
gtint_t, // ld_inc
bool>> {}; // is memory test
TEST_P(dtrsvTest, RandomData)
TEST_P(dtrsvAPI, FunctionalTest)
{
using T = double;
//----------------------------------------------------------
@@ -54,9 +55,9 @@ TEST_P(dtrsvTest, RandomData)
//----------------------------------------------------------
// matrix storage format(row major, column major)
char storage = std::get<0>(GetParam());
// denotes whether matrix a is u,l
// denotes whether matrix A is u,l
char uploa = std::get<1>(GetParam());
// denotes whether matrix a is n,c,t,h
// denotes whether matrix A is n,c,t,h
char transa = std::get<2>(GetParam());
// denotes whether matrix diag is u,n
char diaga = std::get<3>(GetParam());
@@ -64,12 +65,13 @@ TEST_P(dtrsvTest, RandomData)
gtint_t n = std::get<4>(GetParam());
// specifies alpha value
T alpha = std::get<5>(GetParam());
// stride size for x:
// increment for x(incx):
gtint_t incx = std::get<6>(GetParam());
// lda increment.
// If increment is zero, then the array size matches the matrix size.
// If increment are nonnegative, the array size is bigger than the matrix size.
gtint_t lda_inc = std::get<7>(GetParam());
bool is_mem_test = std::get<8>(GetParam());
// Set the threshold for the errors:
// Check gtestsuite trsv.h or netlib source code for reminder of the
@@ -84,62 +86,80 @@ TEST_P(dtrsvTest, RandomData)
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_trsv<T>( storage, uploa, transa, diaga, n, alpha, lda_inc, incx, thresh );
test_trsv<T>( storage, uploa, transa, diaga, n, alpha, lda_inc, incx, thresh, is_mem_test);
}
class dtrsvTestPrint {
class dtrsvPrint {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,double,gtint_t,gtint_t>> str) const {
char sfm = std::get<0>(str.param);
char uploa = std::get<1>(str.param);
char transa = std::get<2>(str.param);
char diaga = std::get<3>(str.param);
gtint_t n = std::get<4>(str.param);
double alpha = std::get<5>(str.param);
gtint_t incx = std::get<6>(str.param);
gtint_t ld_inc = std::get<7>(str.param);
testing::TestParamInfo<std::tuple<char,char,char,char,gtint_t,double,gtint_t,gtint_t,bool>> str) const {
char sfm = std::get<0>(str.param);
char uploa = std::get<1>(str.param);
char transa = std::get<2>(str.param);
char diaga = std::get<3>(str.param);
gtint_t n = std::get<4>(str.param);
double alpha = std::get<5>(str.param);
gtint_t incx = std::get<6>(str.param);
gtint_t ld_inc = std::get<7>(str.param);
bool is_mem_test = std::get<8>(str.param);
#ifdef TEST_BLAS
std::string str_name = "dtrsv_";
std::string str_name = "blas_";
#elif TEST_CBLAS
std::string str_name = "cblas_dtrsv";
std::string str_name = "cblas_";
#else //#elif TEST_BLIS_TYPED
std::string str_name = "bli_dtrsv";
std::string str_name = "bli_";
#endif
str_name = str_name + "_" + sfm;
str_name = str_name + "_" + uploa+transa;
str_name = str_name + "_d" + diaga;
str_name = str_name + "_" + std::to_string(n);
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;
str_name = str_name + "stor_" + sfm;
str_name = str_name + "_uplo_" + uploa;
str_name = str_name + "_transa_" + transa;
str_name = str_name + "_diaga_" + diaga;
str_name = str_name + "_n_" + std::to_string(n);
std::string alpha_str = testinghelpers::get_value_string(alpha);
str_name = str_name + "_alpha_" + alpha_str;
std::string incx_str = ( incx > 0) ? std::to_string(incx) : "m" + std::to_string(std::abs(incx));
str_name = str_name + "_" + incx_str;
str_name = str_name + "_" + std::to_string(ld_inc);
str_name = str_name + "_incx_" + incx_str;
str_name = str_name + "_lda_" + std::to_string(
testinghelpers::get_leading_dimension( sfm, transa, n, n, ld_inc )
);
str_name = str_name + (is_mem_test ? "_mem_test_enabled" : "_mem_test_disabled");
return str_name;
}
};
// Black box testing.
INSTANTIATE_TEST_SUITE_P(
Blackbox,
dtrsvTest,
Native,
dtrsvAPI,
::testing::Combine(
::testing::Values('c'
#ifndef TEST_BLAS
,'r'
,'r'
#endif
), // storage format
::testing::Values('u','l'), // uploa
::testing::Values('n','t'), // transa
::testing::Values('n','u'), // diaga , n=NONUNIT_DIAG u=UNIT_DIAG
::testing::Range(gtint_t(10), gtint_t(31), 10), // n
::testing::Values( 1.0
#ifdef TEST_BLIS_TYPED
, -2.0
::testing::Values(gtint_t(32),
gtint_t(24),
gtint_t(8),
gtint_t(4),
gtint_t(2),
gtint_t(1),
gtint_t(15),
gtint_t(98),
gtint_t(173),
gtint_t(211)
), // n
::testing::Values( 1.0 // Only blis types api supports
#ifdef TEST_BLIS_TYPED // values of alpha other than 1
, -2.2, 5.4, -1.0, 0.0
#endif
), // alpha
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(gtint_t(0), gtint_t(2)) // increment to the leading dim of a
::testing::Values(gtint_t(-153), gtint_t(-10),
gtint_t(-2), gtint_t(-1),
gtint_t( 1), gtint_t( 2),
gtint_t(14), gtint_t(433)), // incx
::testing::Values(gtint_t(0), gtint_t(10), gtint_t(358)), // increment to the leading dim of a
::testing::Values(false, true) // is memory test
),
::dtrsvTestPrint()
::dtrsvPrint()
);

View File

@@ -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,10 +39,24 @@
#include "inc/check_error.h"
#include <stdexcept>
#include <algorithm>
#include "common/testing_helpers.h"
template<typename T>
void test_trsv( char storage, char uploa, char transa, char diaga, gtint_t n,
T alpha, gtint_t lda_inc, gtint_t incx, double thresh )
void test_trsv(
char storage,
char uploa,
char transa,
char diaga,
gtint_t n,
T alpha,
gtint_t lda_inc,
gtint_t incx,
double thresh,
bool is_memory_test = false,
bool is_evt_test = false,
T evt_x = T{0},
T evt_a = T{0}
)
{
// Compute the leading dimensions for matrix size calculation.
gtint_t lda = testinghelpers::get_leading_dimension( storage, transa, n, n, lda_inc );
@@ -50,25 +64,85 @@ void test_trsv( char storage, char uploa, char transa, char diaga, gtint_t n,
//----------------------------------------------------------
// Initialize matrics with random integer numbers.
//----------------------------------------------------------
std::vector<T> a = testinghelpers::get_random_matrix<T>( 1, 5, storage, transa, n, n, lda );
std::vector<T> x = testinghelpers::get_random_vector<T>( 1, 3, n, incx );
testinghelpers::make_triangular<T>( storage, uploa, n, a.data(), lda );
dim_t size_a = testinghelpers::matsize(storage, transa, n, n, lda) * sizeof(T);
// Create a copy of c so that we can check reference results.
std::vector<T> x_ref(x);
// Buffers for A matrix and X vector are always unaligned
testinghelpers::ProtectedBuffer a(size_a, false, is_memory_test );
testinghelpers::datagenerators::randomgenerators<T>( 1, 5, storage, n, n, (T*)(a.greenzone_1), transa, lda );
dim_t size_x = testinghelpers::buff_dim(n, incx) * sizeof(T);
testinghelpers::ProtectedBuffer x(size_x, false, is_memory_test );
testinghelpers::datagenerators::randomgenerators<T>( 1, 3, n, incx, (T*)(x.greenzone_1) );
T* a_ptr = (T*)(a.greenzone_1);
T* x_ptr = (T*)(x.greenzone_1);
// Make A matix diagonal dominant to make sure that algorithm doesn't diverge
// This makes sure that the TRSV problem is solvable
for ( dim_t a_dim = 0; a_dim < n; ++a_dim )
{
a_ptr[ a_dim + (a_dim* lda) ] = a_ptr[ a_dim + (a_dim* lda) ] * T{10};
}
// add extreme values to the X vector
if ( is_evt_test )
{
x_ptr[ (rand() % n) * std::abs(incx) ] = evt_x;
}
// add extreme values to the A matrix
if ( is_evt_test )
{
dim_t n_idx = rand() % n;
dim_t m_idx = std::max((dim_t)0, n_idx - 1);
a_ptr[ m_idx + (n_idx * lda) ] = evt_a;
a_ptr[ m_idx + (m_idx *lda) ] = evt_a;
}
// skipped making A triangular
// A matrix being a non triangular matrix could be a better test
// because we are exepcted to read only from the upper or lower triangular
// part of the data, contents of the rest of the matrix should not change the
// result.
// testinghelpers::make_triangular<T>( storage, uploa, n, a_ptr, lda );
// Create a copy of x so that we can check reference results.
std::vector<T> x_ref(testinghelpers::buff_dim(n, incx));
memcpy(x_ref.data(), x_ptr, size_x);
//----------------------------------------------------------
// Call BLIS function
//----------------------------------------------------------
trsv<T>( storage, uploa, transa, diaga, n, &alpha, a.data(), lda, x.data(), incx );
// add signal handler for segmentation fault
testinghelpers::ProtectedBuffer::start_signal_handler();
try
{
trsv<T>( storage, uploa, transa, diaga, n, &alpha, a_ptr, lda, x_ptr, incx );
if (is_memory_test)
{
memcpy(a.greenzone_2, a.greenzone_1, size_a);
memcpy(x.greenzone_2, x_ref.data(), size_x);
trsv<T>( storage, uploa, transa, diaga, n, &alpha, (T*)a.greenzone_2, lda, (T*)x.greenzone_2, incx );
}
}
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_trsv<T>( storage, uploa, transa, diaga, n, &alpha, a.data(), lda, x_ref.data(), incx );
testinghelpers::ref_trsv<T>( storage, uploa, transa, diaga, n, &alpha, a_ptr, lda, x_ref.data(), incx );
//----------------------------------------------------------
// check component-wise error.
//----------------------------------------------------------
computediff<T>( n, x.data(), x_ref.data(), incx, thresh );
computediff<T>( n, x_ptr, x_ref.data(), incx, thresh, is_evt_test );
}