diff --git a/lapack_api/CMakeLists.txt b/lapack_api/CMakeLists.txt index acb8c0951411f01153767255c2971cfa095e45e4..e6378f2a9619e5053d0581908ee6a6a9d88ccba8 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_zgetrf.c src/lapack_zhemm.c src/lapack_zher2k.c src/lapack_zherk.c diff --git a/lapack_api/include/chameleon/chameleon_zlapack.h b/lapack_api/include/chameleon/chameleon_zlapack.h index 5f8bdae88265b24ce6b4ccf03e11a9cdcf62ef11..8eb62502c7f42dd5500c51c17baf27ddae4cc19d 100644 --- a/lapack_api/include/chameleon/chameleon_zlapack.h +++ b/lapack_api/include/chameleon/chameleon_zlapack.h @@ -119,6 +119,9 @@ int CHAMELEON_lapacke_zpotrs( int matrix_layout, char uplo, int N, int NRHS, int CHAMELEON_lapacke_ztrtri( int matrix_layout, char uplo, char diag, int N, CHAMELEON_Complex64_t *A, int lda ); +int CHAMELEON_lapacke_zgetrf( int matrix_layout, int M, int N, + CHAMELEON_Complex64_t *A, int lda, int *IPIV ); + END_C_DECLS #endif /* _chameleon_zlapack_h_ */ diff --git a/lapack_api/src/lapack_zgetrf.c b/lapack_api/src/lapack_zgetrf.c new file mode 100644 index 0000000000000000000000000000000000000000..1bc69967ebe0f5bed26f9b49d655b42d7f84509e --- /dev/null +++ b/lapack_api/src/lapack_zgetrf.c @@ -0,0 +1,101 @@ +/** + * + * @file lapack_zgetrf.c + * + * @copyright 2022-2025 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. + * + *** + * + * @brief Chameleon lapack and lapacke api for getrf + * + * @version 1.3.0 + * @author Mathieu Faverge + * @author Florent Pruvost + * @date 2025-01-22 + * @precisions normal z -> s d c + * + */ + +#include "chameleon_lapack.h" +#include "lapack_api_common.h" + +/* Fortran LAPACK interface */ + +#define CHAMELEON_lapack_zgetrf CHAMELEON_GLOBAL( chameleon_lapack_zgetrf, CHAMELEON_LAPACK_ZGETRF ) +void CHAMELEON_lapack_zgetrf ( const int *m, const int *n, + CHAMELEON_Complex64_t *a, const int *lda, + int *ipiv, int *info ) +{ + *info = CHAMELEON_lapacke_zgetrf( CblasColMajor, *m, *n, a, *lda, ipiv ); +} + +/* C LAPACKE interface */ + +/** + ******************************************************************************** + * + * @ingroup CHAMELEON_LAPACK_API + * + * CHAMELEON_lapacke_zgetrf - computes an LU factorization of a general M-by-N matrix A + * using partial pivoting with row interchanges. + * + * The factorization has the form + * A = P * L * U + * where P is a permutation matrix, L is lower triangular with unit + * diagonal elements (lower trapezoidal if m > n), and U is upper + * triangular (upper trapezoidal if m < n). + * + ******************************************************************************* + * + * @param[in] matrix_layout + * Specifies whether the matrices are row or column major, it must be + * set to LAPACK_COL_MAJOR or CblasColMajor (102), the matrix_layout + * supported in Chameleon. + * + * @param[in] M + * The number of rows of the matrix A. M >= 0. + * + * @param[in] N + * The number of columns of the matrix A. N >= 0. + * + * @param[in,out] A + * On entry, the M-by-N matrix to be factored. + * On exit, the factors L and U from the factorization + * A = P*L*U; the unit diagonal elements of L are not stored. + * + * @param[in] LDA + * The leading dimension of the array A. LDA >= max(1,M). + * + * @param[out] IPIV + * The pivot indices; for 1 <= i <= min(M,N), row i of the + * matrix was interchanged with row IPIV(i). + * + ******************************************************************************* + * + * @retval =0 successful exit + * @retval <0 if -i, the i-th argument had an illegal value + * @retval >0 if info = i, U(i,i) is exactly zero. The factorization + * has been completed, but the factor U is exactly + * singular, and division by zero will occur if it is used + * to solve a system of equations. + * + ******************************************************************************* + * + * @sa CHAMELEON_lapacke_zgetrf + * @sa CHAMELEON_lapacke_cgetrf + * @sa CHAMELEON_lapacke_dgetrf + * @sa CHAMELEON_lapacke_sgetrf + * + */ +int CHAMELEON_lapacke_zgetrf( int matrix_layout, int M, int N, + CHAMELEON_Complex64_t *A, int lda, + int *IPIV ) +{ + if ( matrix_layout != CblasColMajor ){ + fprintf( stderr, "CHAMELEON ERROR: %s(): %s\n", "CHAMELEON_lapacke_zgetrf", "illegal value of matrix_layout" ); + return -1; + } + + return CHAMELEON_zgetrf( M, N, A, lda, IPIV ); +} diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index aed35c62f6dec5ca0b753784bb7432ff3feda450..58a7050f04b57e92dce168076055055021cfc47f 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -50,6 +50,7 @@ set(ZSRC_W_STDAPI testing_zlansy.c testing_zlantr.c testing_zgemm.c + testing_zgetrf.c testing_zhemm.c testing_zherk.c testing_zher2k.c @@ -79,7 +80,6 @@ set(ZSRC_WO_STDAPI testing_zgenm2.c testing_zgesv_nopiv.c testing_zgesvd.c - testing_zgetrf.c testing_zgetrf_nopiv.c testing_zgetrs_nopiv.c testing_zgeqrf.c diff --git a/testing/testing_zgetrf.c b/testing/testing_zgetrf.c index 4645631a7a86a72e5c8fe2fa5f8b40e61991e66c..9bbc12c3a5b3240124a532945e7800e5a12147c2 100644 --- a/testing/testing_zgetrf.c +++ b/testing/testing_zgetrf.c @@ -158,8 +158,90 @@ testing_zgetrf_desc( run_arg_list_t *args, int check ) } #endif +int +testing_zgetrf_std( run_arg_list_t *args, int check ) +{ + testdata_t test_data = { .args = args }; + int hres = 0; + + /* Read arguments */ + int api = parameters_getvalue_int( "api" ); + int nb = run_arg_get_nb( args ); + int N = run_arg_get_int( args, "N", 1000 ); + int M = run_arg_get_int( args, "M", N ); + int LDA = run_arg_get_int( args, "LDA", M ); + int seedA = run_arg_get_int( args, "seedA", testing_ialea() ); + int minMN = chameleon_min( M, N ); + + /* Descriptors */ + CHAMELEON_Complex64_t *A; + int *IPIV; + + CHAMELEON_Set( CHAMELEON_TILE_SIZE, nb ); + + /* Creates the matrices */ + A = malloc( LDA*N*sizeof(CHAMELEON_Complex64_t) ); + IPIV = malloc( minMN * sizeof(int) ); + + /* Fills the matrix with random values */ + CHAMELEON_zplrnt( M, N, A, LDA, seedA ); + + /* Calculates the solution */ +#if defined(CHAMELEON_TESTINGS_VENDOR) + testing_start( &test_data ); + hres = LAPACKE_zgetrf( LAPACK_COL_MAJOR, M, N, A, LDA, IPIV ); + test_data.hres = hres; + testing_stop( &test_data, flops_zgetrf( M, N ) ); +#else + testing_start( &test_data ); + switch ( api ) { + case 1: + hres = CHAMELEON_zgetrf( M, N, A, LDA, IPIV ); + break; +#if !defined(CHAMELEON_SIMULATION) + case 2: + CHAMELEON_lapacke_zgetrf( CblasColMajor, M, N, A, LDA, IPIV ); + break; +#endif + 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_zgetrf( M, N ) ); + +#if !defined(CHAMELEON_SIMULATION) + /* Checks the factorisation and residue */ + if ( check ) { + CHAMELEON_Complex64_t *A0 = malloc( LDA*N*sizeof(CHAMELEON_Complex64_t) ); + CHAMELEON_zplrnt( M, N, A0, LDA, seedA ); + + /* Compute the permutation of A0: P * A0 */ + LAPACKE_zlaswp( LAPACK_COL_MAJOR, N, A0, M, 1, minMN, IPIV, 1 ); + + hres += check_zxxtrf_std( args, ChamGeneral, ChamUpperLower, M, N, A0, A, LDA ); + + free( A0 ); + } +#endif +#endif + + free ( IPIV ); + free( A ); + + (void)check; + return hres; +} + testing_t test_zgetrf; +#if defined(CHAMELEON_TESTINGS_VENDOR) +const char *zgetrf_params[] = { "m", "n", "lda", "seedA", NULL }; +#else const char *zgetrf_params[] = { "mtxfmt", "nb", "ib", "m", "n", "lda", "seedA", "diag", NULL }; +#endif const char *zgetrf_output[] = { NULL }; const char *zgetrf_outchk[] = { "||A||", "||A-fact(A)||", "RETURN", NULL }; @@ -180,7 +262,7 @@ testing_zgetrf_init( void ) #else test_zgetrf.fptr_desc = testing_zgetrf_desc; #endif - test_zgetrf.fptr_std = NULL; /* testing_zgetrf_std; */ + test_zgetrf.fptr_std = testing_zgetrf_std; test_zgetrf.next = NULL; testing_register( &test_zgetrf ); diff --git a/testing/testings.c b/testing/testings.c index 560e398e8d13f47f87fd5f174a2e3f252a9dadad..670ebb75e91600e8aa476e723b4651e88c8c5dcb 100644 --- a/testing/testings.c +++ b/testing/testings.c @@ -107,6 +107,8 @@ testing_options_init( testing_options_t *options ) options->splitsub = parameters_getvalue_int( "splitsub" ); options->threads = parameters_getvalue_int( "threads" ); options->trace = parameters_getvalue_int( "trace" ); +#else + options->threads = -1; #endif options->file = parameters_getvalue_str( "file" );