From 1a6a3a54cc5a82ca7f4be14de74a3e75091d1e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FEL=C5=A0=C3=96CI=20Marek?= <marek.felsoci@inria.fr> Date: Sun, 5 Nov 2023 18:06:51 +0100 Subject: [PATCH] Keep only the linear system solving test --- include/main.h | 11 -- src/help.c | 5 - src/main.c | 51 +------- src/testHMAT.c | 316 ++++++++++++++++++------------------------------- 4 files changed, 120 insertions(+), 263 deletions(-) diff --git a/include/main.h b/include/main.h index 3cc290f..38ba123 100644 --- a/include/main.h +++ b/include/main.h @@ -45,17 +45,6 @@ extern ScalarType stype; /*! \brief Wavelength (for oscillatory kernels). */ extern double lambda; -/*! \brief List of algorithms that we can test. */ -enum algo { - _undefined, - _gemvHMAT, - _solveHMAT, - _inverseHMAT -} ; - -/*! \brief Algorithms that we want to test. */ -extern enum algo testedAlgo; - /*! \brief Flag to use simple assembly routine for HMAT (default is 0). It can be changed with --use_simple_assembly (read in readFlagsTestHMAT() in hmat.c) diff --git a/src/help.c b/src/help.c index 6a71934..1fd7402 100644 --- a/src/help.c +++ b/src/help.c @@ -24,11 +24,6 @@ int printHelp() { " -height: Height of the cylinder. Default is 4.\n" " For FEM/BEM, the BEM is done on the outer surface of the cylinder (without the upper and lower disks).\n" "\n" - " Choice of the tested algorithm (no default):\n" - " -gemvhmat: gemv HMAT.\n" - " -solvehmat: solve HMAT.\n" - " -inversehmat: inverse HMAT.\n" - "\n" " Options for HMAT tests\n" " --use_simple_assembly: Using simple assembly routine for HMAT. Default: NO.\n" " --hmat_divider: Value of the Hmat clustering divider (number of children per box). Default: 2.\n" diff --git a/src/main.c b/src/main.c index 37d3c6a..83f8bd4 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,6 @@ int simplePrec = 0; int complexALGO = 1; ScalarType stype = DOUBLE_COMPLEX; double lambda; -enum algo testedAlgo = _undefined; int use_simple_assembly = 0; int divider = 2; int hmat_residual = 0; @@ -44,31 +43,6 @@ int main(int argc, char **argv) { ierr=printHelp() ; return ierr; } - /* --- Choix de l'algo a tester (_undefined par defaut) --- */ - if (MpfArgHasName(&argc, argv, 1, "-gemvhmat") > 0) { - testedAlgo = _gemvHMAT ; - printf("Testing : gemv HMAT.\n") ; - } - if (MpfArgHasName(&argc, argv, 1, "-solvehmat") > 0) { - testedAlgo = _solveHMAT ; - printf("Testing : solve HMAT.\n") ; - } - if (MpfArgHasName(&argc, argv, 1, "-inversehmat") > 0) { - testedAlgo = _inverseHMAT ; - printf("Testing : inverse HMAT.\n") ; - } - /* Check the test */ - switch(testedAlgo) { - case _gemvHMAT: - case _solveHMAT: - case _inverseHMAT: - // nothing - break; - case _undefined: - default: - SETERRQ(1, "No algorithm selected. Please choose one (use -h/--help for usage)."); - break; - } /* ------------------------------------------------------------------------- */ /* ---------------------- INITIATION DE MPF (PARALLELE) -------------------*/ @@ -76,18 +50,8 @@ int main(int argc, char **argv) { ierr=SCAB_Init(&argc, &argv) ; CHKERRQ(ierr) ; - switch(testedAlgo) { - case _gemvHMAT: - case _solveHMAT: - case _inverseHMAT: - ierr=readFlagsTestHMAT(&argc, &argv) ; CHKERRQ(ierr) ; - ierr = init_hmat_interface(); CHKERRQ(ierr); - break; - case _undefined: - default: - SETERRQ(1, "No algorithm selected. Please choose one (use -h/--help for usage)."); - break; - } + ierr=readFlagsTestHMAT(&argc, &argv) ; CHKERRQ(ierr) ; + ierr = init_hmat_interface(); CHKERRQ(ierr); /* ------------------------------------------------------------------------- */ /* --------------------- DECODAGE DE LA LIGNE D'OPTIONS -------------------*/ @@ -153,16 +117,7 @@ int main(int argc, char **argv) { ierr = prepareTEST() ; CHKERRQ(ierr) ; double relative_error; /* Run the test */ - switch(testedAlgo) { - case _gemvHMAT: - case _solveHMAT: - case _inverseHMAT: - ierr = testHMAT(&relative_error) ; CHKERRQ(ierr) ; - break; - default: - SETERRQ(1, "Unknown algorithm=%d", testedAlgo); - break; - } + ierr = testHMAT(&relative_error) ; CHKERRQ(ierr) ; int error_exit = 0; if(relative_error > max_error) { error_exit = 1; diff --git a/src/testHMAT.c b/src/testHMAT.c index 55e01f8..bd989a4 100644 --- a/src/testHMAT.c +++ b/src/testHMAT.c @@ -57,219 +57,137 @@ int testHMAT(double * relative_error) { printf("Ratio: %g\n", (double)info.compressed_size/info.uncompressed_size); } - /* Switch on the various HMAT tests */ + /* Perform a HMAT solve */ + printf("\n") ; + + hmat_matrix_t* hmatrix_orig = NULL; + void *solCLA_orig = NULL; + void *solCLA_sum = NULL; + double normRes, normOrig, temps_refine=-getTime(); + int nbIter = 0; + if (hmat_residual) { + hmatrix_orig = hi->copy(hmatrix); // ideally, we do a copy with lower accuracy for factorisation + /* Vector to duplicate solCLA */ + solCLA_orig = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solCLA_orig) ; + /* Norm of the originaal RHS */ + ierr = computeVecNorm(solCLA, &normOrig); CHKERRQ(ierr); + } + if (hmat_refine) { + /* Vector to accumulate solCLA */ + solCLA_sum = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solCLA_sum) ; + } + + /* Factorize the H-matrix */ + + printf("\n**** Factorizing HMAT...\n") ; + temps_initial = getTime (); + + hmat_factorization_context_t ctx; + hmat_factorization_context_init(&ctx); + ctx.progress = &mpf_hmat_settings.progress; + ctx.progress->user_data = NULL; + ctx.factorization = mpf_hmat_settings.factorization_type; + ierr = hi->factorize_generic(hmatrix, &ctx); CHKERRQ(ierr); + + temps_final = getTime (); + temps_cpu = (temps_final - temps_initial) ; + printf("<PERFTESTS> TpsCpuFacto%s = %f \n", postfix_async, temps_cpu) ; - switch(testedAlgo) { - case _gemvHMAT: + temps_refine -= temps_cpu; // We do not count facto in the iterative refinement timer + + /* display some informations (synchronous) */ + if (hmat_get_sync_exec()) { + hmat_info_t info; + hi->get_info(hmatrix, &info); + printf("Compressed size: %ld\n", info.compressed_size); + printf("<PERFTESTS> FactorizedSizeMb = %f \n", (double)info.compressed_size*Mpf_stype_size[stype]/1024./1024.) ; + printf("Uncompressed size: %ld\n", info.uncompressed_size); + printf("Ratio: %g\n", (double)info.compressed_size/info.uncompressed_size); + } - /* Appelle le produit mat.vec : A.rhs -> solHMAT */ + /* Solve the system : A-1.solCLA -> solCLA */ - printf("\n**** Computing HMAT product...\n") ; - void *solHMAT = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solHMAT) ; - temps_initial = getTime (); + printf("\n**** Solve HMAT%s...\n", hmat_refine ? " with Iterative Refinement" : "") ; - if (simplePrec) - doubleToSimple(rhs, vectorSize); +_refineLoop: // Iterative Refinement loop + nbIter++ ; + if (hmat_residual) { + /* Duplicate the RHS solCLA into solCLA_orig */ + memcpy(solCLA_orig, solCLA, vectorSize*sizeof(D_type)); + } - /* Compute the mat.vec product A.rhs -> solHMAT */ - ierr = hi->gemv('N', Mpf_pone[stype], hmatrix, rhs, Mpf_zero[stype], solHMAT, nbRHS); + temps_initial = getTime (); - if (simplePrec) { - simpleToDouble(solHMAT, vectorSize); - simpleToDouble(rhs, vectorSize); - } + if (simplePrec) + doubleToSimple(solCLA, vectorSize); - if (solHMAT) MpfFree(solHMAT); - solHMAT=NULL; - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuGEMV%s = %f \n", postfix_async, temps_cpu) ; + ierr = hi->solve_systems(hmatrix, solCLA, nbRHS); CHKERRQ(ierr); - /* Compare les 2 produits matrice-vecteur */ + if (simplePrec) + simpleToDouble(solCLA, vectorSize); - printf("\n**** Comparing results...\n") ; - ierr=computeRelativeError(solHMAT, solCLA, relative_error); CHKERRQ(ierr); + temps_final = getTime (); + temps_cpu = (temps_final - temps_initial) ; + printf("<PERFTESTS> TpsCpuSolve%s = %f \n", postfix_async, temps_cpu) ; - printf("<PERFTESTS> Error = %.4e \n", *relative_error); - if (solHMAT) MpfFree(solHMAT); - solHMAT=NULL ; - break; + /* Compute the residual solCLA_orig-A_orig.solCLA */ - case _solveHMAT: + if (hmat_residual) { + temps_initial = getTime (); + if (simplePrec) { + doubleToSimple(solCLA, vectorSize); + doubleToSimple(solCLA_orig, vectorSize); + } + ierr = hi->gemv('N', Mpf_mone[stype], hmatrix_orig, solCLA, Mpf_pone[stype], solCLA_orig, nbRHS); + if (simplePrec) { + simpleToDouble(solCLA, vectorSize); + simpleToDouble(solCLA_orig, vectorSize); + } + temps_final = getTime (); + temps_cpu = (temps_final - temps_initial) ; + printf("<PERFTESTS> TpsCpuGEMV%s = %f \n", postfix_async, temps_cpu) ; + ierr = computeVecNorm(solCLA_orig, &normRes); CHKERRQ(ierr); + printf("<PERFTESTS> Residual_%d = %.4e \n", nbIter, normRes/normOrig); + // Test if convergence is achieved or if iteration number is too large + if (normRes/normOrig < mpf_hmat_settings.acaEpsilon/10 || nbIter > 20) { + // TODO stop the computation if the residual norm increases printf("\n") ; + printf("<PERFTESTS> NbIterRefinement = %d \n", nbIter); + hmat_refine=0; + } + } + if (solCLA_sum) { + /* Compute the updated solution solCLA_sum += solCLA */ + size_t k; + for (k=0 ; k<vectorSize ; k++) + ((double*)solCLA_sum)[k] += ((double*)solCLA)[k]; + ierr=computeRelativeError(solCLA_sum, rhs, relative_error) ; CHKERRQ(ierr) ; + printf("<PERFTESTS> Error_%d = %.4e \n", nbIter, *relative_error); + } + if (hmat_refine) { + /* Copy the updated RHS of the system solCLA_orig into solCLA */ + memcpy(solCLA, solCLA_orig, vectorSize*sizeof(D_type)); + goto _refineLoop; + } - hmat_matrix_t* hmatrix_orig = NULL; - void *solCLA_orig = NULL; - void *solCLA_sum = NULL; - double normRes, normOrig, temps_refine=-getTime(); - int nbIter = 0; - if (hmat_residual) { - hmatrix_orig = hi->copy(hmatrix); // ideally, we do a copy with lower accuracy for factorisation - /* Vector to duplicate solCLA */ - solCLA_orig = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solCLA_orig) ; - /* Norm of the originaal RHS */ - ierr = computeVecNorm(solCLA, &normOrig); CHKERRQ(ierr); - } - if (hmat_refine) { - /* Vector to accumulate solCLA */ - solCLA_sum = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solCLA_sum) ; - } - - /* Factorize the H-matrix */ - - printf("\n**** Factorizing HMAT...\n") ; - temps_initial = getTime (); - - hmat_factorization_context_t ctx; - hmat_factorization_context_init(&ctx); - ctx.progress = &mpf_hmat_settings.progress; - ctx.progress->user_data = NULL; - ctx.factorization = mpf_hmat_settings.factorization_type; - ierr = hi->factorize_generic(hmatrix, &ctx); CHKERRQ(ierr); - - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuFacto%s = %f \n", postfix_async, temps_cpu) ; - - temps_refine -= temps_cpu; // We do not count facto in the iterative refinement timer - - /* display some informations (synchronous) */ - if (hmat_get_sync_exec()) { - hmat_info_t info; - hi->get_info(hmatrix, &info); - printf("Compressed size: %ld\n", info.compressed_size); - printf("<PERFTESTS> FactorizedSizeMb = %f \n", (double)info.compressed_size*Mpf_stype_size[stype]/1024./1024.) ; - printf("Uncompressed size: %ld\n", info.uncompressed_size); - printf("Ratio: %g\n", (double)info.compressed_size/info.uncompressed_size); - } - - /* Solve the system : A-1.solCLA -> solCLA */ - - printf("\n**** Solve HMAT%s...\n", hmat_refine ? " with Iterative Refinement" : "") ; + if (hmatrix_orig) hi->destroy(hmatrix_orig); + hmatrix_orig=NULL; + if (solCLA_orig) MpfFree(solCLA_orig); + solCLA_orig=NULL ; + if (solCLA_sum) { // If solCLA_sum has been allocated, I use it as a replacement for solCLA + MpfFree(solCLA) ; + solCLA=solCLA_sum ; + temps_refine += getTime(); + printf("<PERFTESTS> TpsCpuRefinement%s = %f \n", postfix_async, temps_refine) ; -_refineLoop: // Iterative Refinement loop - nbIter++ ; - if (hmat_residual) { - /* Duplicate the RHS solCLA into solCLA_orig */ - memcpy(solCLA_orig, solCLA, vectorSize*sizeof(D_type)); - } - - temps_initial = getTime (); - - if (simplePrec) - doubleToSimple(solCLA, vectorSize); - - ierr = hi->solve_systems(hmatrix, solCLA, nbRHS); CHKERRQ(ierr); - - if (simplePrec) - simpleToDouble(solCLA, vectorSize); - - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuSolve%s = %f \n", postfix_async, temps_cpu) ; - - /* Compute the residual solCLA_orig-A_orig.solCLA */ - - if (hmat_residual) { - temps_initial = getTime (); - if (simplePrec) { - doubleToSimple(solCLA, vectorSize); - doubleToSimple(solCLA_orig, vectorSize); - } - ierr = hi->gemv('N', Mpf_mone[stype], hmatrix_orig, solCLA, Mpf_pone[stype], solCLA_orig, nbRHS); - if (simplePrec) { - simpleToDouble(solCLA, vectorSize); - simpleToDouble(solCLA_orig, vectorSize); - } - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuGEMV%s = %f \n", postfix_async, temps_cpu) ; - ierr = computeVecNorm(solCLA_orig, &normRes); CHKERRQ(ierr); - printf("<PERFTESTS> Residual_%d = %.4e \n", nbIter, normRes/normOrig); - // Test if convergence is achieved or if iteration number is too large - if (normRes/normOrig < mpf_hmat_settings.acaEpsilon/10 || nbIter > 20) { - // TODO stop the computation if the residual norm increases - printf("\n") ; - printf("<PERFTESTS> NbIterRefinement = %d \n", nbIter); - hmat_refine=0; - } - } - if (solCLA_sum) { - /* Compute the updated solution solCLA_sum += solCLA */ - size_t k; - for (k=0 ; k<vectorSize ; k++) - ((double*)solCLA_sum)[k] += ((double*)solCLA)[k]; - ierr=computeRelativeError(solCLA_sum, rhs, relative_error) ; CHKERRQ(ierr) ; - printf("<PERFTESTS> Error_%d = %.4e \n", nbIter, *relative_error); - } - if (hmat_refine) { - /* Copy the updated RHS of the system solCLA_orig into solCLA */ - memcpy(solCLA, solCLA_orig, vectorSize*sizeof(D_type)); - goto _refineLoop; - } - - if (hmatrix_orig) hi->destroy(hmatrix_orig); - hmatrix_orig=NULL; - if (solCLA_orig) MpfFree(solCLA_orig); - solCLA_orig=NULL ; - if (solCLA_sum) { // If solCLA_sum has been allocated, I use it as a replacement for solCLA - MpfFree(solCLA) ; - solCLA=solCLA_sum ; - temps_refine += getTime(); - printf("<PERFTESTS> TpsCpuRefinement%s = %f \n", postfix_async, temps_refine) ; - - } - - /* Compare the two vectors solCLA and rhs */ - - printf("\n**** Comparing results...\n") ; - ierr=computeRelativeError(solCLA, rhs, relative_error); CHKERRQ(ierr); - - printf("<PERFTESTS> Error = %.4e \n", *relative_error); - break; - case _inverseHMAT: - - /* Inverse the H-matrix */ - - printf("\n**** Inversing HMAT...\n") ; - temps_initial = getTime (); - - hi->inverse(hmatrix); - - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuInversion%s = %f \n", postfix_async, temps_cpu) ; - - /* Compute the gemv : A-1.solCLA -> solCLA */ - - printf("\n**** GEMV HMAT...\n") ; - temps_initial = getTime (); - - if (simplePrec) - doubleToSimple(solCLA, vectorSize); - - void *solCLA2 = MpfCalloc(vectorSize, sizeof(D_type)) ; CHKPTRQ(solCLA) ; - memcpy(solCLA2, solCLA, vectorSize*sizeof(D_type)); - ierr = hi->gemv('N', Mpf_pone[stype], hmatrix, solCLA2, Mpf_zero[stype], solCLA, nbRHS); - MpfFree(solCLA2); - - if (simplePrec) - simpleToDouble(solCLA, vectorSize); - - temps_final = getTime (); - temps_cpu = (temps_final - temps_initial) ; - printf("<PERFTESTS> TpsCpuGEMV%s = %f \n", postfix_async, temps_cpu) ; - - /* Compare the two vectors solCLA and rhs */ - - printf("\n**** Comparing results...\n") ; - ierr=computeRelativeError(solCLA, rhs, relative_error); CHKERRQ(ierr); - - printf("<PERFTESTS> Error = %.4e \n", *relative_error); - break; - default: - break; - } /* switch(testedAlgo) */ + } + + /* Compare the two vectors solCLA and rhs */ + + printf("\n**** Comparing results...\n") ; + ierr=computeRelativeError(solCLA, rhs, relative_error); CHKERRQ(ierr); + + printf("<PERFTESTS> Error = %.4e \n", *relative_error); /* Destroys the HMAT structure */ #ifdef TESTFEMBEM_DUMP_HMAT -- GitLab