Added functionality tests for ?NRM2 micro-kernels

- Added unit-test cases for the following AVX2 kernels:
   - bli_snorm2fv_unb_var1_avx2( ... )
   - bli_scnorm2fv_unb_var1_avx2( ... )
   - bli_dnorm2fv_unb_var1_avx2( ... )
   - bli_dznorm2fv_unb_var1_avx2( ... )

- Defined a templatized testing interface and function-pointer
  type. This is used as part of the test-fixture class and
  testsuite definitions, when writing the unit tests.

- The test cases cover the necessary range of values for the sizes
  to ensure code-coverage in the kernels.

- Further added memory tests for these kernels, to check for
  out-of-bounds reads/writes.

AMD-Internal: [CPUPL-4637]
Change-Id: I747ab104b947e87b5f8eda597256b7b8b6f7c2f2
This commit is contained in:
Vignesh Balasubramanian
2024-02-23 16:27:52 +05:30
committed by Vignesh Balasubramanian
parent a5ad1f55d1
commit deea4c611c
5 changed files with 681 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
/*
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_nrm2_ukr.h"
using T = double;
using RT = typename testinghelpers::type_info<T>::real_type;
class dnrm2Ukr :
public ::testing::TestWithParam<std::tuple<nrm2_ker_ft<T, RT>, // Kernel pointer type
gtint_t, // n
gtint_t, // incx
bool>> {}; // is_memory_test
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(dnrm2Ukr);
TEST_P( dnrm2Ukr, AccuracyCheck )
{
//----------------------------------------------------------
// Initialize values from the parameters passed through
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
//----------------------------------------------------------
nrm2_ker_ft<T, RT> ukr_fp = std::get<0>(GetParam());
// vector length
gtint_t n = std::get<1>(GetParam());
// stride size for x
gtint_t incx = std::get<2>(GetParam());
// is_memory_test
bool is_memory_test = std::get<3>(GetParam());
// Set the threshold for the errors:
double thresh = std::sqrt(n)*testinghelpers::getEpsilon<T>();
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_nrm2_ukr<T, RT>( ukr_fp, n, incx, thresh, is_memory_test );
}
// Prints the test case combination
class dnrm2UkrPrint {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<nrm2_ker_ft<T, RT>, gtint_t, gtint_t, bool>> str) const {
gtint_t n = std::get<1>(str.param);
gtint_t incx = std::get<2>(str.param);
bool is_memory_test = std::get<3>(str.param);
std::string str_name = "n" + std::to_string(n);
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 += ( is_memory_test ) ? "_mem_test_enabled" : "_mem_test_disabled";
return str_name;
}
};
#if defined(BLIS_KERNELS_ZEN) && defined(GTEST_AVX2FMA3)
/*
Unit testing for functionality of bli_dnorm2fv_unb_var1_avx2 kernel.
The code structure for bli_dnorm2fv_unb_var1_avx2( ... ) is as follows :
For unit strides :
Main loop : In blocks of 8 --> L8
Fringe loops : In blocks of 4 --> L4
Element-wise loop --> LScalar
For non-unit strides : A single loop, to process element wise.
*/
// Unit testing with unit strides, across all loops.
INSTANTIATE_TEST_SUITE_P(
bli_dnorm2fv_unb_var1_avx2_unitStrides,
dnrm2Ukr,
::testing::Combine(
::testing::Values(bli_dnorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(8), // size n, for L8
gtint_t(4), // L4
gtint_t(3), // 3(LScalar)
gtint_t(40), // 5*L8
gtint_t(43), // 5*L8 + 3(LScalar)
gtint_t(44), // 5*L8 + L4
gtint_t(47)), // 5*L8 + L4 + 3(LScalar)
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::dnrm2UkrPrint()
);
// Unit testing with non-unit strides.
INSTANTIATE_TEST_SUITE_P(
bli_dnorm2fv_unb_var1_avx2_nonUnitStrides,
dnrm2Ukr,
::testing::Combine(
::testing::Values(bli_dnorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(25), // n, size of the vector
gtint_t(41),
gtint_t(17),
gtint_t(9)),
::testing::Values(gtint_t(3), gtint_t(5)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::dnrm2UkrPrint()
);
#endif

View File

@@ -0,0 +1,138 @@
/*
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_nrm2_ukr.h"
using T = dcomplex;
using RT = typename testinghelpers::type_info<T>::real_type;
class dznrm2UkrTest :
public ::testing::TestWithParam<std::tuple<nrm2_ker_ft<T, RT>, // Kernel pointer type
gtint_t, // n
gtint_t, // incx
bool>> {}; // is_memory_test
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(dznrm2UkrTest);
TEST_P( dznrm2UkrTest, AccuracyCheck )
{
//----------------------------------------------------------
// Initialize values from the parameters passed through
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
//----------------------------------------------------------
nrm2_ker_ft<T, RT> ukr_fp = std::get<0>(GetParam());
// vector length
gtint_t n = std::get<1>(GetParam());
// stride size for x
gtint_t incx = std::get<2>(GetParam());
// is_memory_test
bool is_memory_test = std::get<3>(GetParam());
// Set the threshold for the errors:
double thresh = std::sqrt(n)*testinghelpers::getEpsilon<T>();
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_nrm2_ukr<T, RT>( ukr_fp, n, incx, thresh, is_memory_test );
}
// Prints the test case combination
class dznrm2Ukr {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<nrm2_ker_ft<T, RT>, gtint_t, gtint_t, bool>> str) const {
gtint_t n = std::get<1>(str.param);
gtint_t incx = std::get<2>(str.param);
bool is_memory_test = std::get<3>(str.param);
std::string str_name = "n" + std::to_string(n);
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 += ( is_memory_test ) ? "_mem_test_enabled" : "_mem_test_disabled";
return str_name;
}
};
#if defined(BLIS_KERNELS_ZEN) && defined(GTEST_AVX2FMA3)
/*
Unit testing for functionality of bli_dznorm2fv_unb_var1_avx2 kernel.
The code structure for bli_dznorm2fv_unb_var1_avx2( ... ) is as follows :
For unit strides :
Main loop : In blocks of 4 --> L4
Fringe loops : In blocks of 2 --> L2
Element-wise loop --> LScalar
For non-unit strides : A single loop, to process element wise.
*/
// Unit testing with unit strides, across all loops.
INSTANTIATE_TEST_SUITE_P(
bli_dznorm2fv_unb_var1_avx2_unitStrides,
dznrm2UkrTest,
::testing::Combine(
::testing::Values(bli_dznorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(4), // size n, for L4
gtint_t(2), // L2
gtint_t(1), // 1(LScalar)
gtint_t(40), // 10*L4
gtint_t(41), // 10*L4 + 1(LScalar)
gtint_t(42), // 10*L4 + L2
gtint_t(43)), // 10*L4 + L2 + 1(LScalar)
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::dznrm2Ukr()
);
// Unit testing with non-unit strides.
INSTANTIATE_TEST_SUITE_P(
bli_dznorm2fv_unb_var1_avx2_nonUnitStrides,
dznrm2UkrTest,
::testing::Combine(
::testing::Values(bli_dznorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(25), // n, size of the vector
gtint_t(41),
gtint_t(17),
gtint_t(9)),
::testing::Values(gtint_t(3), gtint_t(5)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::dznrm2Ukr()
);
#endif

View File

@@ -0,0 +1,139 @@
/*
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_nrm2_ukr.h"
using T = scomplex;
using RT = typename testinghelpers::type_info<T>::real_type;
class scnrm2Ukr :
public ::testing::TestWithParam<std::tuple<nrm2_ker_ft<T, RT>, // Kernel pointer type
gtint_t, // n
gtint_t, // incx
bool>> {}; // is_memory_test
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(scnrm2Ukr);
TEST_P( scnrm2Ukr, AccuracyCheck )
{
//----------------------------------------------------------
// Initialize values from the parameters passed through
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
//----------------------------------------------------------
nrm2_ker_ft<T, RT> ukr_fp = std::get<0>(GetParam());
// vector length
gtint_t n = std::get<1>(GetParam());
// stride size for x
gtint_t incx = std::get<2>(GetParam());
// is_memory_test
bool is_memory_test = std::get<3>(GetParam());
// Set the threshold for the errors:
double thresh = std::sqrt(n)*testinghelpers::getEpsilon<T>();
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_nrm2_ukr<T, RT>( ukr_fp, n, incx, thresh, is_memory_test );
}
// Prints the test case combination
class scnrm2UkrPrint {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<nrm2_ker_ft<T, RT>, gtint_t, gtint_t, bool>> str) const {
gtint_t n = std::get<1>(str.param);
gtint_t incx = std::get<2>(str.param);
bool is_memory_test = std::get<3>(str.param);
std::string str_name = "n" + std::to_string(n);
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 += ( is_memory_test ) ? "_mem_test_enabled" : "_mem_test_disabled";
return str_name;
}
};
#if defined(BLIS_KERNELS_ZEN) && defined(GTEST_AVX2FMA3)
/*
Unit testing for functionality of bli_scnorm2fv_unb_var1_avx2 kernel.
The code structure for bli_scnorm2fv_unb_var1_avx2( ... ) is as follows :
For unit strides :
Main loop : In blocks of 16 --> L16
Fringe loops : In blocks of 12 --> L12
In blocks of 8 --> L8
In blocks of 4 --> L4(Currently disabled)
Element-wise loop --> LScalar
NOTE : The code to handle unit-strides is taken only if n >= 64.
For non-unit strides : A single loop, to process element wise.
*/
// Unit testing with unit strides, across all loops.
INSTANTIATE_TEST_SUITE_P(
bli_scnorm2fv_unb_var1_avx2_unitStrides,
scnrm2Ukr,
::testing::Combine(
::testing::Values(bli_scnorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(64), // size n, for L16
gtint_t(76), // 4*L16 + L12
gtint_t(72), // 4*L16 + L8
gtint_t(68), // 4*L16 + L4
gtint_t(67)), // 4*L16 + 3(LScalar)
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::scnrm2UkrPrint()
);
// Unit testing with non-unit strides.
INSTANTIATE_TEST_SUITE_P(
bli_scnorm2fv_unb_var1_avx2_nonUnitStrides,
scnrm2Ukr,
::testing::Combine(
::testing::Values(bli_scnorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(25), // n, size of the vector
gtint_t(41),
gtint_t(17),
gtint_t(9)),
::testing::Values(gtint_t(3), gtint_t(5)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::scnrm2UkrPrint()
);
#endif

View File

@@ -0,0 +1,139 @@
/*
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_nrm2_ukr.h"
using T = float;
using RT = typename testinghelpers::type_info<T>::real_type;
class snrm2Ukr :
public ::testing::TestWithParam<std::tuple<nrm2_ker_ft<T, RT>, // Kernel pointer type
gtint_t, // n
gtint_t, // incx
bool>> {}; // is_memory_test
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(snrm2Ukr);
TEST_P( snrm2Ukr, AccuracyCheck )
{
//----------------------------------------------------------
// Initialize values from the parameters passed through
// test suite instantiation (INSTANTIATE_TEST_SUITE_P).
//----------------------------------------------------------
nrm2_ker_ft<T, RT> ukr_fp = std::get<0>(GetParam());
// vector length
gtint_t n = std::get<1>(GetParam());
// stride size for x
gtint_t incx = std::get<2>(GetParam());
// is_memory_test
bool is_memory_test = std::get<3>(GetParam());
// Set the threshold for the errors:
double thresh = std::sqrt(n)*testinghelpers::getEpsilon<T>();
//----------------------------------------------------------
// Call test body using these parameters
//----------------------------------------------------------
test_nrm2_ukr<T, RT>( ukr_fp, n, incx, thresh, is_memory_test );
}
// Prints the test case combination
class snrm2UkrPrint {
public:
std::string operator()(
testing::TestParamInfo<std::tuple<nrm2_ker_ft<T, RT>, gtint_t, gtint_t, bool>> str) const {
gtint_t n = std::get<1>(str.param);
gtint_t incx = std::get<2>(str.param);
bool is_memory_test = std::get<3>(str.param);
std::string str_name = "n" + std::to_string(n);
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 += ( is_memory_test ) ? "_mem_test_enabled" : "_mem_test_disabled";
return str_name;
}
};
#if defined(BLIS_KERNELS_ZEN) && defined(GTEST_AVX2FMA3)
/*
Unit testing for functionality of bli_snorm2fv_unb_var1_avx2 kernel.
The code structure for bli_snorm2fv_unb_var1_avx2( ... ) is as follows :
For unit strides :
Main loop : In blocks of 32 --> L32
Fringe loops : In blocks of 24 --> L24
In blocks of 16 --> L16
In blocks of 8 --> L8(Currently disabled)
Element-wise loop --> LScalar
NOTE : The code to handle unit-strides is taken only if n >= 64.
For non-unit strides : A single loop, to process element wise.
*/
// Unit testing with unit strides, across all loops.
INSTANTIATE_TEST_SUITE_P(
bli_snorm2fv_unb_var1_avx2_unitStrides,
snrm2Ukr,
::testing::Combine(
::testing::Values(bli_snorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(64), // size n, for L32
gtint_t(88), // 2*L32 + L24
gtint_t(80), // 2*L32 + L16
gtint_t(72), // 2*L32 + L8
gtint_t(71)), // 2*L32 + 7(LScalar)
::testing::Values(gtint_t(1)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::snrm2UkrPrint()
);
// Unit testing with non-unit strides.
INSTANTIATE_TEST_SUITE_P(
bli_snorm2fv_unb_var1_avx2_nonUnitStrides,
snrm2Ukr,
::testing::Combine(
::testing::Values(bli_snorm2fv_unb_var1_avx2), // ukr function
// m size of vector
::testing::Values(// Testing the loops standalone
gtint_t(25), // n, size of the vector
gtint_t(41),
gtint_t(17),
gtint_t(9)),
::testing::Values(gtint_t(3), gtint_t(5)), // stride size for x
::testing::Values(true, false) // is_memory_test
),
::snrm2UkrPrint()
);
#endif

View File

@@ -0,0 +1,127 @@
/*
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 "util/nrm2/nrm2.h"
#include <limits>
#include "util/ref_nrm2.h"
#include "inc/check_error.h"
// Defining the function pointer type for ?norm2fv vectorized kernels
// It is based on two template parameters :
// T : datatype of input vector x
// RT : datatype of output norm
template<typename T, typename RT>
using nrm2_ker_ft = void (*)
(
dim_t n,
T* x, inc_t incx,
RT* norm,
cntx_t* cntx
);
// Function to test the ?norm2fv micro-kernels
// The function is templatized based on the datatype of the input and output operands.
// The first parameter(function pointer) uses these template parameters to take the appropriate type.
template<typename T, typename RT>
static void test_nrm2_ukr( nrm2_ker_ft<T, RT> ukr_fp, gtint_t n, gtint_t incx, double thresh,
bool is_memory_test = false)
{
// Pointers to obtain the required memory.
T *x, *x_copy;
gtint_t size_x = testinghelpers::buff_dim( n, incx ) * sizeof( T );
// Create the objects for the input and output operands
// The kernel does not expect the memory to be aligned
testinghelpers::ProtectedBuffer x_buffer( size_x, false, is_memory_test );
// Creating x_copy, to save the contents of x
testinghelpers::ProtectedBuffer x_copy_buffer( size_x, false, false );
// Acquire the first greenzone for x
x = ( T* )x_buffer.greenzone_1;
x_copy = ( T* )x_copy_buffer.greenzone_1; // For x_copy, there is no greenzone_2
// Initiaize the memory with random data
testinghelpers::datagenerators::randomgenerators( -10, 10, n, incx, x );
// Copying the contents of x to x_copy
memcpy( x_copy, x, size_x );
RT norm = 0.0;
// Add signal handler for segmentation fault
testinghelpers::ProtectedBuffer::start_signal_handler();
try
{
// Call the ukr function.
// This call is made irrespective of is_memory_test.
// This will check for out of bounds access with first redzone(if memory test is true)
// Else, it will just call the ukr function.
ukr_fp( n, x, incx, &norm, NULL );
if ( is_memory_test )
{
// Acquire the pointers near the second redzone
x = ( T* )x_buffer.greenzone_2;
// Copy the data for x from x_copy accordingly
memcpy( x, x_copy, size_x );
norm = 0.0;
ukr_fp( n, x, incx, &norm, NULL );
}
}
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 to get ref results.
//----------------------------------------------------------
RT norm_ref = testinghelpers::ref_nrm2<T>( n, x, incx );
//----------------------------------------------------------
// Compute error.
//----------------------------------------------------------
computediff<RT>( norm, norm_ref, thresh );
}