diff --git a/lapack_api/CMakeLists.txt b/lapack_api/CMakeLists.txt index 9917a0399dc7c01698544a72d7227a66763842d6..c5380b814c193929b86205143c6e626cab3b9397 100644 --- a/lapack_api/CMakeLists.txt +++ b/lapack_api/CMakeLists.txt @@ -57,6 +57,7 @@ install( FILES ${CHAMELEON_LAPACK_HDRS} set(LAPACK_SRCS_GENERATED "") set(ZSRC src/lapack_zgemm.c + src/lapack_zsymm.c ) precisions_rules_py(LAPACK_SRCS_GENERATED "${ZSRC}" PRECISIONS "${CHAMELEON_PRECISION}") diff --git a/lapack_api/include/chameleon/chameleon_zlapack.h b/lapack_api/include/chameleon/chameleon_zlapack.h index 71cc73ca90f7b473cf3b320f68efcfe367eb9312..465327f4e474811288a4f423e01b350b7fd83721 100644 --- a/lapack_api/include/chameleon/chameleon_zlapack.h +++ b/lapack_api/include/chameleon/chameleon_zlapack.h @@ -33,6 +33,12 @@ void CHAMELEON_cblas_zgemm( const CBLAS_ORDER Order, const CBLAS_TRANSPOSE Trans const CHAMELEON_Complex64_t *B, const int ldb, const void *beta, CHAMELEON_Complex64_t *C, const int ldc ); +void CHAMELEON_cblas_zsymm( const CBLAS_ORDER Order, const CBLAS_SIDE Side, const CBLAS_UPLO Uplo, + const int M, const int N, + const void *alpha, const CHAMELEON_Complex64_t *A, const int lda, + const CHAMELEON_Complex64_t *B, const int ldb, + const void *beta, CHAMELEON_Complex64_t *C, const int ldc ); + END_C_DECLS #endif /* _chameleon_zlapack_h_ */ diff --git a/lapack_api/include/lapack_api_common.h b/lapack_api/include/lapack_api_common.h index bc46abf2beb3f07d70811d31cb7af092fad6e4b5..7dddd8f3ba5d761166187bacf418f784f6f42fa0 100644 --- a/lapack_api/include/lapack_api_common.h +++ b/lapack_api/include/lapack_api_common.h @@ -31,5 +31,7 @@ */ int chameleon_blastocblas_trans(const char* value); +int chameleon_blastocblas_side(const char* side); +int chameleon_blastocblas_uplo(const char* uplo); #endif /* _lapack_api_common_h_ */ diff --git a/lapack_api/src/lapack_api_common.c b/lapack_api/src/lapack_api_common.c index 5ab9e261e5ff0f12c6f5e3bc65024a4634fca146..097362d868d7d9ac09e4eeb40c6bf2ffceb79dec 100644 --- a/lapack_api/src/lapack_api_common.c +++ b/lapack_api/src/lapack_api_common.c @@ -37,3 +37,39 @@ int chameleon_blastocblas_trans(const char* trans) return CHAMELEON_ERR_ILLEGAL_VALUE; } } + +/** + * @brief Convert the input char BLAS side parameter to a compatible parameter + * for the Cblas API. + * @param[in] uplo The input char BLAS side parameter + * @return The CBLAS equivalent parameter (CblasLeft or CblasRight). + */ +int chameleon_blastocblas_side(const char* side) +{ + if ( (*side == 'L') || (*side == 'l') ) { + return CblasLeft; + } else if ( (*side == 'R') || (*side == 'r') ) { + return CblasRight; + } else { + fprintf(stderr, "CHAMELEON ERROR: %s(): %s\n", "chameleon_blastocblas_side", "illegal value of BLAS side parameter"); + return CHAMELEON_ERR_ILLEGAL_VALUE; + } +} + +/** + * @brief Convert the input char BLAS uplo parameter to a compatible parameter + * for the Cblas API. + * @param[in] uplo The input char BLAS uplo parameter + * @return The CBLAS equivalent parameter (CblasUpper or CblasLower). + */ +int chameleon_blastocblas_uplo(const char* uplo) +{ + if ( (*uplo == 'U') || (*uplo == 'u') ) { + return CblasUpper; + } else if ( (*uplo == 'L') || (*uplo == 'l') ) { + return CblasLower; + } else { + fprintf(stderr, "CHAMELEON ERROR: %s(): %s\n", "chameleon_blastocblas_uplo", "illegal value of BLAS uplo parameter"); + return CHAMELEON_ERR_ILLEGAL_VALUE; + } +} diff --git a/lapack_api/src/lapack_zgemm.c b/lapack_api/src/lapack_zgemm.c index d3723b9617f6dd9461dc4dd19ed6411fdd2a63fe..dccd819335479ae189d19250946fd52313eb3fa5 100644 --- a/lapack_api/src/lapack_zgemm.c +++ b/lapack_api/src/lapack_zgemm.c @@ -17,6 +17,7 @@ * */ +#include "chameleon_lapack.h" #include "lapack_api_common.h" /* Fortran BLAS interface */ @@ -57,13 +58,17 @@ void CHAMELEON_blas_zgemm ( const char* transa, const char* transb, * ******************************************************************************* * - * @param[in] transA + * @param[in] Order + * Specifies whether the matrices are row or column major, it must be + * set to CblasColMajor, the order supported in Chameleon. + * + * @param[in] TransA * Specifies whether the matrix A is transposed, not transposed or conjugate transposed: * = ChamNoTrans: A is not transposed; * = ChamTrans: A is transposed; * = ChamConjTrans: A is conjugate transposed. * - * @param[in] transB + * @param[in] TransB * Specifies whether the matrix B is transposed, not transposed or conjugate transposed: * = ChamNoTrans: B is not transposed; * = ChamTrans: B is transposed; @@ -106,11 +111,7 @@ void CHAMELEON_blas_zgemm ( const char* transa, const char* transb, * @param[in] LDC * The leading dimension of the array C. LDC >= max(1,M). * - ******************************************************************************* - * - * @retval CHAMELEON_SUCCESS successful exit - * - ******************************************************************************* + ****************************************************************************** * * @sa CHAMELEON_cblas_zgemm * @sa CHAMELEON_cblas_cgemm diff --git a/lapack_api/src/lapack_zsymm.c b/lapack_api/src/lapack_zsymm.c new file mode 100644 index 0000000000000000000000000000000000000000..1f5985406e2ef3085feb98d5f69c0b59a5f327a2 --- /dev/null +++ b/lapack_api/src/lapack_zsymm.c @@ -0,0 +1,142 @@ +/** + * + * @file lapack_zsymm.c + * + * @copyright 2022 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. + * + *** + * + * @brief Chameleon blas and cblas api for symm + * + * @version 1.2.0 + * @author Mathieu Faverge + * @author Florent Pruvost + * @date 2022-08-18 + * @precisions normal z -> s d c + * + */ + +#include "chameleon_lapack.h" +#include "lapack_api_common.h" + +/* Fortran BLAS interface */ + +#define CHAMELEON_blas_zsymm CHAMELEON_GLOBAL( chameleon_blas_zsymm, CHAMELEON_BLAS_Zsymm ) +void CHAMELEON_blas_zsymm ( const char* side, const char* uplo, + const int* m, const int* n, + const CHAMELEON_Complex64_t* alpha, const CHAMELEON_Complex64_t* a, const int* lda, + const CHAMELEON_Complex64_t* b, const int* ldb, + const CHAMELEON_Complex64_t* beta, CHAMELEON_Complex64_t* c, const int* ldc ) +{ + CHAMELEON_cblas_zsymm( CblasColMajor, + chameleon_blastocblas_side(side), + chameleon_blastocblas_uplo(uplo), + *m, *n, + CBLAS_SADDR(*alpha), a, *lda, + b, *ldb, + CBLAS_SADDR(*beta), c, *ldc ); +} + +/* C CBLAS interface */ + +/** + ******************************************************************************** + * + * @ingroup CHAMELEON_LAPACK_API + * + * CHAMELEON_cblas_zsymm - Performs one of the matrix-matrix operations + * + * \f[ C = \alpha \times A \times B + \beta \times C \f] + * + * or + * + * \f[ C = \alpha \times B \times A + \beta \times C \f] + * + * where alpha and beta are scalars, A is a symmetric matrix and B and + * C are m by n matrices. + * + ******************************************************************************* + * + * @param[in] Order + * Specifies whether the matrices are row or column major, it must be + * set to CblasColMajor, the order supported in Chameleon. + * + * @param[in] Side + * Specifies whether the symmetric matrix A appears on the + * left or right in the operation as follows: + * = ChamLeft: \f[ C = \alpha \times A \times B + \beta \times C \f] + * = ChamRight: \f[ C = \alpha \times B \times A + \beta \times C \f] + * + * @param[in] Uplo + * Specifies whether the upper or lower triangular part of + * the symmetric matrix A is to be referenced as follows: + * = ChamLower: Only the lower triangular part of the + * symmetric matrix A is to be referenced. + * = ChamUpper: Only the upper triangular part of the + * symmetric matrix A is to be referenced. + * + * @param[in] M + * Specifies the number of rows of the matrix C. M >= 0. + * + * @param[in] N + * Specifies the number of columns of the matrix C. N >= 0. + * + * @param[in] alpha + * Specifies the scalar alpha. + * + * @param[in] A + * A is a LDA-by-ka matrix, where ka is M when side = ChamLeft, + * and is N otherwise. Only the uplo triangular part is referenced. + * + * @param[in] LDA + * The leading dimension of the array A. LDA >= max(1,ka). + * + * @param[in] B + * B is a LDB-by-N matrix, where the leading M-by-N part of + * the array B must contain the matrix B. + * + * @param[in] LDB + * The leading dimension of the array B. LDB >= max(1,M). + * + * @param[in] beta + * Specifies the scalar beta. + * + * @param[in,out] C + * C is a LDC-by-N matrix. + * On exit, the array is overwritten by the M by N updated matrix. + * + * @param[in] LDC + * The leading dimension of the array C. LDC >= max(1,M). + * + ****************************************************************************** + * + * @sa CHAMELEON_cblas_zsymm + * @sa CHAMELEON_cblas_csymm + * @sa CHAMELEON_cblas_dsymm + * @sa CHAMELEON_cblas_ssymm + * + */ +void CHAMELEON_cblas_zsymm( const CBLAS_ORDER Order, const CBLAS_SIDE Side, const CBLAS_UPLO Uplo, + const int M, const int N, + const void *alpha, const CHAMELEON_Complex64_t *A, const int lda, + const CHAMELEON_Complex64_t *B, const int ldb, + const void *beta, CHAMELEON_Complex64_t *C, const int ldc ) +{ + if (Order != CblasColMajor){ + fprintf(stderr, "CHAMELEON ERROR: %s(): %s\n", "CHAMELEON_cblas_zsymm", "illegal value of order"); + } + +#if defined(PRECISION_z) || defined(PRECISION_c) + CHAMELEON_Complex64_t alphac = *(CHAMELEON_Complex64_t *)alpha; + CHAMELEON_Complex64_t betac = *(CHAMELEON_Complex64_t *)beta; +#else + CHAMELEON_Complex64_t alphac = alpha; + CHAMELEON_Complex64_t betac = beta; +#endif + + CHAMELEON_zsymm( (cham_side_t)Side, (cham_uplo_t)Uplo, M, N, + alphac, (CHAMELEON_Complex64_t *)A, lda, + (CHAMELEON_Complex64_t *)B, ldb, + betac, (CHAMELEON_Complex64_t *)C, ldc ); +} diff --git a/testing/testing_zsymm.c b/testing/testing_zsymm.c index a4d94002c865edce86c4d7fc1efee3bb2a4bac07..1c1cafe6dc89e2ef46d93db7e4e970761ef6435e 100644 --- a/testing/testing_zsymm.c +++ b/testing/testing_zsymm.c @@ -127,6 +127,7 @@ testing_zsymm_std( run_arg_list_t *args, int check ) int hres = 0; /* Read arguments */ + int api = parameters_getvalue_int( "api" ); int nb = run_arg_get_int( args, "nb", 320 ); cham_side_t side = run_arg_get_side( args, "side", ChamLeft ); cham_uplo_t uplo = run_arg_get_uplo( args, "uplo", ChamUpper ); @@ -173,7 +174,21 @@ testing_zsymm_std( run_arg_list_t *args, int check ) testing_stop( &test_data, flops_zsymm( side, M, N ) ); #else testing_start( &test_data ); - hres = CHAMELEON_zsymm( side, uplo, M, N, alpha, A, LDA, B, LDB, beta, C, LDC ); + switch ( api ) { + case 1: + hres = CHAMELEON_zsymm( side, uplo, M, N, alpha, A, LDA, B, LDB, beta, C, LDC ); + break; + case 2: + CHAMELEON_cblas_zsymm( CblasColMajor, (CBLAS_SIDE)side, (CBLAS_UPLO)uplo, M, N, + CBLAS_SADDR(alpha), A, LDA, B, LDB, CBLAS_SADDR(beta), C, LDC ); + break; + default: + if ( CHAMELEON_Comm_rank() == 0 ) { + fprintf( stderr, + "SKIPPED: This function can only be used with the option --api 1 or --api 2.\n" ); + } + return -1; + } test_data.hres = hres; testing_stop( &test_data, flops_zsymm( side, M, N ) );