Added dotxf reference implementation for gtestsuite

- dotxf is a blis specific kernel, which performs dotxv 
operation but in multiple of fused factors to speed up
the operations.

- So dotxf reference function is implemented for gtestsuite,
where dotxf computation compared against computation done by
looping over dotxv function.

AMD-Internal: [CPUPL-4764]
Change-Id: I342dab066ceb1710649e54bb73afc5a23e2a8177
This commit is contained in:
Harsh Dave
2024-03-11 14:05:00 +05:30
parent 8f60c9ff6b
commit 51e1bfc1f1
5 changed files with 548 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
/*
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.
*/
#pragma once
#include "common/testing_helpers.h"
namespace testinghelpers {
template<typename T>
void ref_dotxf( conj_t conja,
conj_t conjx,
gint_t m,
gint_t b_n,
T *alpha,
T* a,
gint_t inca,
gint_t lda,
T* x,
gint_t incx,
T *beta,
T* y,
gint_t incy
);
} //end of namespace testinghelpers

View File

@@ -0,0 +1,146 @@
/*
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 "blis.h"
#include "level1/ref_dotxv.h"
#include "level1/ref_dotxf.h"
/**
* dotxf operation is defined as :
* y := y + alpha * conja(A) * conjx(x)
* where A is an m x b matrix, and y and x are vectors.
*/
namespace testinghelpers {
template<typename T>
void ref_dotxf( conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
T *alpha,
T* A,
gint_t inca,
gint_t lda,
T* x,
gint_t incx,
T * beta,
T* y,
gint_t incy
)
{
for ( dim_t i = 0; i < b; ++i )
{
T* a1 = A + (0 )*inca + (i )*lda;
T* x1 = x + (0 )*incx;
T* psi1 = y + (i )*incy;
testinghelpers::ref_dotxv<T>
(
conja,
conjx,
m,
*alpha,
a1, inca,
x1, incx,
*beta,
psi1
);
}
}
template void ref_dotxf<double>(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
double *alpha,
double* A,
gint_t inca,
gint_t lda,
double* x,
gint_t incx,
double *beta,
double* y,
gint_t incy
);
template void ref_dotxf<float>(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
float *alpha,
float* A,
gint_t inca,
gint_t lda,
float* x,
gint_t incx,
float *beta,
float* y,
gint_t incy
);
template void ref_dotxf<scomplex>(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
scomplex *alpha,
scomplex* A,
gint_t inca,
gint_t lda,
scomplex* x,
gint_t incx,
scomplex *beta,
scomplex* y,
gint_t incy
);
template void ref_dotxf<dcomplex>(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
dcomplex *alpha,
dcomplex* A,
gint_t inca,
gint_t lda,
dcomplex* x,
gint_t incx,
dcomplex *beta,
dcomplex* y,
gint_t incy
);
}

View File

@@ -0,0 +1,141 @@
/*
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_dotxf.h"
class ddotxffGenericTest :
public ::testing::TestWithParam<std::tuple<char, // conj_x
char, // conj_a
gtint_t, // m
gtint_t, // b
double, // alpha
gtint_t, // inca
gtint_t, // lda
gtint_t, // incx
double, // beta
gtint_t // incy
>> {};
// Tests using random integers as vector elements.
TEST_P( ddotxffGenericTest, FunctionalTest )
{
using T = double;
//----------------------------------------------------------
// Initialize values from the parameters passed through
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
//----------------------------------------------------------
char conj_x = std::get<0>(GetParam());
conj_t conjx;
testinghelpers::char_to_blis_conj( conj_x, &conjx );
char conj_a = std::get<1>(GetParam());
conj_t conja;
testinghelpers::char_to_blis_conj( conj_a, &conja );
gint_t m = std::get<2>(GetParam());
gint_t b = std::get<3>(GetParam());
T alpha = std::get<4>(GetParam());
// stride size for x:
gtint_t inca = std::get<5>(GetParam());
// stride size for y:
gtint_t lda = std::get<6>(GetParam());
gtint_t incx = std::get<7>(GetParam());
T beta = std::get<8>(GetParam());
gtint_t incy = std::get<9>(GetParam());
//----------------------------------------------------------
// Call generic test body using those parameters
//----------------------------------------------------------
test_dotxf<T>( conjx, conja, m, b, &alpha, inca, lda, incx, &beta, incy );
}
// Test-case logger : Used to print the test-case details
class ddotxfGenericTestPrint {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<char,
char,
gtint_t,
gtint_t,
double,
gtint_t,
gtint_t,
gtint_t,
double,
gtint_t>> str) const {
char conja = std::get<0>(str.param);
char conjx = std::get<1>(str.param);
gtint_t m = std::get<2>(str.param);
gtint_t b = std::get<3>(str.param);
double alpha = std::get<4>(str.param);
gtint_t incx = std::get<7>(str.param);
double beta = std::get<8>(str.param);
gtint_t incy = std::get<9>(str.param);
std::string str_name = "bli_";
str_name += ( conja == 'n' )? "_conja_n" : "_conja_t";
str_name += ( conjx == 'n' )? "_conjx_n" : "_conjx_t";
str_name += "_m" + std::to_string(m);
str_name += "_b" + std::to_string(b);
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;
std::string incx_str = ( incx >= 0) ? std::to_string(incx) : "m" + std::to_string(std::abs(incx));
str_name += "_incx" + incx_str;
std::string incy_str = ( incy >= 0) ? std::to_string(incy) : "m" + std::to_string(std::abs(incy));
str_name += "_incy" + incy_str;
return str_name;
}
};
// Black box testing for generic and main use of ddotxf.
INSTANTIATE_TEST_SUITE_P(
FunctionalTest,
ddotxffGenericTest,
::testing::Combine(
::testing::Values('n'), // n: use x, not conj(x) (since it is real)
::testing::Values('n'), // n: use x, not conj(x) (since it is real)
::testing::Range(gtint_t(10), gtint_t(101), 10), // m size of matrix
::testing::Range(gtint_t(6), gtint_t(10), 1), // b size of matrix
::testing::Values(double(0.0), double(1.0), double(2.3)), // alpha
::testing::Values(gtint_t(0)), // lda increament
::testing::Values(gtint_t(1)), // stride size for a
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(double(0.0), double(1.0)), // beta
::testing::Values(gtint_t(1)) // stride size for y
),
::ddotxfGenericTestPrint()
);

View File

@@ -0,0 +1,115 @@
/*
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.
*/
#pragma once
#include "blis.h"
#include "common/testing_helpers.h"
template<typename T>
static void typed_dotxf(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
T *alpha,
T* A,
gint_t inca,
gint_t lda,
T* x,
gint_t incx,
T *beta,
T* y,
gint_t incy)
{
conj_t conj_a;
conj_t conj_x;
// Map parameter characters to BLIS constants.
testinghelpers::char_to_blis_conj( conja, &conj_a );
testinghelpers::char_to_blis_conj( conjx, &conj_x );
if constexpr (std::is_same<T, float>::value)
bli_sdotxf(conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy);
else if constexpr (std::is_same<T, double>::value)
bli_ddotxf( conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy );
else if constexpr (std::is_same<T, scomplex>::value)
bli_cdotxf( conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy );
else if constexpr (std::is_same<T, dcomplex>::value)
bli_zdotxf( conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy );
else
throw std::runtime_error("Error in testsuite/level1/dotv.h: Invalid typename in typed_dotv().");
}
template<typename T>
static void dotxf(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
T *alpha,
T* A,
gint_t inca,
gint_t lda,
T* x,
gint_t incx,
T *beta,
T* y,
gint_t incy
)
{
#ifdef TEST_UPPERCASE_ARGS
conja = static_cast<char>(std::toupper(static_cast<unsigned char>(conja)));
conjx = static_cast<char>(std::toupper(static_cast<unsigned char>(conjx)));
#endif
/**
* dotxf operation is defined as :
* y := y + alpha * conja(A) * conjx(x)
* where A is an m x b matrix, and y and x are vectors.
*/
typed_dotxf<T>(
conja,
conjx,
m,
b,
alpha,
A,
inca,
lda,
x,
incx,
beta,
y,
incy );
}

View File

@@ -0,0 +1,89 @@
/*
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.
*/
#pragma once
#include "dotxf.h"
#include "level1/ref_dotxf.h"
#include "inc/check_error.h"
template<typename T>
static void test_dotxf(
conj_t conja,
conj_t conjx,
gint_t m,
gint_t b,
T *alpha,
gint_t inca,
gint_t lda_inc,
gint_t incx,
T *beta,
gint_t incy
)
{
//----------------------------------------------------------
// Initialize vectors with random numbers.
//----------------------------------------------------------
// Compute the leading dimensions of a, b, and c.
gtint_t lda = testinghelpers::get_leading_dimension( 'c', 'n', m, b, lda_inc );
//----------------------------------------------------------
// Initialize matrics with random numbers
//----------------------------------------------------------
std::vector<T> A = testinghelpers::get_random_matrix<T>( -2, 8, 'c', 'n', m, b, lda );
std::vector<T> x = testinghelpers::get_random_vector<T>( -10, 10, m, incx );
std::vector<T> y = testinghelpers::get_random_vector<T>( -10, 10, m, incy );
//----------------------------------------------------------
// Call reference implementation to get ref results.
//----------------------------------------------------------
// Create a copy of y so that we can check reference results.
std::vector<T> y_ref(y);
testinghelpers::ref_dotxf<T>( conja, conjx, m, b, alpha, A.data(), inca, lda, x.data(), incx, beta, y_ref.data(), incy );
//----------------------------------------------------------
// Call BLIS function.
//----------------------------------------------------------
dotxf<T>( conja, conjx, m, b, alpha, A.data(), inca, lda, x.data(), incx, beta, y.data(), incy );
//---------------------------------------------------------
// Compute component-wise error.
//----------------------------------------------------------
double thresh = testinghelpers::getEpsilon<T>();
computediff<T>( m, y.data(), y_ref.data(), incy, thresh, true );
}