diff --git a/testing/chameleon_ztesting.c b/testing/chameleon_ztesting.c index ca5204ccccb63dbc0bcd106dabfcacb153a6958e..61ae3d8f50059f4df87c04965bfe1e8f9dc8fbd3 100644 --- a/testing/chameleon_ztesting.c +++ b/testing/chameleon_ztesting.c @@ -111,6 +111,10 @@ parameter_t parameters[] = { { "llvl", "Tree used for low level reduction insides nodes", -22, PARAM_OPTION | PARAM_INPUT | PARAM_OUTPUT, 2, 4, TestValInt, {0}, NULL, pread_int, sprint_int }, { "hlvl", "Tree used for high level reduction between nodes", -23, PARAM_OPTION | PARAM_INPUT | PARAM_OUTPUT, 2, 4, TestValInt, {0}, NULL, pread_int, sprint_int }, { "domino", "Enable/Disable the domino between upper and lower trees", -24, PARAM_OPTION | PARAM_INPUT | PARAM_OUTPUT, 2, 6, TestValInt, {0}, NULL, pread_int, sprint_int }, + + { NULL, "SVD parameters", 0, PARAM_OPTION, 0, 0, 0, {0}, NULL, NULL, NULL }, + { "jobu", "Value of the jobu parameter", -50, PARAM_OPTION | PARAM_INPUT | PARAM_OUTPUT, 2, 4, TestJob, {0}, NULL, pread_job, sprint_job }, + { "jobvt", "Value of the jobvt parameter", -51, PARAM_OPTION | PARAM_INPUT | PARAM_OUTPUT, 2, 5, TestJob, {0}, NULL, pread_job, sprint_job }, #endif { "tsub", "Graph submission time in s", 999, PARAM_OUTPUT, 2, 13, TestValFixdbl, {0}, NULL, pread_fixdbl, sprint_fixdbl }, diff --git a/testing/input/gesvd.in b/testing/input/gesvd.in index ac35a8ecb91acfa3f46ae652a1905dc6f3fb7eec..909b6787d359c95ca4470217c2aeb81b6ee728e9 100644 --- a/testing/input/gesvd.in +++ b/testing/input/gesvd.in @@ -6,9 +6,13 @@ # M: Number of rows of matrix A and C # N: Number of columns of matrix B and C # LDA: Leading dimension of matrix A +# JobU: value of jobu +# JobVt: value of jobvt op = gesvd nb = 3, 4, 16, 17 m = 15, 32, 37 n = 13, 24, 35 +jobu = NoVec, AllVec +jobvt = NoVec, AllVec lda = 41 diff --git a/testing/run_list.c b/testing/run_list.c index 1d13d861d65084c6d569d1c2deb9a413c2b8b13d..708248e0dfd9627bcfd85e71476d398b739a9196 100644 --- a/testing/run_list.c +++ b/testing/run_list.c @@ -441,6 +441,32 @@ run_arg_get_side( run_arg_list_t *arglist, const char *name, cham_side_t defval return rval.side; } +/** + * @brief Searches for a cham_job_t value by its name. + * + * @param[inout] arglist + * The list of arguments. + * On exit, if the argument was not in the list, the default value is + * stored in it. + * + * @param[in] name + * The name of the argument to look for. + * + * @param[in] defval + * The default value if no argument is found with this name. This value + * is added to the list if not found. + * + * @retval The value of the argument _name_. + */ +cham_job_t +run_arg_get_job( run_arg_list_t *arglist, const char *name, cham_job_t defval ) +{ + val_t val, rval; + val.job = defval; + rval = run_arg_get( arglist, name, val ); + return rval.job; +} + /** * @brief Searches for a cham_normtype_t value by its name. * @@ -736,6 +762,7 @@ run_print_header_partial( const char **list, int human, char *str ) case TestUplo: case TestDiag: case TestSide: + case TestJob: case TestNormtype: case TestString: rc = sprintf( str, " %-*s", param->psize, *pname ); diff --git a/testing/testing_zcheck_svd.c b/testing/testing_zcheck_svd.c index 84c53b9bc4e48ba0e2b4d101c00c0b36d3b565ec..d6c0aa499d5429435357bf10884678414624cf92 100644 --- a/testing/testing_zcheck_svd.c +++ b/testing/testing_zcheck_svd.c @@ -77,7 +77,9 @@ * @param[in] U * The orthogonal matrix U computed by the Chameleon SVD algorithm can * contain all of U, a part of U or nothing (NULL) depending on the value of jobu; - * dimension: M * K = min(M, N). + * if jobu == AllVec : dimension: M * M + * if jobu == SVec : dimension: M * min(M, N) + * if jobu == NoVec or OVec : U = NULL * * @param[in] LDU * The leading dimension of the matrix U. @@ -85,7 +87,9 @@ * @param[in] Vt * The orthogonal matrix Vt computed by the Chameleon SVD algorithm can * contain all of Vt, a part of Vt or nothing (NULL) depending on the value of jobvt; - * dimension: K = min(M, N) * N. + * if jobuvt == AllVec : dimension: N * N + * if jobvt == SVec : dimension: min(M, N) * N + * if jobvt == NoVec or OVec : Vt = NULL * * @param[in] LDVt * The leading dimension of the matrix Vt. @@ -99,6 +103,7 @@ int check_zgesvd_std( run_arg_list_t *args, cham_job_t jobu, cham_job_t jobvt, i { int info_solution = 0; double result; + int k; int K = chameleon_min(M, N); double eps = LAPACKE_dlamch_work('e'); @@ -137,7 +142,7 @@ int check_zgesvd_std( run_arg_list_t *args, cham_job_t jobu, cham_job_t jobvt, i double maxSVdiff = fabs( fabs(Sinit[0]) - fabs(S[0]) ); double maxtmp, maxdifftmp; - for ( int k = 1; k < K; k++ ) { + for ( k = 1; k < K; k++ ) { maxdifftmp = fabs( fabs(Sinit[k]) - fabs(S[k]) ); maxtmp = chameleon_max( fabs(Sinit[k]), fabs(S[k]) ); @@ -152,7 +157,7 @@ int check_zgesvd_std( run_arg_list_t *args, cham_job_t jobu, cham_job_t jobvt, i info_solution += 1; } - if ( jobu == ChamAllVec && jobvt == ChamAllVec ) { + if ( (jobu == ChamAllVec) && (jobvt == ChamAllVec) ) { /* To do: create mat( S ) */ } result = info_solution; @@ -199,7 +204,9 @@ int check_zgesvd_std( run_arg_list_t *args, cham_job_t jobu, cham_job_t jobvt, i * @param[in] U * The orthogonal matrix U computed by the Chameleon SVD algorithm can * contain all of U, a part of U or nothing (NULL) depending on the value of jobu; - * dimension: M * K = min(M, N). + * if jobu == AllVec : dimension: M * M + * if jobu == SVec : dimension: M * min(M, N) + * if jobu == NoVec or OVec : U = NULL * * @param[in] LDU * The leading dimension of the matrix U. @@ -207,7 +214,9 @@ int check_zgesvd_std( run_arg_list_t *args, cham_job_t jobu, cham_job_t jobvt, i * @param[in] Vt * The orthogonal matrix Vt computed by the Chameleon SVD algorithm can * contain all of Vt, a part of Vt or nothing (NULL) depending on the value of jobvt; - * dimension: K = min(M, N) * N. + * if jobuvt == AllVec : dimension: N * N + * if jobvt == SVec : dimension: min(M, N) * N + * if jobvt == NoVec or OVec : Vt = NULL * * @param[in] LDVt * The leading dimension of the matrix Vt. diff --git a/testing/testing_zgesvd.c b/testing/testing_zgesvd.c index 04582eb1dd9bc92fe3193f038301c1a5456346cc..a95eeb7338297bcc225a50197cdf487316711c09 100644 --- a/testing/testing_zgesvd.c +++ b/testing/testing_zgesvd.c @@ -21,10 +21,39 @@ #include <chameleon/flops.h> static cham_fixdbl_t -flops_zgesvd( int M, int N ) +flops_zgesvd( int M, int N, int K, cham_job_t jobu, cham_job_t jobvt ) { cham_fixdbl_t flops = flops_zgebrd( M, N ); - return flops; + + switch ( jobu ) { + case ChamAllVec: + flops += flops_zunmqr( ChamLeft, M, N, N ); + break; + case ChamOVec: + case ChamSVec: + flops += flops_zunmqr( ChamLeft, M, K, K ); + break; + case ChamNoVec: + break; + default: + ; + } + + switch ( jobvt ) { + case ChamAllVec: + flops += flops_zunmlq( ChamRight, M, N, M ); + break; + case ChamOVec: + case ChamSVec: + flops += flops_zunmlq( ChamRight, K, N, K ); + break; + case ChamNoVec: + break; + default: + ; + } + + return -1; } int @@ -34,18 +63,21 @@ testing_zgesvd_desc( run_arg_list_t *args, int check ) int hres = 0; /* Read arguments */ - int async = parameters_getvalue_int( "async" ); - intptr_t mtxfmt = parameters_getvalue_int( "mtxfmt" ); - int nb = run_arg_get_int( args, "nb", 320 ); - int P = parameters_getvalue_int( "P" ); - int N = run_arg_get_int( args, "N", 1000 ); - int M = run_arg_get_int( args, "M", N ); - int K = chameleon_min( M, N ); - int LDA = run_arg_get_int( args, "LDA", M ); - int seedA = run_arg_get_int( args, "seedA", random() ); - double cond = run_arg_get_double( args, "cond", 1.e16 ); - int mode = run_arg_get_int( args, "mode", 4 ); - int Q = parameters_compute_q( P ); + int async = parameters_getvalue_int( "async" ); + intptr_t mtxfmt = parameters_getvalue_int( "mtxfmt" ); + int nb = run_arg_get_int( args, "nb", 320 ); + int P = parameters_getvalue_int( "P" ); + int N = run_arg_get_int( args, "N", 1000 ); + int M = run_arg_get_int( args, "M", N ); + int K = chameleon_min( M, N ); + int LDA = run_arg_get_int( args, "LDA", M ); + int seedA = run_arg_get_int( args, "seedA", random() ); + double cond = run_arg_get_double( args, "cond", 1.e16 ); + int mode = run_arg_get_int( args, "mode", 4 ); + int Q = parameters_compute_q( P ); + cham_job_t jobu = run_arg_get_job( args, "jobu", ChamNoVec ); + cham_job_t jobvt = run_arg_get_job( args, "jobvt", ChamNoVec ); + int runtime; /* Descriptors */ CHAM_desc_t *descA, *descT, *descA0; @@ -54,11 +86,18 @@ testing_zgesvd_desc( run_arg_list_t *args, int check ) int LDU = M; int LDVt = N; int Un, Vtn; - cham_job_t jobu = ChamAllVec; - cham_job_t jobvt = ChamAllVec; CHAMELEON_Set( CHAMELEON_TILE_SIZE, nb ); + CHAMELEON_Get( CHAMELEON_RUNTIME, &runtime ); + if ( runtime == RUNTIME_SCHED_PARSEC ) { + if ( CHAMELEON_Comm_rank() == 0 ) { + fprintf( stderr, + "SKIPPED: The SVD is not supported with PaRSEC\n" ); + } + return -1; + } + /* Creates the matrices */ CHAMELEON_Desc_Create( &descA, (void*)(-mtxfmt), ChamComplexDouble, nb, nb, nb * nb, LDA, N, 0, 0, M, N, P, Q ); @@ -111,7 +150,7 @@ testing_zgesvd_desc( run_arg_list_t *args, int check ) hres = CHAMELEON_zgesvd_Tile( jobu, jobvt, descA, S, descT, U, LDU, Vt, LDVt ); } test_data.hres = hres; - testing_stop( &test_data, flops_zgesvd( M, N ) ); + testing_stop( &test_data, flops_zgesvd( M, N, K, jobu, jobvt ) ); /* Checks the factorisation and residue */ if ( check ) { @@ -124,10 +163,10 @@ testing_zgesvd_desc( run_arg_list_t *args, int check ) CHAMELEON_Desc_Destroy( &descT ); free( S ); free( D ); - if ( jobu == ChamAllVec || jobu == ChamSVec ) { + if ( (jobu == ChamAllVec) || (jobu == ChamSVec) ) { free( U ); } - if ( jobvt == ChamAllVec || jobvt == ChamSVec ) { + if ( (jobvt == ChamAllVec) || (jobvt == ChamSVec) ) { free( Vt ); } @@ -141,14 +180,17 @@ testing_zgesvd_std( run_arg_list_t *args, int check ) int hres = 0; /* Read arguments */ - int nb = run_arg_get_int( args, "nb", 320 ); - int N = run_arg_get_int( args, "N", 1000 ); - int M = run_arg_get_int( args, "M", N ); - int K = chameleon_min( M, N ); - int LDA = run_arg_get_int( args, "LDA", M ); - int seedA = run_arg_get_int( args, "seedA", random() ); - double cond = run_arg_get_double( args, "cond", 1.e16 ); - int mode = run_arg_get_int( args, "mode", 4 ); + int nb = run_arg_get_int( args, "nb", 320 ); + int N = run_arg_get_int( args, "N", 1000 ); + int M = run_arg_get_int( args, "M", N ); + int K = chameleon_min( M, N ); + int LDA = run_arg_get_int( args, "LDA", M ); + int seedA = run_arg_get_int( args, "seedA", random() ); + double cond = run_arg_get_double( args, "cond", 1.e16 ); + int mode = run_arg_get_int( args, "mode", 4 ); + cham_job_t jobu = run_arg_get_job( args, "jobu", ChamNoVec ); + cham_job_t jobvt = run_arg_get_job( args, "jobvt", ChamNoVec ); + int runtime; /* Descriptors */ CHAM_desc_t *descT; @@ -157,11 +199,18 @@ testing_zgesvd_std( run_arg_list_t *args, int check ) int LDU = M; int LDVt = N; int Un, Vtn; - cham_job_t jobu = ChamAllVec; - cham_job_t jobvt = ChamAllVec; CHAMELEON_Set( CHAMELEON_TILE_SIZE, nb ); + CHAMELEON_Get( CHAMELEON_RUNTIME, &runtime ); + if ( runtime == RUNTIME_SCHED_PARSEC ) { + if ( CHAMELEON_Comm_rank() == 0 ) { + fprintf( stderr, + "SKIPPED: The SVD is not supported with PaRSEC\n" ); + } + return -1; + } + /* Creates the matrices */ A = malloc( LDA*N*sizeof(CHAMELEON_Complex64_t) ); CHAMELEON_Alloc_Workspace_zgesvd( M, N, &descT, 1, 1 ); @@ -206,7 +255,7 @@ testing_zgesvd_std( run_arg_list_t *args, int check ) testing_start( &test_data ); hres = CHAMELEON_zgesvd( jobu, jobvt, M, N, A, LDA, S, descT, U, LDU, Vt, LDVt ); test_data.hres = hres; - testing_stop( &test_data, flops_zgesvd( M, N ) ); + testing_stop( &test_data, flops_zgesvd( M, N, K, jobu, jobvt ) ); /* Checks the factorisation and residue */ if ( check ) { @@ -217,10 +266,10 @@ testing_zgesvd_std( run_arg_list_t *args, int check ) free( A ); free( S ); - if ( jobu == ChamAllVec || jobu == ChamSVec ) { + if ( (jobu == ChamAllVec) || (jobu == ChamSVec) ) { free( U ); } - if ( jobvt == ChamAllVec || jobvt == ChamSVec ) { + if ( (jobvt == ChamAllVec) || (jobvt == ChamSVec) ) { free( Vt ); } CHAMELEON_Desc_Destroy( &descT ); @@ -229,7 +278,7 @@ testing_zgesvd_std( run_arg_list_t *args, int check ) } testing_t test_zgesvd; -const char *zgesvd_params[] = { "mtxfmt", "nb", "m", "n", "lda", "seedA", NULL }; +const char *zgesvd_params[] = { "mtxfmt", "nb", "jobu", "jobvt", "m", "n", "lda", "seedA", NULL }; const char *zgesvd_output[] = { NULL }; const char *zgesvd_outchk[] = { "||R||", "||I-QQ'||", "RETURN", NULL }; diff --git a/testing/testings.h b/testing/testings.h index a938f45b746927e84aa5893df42af24315e17ff1..2832223f4edeac53eba444a13c5e8249fc4592ed 100644 --- a/testing/testings.h +++ b/testing/testings.h @@ -43,6 +43,7 @@ typedef enum valtype_ { TestUplo, TestDiag, TestSide, + TestJob, TestNormtype, TestString, } valtype_e; @@ -56,6 +57,7 @@ union val_u { cham_uplo_t uplo; cham_diag_t diag; cham_side_t side; + cham_job_t job; cham_normtype_t ntype; CHAMELEON_Complex64_t zval; CHAMELEON_Complex32_t cval; @@ -164,6 +166,7 @@ val_t pread_trans ( const char *str ); val_t pread_uplo ( const char *str ); val_t pread_diag ( const char *str ); val_t pread_side ( const char *str ); +val_t pread_job ( const char *str ); val_t pread_norm ( const char *str ); val_t pread_string ( const char *str ); @@ -180,6 +183,7 @@ char *sprint_trans ( val_t val, int human, int nbchar, char *str_in ); char *sprint_uplo ( val_t val, int human, int nbchar, char *str_in ); char *sprint_diag ( val_t val, int human, int nbchar, char *str_in ); char *sprint_side ( val_t val, int human, int nbchar, char *str_in ); +char *sprint_job ( val_t val, int human, int nbchar, char *str_in ); char *sprint_norm ( val_t val, int human, int nbchar, char *str_in ); char *sprint_string ( val_t val, int human, int nbchar, char *str_in ); char *sprint_check ( val_t val, int human, int nbchar, char *str_in ); @@ -202,6 +206,7 @@ cham_trans_t run_arg_get_trans ( run_arg_list_t *arglist, const char cham_uplo_t run_arg_get_uplo ( run_arg_list_t *arglist, const char *name, cham_uplo_t defval ); cham_diag_t run_arg_get_diag ( run_arg_list_t *arglist, const char *name, cham_diag_t defval ); cham_side_t run_arg_get_side ( run_arg_list_t *arglist, const char *name, cham_side_t defval ); +cham_job_t run_arg_get_job ( run_arg_list_t *arglist, const char *name, cham_job_t defval ); cham_normtype_t run_arg_get_ntype ( run_arg_list_t *arglist, const char *name, cham_normtype_t defval ); int run_arg_add_int ( run_arg_list_t *arglist, const char *name, int defval ); diff --git a/testing/values.c b/testing/values.c index 0a1b7db8d142fde1b3bd7a6d96737a81a9921a68..678b9e31c46b456c3cb714b664f1327392c89fe7 100644 --- a/testing/values.c +++ b/testing/values.c @@ -11,6 +11,7 @@ * @version 1.2.0 * @author Lucas Barros de Assis * @author Mathieu Faverge + * @author Alycia Lisito * @date 2022-02-22 * */ @@ -258,6 +259,76 @@ val_t pread_side( const char *str ) return val; } +/** + * @brief Convert the input string to a cham_job_t + * @param[in] str + * The input string + * @return The cham_job_t read. + */ +val_t pread_job( const char *str ) +{ + val_t val; + val.job = ChamNoVec; + + if ( ( strcasecmp( "ChamNoVec", str ) == 0 ) || + ( strcasecmp( "NoVec", str ) == 0 ) || + ( strcasecmp( "N", str ) == 0 ) ) + { + val.job = ChamNoVec; + } + else if ( ( strcasecmp( "ChamVec", str ) == 0 ) || + ( strcasecmp( "Vec", str ) == 0 ) ) + { + val.job = ChamVec; + } + else if ( ( strcasecmp( "ChamIvec", str ) == 0 ) || + ( strcasecmp( "Ivec", str ) == 0 ) || + ( strcasecmp( "I", str ) == 0 ) ) + { + val.job = ChamIvec; + } + else if ( ( strcasecmp( "ChamAllVec", str ) == 0 ) || + ( strcasecmp( "AllVec", str ) == 0 ) || + ( strcasecmp( "A", str ) == 0 ) ) + { + val.job = ChamAllVec; + } + else if ( ( strcasecmp( "ChamSVec", str ) == 0 ) || + ( strcasecmp( "SVec", str ) == 0 ) || + ( strcasecmp( "S", str ) == 0 ) ) + { + val.job = ChamSVec; + } + else if ( ( strcasecmp( "ChamOVec", str ) == 0 ) || + ( strcasecmp( "OVec", str ) == 0 ) || + ( strcasecmp( "O", str ) == 0 ) ) + { + val.job = ChamOVec; + } + else { + int v = atoi( str ); + if ( (v == ChamVec) || (v == (ChamVec-ChamNoVec)) ) { + val.job = ChamVec; + } + else if ( (v == ChamIvec) || (v == (ChamIvec-ChamNoVec)) ) { + val.job = ChamIvec; + } + else if ( (v == ChamAllVec) || (v == (ChamAllVec-ChamNoVec)) ) { + val.job = ChamAllVec; + } + else if ( (v == ChamSVec) || (v == (ChamSVec-ChamNoVec)) ) { + val.job = ChamSVec; + } + else if ( (v == ChamOVec) || (v == (ChamOVec-ChamNoVec)) ) { + val.job = ChamOVec; + } + else { + val.job = ChamNoVec; + } + } + return val; +} + /** * @brief Convert the input string to a cham_normtype_t * @param[in] str @@ -497,6 +568,47 @@ char *sprint_side( val_t val, int human, int nbchar, char *str_in ) return str_in+rc; } +/** + * @brief Convert the input string to a cham_job_t + * @param[in] str + * The input string + * @return The cham_job_t read. + */ +char *sprint_job( val_t val, int human, int nbchar, char *str_in ) +{ + int rc; + if ( human ) { + char *name; + switch( val.job ) { + case ChamNoVec: + name = "No Vec"; + break; + case ChamVec: + name = "Vec"; + break; + case ChamIvec: + name = "Ivec"; + break; + case ChamAllVec: + name = "All Vec"; + break; + case ChamSVec: + name = "S Vec"; + break; + case ChamOVec: + name = "O Vec"; + break; + default: + name = "ERR"; + } + rc = sprintf( str_in, " %-*s", nbchar, name ); + } + else { + rc = sprintf( str_in, ";%d", val.job ); + } + return str_in+rc; +} + /** * @brief Convert the input string to a cham_normtype_t * @param[in] str