From 51e1bfc1f1ccee22ccb87229cc9dadfe34f3b421 Mon Sep 17 00:00:00 2001 From: Harsh Dave Date: Mon, 11 Mar 2024 14:05:00 +0530 Subject: [PATCH] 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 --- .../testinghelpers/inc/level1/ref_dotxf.h | 57 +++++++ .../testinghelpers/src/level1/ref_dotxf.cpp | 146 ++++++++++++++++++ .../testsuite/level1/dotxf/ddotxf_generic.cpp | 141 +++++++++++++++++ gtestsuite/testsuite/level1/dotxf/dotxf.h | 115 ++++++++++++++ .../testsuite/level1/dotxf/test_dotxf.h | 89 +++++++++++ 5 files changed, 548 insertions(+) create mode 100644 gtestsuite/testinghelpers/inc/level1/ref_dotxf.h create mode 100644 gtestsuite/testinghelpers/src/level1/ref_dotxf.cpp create mode 100644 gtestsuite/testsuite/level1/dotxf/ddotxf_generic.cpp create mode 100644 gtestsuite/testsuite/level1/dotxf/dotxf.h create mode 100644 gtestsuite/testsuite/level1/dotxf/test_dotxf.h diff --git a/gtestsuite/testinghelpers/inc/level1/ref_dotxf.h b/gtestsuite/testinghelpers/inc/level1/ref_dotxf.h new file mode 100644 index 000000000..70c3aa93f --- /dev/null +++ b/gtestsuite/testinghelpers/inc/level1/ref_dotxf.h @@ -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 +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 diff --git a/gtestsuite/testinghelpers/src/level1/ref_dotxf.cpp b/gtestsuite/testinghelpers/src/level1/ref_dotxf.cpp new file mode 100644 index 000000000..5d05f5bdb --- /dev/null +++ b/gtestsuite/testinghelpers/src/level1/ref_dotxf.cpp @@ -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 +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 + ( + conja, + conjx, + m, + *alpha, + a1, inca, + x1, incx, + *beta, + psi1 + ); + } + } + +template void ref_dotxf( + 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( + 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( + 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( + 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 + ); +} + + diff --git a/gtestsuite/testsuite/level1/dotxf/ddotxf_generic.cpp b/gtestsuite/testsuite/level1/dotxf/ddotxf_generic.cpp new file mode 100644 index 000000000..93482e71a --- /dev/null +++ b/gtestsuite/testsuite/level1/dotxf/ddotxf_generic.cpp @@ -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 +#include "test_dotxf.h" + +class ddotxffGenericTest : + public ::testing::TestWithParam> {}; +// 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( 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> 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() + ); + diff --git a/gtestsuite/testsuite/level1/dotxf/dotxf.h b/gtestsuite/testsuite/level1/dotxf/dotxf.h new file mode 100644 index 000000000..9b8563693 --- /dev/null +++ b/gtestsuite/testsuite/level1/dotxf/dotxf.h @@ -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 +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::value) + bli_sdotxf(conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy); + else if constexpr (std::is_same::value) + bli_ddotxf( conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy ); + else if constexpr (std::is_same::value) + bli_cdotxf( conj_a, conj_x, m, b, alpha, A, inca, lda, x, incx, beta, y, incy ); + else if constexpr (std::is_same::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 +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(std::toupper(static_cast(conja))); + conjx = static_cast(std::toupper(static_cast(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( + conja, + conjx, + m, + b, + alpha, + A, + inca, + lda, + x, + incx, + beta, + y, + incy ); +} diff --git a/gtestsuite/testsuite/level1/dotxf/test_dotxf.h b/gtestsuite/testsuite/level1/dotxf/test_dotxf.h new file mode 100644 index 000000000..b6ba34ea1 --- /dev/null +++ b/gtestsuite/testsuite/level1/dotxf/test_dotxf.h @@ -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 +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 A = testinghelpers::get_random_matrix( -2, 8, 'c', 'n', m, b, lda ); + + std::vector x = testinghelpers::get_random_vector( -10, 10, m, incx ); + std::vector y = testinghelpers::get_random_vector( -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 y_ref(y); + + testinghelpers::ref_dotxf( conja, conjx, m, b, alpha, A.data(), inca, lda, x.data(), incx, beta, y_ref.data(), incy ); + + //---------------------------------------------------------- + // Call BLIS function. + //---------------------------------------------------------- + dotxf( conja, conjx, m, b, alpha, A.data(), inca, lda, x.data(), incx, beta, y.data(), incy ); + + //--------------------------------------------------------- + // Compute component-wise error. + //---------------------------------------------------------- + double thresh = testinghelpers::getEpsilon(); + computediff( m, y.data(), y_ref.data(), incy, thresh, true ); +}