From 7969d43f2c1b357a7f7b3a31fb92c8fb9ebb9f19 Mon Sep 17 00:00:00 2001 From: "Smyth, Edward" Date: Wed, 20 Aug 2025 22:38:45 +0100 Subject: [PATCH] Improve BLAS3 IIT_ERS tests New tests: - Add IIT_ERS tests for TRMM, SYMM, SYRK, SYR2K, HEMM, HERK, HER2K Corrections and improvements: - GEMM: Use local definitions of input size, trans, etc arguments to allow finer control of choices, especially for testing invalid leading dimensions. - GEMM, GEMMT, GEMM_COMPUTE, TRMM, TRSM: In alpha=beta=zero test, initialize C to extreme value to test that C is set rather than scaled - GEMM: Use correct M x N dimensions for C in calls to computediff - GEMM: Declare info variable in disabled tests in gemm_IIT_ERS.cpp AMD-Internal: [CPUPL-6725] --- .../level3/gemm/IIT_ERS/gemm_IIT_ERS.cpp | 559 ++++++++--- .../IIT_ERS/gemm_compute_IIT_ERS.cpp | 18 +- .../level3/gemmt/IIT_ERS/gemmt_IIT_ERS.cpp | 2 +- .../level3/hemm/IIT_ERS/hemm_IIT_ERS.cpp | 681 +++++++++++++ .../level3/her2k/IIT_ERS/her2k_IIT_ERS.cpp | 899 ++++++++++++++++++ .../level3/herk/IIT_ERS/herk_IIT_ERS.cpp | 713 ++++++++++++++ .../level3/symm/IIT_ERS/symm_IIT_ERS.cpp | 681 +++++++++++++ .../level3/syr2k/IIT_ERS/syr2k_IIT_ERS.cpp | 873 +++++++++++++++++ .../level3/syrk/IIT_ERS/syrk_IIT_ERS.cpp | 704 ++++++++++++++ .../level3/trmm/IIT_ERS/trmm_IIT_ERS.cpp | 482 ++++++++++ .../level3/trsm/IIT_ERS/trsm_IIT_ERS.cpp | 12 +- 11 files changed, 5495 insertions(+), 129 deletions(-) create mode 100644 gtestsuite/testsuite/level3/hemm/IIT_ERS/hemm_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/her2k/IIT_ERS/her2k_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/herk/IIT_ERS/herk_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/symm/IIT_ERS/symm_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/syr2k/IIT_ERS/syr2k_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/syrk/IIT_ERS/syrk_IIT_ERS.cpp create mode 100644 gtestsuite/testsuite/level3/trmm/IIT_ERS/trmm_IIT_ERS.cpp diff --git a/gtestsuite/testsuite/level3/gemm/IIT_ERS/gemm_IIT_ERS.cpp b/gtestsuite/testsuite/level3/gemm/IIT_ERS/gemm_IIT_ERS.cpp index 88e471fda..4cada5584 100644 --- a/gtestsuite/testsuite/level3/gemm/IIT_ERS/gemm_IIT_ERS.cpp +++ b/gtestsuite/testsuite/level3/gemm/IIT_ERS/gemm_IIT_ERS.cpp @@ -4,7 +4,7 @@ An object-based framework for developing high-performance BLAS-like libraries. - Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved. + Copyright (C) 2023 - 2025, 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 @@ -36,7 +36,7 @@ #include "common/testing_helpers.h" #include "level3/gemm/test_gemm.h" #include "inc/check_error.h" -#include "common/wrong_inputs_helpers.h" +//#include "common/wrong_inputs_helpers.h" template class gemm_IIT_ERS : public ::testing::Test {}; @@ -44,7 +44,7 @@ typedef ::testing::Types TypeParam; // The su TYPED_TEST_SUITE(gemm_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. // Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. -using namespace testinghelpers::IIT; +//using namespace testinghelpers::IIT; #if defined(TEST_CBLAS) #define INFO_OFFSET 1 @@ -58,29 +58,38 @@ using namespace testinghelpers::IIT; TYPED_TEST(gemm_IIT_ERS, invalid_storage) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. - gemm( 'x', TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( 'x', TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); computediff( "info", info, 1 ); #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for TRANS value for A. - gemm( 'x', TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( 'x', TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -111,16 +120,25 @@ TYPED_TEST(gemm_IIT_ERS, invalid_storage) TYPED_TEST(gemm_IIT_ERS, invalid_transa) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, 'p', TRANS, M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, 'p', TRANSB, M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, 'p', TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, 'p', TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -128,16 +146,16 @@ TYPED_TEST(gemm_IIT_ERS, invalid_transa) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for TRANS value for A. - gemm( STORAGE, 'p', TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, 'p', TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -149,16 +167,25 @@ TYPED_TEST(gemm_IIT_ERS, invalid_transa) TYPED_TEST(gemm_IIT_ERS, invalid_transb) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, 'p', M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, 'p', M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, 'p', M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, 'p', M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -166,16 +193,16 @@ TYPED_TEST(gemm_IIT_ERS, invalid_transb) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for TRANS value for B. - gemm( STORAGE, TRANS, 'p', M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, 'p', M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -187,16 +214,25 @@ TYPED_TEST(gemm_IIT_ERS, invalid_transb) TYPED_TEST(gemm_IIT_ERS, m_lt_zero) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, -1, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, -1, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, -1, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, -1, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -204,16 +240,16 @@ TYPED_TEST(gemm_IIT_ERS, m_lt_zero) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for m. - gemm( STORAGE, TRANS, TRANS, -1, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, -1, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -225,16 +261,25 @@ TYPED_TEST(gemm_IIT_ERS, m_lt_zero) TYPED_TEST(gemm_IIT_ERS, n_lt_zero) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, -1, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, -1, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, -1, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, -1, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -242,16 +287,16 @@ TYPED_TEST(gemm_IIT_ERS, n_lt_zero) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for n. - gemm( STORAGE, TRANS, TRANS, M, -1, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, -1, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -263,16 +308,25 @@ TYPED_TEST(gemm_IIT_ERS, n_lt_zero) TYPED_TEST(gemm_IIT_ERS, k_lt_zero) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, -1, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, -1, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, N, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -280,16 +334,16 @@ TYPED_TEST(gemm_IIT_ERS, k_lt_zero) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for k. - gemm( STORAGE, TRANS, TRANS, M, N, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -298,19 +352,28 @@ TYPED_TEST(gemm_IIT_ERS, k_lt_zero) } // When info == 8 -TYPED_TEST(gemm_IIT_ERS, invalid_lda) +TYPED_TEST(gemm_IIT_ERS, invalid_lda_transa_n) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 7; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -318,16 +381,110 @@ TYPED_TEST(gemm_IIT_ERS, invalid_lda) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for lda. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 8 ); +#endif +} + +// When info == 8 +TYPED_TEST(gemm_IIT_ERS, invalid_lda_transa_t) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANSA = 't'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 8 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS Gemm with a invalid value for lda. + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 8 ); +#endif +} + +// When info == 8 +TYPED_TEST(gemm_IIT_ERS, invalid_lda_transa_c) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANSA = 'c'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 8 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS Gemm with a invalid value for lda. + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -336,19 +493,28 @@ TYPED_TEST(gemm_IIT_ERS, invalid_lda) } // When info == 10 -TYPED_TEST(gemm_IIT_ERS, invalid_ldb) +TYPED_TEST(gemm_IIT_ERS, invalid_ldb_transb_n) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -356,16 +522,110 @@ TYPED_TEST(gemm_IIT_ERS, invalid_ldb) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for ldb. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif +} + +// When info == 10 +TYPED_TEST(gemm_IIT_ERS, invalid_ldb_transb_t) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 't'; + static const gtint_t M = 4; + static const gtint_t N = 7; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); +#else + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS Gemm with a invalid value for ldb. + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif +} + +// When info == 10 +TYPED_TEST(gemm_IIT_ERS, invalid_ldb_transb_c) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'c'; + static const gtint_t M = 4; + static const gtint_t N = 7; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); +#else + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS Gemm with a invalid value for ldb. + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -377,16 +637,25 @@ TYPED_TEST(gemm_IIT_ERS, invalid_ldb) TYPED_TEST(gemm_IIT_ERS, invalid_ldc) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 7; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC - 1 ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC - 1 ); #else - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC - 1 ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC - 1 ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -394,16 +663,16 @@ TYPED_TEST(gemm_IIT_ERS, invalid_ldc) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); // Call BLIS Gemm with a invalid value for ldc. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC - 1 ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC - 1 ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -428,16 +697,25 @@ TYPED_TEST(gemm_IIT_ERS, invalid_ldc) TYPED_TEST(gemm_IIT_ERS, m_eq_zero) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, 0, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, 0, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, 0, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, 0, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -445,15 +723,15 @@ TYPED_TEST(gemm_IIT_ERS, m_eq_zero) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); - gemm( STORAGE, TRANS, TRANS, 0, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, 0, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -465,16 +743,25 @@ TYPED_TEST(gemm_IIT_ERS, m_eq_zero) TYPED_TEST(gemm_IIT_ERS, n_eq_zero) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, 0, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, 0, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, 0, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, 0, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -482,15 +769,15 @@ TYPED_TEST(gemm_IIT_ERS, n_eq_zero) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); - gemm( STORAGE, TRANS, TRANS, M, 0, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, 0, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -502,16 +789,25 @@ TYPED_TEST(gemm_IIT_ERS, n_eq_zero) TYPED_TEST(gemm_IIT_ERS, alpha_zero_beta_one) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initzero( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -519,15 +815,15 @@ TYPED_TEST(gemm_IIT_ERS, alpha_zero_beta_one) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -539,16 +835,25 @@ TYPED_TEST(gemm_IIT_ERS, alpha_zero_beta_one) TYPED_TEST(gemm_IIT_ERS, k_zero_beta_one) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initone( alpha ); testinghelpers::initone( beta ); // Test with nullptr for all suitable arguments that shouldn't be accessed. #if defined(TEST_BLAS_LIKE) - gemm( STORAGE, TRANS, TRANS, M, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #else - gemm( STORAGE, TRANS, TRANS, M, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); #endif #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -556,15 +861,15 @@ TYPED_TEST(gemm_IIT_ERS, k_zero_beta_one) #endif // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); - gemm( STORAGE, TRANS, TRANS, M, N, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE info = bli_info_get_info_value(); @@ -576,18 +881,29 @@ TYPED_TEST(gemm_IIT_ERS, k_zero_beta_one) TYPED_TEST(gemm_IIT_ERS, ZeroAlpha_ZeroBeta) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initzero( alpha ); testinghelpers::initzero( beta ); - std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - // Copy so that we check that the elements of C are not modified. + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); std::vector c2(c); - std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); + // Set up expected output matrix + std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'N', M, N, LDB); // Test with nullptr for all suitable arguments that shouldn't be accessed. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -595,9 +911,9 @@ TYPED_TEST(gemm_IIT_ERS, ZeroAlpha_ZeroBeta) #endif // Test with all arguments correct except for the value we are choosing to test. - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); @@ -611,24 +927,33 @@ TYPED_TEST(gemm_IIT_ERS, ZeroAlpha_ZeroBeta) TYPED_TEST(gemm_IIT_ERS, ZeroAlpha_OtherBeta) { using T = TypeParam; - + static const char STORAGE = 'c'; + static const char TRANSA = 'n'; + static const char TRANSB = 'n'; + static const gtint_t M = 4; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANSA == 'n')||(TRANSA == 'N'))? M : K; + gtint_t LDB = ((TRANSB == 'n')||(TRANSB == 'N'))? K : N; + gtint_t LDC = M; T alpha, beta; testinghelpers::initzero( alpha ); beta = T{2.0}; double thresh = testinghelpers::getEpsilon(); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); // Copy so that we check that the elements of C are not modified. std::vector c2(c); std::vector c_ref(c); - testinghelpers::ref_gemm( STORAGE, TRANS, TRANS, M, N, K, alpha, + testinghelpers::ref_gemm( STORAGE, TRANSA, TRANSB, M, N, K, alpha, a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); // Test with nullptr for all suitable arguments that shouldn't be accessed. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); #ifdef CAN_TEST_INFO_VALUE gtint_t info = bli_info_get_info_value(); @@ -636,7 +961,7 @@ TYPED_TEST(gemm_IIT_ERS, ZeroAlpha_OtherBeta) #endif // Test with all arguments correct except for the value we are choosing to test. - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); @@ -657,7 +982,7 @@ TYPED_TEST(gemm_IIT_ERS, null_a_matrix) { using T = TypeParam; std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSB, K, N, LDB); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); T alpha, beta; @@ -665,12 +990,12 @@ TYPED_TEST(gemm_IIT_ERS, null_a_matrix) testinghelpers::initone( alpha ); testinghelpers::initone( beta ); - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, nullptr, LDA, b.data(), LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, nullptr, LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE - info = bli_info_get_info_value(); + gtint_t info = bli_info_get_info_value(); computediff( "info", info, 0 ); #endif } @@ -680,7 +1005,7 @@ TYPED_TEST(gemm_IIT_ERS, null_b_matrix) { using T = TypeParam; std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); - std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANSA, M, K, LDA); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); T alpha, beta; @@ -688,12 +1013,12 @@ TYPED_TEST(gemm_IIT_ERS, null_b_matrix) testinghelpers::initone( alpha ); testinghelpers::initone( beta ); - gemm( STORAGE, TRANS, TRANS, M, N, K, &alpha, a.data(), LDA, nullptr, LDB, &beta, c.data(), LDC ); + gemm( STORAGE, TRANSA, TRANSB, M, N, K, &alpha, a.data(), LDA, nullptr, LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). - computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); #ifdef CAN_TEST_INFO_VALUE - info = bli_info_get_info_value(); + gtint_t info = bli_info_get_info_value(); computediff( "info", info, 0 ); #endif } diff --git a/gtestsuite/testsuite/level3/gemm_compute/IIT_ERS/gemm_compute_IIT_ERS.cpp b/gtestsuite/testsuite/level3/gemm_compute/IIT_ERS/gemm_compute_IIT_ERS.cpp index 68bda7964..88d43da6d 100644 --- a/gtestsuite/testsuite/level3/gemm_compute/IIT_ERS/gemm_compute_IIT_ERS.cpp +++ b/gtestsuite/testsuite/level3/gemm_compute/IIT_ERS/gemm_compute_IIT_ERS.cpp @@ -586,14 +586,16 @@ TYPED_TEST(gemm_compute_IIT_ERS, ZeroAlpha_ZeroBeta_UU) // Test with all arguments correct except for the value we are choosing to test. std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); - std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); // Copy so that we check that the elements of C are not modified. std::vector c_ref(c); testinghelpers::ref_gemm_compute( STORAGE, TRANS, TRANS, 'U', 'U', M, N, K, alpha, a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); - // Enable packing of A matrix to accound for alpha = 0 scaling. + // Enable packing of A matrix to account for alpha = 0 scaling. gemm_compute( STORAGE, TRANS, TRANS, 'U', 'U', M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); @@ -612,7 +614,9 @@ TYPED_TEST(gemm_compute_IIT_ERS, ZeroAlpha_ZeroBeta_PU) testinghelpers::initzero( alpha ); testinghelpers::initzero( beta ); - std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); // Copy so that we check that the elements of C are not modified. std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); @@ -620,7 +624,7 @@ TYPED_TEST(gemm_compute_IIT_ERS, ZeroAlpha_ZeroBeta_PU) std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); - // Enable packing of A matrix to accound for alpha = 0 scaling. + // Enable packing of A matrix to account for alpha = 0 scaling. gemm_compute( STORAGE, TRANS, TRANS, 'P', 'U', M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); @@ -639,7 +643,9 @@ TYPED_TEST(gemm_compute_IIT_ERS, ZeroAlpha_ZeroBeta_UP) testinghelpers::initzero( alpha ); testinghelpers::initzero( beta ); - std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); // Copy so that we check that the elements of C are not modified. std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); @@ -647,7 +653,7 @@ TYPED_TEST(gemm_compute_IIT_ERS, ZeroAlpha_ZeroBeta_UP) std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, K, LDA); std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, N, LDB); - // Enable packing of A matrix to accound for alpha = 0 scaling. + // Enable packing of A matrix to account for alpha = 0 scaling. gemm_compute( STORAGE, TRANS, TRANS, 'U', 'P', M, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); // Use bitwise comparison (no threshold). computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); diff --git a/gtestsuite/testsuite/level3/gemmt/IIT_ERS/gemmt_IIT_ERS.cpp b/gtestsuite/testsuite/level3/gemmt/IIT_ERS/gemmt_IIT_ERS.cpp index 0d67e45f9..82d2b8e2e 100644 --- a/gtestsuite/testsuite/level3/gemmt/IIT_ERS/gemmt_IIT_ERS.cpp +++ b/gtestsuite/testsuite/level3/gemmt/IIT_ERS/gemmt_IIT_ERS.cpp @@ -4,7 +4,7 @@ An object-based framework for developing high-performance BLAS-like libraries. - Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved. + Copyright (C) 2023 - 2025, 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 diff --git a/gtestsuite/testsuite/level3/hemm/IIT_ERS/hemm_IIT_ERS.cpp b/gtestsuite/testsuite/level3/hemm/IIT_ERS/hemm_IIT_ERS.cpp new file mode 100644 index 000000000..988894ba3 --- /dev/null +++ b/gtestsuite/testsuite/level3/hemm/IIT_ERS/hemm_IIT_ERS.cpp @@ -0,0 +1,681 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/hemm/test_hemm.h" +#include "inc/check_error.h" +#include "common/wrong_inputs_helpers.h" + +template +class hemm_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for hemm +TYPED_TEST_SUITE(hemm_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(hemm_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + hemm( 'x', SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for TRANS value for A. + hemm( 'x', SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for hemm): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 7. When ldb < max(1, m) (info = 9) + 8. When ldc < max(1, m) (info = 12) + +*/ + +// When info == 1 +TYPED_TEST(hemm_IIT_ERS, invalid_side) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for TRANS value for A. + hemm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(hemm_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for TRANS value for B. + hemm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(hemm_IIT_ERS, m_lt_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for m. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(hemm_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for n. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(hemm_IIT_ERS, invalid_lda_side_l) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, nullptr, nullptr, M - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, &alpha, nullptr, M - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for lda. + hemm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, &alpha, a.data(), M - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 +TYPED_TEST(hemm_IIT_ERS, invalid_lda_side_r) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, N - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, N - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for lda. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), N - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 9 +TYPED_TEST(hemm_IIT_ERS, invalid_ldb) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, M - 1, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, M - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for ldb. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), M - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 12 +TYPED_TEST(hemm_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, M - 1 ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, M - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS hemm with a invalid value for ldc. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), M - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The hemm API is expected to return early in the following cases: + + 1. When m == 0. + 2. When n == 0. + 3. When (alpha == 0 or k == 0) and beta == 1. + 4. When alpha == 0 and beta == 0, set C = 0 only + 5. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When m is 0 +TYPED_TEST(hemm_IIT_ERS, m_eq_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When n is 0 +TYPED_TEST(hemm_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(hemm_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(hemm_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(hemm_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(hemm_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + beta = T{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, alpha, + a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + hemm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/her2k/IIT_ERS/her2k_IIT_ERS.cpp b/gtestsuite/testsuite/level3/her2k/IIT_ERS/her2k_IIT_ERS.cpp new file mode 100644 index 000000000..815535596 --- /dev/null +++ b/gtestsuite/testsuite/level3/her2k/IIT_ERS/her2k_IIT_ERS.cpp @@ -0,0 +1,899 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/her2k/test_her2k.h" +#include "inc/check_error.h" +#include "common/wrong_inputs_helpers.h" + +template +class her2k_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for her2k +TYPED_TEST_SUITE(her2k_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +//using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(her2k_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + her2k( 'x', UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for TRANS value for A. + her2k( 'x', UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for her2k): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 7. When ldb < max(1, m) (info = 9) + 8. When ldc < max(1, m) (info = 12) + +*/ + +// When info == 1 +TYPED_TEST(her2k_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, 'p', TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, 'p', TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for TRANS value for A. + her2k( STORAGE, 'p', TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(her2k_IIT_ERS, invalid_trans) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, 'p', TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, 'p', TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for TRANS value for B. + her2k( STORAGE, UPLO, 'p', TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(her2k_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, -1, K, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, -1, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for m. + her2k( STORAGE, UPLO, TRANS, TRANS, -1, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(her2k_IIT_ERS, k_lt_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, -1, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for n. + her2k( STORAGE, UPLO, TRANS, TRANS, N, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(her2k_IIT_ERS, invalid_lda_trans_n) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for lda. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 2 (invalid value of trans) +TYPED_TEST(her2k_IIT_ERS, invalid_lda_trans_t) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for lda. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif +} + +// When info == 7 +TYPED_TEST(her2k_IIT_ERS, invalid_lda_trans_c) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for lda. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 9 +TYPED_TEST(her2k_IIT_ERS, invalid_ldb_trans_n) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for ldb. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 2 (invalid value of trans) +TYPED_TEST(her2k_IIT_ERS, invalid_ldb_trans_t) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for ldb. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif +} + +// When info == 9 for real data. With complex data, info == 2. +TYPED_TEST(her2k_IIT_ERS, invalid_ldb_trans_c) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for ldb. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 12 +TYPED_TEST(her2k_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC - 1 ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS her2k with a invalid value for ldc. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The her2k API is expected to return early in the following cases: + + 1. When n == 0. + 2. When (alpha == 0 or k == 0) and beta == 1. + 3. When alpha == 0 and beta == 0, set C = 0 only + 4. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When n is 0 +TYPED_TEST(her2k_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, 0, N, nullptr, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, 0, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + her2k( STORAGE, UPLO, TRANS, TRANS, 0, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(her2k_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(her2k_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + her2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + her2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + her2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(her2k_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, zero; + RT beta; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + testinghelpers::initzero( zero ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, c.data(), UPLO, LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, zero_mat.data(), UPLO, LDC, zero ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(her2k_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha; + RT beta; + testinghelpers::initzero( alpha ); + beta = RT{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, + a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + her2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/herk/IIT_ERS/herk_IIT_ERS.cpp b/gtestsuite/testsuite/level3/herk/IIT_ERS/herk_IIT_ERS.cpp new file mode 100644 index 000000000..0e4a5f035 --- /dev/null +++ b/gtestsuite/testsuite/level3/herk/IIT_ERS/herk_IIT_ERS.cpp @@ -0,0 +1,713 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/herk/test_herk.h" +#include "inc/check_error.h" +#include "common/wrong_inputs_helpers.h" + +template +class herk_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for herk +TYPED_TEST_SUITE(herk_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +//using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(herk_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + herk( 'x', UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for TRANS value for A. + herk( 'x', UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for herk): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 8. When ldc < max(1, m) (info = 10) + +*/ + +// When info == 1 +TYPED_TEST(herk_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, 'p', TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, 'p', TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for TRANS value for A. + herk( STORAGE, 'p', TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(herk_IIT_ERS, invalid_trans) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, 'p', N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, 'p', N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for TRANS value for B. + herk( STORAGE, UPLO, 'p', N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(herk_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, -1, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, -1, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for m. + herk( STORAGE, UPLO, TRANS, -1, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(herk_IIT_ERS, k_lt_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, -1, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, -1, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for n. + herk( STORAGE, UPLO, TRANS, N, -1, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(herk_IIT_ERS, invalid_lda_trans_n) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for lda. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 2 (invalid value of trans) +TYPED_TEST(herk_IIT_ERS, invalid_lda_trans_t) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for lda. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 2 ); +#endif +} + +// When info == 7 +TYPED_TEST(herk_IIT_ERS, invalid_lda_trans_c) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for lda. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 10 +TYPED_TEST(herk_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC - 1 ); +#else + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS herk with a invalid value for ldc. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The herk API is expected to return early in the following cases: + + 1. When n == 0. + 2. When (alpha == 0 or k == 0) and beta == 1. + 3. When alpha == 0 and beta == 0, set C = 0 only + 4. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When n is 0 +TYPED_TEST(herk_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, 0, N, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, 0, N, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + herk( STORAGE, UPLO, TRANS, 0, N, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(herk_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(herk_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + herk( STORAGE, UPLO, TRANS, N, 0, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + herk( STORAGE, UPLO, TRANS, N, 0, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + herk( STORAGE, UPLO, TRANS, N, 0, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(herk_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + T zero; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + testinghelpers::initzero( zero ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, c.data(), UPLO, LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, zero_mat.data(), UPLO, LDC, zero ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(herk_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + using RT = typename testinghelpers::type_info::real_type; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + RT alpha, beta; + testinghelpers::initzero( alpha ); + beta = RT{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_herk( STORAGE, UPLO, TRANS, N, K, alpha, + a.data(), LDA, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + herk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/symm/IIT_ERS/symm_IIT_ERS.cpp b/gtestsuite/testsuite/level3/symm/IIT_ERS/symm_IIT_ERS.cpp new file mode 100644 index 000000000..de160a0f5 --- /dev/null +++ b/gtestsuite/testsuite/level3/symm/IIT_ERS/symm_IIT_ERS.cpp @@ -0,0 +1,681 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/symm/test_symm.h" +#include "inc/check_error.h" +#include "common/wrong_inputs_helpers.h" + +template +class symm_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for symm +TYPED_TEST_SUITE(symm_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(symm_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + symm( 'x', SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for TRANS value for A. + symm( 'x', SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for symm): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 7. When ldb < max(1, m) (info = 9) + 8. When ldc < max(1, m) (info = 12) + +*/ + +// When info == 1 +TYPED_TEST(symm_IIT_ERS, invalid_side) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for TRANS value for A. + symm( STORAGE, 'p', UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(symm_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for TRANS value for B. + symm( STORAGE, SIDE, 'p', CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(symm_IIT_ERS, m_lt_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for m. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, -1, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(symm_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for n. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(symm_IIT_ERS, invalid_lda_side_l) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, nullptr, nullptr, M - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, &alpha, nullptr, M - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for lda. + symm( STORAGE, 'l', UPLO, CONJ, TRANS, M, N, &alpha, a.data(), M - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 +TYPED_TEST(symm_IIT_ERS, invalid_lda_side_r) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, N - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, N - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for lda. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), N - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 9 +TYPED_TEST(symm_IIT_ERS, invalid_ldb) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, M - 1, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, M - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for ldb. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), M - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 12 +TYPED_TEST(symm_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, M - 1 ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, M - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS symm with a invalid value for ldc. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), M - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The symm API is expected to return early in the following cases: + + 1. When m == 0. + 2. When n == 0. + 3. When (alpha == 0 or k == 0) and beta == 1. + 4. When alpha == 0 and beta == 0, set C = 0 only + 5. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When m is 0 +TYPED_TEST(symm_IIT_ERS, m_eq_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, 0, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When n is 0 +TYPED_TEST(symm_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(symm_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(symm_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(symm_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', M, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, M, N, c.data(), 'N', LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, M, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(symm_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + + T alpha, beta; + testinghelpers::initzero( alpha ); + beta = T{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Set the dimension for row/col of A, depending on the value of side. + gtint_t K = ((SIDE == 'l')||(SIDE == 'L'))? M : N; + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', K, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', M, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, alpha, + a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, M, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + symm( STORAGE, SIDE, UPLO, CONJ, TRANS, M, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, M, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/syr2k/IIT_ERS/syr2k_IIT_ERS.cpp b/gtestsuite/testsuite/level3/syr2k/IIT_ERS/syr2k_IIT_ERS.cpp new file mode 100644 index 000000000..dc0ff27a7 --- /dev/null +++ b/gtestsuite/testsuite/level3/syr2k/IIT_ERS/syr2k_IIT_ERS.cpp @@ -0,0 +1,873 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/syr2k/test_syr2k.h" +#include "inc/check_error.h" + +template +class syr2k_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for syr2k +TYPED_TEST_SUITE(syr2k_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(syr2k_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syr2k( 'x', UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for TRANS value for A. + syr2k( 'x', UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for syr2k): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 7. When ldb < max(1, m) (info = 9) + 8. When ldc < max(1, m) (info = 12) + +*/ + +// When info == 1 +TYPED_TEST(syr2k_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, 'p', TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, 'p', TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for TRANS value for A. + syr2k( STORAGE, 'p', TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(syr2k_IIT_ERS, invalid_trans) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, 'p', TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, 'p', TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for TRANS value for B. + syr2k( STORAGE, UPLO, 'p', TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(syr2k_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, -1, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, -1, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for m. + syr2k( STORAGE, UPLO, TRANS, TRANS, -1, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(syr2k_IIT_ERS, k_lt_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, -1, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, -1, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for n. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, -1, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(syr2k_IIT_ERS, invalid_lda_trans_n) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 7; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for lda. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 +TYPED_TEST(syr2k_IIT_ERS, invalid_lda_trans_t) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for lda. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 for real data. With complex data, info == 2. +TYPED_TEST(syr2k_IIT_ERS, invalid_lda_trans_c) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA - 1, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 7 ); + else + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for lda. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA - 1, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 7 ); + else + computediff( "info", info, 2 ); +#endif +} + +// When info == 9 +TYPED_TEST(syr2k_IIT_ERS, invalid_ldb_trans_n) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 7; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for ldb. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 9 +TYPED_TEST(syr2k_IIT_ERS, invalid_ldb_trans_t) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for ldb. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +// When info == 9 for real data. With complex data, info == 2. +TYPED_TEST(syr2k_IIT_ERS, invalid_ldb_trans_c) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 7; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB - 1, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 9 ); + else + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for ldb. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 9 ); + else + computediff( "info", info, 2 ); +#endif +} + +// When info == 12 +TYPED_TEST(syr2k_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 7; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC - 1 ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syr2k with a invalid value for ldc. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 12 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The syr2k API is expected to return early in the following cases: + + 1. When n == 0. + 2. When (alpha == 0 or k == 0) and beta == 1. + 3. When alpha == 0 and beta == 0, set C = 0 only + 4. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When n is 0 +TYPED_TEST(syr2k_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, 0, N, nullptr, nullptr, LDA, nullptr, LDB, nullptr, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, 0, N, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syr2k( STORAGE, UPLO, TRANS, TRANS, 0, N, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(syr2k_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(syr2k_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syr2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#else + syr2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, nullptr, LDA, nullptr, LDB, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syr2k( STORAGE, UPLO, TRANS, TRANS, N, 0, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(syr2k_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta, zero; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + testinghelpers::initzero( zero ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, c.data(), UPLO, LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, zero_mat.data(), UPLO, LDC, zero ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(syr2k_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDB = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initzero( alpha ); + beta = T{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector b = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDB); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, alpha, + a.data(), LDA, b.data(), LDB, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, nullptr, LDA, nullptr, LDB, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + syr2k( STORAGE, UPLO, TRANS, TRANS, N, K, &alpha, a.data(), LDA, b.data(), LDB, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/syrk/IIT_ERS/syrk_IIT_ERS.cpp b/gtestsuite/testsuite/level3/syrk/IIT_ERS/syrk_IIT_ERS.cpp new file mode 100644 index 000000000..69dd08775 --- /dev/null +++ b/gtestsuite/testsuite/level3/syrk/IIT_ERS/syrk_IIT_ERS.cpp @@ -0,0 +1,704 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "common/testing_helpers.h" +#include "level3/syrk/test_syrk.h" +#include "inc/check_error.h" +#include "common/wrong_inputs_helpers.h" + +template +class syrk_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; // The supported datatypes from BLAS calls for syrk +TYPED_TEST_SUITE(syrk_IIT_ERS, TypeParam); // Defining individual testsuites based on the datatype support. + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +//using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +// When info == 1 +TYPED_TEST(syrk_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syrk( 'x', UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for TRANS value for A. + syrk( 'x', UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/* + Incorrect Input Testing(IIT) + + BLAS exceptions get triggered in the following cases(for syrk): + 1. When SIDE != 'L' || SIDE != 'R' (info = 1) + 2. When UPLO != 'U' || UPLO != 'L' (info = 2) + 3. When m < 0 (info = 3) + 4. When n < 0 (info = 4) + 6. When lda < max(1, thresh) (info = 7), thresh set based on SIDE value + 8. When ldc < max(1, m) (info = 10) + +*/ + +// When info == 1 +TYPED_TEST(syrk_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, 'p', TRANS, N, K, nullptr, nullptr, LDA, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, 'p', TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for TRANS value for A. + syrk( STORAGE, 'p', TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +// When info == 2 +TYPED_TEST(syrk_IIT_ERS, invalid_trans) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, 'p', N, K, nullptr, nullptr, LDA, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, 'p', N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for TRANS value for B. + syrk( STORAGE, UPLO, 'p', N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +// When info == 3 +TYPED_TEST(syrk_IIT_ERS, n_lt_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, -1, K, nullptr, nullptr, LDA, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, -1, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for m. + syrk( STORAGE, UPLO, TRANS, -1, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 3 ); +#endif +} + +// When info == 4 +TYPED_TEST(syrk_IIT_ERS, k_lt_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, -1, nullptr, nullptr, LDA, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, -1, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for n. + syrk( STORAGE, UPLO, TRANS, N, -1, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 4 ); +#endif +} + +// When info == 7 +TYPED_TEST(syrk_IIT_ERS, invalid_lda_trans_n) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for lda. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 +TYPED_TEST(syrk_IIT_ERS, invalid_lda_trans_t) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'T'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for lda. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 7 ); +#endif +} + +// When info == 7 for real data. With complex data, info == 2. +TYPED_TEST(syrk_IIT_ERS, invalid_lda_trans_c) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'C'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, K, nullptr, nullptr, LDA - 1, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA - 1, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 7 ); + else + computediff( "info", info, 2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for lda. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA - 1, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + if constexpr (testinghelpers::type_info::is_real) + computediff( "info", info, 7 ); + else + computediff( "info", info, 2 ); +#endif +} + +// When info == 10 +TYPED_TEST(syrk_IIT_ERS, invalid_ldc) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, K, nullptr, nullptr, LDA, nullptr, nullptr, LDC - 1 ); +#else + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC - 1 ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + // Call BLIS syrk with a invalid value for ldc. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC - 1 ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 10 ); +#endif +} + +/* + Early Return Scenarios(ERS) : + + The syrk API is expected to return early in the following cases: + + 1. When n == 0. + 2. When (alpha == 0 or k == 0) and beta == 1. + 3. When alpha == 0 and beta == 0, set C = 0 only + 4. When alpha == 0 and beta /= 0 or 1, scale C by beta only + +*/ + +// When n is 0 +TYPED_TEST(syrk_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, 0, N, nullptr, nullptr, LDA, nullptr, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, 0, N, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syrk( STORAGE, UPLO, TRANS, 0, N, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When alpha is 0 and beta is 1 +TYPED_TEST(syrk_IIT_ERS, alpha_zero_beta_one) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initzero( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// When k is 0 and beta is 1 +TYPED_TEST(syrk_IIT_ERS, k_zero_beta_one) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initone( alpha ); + testinghelpers::initone( beta ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + syrk( STORAGE, UPLO, TRANS, N, 0, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#else + syrk( STORAGE, UPLO, TRANS, N, 0, &alpha, nullptr, LDA, &beta, nullptr, LDC ); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c_ref(c); + + syrk( STORAGE, UPLO, TRANS, N, 0, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and zero beta - set C to 0 +TYPED_TEST(syrk_IIT_ERS, ZeroAlpha_ZeroBeta) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta, zero; + testinghelpers::initzero( alpha ); + testinghelpers::initzero( beta ); + testinghelpers::initzero( zero ); + + // Matrix C should not be read, only set. + std::vector c( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, c.data(), UPLO, LDC, testinghelpers::aocl_extreme() ); + std::vector c2(c); + // Set up expected output matrix + std::vector zero_mat( testinghelpers::matsize( STORAGE, 'N', N, N, LDC ) ); + testinghelpers::set_matrix( STORAGE, N, zero_mat.data(), UPLO, LDC, zero ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), zero_mat.data(), LDC); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), zero_mat.data(), LDC); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +// zero alpha and non-zero/non-unit beta - scale C only +TYPED_TEST(syrk_IIT_ERS, ZeroAlpha_OtherBeta) +{ + using T = TypeParam; + static const char STORAGE = 'c'; + static const char UPLO = 'u'; + static const char TRANS = 'n'; + static const gtint_t N = 4; + static const gtint_t K = 4; + // Set the dimension for row/col of A and B, depending on the value of trans. + gtint_t LDA = ((TRANS == 'n')||(TRANS == 'N'))? N : K; + gtint_t LDC = N; + T alpha, beta; + testinghelpers::initzero( alpha ); + beta = T{2.0}; + double thresh = testinghelpers::getEpsilon(); + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(-10, 10, STORAGE, TRANS, N, K, LDA); + std::vector c = testinghelpers::get_random_matrix(-10, 10, STORAGE, 'N', N, N, LDC); + // Copy so that we check that the elements of C are not modified. + std::vector c2(c); + std::vector c_ref(c); + + testinghelpers::ref_syrk( STORAGE, UPLO, TRANS, N, K, alpha, + a.data(), LDA, beta, c_ref.data(), LDC ); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, nullptr, LDA, &beta, c2.data(), LDC ); + computediff( "C", STORAGE, N, N, c2.data(), c_ref.data(), LDC, thresh); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + syrk( STORAGE, UPLO, TRANS, N, K, &alpha, a.data(), LDA, &beta, c.data(), LDC ); + // Use bitwise comparison (no threshold). + computediff( "C", STORAGE, N, N, c.data(), c_ref.data(), LDC, thresh); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif + diff --git a/gtestsuite/testsuite/level3/trmm/IIT_ERS/trmm_IIT_ERS.cpp b/gtestsuite/testsuite/level3/trmm/IIT_ERS/trmm_IIT_ERS.cpp new file mode 100644 index 000000000..4aba63b87 --- /dev/null +++ b/gtestsuite/testsuite/level3/trmm/IIT_ERS/trmm_IIT_ERS.cpp @@ -0,0 +1,482 @@ +/* + + BLIS + An object-based framework for developing high-performance BLAS-like + libraries. + + Copyright (C) 2025, 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 "level3/trmm/trmm.h" +#include "inc/check_error.h" +#include "common/testing_helpers.h" +#include "common/wrong_inputs_helpers.h" +#include +#include +#include + + +template +class trmm_IIT_ERS : public ::testing::Test {}; +typedef ::testing::Types TypeParam; +TYPED_TEST_SUITE(trmm_IIT_ERS, TypeParam); + +// Adding namespace to get default parameters(valid case) from testinghelpers/common/wrong_input_helpers.h. +using namespace testinghelpers::IIT; + +#if defined(TEST_CBLAS) +#define INFO_OFFSET 1 +#else +#define INFO_OFFSET 0 +#endif + +#if defined(TEST_CBLAS) + +/** + * @brief test TRMM when storage argument is incorrect + * when info == 1 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_storage) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + trmm( 'x', SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, nullptr, LDB); + +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( 'x', SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 1 ); +#endif +} + +#endif + +#if defined(TEST_BLAS_LIKE) || defined(TEST_CBLAS) + +/** + * @brief test TRMM when side argument is incorrect + * when info == 1 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_side) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, 'a', UPLO, TRANS, DIAG, M, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, 'a', UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, 'a', UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+1 ); +#endif +} + +/** + * @brief test TRMM when UPLO argument is incorrect + * when info == 2 + * + */ +TYPED_TEST(trmm_IIT_ERS, invalid_uplo) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, 'a', TRANS, DIAG, M, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, 'a', TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, 'a', TRANS, DIAG, M, N, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+2 ); +#endif +} + +/** + * @brief test TRMM when TRANS argument is incorrect + * when info == 3 + * + */ +TYPED_TEST(trmm_IIT_ERS, invalid_trans) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, 'a', DIAG, M, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, 'a', DIAG, M, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+3 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, 'a', DIAG, M, N, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+3 ); +#endif +} + +/** + * @brief test TRMM when DIAG argument is incorrect + * when info == 4 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_DIAG) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, 'a', M, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, 'a', M, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+4 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, 'a', M, N, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, INFO_OFFSET+4 ); +#endif +} + +/** + * @brief test TRMM when m is negative + * when info == 5 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_m) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, -1, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, -1, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 5 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, -1, N, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 5 ); +#endif +} + +/** + * @brief test TRMM when n is negative + * when info == 6 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_n) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, -1, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, -1, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 6 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, -1, &ALPHA, a.data(), LDA, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 6 ); +#endif +} + +/** + * @brief test TRMM when lda is incorrect + * when info == 9 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_lda) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, nullptr, nullptr, LDA - 1, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA - 1, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, a.data(), LDA - 1, b.data(), LDB); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 9 ); +#endif +} + +/** + * @brief test TRMM when ldb is incorrect + * when info == 11 + */ +TYPED_TEST(trmm_IIT_ERS, invalid_ldb) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, nullptr, nullptr, LDA, nullptr, LDB - 1); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, nullptr, LDB - 1); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 11 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, a.data(), LDA, b.data(), LDB - 1); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 11 ); +#endif +} + + +/* + Early Return Scenarios(ERS) : + + The trmm API is expected to return early in the following cases: + + 1. When m == 0. + 2. When n == 0. + 3. When alpha == 0, set B to 0 only. + +*/ + +/** + * @brief test TRMM when M is zero + */ +TYPED_TEST(trmm_IIT_ERS, m_eq_zero) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, 0, N, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, 0, N, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, 0, N, &ALPHA, a.data(), LDA, b.data(), LDB ); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +/** + * @brief test TRMM when N is zero + */ +TYPED_TEST(trmm_IIT_ERS, n_eq_zero) +{ + using T = TypeParam; + T ALPHA = T{2.3}; + + // Test with nullptr for all suitable arguments that shouldn't be accessed. +#if defined(TEST_BLAS_LIKE) + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, 0, nullptr, nullptr, LDA, nullptr, LDB); +#else + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, 0, &ALPHA, nullptr, LDA, nullptr, LDB); +#endif +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + std::vector b_ref(b); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, 0, &ALPHA, a.data(), LDA, b.data(), LDB ); + computediff( "B", STORAGE, M, N, b.data(), b_ref.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +/** + * @brief test TRMM when alpha is zero - set B to 0 + */ +TYPED_TEST(trmm_IIT_ERS, alpha_eq_zero) +{ + using T = TypeParam; + T ALPHA; + testinghelpers::initzero( ALPHA ); + + // Matrix B should not be read, only set. + std::vector b( testinghelpers::matsize( STORAGE, 'N', M, N, LDB ) ); + testinghelpers::set_matrix( STORAGE, M, N, b.data(), 'N', LDB, testinghelpers::aocl_extreme() ); + std::vector b2(b); + std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB); + + // Test with nullptr for all suitable arguments that shouldn't be accessed. + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, nullptr, LDA, b2.data(), LDB); + computediff( "B", STORAGE, M, N, b2.data(), zero_mat.data(), LDB ); +#ifdef CAN_TEST_INFO_VALUE + gtint_t info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif + + // Test with all arguments correct except for the value we are choosing to test. + std::vector a = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + + trmm( STORAGE, SIDE, UPLO, TRANS, DIAG, M, N, &ALPHA, a.data(), LDA, b.data(), LDB ); + computediff( "B", STORAGE, M, N, b.data(), zero_mat.data(), LDB ); + +#ifdef CAN_TEST_INFO_VALUE + info = bli_info_get_info_value(); + computediff( "info", info, 0 ); +#endif +} + +#endif diff --git a/gtestsuite/testsuite/level3/trsm/IIT_ERS/trsm_IIT_ERS.cpp b/gtestsuite/testsuite/level3/trsm/IIT_ERS/trsm_IIT_ERS.cpp index ed1f14c8b..a378b24d9 100644 --- a/gtestsuite/testsuite/level3/trsm/IIT_ERS/trsm_IIT_ERS.cpp +++ b/gtestsuite/testsuite/level3/trsm/IIT_ERS/trsm_IIT_ERS.cpp @@ -4,7 +4,7 @@ An object-based framework for developing high-performance BLAS-like libraries. - Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. + Copyright (C) 2024 - 2025, 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 @@ -131,7 +131,7 @@ TYPED_TEST(trsm_IIT_ERS, invalid_side) * when info == 2 * */ -TYPED_TEST(trsm_IIT_ERS, invalid_UPLO) +TYPED_TEST(trsm_IIT_ERS, invalid_uplo) { using T = TypeParam; T ALPHA = T{2.3}; @@ -166,7 +166,7 @@ TYPED_TEST(trsm_IIT_ERS, invalid_UPLO) * when info == 3 * */ -TYPED_TEST(trsm_IIT_ERS, invalid_TRANS) +TYPED_TEST(trsm_IIT_ERS, invalid_trans) { using T = TypeParam; T ALPHA = T{2.3}; @@ -445,7 +445,7 @@ TYPED_TEST(trsm_IIT_ERS, n_eq_zero) } /** - * @brief Test TRSM when alpha is zero + * @brief Test TRSM when alpha is zero - set B to 0 */ TYPED_TEST(trsm_IIT_ERS, alpha_eq_zero) { @@ -453,7 +453,9 @@ TYPED_TEST(trsm_IIT_ERS, alpha_eq_zero) T ALPHA; testinghelpers::initzero( ALPHA ); - std::vector b = testinghelpers::get_random_matrix(0, 1, STORAGE, 'n', M, N, LDB); + // Matrix B should not be read, only set. + std::vector b( testinghelpers::matsize( STORAGE, 'N', M, N, LDB ) ); + testinghelpers::set_matrix( STORAGE, M, N, b.data(), 'N', LDB, testinghelpers::aocl_extreme() ); std::vector b2(b); std::vector zero_mat = testinghelpers::get_random_matrix(0, 0, STORAGE, 'n', M, N, LDB);