From 70b57cd16f53aa72cb538d6b5a3d1f1338d7401e Mon Sep 17 00:00:00 2001 From: Vignesh Balasubramanian Date: Thu, 21 Mar 2024 10:59:32 +0530 Subject: [PATCH] Test-case development for ?OMATCOPY APIs - Added test-cases to verify the functional behaviour of the BLAS-extension API ?omatcopy_(). The test-cases cover the following categories for the supported datatypes : - Functional and memory testing. - Negative parameter testing with invalid inputs. - Early return scenarios. - Exception value testing. - Implemented a function to load the reference symbol, based on the choice of the reference library. The function definition is overloaded due to different API standards being exposed by different libraries. AMD-Internal: [CPUPL-4810][SWLCSG-2706] Change-Id: I8dcaeeaa36d392b752eb0685e32583a12ddc4220 --- .../inc/extension/ref_omatcopy.h | 55 ++++ .../src/extension/ref_omatcopy.cpp | 234 +++++++++++++++++ .../extension/omatcopy/comatcopy_evt.cpp | 176 +++++++++++++ .../extension/omatcopy/comatcopy_generic.cpp | 148 +++++++++++ .../extension/omatcopy/domatcopy_evt.cpp | 173 +++++++++++++ .../extension/omatcopy/domatcopy_generic.cpp | 146 +++++++++++ .../testsuite/extension/omatcopy/omatcopy.h | 77 ++++++ .../extension/omatcopy/omatcopy_IIT_ERS.cpp | 241 ++++++++++++++++++ .../extension/omatcopy/somatcopy_evt.cpp | 173 +++++++++++++ .../extension/omatcopy/somatcopy_generic.cpp | 146 +++++++++++ .../extension/omatcopy/test_omatcopy.h | 144 +++++++++++ .../extension/omatcopy/zomatcopy_evt.cpp | 176 +++++++++++++ .../extension/omatcopy/zomatcopy_generic.cpp | 148 +++++++++++ 13 files changed, 2037 insertions(+) create mode 100644 gtestsuite/testinghelpers/inc/extension/ref_omatcopy.h create mode 100644 gtestsuite/testinghelpers/src/extension/ref_omatcopy.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/comatcopy_evt.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/comatcopy_generic.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/domatcopy_evt.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/domatcopy_generic.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/omatcopy.h create mode 100644 gtestsuite/testsuite/extension/omatcopy/omatcopy_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/somatcopy_evt.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/somatcopy_generic.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/test_omatcopy.h create mode 100644 gtestsuite/testsuite/extension/omatcopy/zomatcopy_evt.cpp create mode 100644 gtestsuite/testsuite/extension/omatcopy/zomatcopy_generic.cpp diff --git a/gtestsuite/testinghelpers/inc/extension/ref_omatcopy.h b/gtestsuite/testinghelpers/inc/extension/ref_omatcopy.h new file mode 100644 index 000000000..d6b68e0e7 --- /dev/null +++ b/gtestsuite/testinghelpers/inc/extension/ref_omatcopy.h @@ -0,0 +1,55 @@ +/* + + 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" + +/* + * ========================================================================== + * OMATCOPY performs vector operations + * B := alpha * op(A) + * where A and B are input and output matrices, and alpha is the scaling factor. + * op(A) could be one of the following operations : no-transpose('n'), transpose('t'), + * conjugate('c'), conjugate-transpose('r'). + * ========================================================================== +**/ + +namespace testinghelpers { + +template +void ref_omatcopy( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ); + +} //end of namespace testinghelpers diff --git a/gtestsuite/testinghelpers/src/extension/ref_omatcopy.cpp b/gtestsuite/testinghelpers/src/extension/ref_omatcopy.cpp new file mode 100644 index 000000000..7e826b4fd --- /dev/null +++ b/gtestsuite/testinghelpers/src/extension/ref_omatcopy.cpp @@ -0,0 +1,234 @@ +/* + + 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 "extension/ref_omatcopy.h" + +namespace testinghelpers { + +#if defined(REF_IS_OPENBLAS) + +// Template function to load and call CBLAS call of OpenBLAS ?omatcopy, only for real datatypes +template +void ref_omatcopy_real( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ) { + + // Since CBLAS call does not support plain conjugation, we need to conjugate A + // in case trans == 'r'(only conjugation) + if( trans == 'r' ) + { + gtint_t size_a = testinghelpers::matsize(storage, 'n', m, n, lda); + std::vector A_conj( size_a ); + memcpy( A_conj.data(), A, size_a * sizeof(T) ); + testinghelpers::conj( storage, A_conj.data(), m, n, lda ); + memcpy( A, A_conj.data(), size_a * sizeof(T) ); + trans = 'n'; + } + + enum CBLAS_ORDER cblas_order; + enum CBLAS_TRANSPOSE cblas_trans; + + char_to_cblas_order( storage, &cblas_order ); + char_to_cblas_trans( trans, &cblas_trans ); + + // Defining the function pointer type for CBLAS call of OMATCOPY + typedef void (*Fptr_ref_cblas_omatcopy)( + const CBLAS_ORDER, const CBLAS_TRANSPOSE, + const f77_int, const f77_int, const T, + const T *, const f77_int, const T *, + const f77_int + ); + + // Function pointer to load the CBLAS symbol + Fptr_ref_cblas_omatcopy ref_cblas_omatcopy = nullptr; + + // Call C function + /* Check the typename T passed to this function template and call respective function.*/ + if (typeid(T) == typeid(float)) + { + ref_cblas_omatcopy = (Fptr_ref_cblas_omatcopy)refCBLASModule.loadSymbol("cblas_somatcopy"); + } + else if (typeid(T) == typeid(double)) + { + ref_cblas_omatcopy = (Fptr_ref_cblas_omatcopy)refCBLASModule.loadSymbol("cblas_domatcopy"); + } + + if (!ref_cblas_omatcopy) { + throw std::runtime_error("Error in ref_omatcopy.cpp: Function pointer == 0 -- symbol not found."); + } + + ref_cblas_omatcopy( cblas_order, cblas_trans, m, n, alpha, A, lda, B, ldb ); +} + +// Template function to load and call CBLAS call of OpenBLAS ?omatcopy, only for complex datatypes +template +void ref_omatcopy_complex( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ) { + + // Since CBLAS call does not support plain conjugation, we need to conjugate A + // in case trans == 'r'(only conjugation) + if( trans == 'r' ) + { + gtint_t size_a = testinghelpers::matsize(storage, 'n', m, n, lda); + std::vector A_conj( size_a ); + memcpy( A_conj.data(), A, size_a * sizeof(T) ); + testinghelpers::conj( storage, A_conj.data(), m, n, lda ); + memcpy( A, A_conj.data(), size_a * sizeof(T) ); + trans = 'n'; + } + + // Getting the real-precision of the complex datatype + using RT = typename testinghelpers::type_info::real_type; + + enum CBLAS_ORDER cblas_order; + enum CBLAS_TRANSPOSE cblas_trans; + + char_to_cblas_order( storage, &cblas_order ); + char_to_cblas_trans( trans, &cblas_trans ); + + // Defining the function pointer type for CBLAS call of OMATCOPY + typedef void (*Fptr_ref_cblas_omatcopy)( + const CBLAS_ORDER, const CBLAS_TRANSPOSE, + const f77_int, const f77_int, const RT *, + const RT *, const f77_int, const RT *, + const f77_int + ); + + // Function pointer to load the CBLAS symbol + Fptr_ref_cblas_omatcopy ref_cblas_omatcopy = nullptr; + + // Call C function + /* Check the typename T passed to this function template and call respective function.*/ + if (typeid(T) == typeid(scomplex)) + { + ref_cblas_omatcopy = (Fptr_ref_cblas_omatcopy)refCBLASModule.loadSymbol("cblas_comatcopy"); + } + else if (typeid(T) == typeid(dcomplex)) + { + ref_cblas_omatcopy = (Fptr_ref_cblas_omatcopy)refCBLASModule.loadSymbol("cblas_zomatcopy"); + } + + if (!ref_cblas_omatcopy) { + throw std::runtime_error("Error in ref_omatcopy.cpp: Function pointer == 0 -- symbol not found."); + } + + ref_cblas_omatcopy( cblas_order, cblas_trans, m, n, (RT *)(&alpha), (RT *)A, lda, (RT *)B, ldb ); +} + +template +void ref_omatcopy( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ) { + + // Due to difference in the CBLAS API signature for OpenBLAS ?omatcopy(among real and complex) + // types, we have two different template functions(front-ends), that will be called based on the + // datatype. + if ((typeid(T) == typeid(float)) || (typeid(T) == typeid(double))) + { + ref_omatcopy_real( storage, trans, m, n, alpha, A, lda, B, ldb ); + } + else if ((typeid(T) == typeid(scomplex)) || (typeid(T) == typeid(dcomplex))) + { + ref_omatcopy_complex( storage, trans, m, n, alpha, A, lda, B, ldb ); + } + else + { + throw std::runtime_error("Error in ref_omatcopy.cpp: Invalid typename is passed function template."); + } +} + +#elif defined(REF_IS_MKL) +template +void ref_omatcopy( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ) { + + // Defining the function pointer type for the native MKL call of OMATCOPY + typedef void (*Fptr_ref_mkl_omatcopy)( + char, char, size_t, size_t, + const T, const T *, size_t, + T *, size_t + ); + + // Function pointer to load the MKL symbol + Fptr_ref_mkl_omatcopy ref_mkl_omatcopy = nullptr; + + // Call C function + /* Check the typename T passed to this function template and call respective function.*/ + if (typeid(T) == typeid(float)) + { + ref_mkl_omatcopy = (Fptr_ref_mkl_omatcopy)refCBLASModule.loadSymbol("MKL_Somatcopy"); + } + else if (typeid(T) == typeid(double)) + { + ref_mkl_omatcopy = (Fptr_ref_mkl_omatcopy)refCBLASModule.loadSymbol("MKL_Domatcopy"); + } + else if (typeid(T) == typeid(scomplex)) + { + ref_mkl_omatcopy = (Fptr_ref_mkl_omatcopy)refCBLASModule.loadSymbol("MKL_Comatcopy"); + } + else if (typeid(T) == typeid(dcomplex)) + { + ref_mkl_omatcopy = (Fptr_ref_mkl_omatcopy)refCBLASModule.loadSymbol("MKL_Zomatcopy"); + } + else + { + throw std::runtime_error("Error in ref_omatcopy.cpp: Invalid typename is passed function template."); + } + if (!ref_mkl_omatcopy) { + throw std::runtime_error("Error in ref_omatcopy.cpp: Function pointer == 0 -- symbol not found."); + } + + ref_mkl_omatcopy( storage, trans, m, n, alpha, A, lda, B, ldb ); +} +#else +template +void ref_omatcopy( char storage, char trans, gtint_t m, gtint_t n, T alpha, T* A, + gtint_t lda, T* B, gtint_t ldb ) { + throw std::runtime_error("Error in ref_omatcopy.cpp: The provided reference does not support the required operation."); +} +#endif + +// Explicit template instantiations +#if defined(REF_IS_OPENBLAS) +template void ref_omatcopy_real( char, char, gtint_t, gtint_t, float, float*, gtint_t, float*, gtint_t ); +template void ref_omatcopy_real( char, char, gtint_t, gtint_t, double, double*, gtint_t, double*, gtint_t ); +template void ref_omatcopy_complex( char, char, gtint_t, gtint_t, scomplex, scomplex*, gtint_t, scomplex*, gtint_t ); +template void ref_omatcopy_complex( char, char, gtint_t, gtint_t, dcomplex, dcomplex*, gtint_t, dcomplex*, gtint_t ); +#endif + +template void ref_omatcopy( char, char, gtint_t, gtint_t, float, float*, gtint_t, float*, gtint_t ); +template void ref_omatcopy( char, char, gtint_t, gtint_t, double, double*, gtint_t, double*, gtint_t ); +template void ref_omatcopy( char, char, gtint_t, gtint_t, scomplex, scomplex*, gtint_t, scomplex*, gtint_t ); +template void ref_omatcopy( char, char, gtint_t, gtint_t, dcomplex, dcomplex*, gtint_t, dcomplex*, gtint_t ); + +} //end of namespace testinghelpers diff --git a/gtestsuite/testsuite/extension/omatcopy/comatcopy_evt.cpp b/gtestsuite/testsuite/extension/omatcopy/comatcopy_evt.cpp new file mode 100644 index 000000000..fc33eeee2 --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/comatcopy_evt.cpp @@ -0,0 +1,176 @@ +/* + + 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_omatcopy.h" + +class comatcopyEVT : + public ::testing::TestWithParam> {}; // is_nan_inf_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(comatcopyEVT); + +// Tests using random numbers as vector elements. +TEST_P( comatcopyEVT, NanInfCheck ) +{ + using T = scomplex; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // exval + T exval = std::get<7>(GetParam()); + // is_nan_inf_test + bool is_nan_inf_test = std::get<8>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) && !(std::isnan(alpha.real) || std::isnan(alpha.imag)) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + // Note: is_memory_test is passed as false(hard-coded), since memory tests are done in _generic.cpp files + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, false, is_nan_inf_test, exval ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class comatcopyEVTPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + scomplex alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + scomplex exval = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + str_name = str_name + "_alpha_exval" + testinghelpers::get_value_string(alpha); + str_name = str_name + "_A_exval" + testinghelpers::get_value_string(exval); + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + + return str_name; + } +}; + +static float AOCL_NAN = std::numeric_limits::quiet_NaN(); +static float AOCL_INF = std::numeric_limits::infinity(); + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// EVT testing for comatcopy, with exception values in A matrix +INSTANTIATE_TEST_SUITE_P( + matrixA, + comatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(scomplex{2.3, -3.5}, scomplex{1.0, 0.0}, + scomplex{0.0, 0.0}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(scomplex{AOCL_INF, 0.0}, scomplex{0.0, -AOCL_INF}, + scomplex{0.0, AOCL_NAN}, scomplex{AOCL_NAN, AOCL_INF}), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::comatcopyEVTPrint() + ); + +// EVT testing for comatcopy, with exception values in alpha +INSTANTIATE_TEST_SUITE_P( + alpha, + comatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(scomplex{AOCL_INF, 0.0}, scomplex{0.0, -AOCL_INF}, + scomplex{0.0, AOCL_NAN}, scomplex{AOCL_NAN, AOCL_INF}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(scomplex{0.0, 0.0}), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::comatcopyEVTPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/comatcopy_generic.cpp b/gtestsuite/testsuite/extension/omatcopy/comatcopy_generic.cpp new file mode 100644 index 000000000..cec7649b9 --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/comatcopy_generic.cpp @@ -0,0 +1,148 @@ +/* + + 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_omatcopy.h" + +class comatcopyAPI : + public ::testing::TestWithParam> {}; // is_memory_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(comatcopyAPI); + +// Tests using random numbers as vector elements. +TEST_P( comatcopyAPI, FunctionalTest ) +{ + using T = scomplex; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // is_memory_test + bool is_memory_test = std::get<7>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, is_memory_test ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class comatcopyAPIPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + scomplex alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + bool is_memory_test = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + std::string alpha_str = ( alpha.real >= 0) ? std::to_string(int(alpha.real)) : ("m" + std::to_string(int(std::abs(alpha.real)))); + alpha_str += "pi" + (( alpha.imag >= 0) ? std::to_string(int(alpha.imag)) : ("m" + std::to_string(int(std::abs(alpha.imag))))); + str_name = str_name + "_a" + alpha_str; + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + str_name += ( is_memory_test )? "_mem_test_enabled" : "_mem_test_disabled"; + + return str_name; + } +}; + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// Black box testing for generic and main use of comatcopy. +INSTANTIATE_TEST_SUITE_P( + Blackbox, + comatcopyAPI, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(scomplex{2.3, -3.5}, scomplex{-3.1, 1.7}, + scomplex{1.0, 0.0}, scomplex{0.0, 0.0}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(false, true) // is_memory_test + ), + ::comatcopyAPIPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/domatcopy_evt.cpp b/gtestsuite/testsuite/extension/omatcopy/domatcopy_evt.cpp new file mode 100644 index 000000000..9aafb1cea --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/domatcopy_evt.cpp @@ -0,0 +1,173 @@ +/* + + 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_omatcopy.h" + +class domatcopyEVT : + public ::testing::TestWithParam> {}; // is_nan_inf_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(domatcopyEVT); + +// Tests using random numbers as vector elements. +TEST_P( domatcopyEVT, NanInfCheck ) +{ + using T = double; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // exval + T exval = std::get<7>(GetParam()); + // is_nan_inf_test + bool is_nan_inf_test = std::get<8>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) && !(std::isnan(alpha)) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + // Note: is_memory_test is passed as false(hard-coded), since memory tests are done in _generic.cpp files + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, false, is_nan_inf_test, exval ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class domatcopyEVTPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + double alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + double exval = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + str_name = str_name + "_alpha_exval" + testinghelpers::get_value_string(alpha); + str_name = str_name + "_A_exval" + testinghelpers::get_value_string(exval); + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + + return str_name; + } +}; + +static double AOCL_NAN = std::numeric_limits::quiet_NaN(); +static double AOCL_INF = std::numeric_limits::infinity(); + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// EVT testing for domatcopy, with exception values in A matrix +INSTANTIATE_TEST_SUITE_P( + matrixA, + domatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(2.0, -3.0, 1.0, 0.0), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(AOCL_NAN, AOCL_INF, -AOCL_INF), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::domatcopyEVTPrint() + ); + +// EVT testing for domatcopy, with exception values in alpha +INSTANTIATE_TEST_SUITE_P( + alpha, + domatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(AOCL_NAN, AOCL_INF, -AOCL_INF), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(0.0), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::domatcopyEVTPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/domatcopy_generic.cpp b/gtestsuite/testsuite/extension/omatcopy/domatcopy_generic.cpp new file mode 100644 index 000000000..7a5bbd23f --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/domatcopy_generic.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 +#include "test_omatcopy.h" + +class domatcopyAPI : + public ::testing::TestWithParam> {}; // is_memory_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(domatcopyAPI); + +// Tests using random numbers as vector elements. +TEST_P( domatcopyAPI, FunctionalTest ) +{ + using T = double; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // is_memory_test + bool is_memory_test = std::get<7>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, is_memory_test ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class domatcopyAPIPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + float alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + bool is_memory_test = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + 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; + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + str_name += ( is_memory_test )? "_mem_test_enabled" : "_mem_test_disabled"; + + return str_name; + } +}; + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// Black box testing for generic and main use of domatcopy. +INSTANTIATE_TEST_SUITE_P( + Blackbox, + domatcopyAPI, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(2.0, -3.0, 1.0, 0.0), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(false, true) // is_memory_test + ), + ::domatcopyAPIPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/omatcopy.h b/gtestsuite/testsuite/extension/omatcopy/omatcopy.h new file mode 100644 index 000000000..56803bd1d --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/omatcopy.h @@ -0,0 +1,77 @@ +/* + + 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" + +/** + * @brief Performs the operation: + * B := alpha * op(A), + * where op(A) could be A, A(transpose), A(conjugate), A(conjugate-transpose) + * @param[in] m number of rows in A, number of rows/columns in B + * @param[in] n number of columns in A, number of columns/rows in B + * @param[in] alpha scalar + * @param[in] A pointer which points to the first element of A matrix + * @param[in] lda leading dimension of A matrix + * @param[in, out] B pointer which points to the first element of B matrix + * @param[in] ldb leading dimension of B matrix + */ + +template +static void omatcopy_( char trans, gtint_t m, gtint_t n, T alpha, T* A, gtint_t lda, T* B, gtint_t ldb ) +{ + if constexpr (std::is_same::value) + somatcopy_( &trans, &m, &n, (const float *)&alpha, A, &lda, B, &ldb ); + else if constexpr (std::is_same::value) + domatcopy_( &trans, &m, &n, (const double *)&alpha, A, &lda, B, &ldb ); + else if constexpr (std::is_same::value) + comatcopy_( &trans, &m, &n, (const scomplex *)&alpha, A, &lda, B, &ldb ); + else if constexpr (std::is_same::value) + zomatcopy_( &trans, &m, &n, (const dcomplex *)&alpha, A, &lda, B, &ldb ); + else + throw std::runtime_error("Error in testsuite/level1/omatcopy.h: Invalid typename in omatcopy_()."); +} + +template +static void omatcopy( char trans, gtint_t m, gtint_t n, T alpha, T* A, gtint_t lda, T* B, gtint_t ldb ) +{ +#ifdef TEST_BLAS + omatcopy_( trans, m, n, alpha, A, lda, B, ldb ); +#else + throw std::runtime_error("Error in testsuite/level1/omatcopy.h: No interfaces are set to be tested."); +#endif +} + diff --git a/gtestsuite/testsuite/extension/omatcopy/omatcopy_IIT_ERS.cpp b/gtestsuite/testsuite/extension/omatcopy/omatcopy_IIT_ERS.cpp new file mode 100644 index 000000000..189518edd --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/omatcopy_IIT_ERS.cpp @@ -0,0 +1,241 @@ +/* + + 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_omatcopy.h" +#include "common/wrong_inputs_helpers.h" +#include "common/testing_helpers.h" +#include "inc/check_error.h" + +template +class omatcopy_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; +TYPED_TEST_SUITE(omatcopy_IIT_ERS, TypeParam); + +using namespace testinghelpers::IIT; + +#if defined(TEST_BLAS) + +/* + Incorrect Input Testing(IIT) + + The exceptions get triggered in the following cases: + 1. When TRANS != 'n' || TRANS != 't' || TRANS != 'c' || TRANS != 'r' + 2. When m < 0 + 3. When n < 0 + 4. When lda < max(1, m). + 5. When ldb < max(1, thresh), thresh set based on TRANS value +*/ + +// When TRANS is invalid +TYPED_TEST(omatcopy_IIT_ERS, invalid_transa) +{ + using T = TypeParam; + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDA ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDB ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid value for TRANS value for the operation. + omatcopy( 'Q', M, N, alpha, A.data(), LDA, B.data(), LDB); + // Use bitwise comparison (no threshold). + computediff( 'c', M, N, B.data(), B_ref.data(), LDB ); +} + +// When m < 0 +TYPED_TEST(omatcopy_IIT_ERS, m_lt_zero) +{ + using T = TypeParam; + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDA ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDB ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid m for the operation. + omatcopy( TRANS, -1, N, alpha, A.data(), LDA, B.data(), LDB); + // Use bitwise comparison (no threshold). + computediff( 'c', M, N, B.data(), B_ref.data(), LDB ); +} + +// When n < 0 +TYPED_TEST(omatcopy_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDA ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', M, N, LDB ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid n for the operation. + omatcopy( TRANS, M, -1, alpha, A.data(), LDA, B.data(), LDB); + // Use bitwise comparison (no threshold). + computediff( 'c', M, N, B.data(), B_ref.data(), LDB ); +} + +// When lda < m +TYPED_TEST(omatcopy_IIT_ERS, invalid_lda) +{ + using T = TypeParam; + + // Having different values for m and n + gtint_t m = 5; + gtint_t n = 10; + + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid lda for the operation. + omatcopy( 'n', m, n, alpha, A.data(), m - 1, B.data(), m); + // Use bitwise comparison (no threshold). + computediff( 'c', m, n, B.data(), B_ref.data(), m ); +} + +// When ldb < m, with trans == 'n' +TYPED_TEST(omatcopy_IIT_ERS, invalid_ldb_no_transpose) +{ + using T = TypeParam; + + // Having different values for m and n + gtint_t m = 5; + gtint_t n = 10; + char trans = 'n'; + + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid ldb for the operation. + omatcopy( trans, m, n, alpha, A.data(), m - 1, B.data(), m ); + // Use bitwise comparison (no threshold). + computediff( 'c', m, n, B.data(), B_ref.data(), m ); +} + +// When ldb < m, with trans == 'r' +TYPED_TEST(omatcopy_IIT_ERS, invalid_ldb_conjugate) +{ + using T = TypeParam; + + // Having different values for m and n + gtint_t m = 5; + gtint_t n = 10; + char trans = 'r'; + + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid ldb for the operation. + omatcopy( trans, m, n, alpha, A.data(), m, B.data(), m - 1 ); + // Use bitwise comparison (no threshold). + computediff( 'c', m, n, B.data(), B_ref.data(), m ); +} + +// When ldb < m, with trans == 't' +TYPED_TEST(omatcopy_IIT_ERS, invalid_ldb_transpose) +{ + using T = TypeParam; + + // Having different values for m and n + gtint_t m = 5; + gtint_t n = 10; + char trans = 't'; + + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 't', m, n, n ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid ldb for the operation. + omatcopy( trans, m, n, alpha, A.data(), m, B.data(), n - 1 ); + // Use bitwise comparison (no threshold). + computediff( 'c', n, m, B.data(), B_ref.data(), n ); +} + +// When ldb < m, with trans == 'c' +TYPED_TEST(omatcopy_IIT_ERS, invalid_ldb_conjugate_transpose) +{ + using T = TypeParam; + + // Having different values for m and n + gtint_t m = 5; + gtint_t n = 10; + char trans = 'c'; + + // Defining the A and B matrices with values for debugging purposes + std::vector A = testinghelpers::get_random_matrix(-10, 10, 'c', 'n', m, n, m ); + std::vector B = testinghelpers::get_random_matrix(-10, 10, 'c', 't', m, n, n ); + // Copy so that we check that the elements of B are not modified. + std::vector B_ref(B); + + T alpha; + testinghelpers::initone( alpha ); + + // Call OMATCOPY with a invalid ldb for the operation. + omatcopy( trans, m, n, alpha, A.data(), m, B.data(), n - 1 ); + // Use bitwise comparison (no threshold). + computediff( 'c', n, m, B.data(), B_ref.data(), n ); +} +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/somatcopy_evt.cpp b/gtestsuite/testsuite/extension/omatcopy/somatcopy_evt.cpp new file mode 100644 index 000000000..370a61714 --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/somatcopy_evt.cpp @@ -0,0 +1,173 @@ +/* + + 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_omatcopy.h" + +class somatcopyEVT : + public ::testing::TestWithParam> {}; // is_nan_inf_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(somatcopyEVT); + +// Tests using random numbers as vector elements. +TEST_P( somatcopyEVT, NanInfCheck ) +{ + using T = float; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // exval + T exval = std::get<7>(GetParam()); + // is_nan_inf_test + bool is_nan_inf_test = std::get<8>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) && !(std::isnan(alpha)) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + // Note: is_memory_test is passed as false(hard-coded), since memory tests are done in _generic.cpp files + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, false, is_nan_inf_test, exval ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class somatcopyEVTPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + float alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + float exval = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + str_name = str_name + "_alpha_exval" + testinghelpers::get_value_string(alpha); + str_name = str_name + "_A_exval" + testinghelpers::get_value_string(exval); + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + + return str_name; + } +}; + +static float AOCL_NAN = std::numeric_limits::quiet_NaN(); +static float AOCL_INF = std::numeric_limits::infinity(); + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// EVT testing for somatcopy, with exception values in A matrix +INSTANTIATE_TEST_SUITE_P( + matrixA, + somatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(2.0f, -3.0f, 1.0f, 0.0f), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(AOCL_NAN, AOCL_INF, -AOCL_INF), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::somatcopyEVTPrint() + ); + +// EVT testing for somatcopy, with exception values in alpha +INSTANTIATE_TEST_SUITE_P( + alpha, + somatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(AOCL_NAN, AOCL_INF, -AOCL_INF), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(0.0f), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::somatcopyEVTPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/somatcopy_generic.cpp b/gtestsuite/testsuite/extension/omatcopy/somatcopy_generic.cpp new file mode 100644 index 000000000..2a14e12de --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/somatcopy_generic.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 +#include "test_omatcopy.h" + +class somatcopyAPI : + public ::testing::TestWithParam> {}; // is_memory_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(somatcopyAPI); + +// Tests using random numbers as vector elements. +TEST_P( somatcopyAPI, FunctionalTest ) +{ + using T = float; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // is_memory_test + bool is_memory_test = std::get<7>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, is_memory_test ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class somatcopyAPIPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + float alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + bool is_memory_test = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + 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; + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + str_name += ( is_memory_test )? "_mem_test_enabled" : "_mem_test_disabled"; + + return str_name; + } +}; + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// Black box testing for generic and main use of somatcopy. +INSTANTIATE_TEST_SUITE_P( + Blackbox, + somatcopyAPI, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(2.0f, -3.0f, 1.0f, 0.0f), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(false, true) // is_memory_test + ), + ::somatcopyAPIPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/test_omatcopy.h b/gtestsuite/testsuite/extension/omatcopy/test_omatcopy.h new file mode 100644 index 000000000..1080410f3 --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/test_omatcopy.h @@ -0,0 +1,144 @@ +/* + + 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 "omatcopy.h" +#include "extension/ref_omatcopy.h" +#include "inc/check_error.h" +#include + +/** + * @brief Generic test body for omatcopy operation. + */ + +template +static void test_omatcopy( char storage, char trans, gtint_t m, gtint_t n, T alpha, gtint_t lda_inc, gtint_t ldb_inc, + double thresh, bool is_memory_test = false, bool is_nan_inf_test = false, T exval = T{0.0} ) +{ + // Set an alternative trans value that corresponds to only + // whether the B matrix should be mxn or nxm(only transposing) + char B_trans; + B_trans = ( ( trans == 'n' ) || ( trans == 'r' ) )? 'n' : 't'; + + // Compute the leading dimensions of A and B. + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, B_trans, m, n, ldb_inc ); + + // Compute sizes of A and B, in bytes + gtint_t size_a = testinghelpers::matsize( storage, 'n', m, n, lda ) * sizeof( T ); + gtint_t size_b = testinghelpers::matsize( storage, B_trans, m, n, ldb ) * sizeof( T ); + + // Create the objects for the input and output operands + // The API does not expect the memory to be aligned + testinghelpers::ProtectedBuffer A_buf( size_a, false, is_memory_test ); + testinghelpers::ProtectedBuffer B_buf( size_b, false, is_memory_test ); + testinghelpers::ProtectedBuffer B_ref_buf( size_b, false, false ); + + // Pointers to access the memory chunks + T *A, *B, *B_ref; + + // Acquire the first set of greenzones for A and B + A = ( T* )A_buf.greenzone_1; + B = ( T* )B_buf.greenzone_1; + B_ref = ( T* )B_ref_buf.greenzone_1; // For B_ref, there is no greenzone_2 + + // Initiaize the memory with random data + testinghelpers::datagenerators::randomgenerators( -10, 10, storage, m, n, A, 'n', lda ); + testinghelpers::datagenerators::randomgenerators( -10, 10, storage, m, n, B, B_trans, ldb ); + + if( is_nan_inf_test ) + { + gtint_t rand_m = rand() % m; + gtint_t rand_n = rand() % n; + gtint_t idx = ( storage == 'c' || storage == 'C' )? ( rand_m + rand_n * lda ) : ( rand_n + rand_m * lda ); + + A[idx] = exval; + } + // Copying the contents of B to B_ref + memcpy( B_ref, B, size_b ); + + // Add signal handler for segmentation fault + testinghelpers::ProtectedBuffer::start_signal_handler(); + try + { + // Call the API. + // 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. + omatcopy( trans, m, n, alpha, A, lda, B, ldb); + + if ( is_memory_test ) + { + // Acquire the pointers near the second redzone + A = ( T* )A_buf.greenzone_2; + B = ( T* )B_buf.greenzone_2; + + // Copy the data for A and B accordingly + // NOTE : The objects for A and B will have acquired enough memory + // such that the greenzones in each do not overlap. + memcpy( A, A_buf.greenzone_1, size_a ); + memcpy( B, B_buf.greenzone_1, size_b ); + + // Call the API, to check with the second redzone. + omatcopy( trans, m, n, alpha, A, lda, B, ldb); + } + } + 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. + //---------------------------------------------------------- + testinghelpers::ref_omatcopy( storage, trans, m, n, alpha, A, lda, B_ref, ldb ); + + //---------------------------------------------------------- + // Compute component-wise error. + //---------------------------------------------------------- + + if( B_trans == 'n' ) + computediff( storage, m, n, B, B_ref, ldb, thresh, is_nan_inf_test ); + else + computediff( storage, n, m, B, B_ref, ldb, thresh, is_nan_inf_test ); + +} + diff --git a/gtestsuite/testsuite/extension/omatcopy/zomatcopy_evt.cpp b/gtestsuite/testsuite/extension/omatcopy/zomatcopy_evt.cpp new file mode 100644 index 000000000..0bafeb62e --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/zomatcopy_evt.cpp @@ -0,0 +1,176 @@ +/* + + 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_omatcopy.h" + +class zomatcopyEVT : + public ::testing::TestWithParam> {}; // is_nan_inf_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(zomatcopyEVT); + +// Tests using random numbers as vector elements. +TEST_P( zomatcopyEVT, NanInfCheck ) +{ + using T = dcomplex; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // exval + T exval = std::get<7>(GetParam()); + // is_nan_inf_test + bool is_nan_inf_test = std::get<8>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) && !(std::isnan(alpha.real) || std::isnan(alpha.imag)) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + // Note: is_memory_test is passed as false(hard-coded), since memory tests are done in _generic.cpp files + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, false, is_nan_inf_test, exval ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class zomatcopyEVTPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + dcomplex alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + dcomplex exval = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + str_name = str_name + "_alpha_exval" + testinghelpers::get_value_string(alpha); + str_name = str_name + "_A_exval" + testinghelpers::get_value_string(exval); + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + + return str_name; + } +}; + +static double AOCL_NAN = std::numeric_limits::quiet_NaN(); +static double AOCL_INF = std::numeric_limits::infinity(); + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// EVT testing for zomatcopy, with exception values in A matrix +INSTANTIATE_TEST_SUITE_P( + matrixA, + zomatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(dcomplex{2.3, -3.5}, dcomplex{1.0, 0.0}, + dcomplex{0.0, 0.0}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(dcomplex{AOCL_INF, 0.0}, dcomplex{0.0, -AOCL_INF}, + dcomplex{0.0, AOCL_NAN}, dcomplex{AOCL_NAN, AOCL_INF}), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::zomatcopyEVTPrint() + ); + +// EVT testing for zomatcopy, with exception values in alpha +INSTANTIATE_TEST_SUITE_P( + alpha, + zomatcopyEVT, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(dcomplex{AOCL_INF, 0.0}, dcomplex{0.0, -AOCL_INF}, + dcomplex{0.0, AOCL_NAN}, dcomplex{AOCL_NAN, AOCL_INF}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(dcomplex{0.0, 0.0}), // exval + ::testing::Values(true) // is_nan_inf_test + ), + ::zomatcopyEVTPrint() + ); +#endif diff --git a/gtestsuite/testsuite/extension/omatcopy/zomatcopy_generic.cpp b/gtestsuite/testsuite/extension/omatcopy/zomatcopy_generic.cpp new file mode 100644 index 000000000..36cc06828 --- /dev/null +++ b/gtestsuite/testsuite/extension/omatcopy/zomatcopy_generic.cpp @@ -0,0 +1,148 @@ +/* + + 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_omatcopy.h" + +class zomatcopyAPI : + public ::testing::TestWithParam> {}; // is_memory_test + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(zomatcopyAPI); + +// Tests using random numbers as vector elements. +TEST_P( zomatcopyAPI, FunctionalTest ) +{ + using T = dcomplex; + //---------------------------------------------------------- + // Initialize values from the parameters passed through + // test suite instantiation (INSTANTIATE_TEST_SUITE_P). + //---------------------------------------------------------- + // denotes the storage format of the input matrices + char storage = std::get<0>(GetParam()); + // denotes the trans value for the operation + char trans = std::get<1>(GetParam()); + // m dimension + gtint_t m = std::get<2>(GetParam()); + // n dimension + gtint_t n = std::get<3>(GetParam()); + // alpha + T alpha = std::get<4>(GetParam()); + // lda_inc for A + gtint_t lda_inc = std::get<5>(GetParam()); + // ldb_inc for B + gtint_t ldb_inc = std::get<6>(GetParam()); + // is_memory_test + bool is_memory_test = std::get<7>(GetParam()); + + double thresh = 0.0; + // Set the threshold for the errors + if( ( alpha != testinghelpers::ZERO() || alpha != testinghelpers::ONE() ) ) + thresh = 3 * testinghelpers::getEpsilon(); + + //---------------------------------------------------------- + // Call generic test body using those parameters + //---------------------------------------------------------- + test_omatcopy( storage, trans, m, n, alpha, lda_inc, ldb_inc, thresh, is_memory_test ); +} + +// Test-case logger : Used to print the test-case details based on parameters +// The string format is as follows : +// {blas_/cblas_/bli_}_storage_trans_m_n_alpha_lda_ldb_{mem_test_enabled/mem_test_disabled} +class zomatcopyAPIPrint { +public: + std::string operator()( + testing::TestParamInfo> str) const { + char storage = std::get<0>(str.param); + char trans = std::get<1>(str.param); + gtint_t m = std::get<2>(str.param); + gtint_t n = std::get<3>(str.param); + dcomplex alpha = std::get<4>(str.param); + gtint_t lda_inc = std::get<5>(str.param); + gtint_t ldb_inc = std::get<6>(str.param); + bool is_memory_test = std::get<7>(str.param); +// Currently, BLIS only has the BLAS standard wrapper for this API. +// The CBLAS and BLIS strings are also added here(with macro guards), +// in case we add the CBLAS and BLIS wrappers to the library in future. +#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 += std::string(&storage, 1); + str_name += "_" + std::string(&trans, 1); + str_name += "_" + std::to_string(m); + str_name += "_" + std::to_string(n); + std::string alpha_str = ( alpha.real >= 0) ? std::to_string(int(alpha.real)) : ("m" + std::to_string(int(std::abs(alpha.real)))); + alpha_str += "pi" + (( alpha.imag >= 0) ? std::to_string(int(alpha.imag)) : ("m" + std::to_string(int(std::abs(alpha.imag))))); + str_name = str_name + "_a" + alpha_str; + gtint_t lda = testinghelpers::get_leading_dimension( storage, 'n', m, n, lda_inc ); + gtint_t ldb = testinghelpers::get_leading_dimension( storage, trans, m, n, ldb_inc ); + str_name += "_lda" + std::to_string(lda); + str_name += "_ldb" + std::to_string(ldb); + str_name += ( is_memory_test )? "_mem_test_enabled" : "_mem_test_disabled"; + + return str_name; + } +}; + +#if defined(TEST_BLAS) && (defined(REF_IS_MKL) || defined(REF_IS_OPENBLAS)) +// Black box testing for generic and main use of zomatcopy. +INSTANTIATE_TEST_SUITE_P( + Blackbox, + zomatcopyAPI, + ::testing::Combine( + ::testing::Values('c'), // storage format(currently only for BLAS testing) + ::testing::Values('n', 't', 'r', 'c'), // trans(and/or conj) value + // 'n' - no-transpose, 't' - transpose + // 'r' - conjugate, 'c' - conjugate-transpose + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // m + ::testing::Values(gtint_t(10), gtint_t(55), gtint_t(243)), // n + ::testing::Values(dcomplex{2.3, -3.5}, dcomplex{-3.1, 1.7}, + dcomplex{1.0, 0.0}, dcomplex{0.0, 0.0}), // alpha + ::testing::Values(gtint_t(0), gtint_t(25)), // increment of lda + ::testing::Values(gtint_t(0), gtint_t(17)), // increment of ldb + ::testing::Values(false, true) // is_memory_test + ), + ::zomatcopyAPIPrint() + ); +#endif