mise en place de tous les chargements en MPI: expicite et implicite

This commit is contained in:
Gérard Rio 2023-09-05 12:47:10 +02:00
parent ce2d011450
commit d599e5fcb0
6 changed files with 1359 additions and 465 deletions

View file

@ -200,6 +200,8 @@ Charge::Charge () : // constructeur par defaut
,temps_cpu_chargement() ,temps_cpu_chargement()
#ifdef UTILISATION_MPI #ifdef UTILISATION_MPI
,temps_transfert_court(),temps_transfert_long(),temps_attente() ,temps_transfert_court(),temps_transfert_long(),temps_attente()
,tab_reqs1(),tab_reqs2(),tab_reqs3()
,tabV_transfert(),tabMat_transfert(),tab_six_faux_entiers()
#endif #endif
{// mise à jour de la valeur par défaut du chargement au cas où aucun chargement {// mise à jour de la valeur par défaut du chargement au cas où aucun chargement
@ -207,6 +209,19 @@ Charge::Charge () : // constructeur par defaut
nomtypeCharge ="TYPE1"; nomtypeCharge ="TYPE1";
tabType.Change_taille(1); tabType.Change_taille(1);
tabType(1) = 1.; tabType(1) = 1.;
#ifdef UTILISATION_MPI
// on définit les conteneurs de passage d'info
int taille_passage = 8;
tab_reqs1.Change_taille(taille_passage);
tab_reqs2.Change_taille(taille_passage);
tab_reqs3.Change_taille(taille_passage);
tabV_transfert.Change_taille(taille_passage);
tabMat_transfert.Change_taille(taille_passage);
tab_six_faux_entiers.Change_taille(taille_passage);
for (int i=1;i<=taille_passage;i++)tab_six_faux_entiers(i).Change_taille(6);
#endif
} }
Charge::~Charge () Charge::~Charge ()
{ if (f_charge != NULL) { if (f_charge != NULL)
@ -1305,5 +1320,115 @@ void Charge::Ecriture_base_info(ofstream& sort,const int cas)
}; };
}; };
#ifdef UTILISATION_MPI
// transfert du second membre "SM_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Charge::Transfert_SM(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
int& index_transfert,
const int & numail,
const int & numelem
)
{
temps_attente.Mise_en_route_du_comptage(); // comptage cpu
mpi::request & reqs1 = tab_reqs1(index_transfert); // pour simplifier
mpi::request & reqs2 = tab_reqs2(index_transfert); // pour simplifier
int taille_tableau = tab_six_faux_entiers.Taille();
// on récupère un signal du process 0
if (premier_passage) {premier_passage = false;}
else // on regarde l'activité , car au début avant le balayage de tous les éléments des tableaux
{if (reqs1.active()) reqs1.wait(); // les requests ne sont pas alimentés
if (reqs2.active()) reqs2.wait(); // car aucun transfert n'a encore été effectué
};
temps_attente.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu
Vecteur& six_faux_entiers = tab_six_faux_entiers(index_transfert); // pour simplifier
six_faux_entiers(1) = (double) numelem;
six_faux_entiers(2) = (double) numail;
six_faux_entiers(3) = (double) tyfront;
six_faux_entiers(4) = (double) num_front;
six_faux_entiers(5) = (double) SM_transfert.Taille();
six_faux_entiers(6) = (double) index_transfert;
// on transmet les numéros d'élément et de maillage etc.
reqs1 = six_faux_entiers.Ienvoi_MPI(0, 34);
temps_transfert_court.Arret_du_comptage(); // fin comptage cpu
// puis on transmets le vecteur résidu sauf si tyfront est négatif
if (tyfront > 0)
{temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
reqs2 = SM_transfert.Ienvoi_MPI(0,35);
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
// // debug
// cout << "\n debug Charge::Transfert_SM( proc= "<< ParaGlob::Monde()->rank()
// << " six_faux_entiers= " << six_faux_entiers
// << " SM_transfert= " << SM_transfert << flush;
// // fin debug
};
// ici on utilise un nouveau élément de tableau pour éviter d'écraser la précédente version qui peut être encore
// en transfert vers le proc 0
index_transfert++;
if (index_transfert > taille_tableau) // on fait une permutation circulaire
index_transfert = 1;// on revient au premier élément des tableaux de transfert
};
// transfert du second membre "SM_transfert" et de la matrice "MAT_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Charge::Transfert_MatSm(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
Mat_pleine * MAT_transfert,
int& index_transfert,
const int & numail,
const int & numelem
)
{
temps_attente.Mise_en_route_du_comptage(); // comptage cpu
mpi::request & reqs1 = tab_reqs1(index_transfert); // pour simplifier
mpi::request & reqs2 = tab_reqs2(index_transfert); // pour simplifier
mpi::request & reqs3 = tab_reqs3(index_transfert); // pour simplifier
int taille_tableau = tab_six_faux_entiers.Taille();
// on récupère un signal du process 0
if (premier_passage) {premier_passage = false;}
else // on regarde l'activité , car au début avant le balayage de tous les éléments des tableaux
{if (reqs1.active()) reqs1.wait(); // les requests ne sont pas alimentés
if (reqs2.active()) reqs2.wait(); // car aucun transfert n'a encore été effectué
if (reqs3.active()) reqs3.wait(); // car aucun transfert n'a encore été effectué
};
temps_attente.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu
Vecteur& six_faux_entiers = tab_six_faux_entiers(index_transfert); // pour simplifier
six_faux_entiers(1) = (double) numelem;
six_faux_entiers(2) = (double) numail;
six_faux_entiers(3) = (double) tyfront;
six_faux_entiers(4) = (double) num_front;
six_faux_entiers(5) = (double) SM_transfert.Taille();
six_faux_entiers(6) = (double) index_transfert;
// on transmet les numéros d'élément et de maillage etc.
reqs1 = six_faux_entiers.Ienvoi_MPI(0, 34);
// // debug
// cout << "\n debug Charge::Transfert_SM( proc= "<< ParaGlob::Monde()->rank()
// << " six_faux_entiers= " << six_faux_entiers
// << " SM_transfert= " << SM_transfert << flush;
// // fin debug
temps_transfert_court.Arret_du_comptage(); // fin comptage cpu
// puis on transmets le vecteur résidu
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
reqs2 = SM_transfert.Ienvoi_MPI(0,35);
// puis on transmets éventuellementla matrice de raideur
if (MAT_transfert != NULL)
reqs3 = MAT_transfert->Ienvoi_MPI(0,36);
// ici on utilise un nouveau élément de tableau pour éviter d'écraser la précédente version qui peut être encore
// en transfert vers le proc 0
index_transfert++;
if (index_transfert > taille_tableau) // on fait une permutation circulaire
index_transfert = 1;// on revient au premier élément des tableaux de transfert
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
};
#endif

View file

@ -369,14 +369,47 @@ class Charge
// de la variation du pas de temps // de la variation du pas de temps
// mise à jour avec la méthode : Change_temps_fin_non_stricte(int methode) // mise à jour avec la méthode : Change_temps_fin_non_stricte(int methode)
Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
#ifdef UTILISATION_MPI #ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process // cas d'un calcul parallèle: // passage des infos entre process
Temps_CPU_HZpp temps_transfert_court ; Temps_CPU_HZpp temps_transfert_court ;
Temps_CPU_HZpp temps_transfert_long ; Temps_CPU_HZpp temps_transfert_long ;
Temps_CPU_HZpp temps_attente ; Temps_CPU_HZpp temps_attente ;
// on définit les conteneurs de passage d'info
Tableau <mpi::request > tab_reqs1;
Tableau <mpi::request > tab_reqs2;
Tableau <mpi::request > tab_reqs3;
Tableau <Vecteur > tabV_transfert;
Tableau <Mat_pleine> tabMat_transfert;
Tableau <Vecteur > tab_six_faux_entiers;
// transfert du second membre "SM_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Transfert_SM(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
int& index_transfert,
const int & numail,
const int & numelem
);
// transfert du second membre "SM_transfert" et de la matrice "MAT_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Transfert_MatSm(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
Mat_pleine * MAT_transfert,
int& index_transfert,
const int & numail,
const int & numelem
);
#endif #endif
Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
// les autres parametres relatif au temps // les autres parametres relatif au temps
//-// double deltatmaxi; // increment de temps maxi //-// double deltatmaxi; // increment de temps maxi

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@
EnumLangue ParaGlob::langueHZ = FRANCAIS; // langue utilisée pour les entrées sorties EnumLangue ParaGlob::langueHZ = FRANCAIS; // langue utilisée pour les entrées sorties
int ParaGlob::nbComposantesTenseur = 1; // nombre de composantes par defaut a 1 int ParaGlob::nbComposantesTenseur = 1; // nombre de composantes par defaut a 1
int ParaGlob::nivImpression = 2; // niveau d'impression int ParaGlob::nivImpression = 2; // niveau d'impression
string ParaGlob::nbVersion = "7.018" ; // numéro de version du logiciel string ParaGlob::nbVersion = "7.019" ; // numéro de version du logiciel
string ParaGlob::NbVersionsurfichier = ""; // numéro de version lue en entrée fichier string ParaGlob::NbVersionsurfichier = ""; // numéro de version lue en entrée fichier
int ParaGlob::nb_diggit_double_calcul= 17; // nombre de chiffre significatifs utilisé pour int ParaGlob::nb_diggit_double_calcul= 17; // nombre de chiffre significatifs utilisé pour
// l'affichage des double précision pour l'archivage // l'affichage des double précision pour l'archivage

View file

@ -34,55 +34,55 @@
short int Temps_CPU_HZpp::impre_schem_XML=0; short int Temps_CPU_HZpp::impre_schem_XML=0;
// CONSTRUCTEURS : // CONSTRUCTEURS :
// par défaut on initialise à défaut //// par défaut on initialise à défaut
Temps_CPU_HZpp::Temps_CPU_HZpp(): //Temps_CPU_HZpp::Temps_CPU_HZpp():
temps_user(0),debut_temps_user(0),comptage_en_cours(false) // temps_user(0),debut_temps_user(0),comptage_en_cours(false)
{}; // {};
// mise en route du comptage //// mise en route du comptage
void Temps_CPU_HZpp::Mise_en_route_du_comptage() //void Temps_CPU_HZpp::Mise_en_route_du_comptage()
{ // {
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST //#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST
if (!comptage_en_cours) // if (!comptage_en_cours)
{ comptage_en_cours = true; // { comptage_en_cours = true;
// on récup le temps depuis le début : c'est la seule qui marche pour le cumul // // on récup le temps depuis le début : c'est la seule qui marche pour le cumul
//high_resolution_clock ////high_resolution_clock
// -- pour le temps user // // -- pour le temps user
// boost::chrono::process_user_cpu_clock::duration tuti_1 //// boost::chrono::process_user_cpu_clock::duration tuti_1
// = boost::chrono::process_user_cpu_clock::now().time_since_epoch(); //// = boost::chrono::process_user_cpu_clock::now().time_since_epoch();
boost::chrono::high_resolution_clock::duration tuti_1 // boost::chrono::high_resolution_clock::duration tuti_1
= boost::chrono::high_resolution_clock::now().time_since_epoch(); // = boost::chrono::high_resolution_clock::now().time_since_epoch();
// on transforme en microseconde // // on transforme en microseconde
// debut_temps_user = boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1); //// debut_temps_user = boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1);
debut_temps_user = boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1); // debut_temps_user = boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1);
}; // };
#endif //#endif
}; // };
// arrêt du comptage et cumul //// arrêt du comptage et cumul
void Temps_CPU_HZpp::Arret_du_comptage() //void Temps_CPU_HZpp::Arret_du_comptage()
{ // comptage // { // comptage
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST //#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST
if (comptage_en_cours) // if (comptage_en_cours)
{ comptage_en_cours = false; // { comptage_en_cours = false;
// on récup le temps en nano depuis le début // // on récup le temps en nano depuis le début
//
// -- pour le temps user // // -- pour le temps user
// boost::chrono::process_user_cpu_clock::duration tuti_1 //// boost::chrono::process_user_cpu_clock::duration tuti_1
// = boost::chrono::process_user_cpu_clock::now().time_since_epoch(); //// = boost::chrono::process_user_cpu_clock::now().time_since_epoch();
boost::chrono::high_resolution_clock::duration tuti_1 // boost::chrono::high_resolution_clock::duration tuti_1
= boost::chrono::high_resolution_clock::now().time_since_epoch(); // = boost::chrono::high_resolution_clock::now().time_since_epoch();
// on transforme en microseconde et on incrémente // // on transforme en microseconde et on incrémente
// temps_user += boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1) - debut_temps_user; //// temps_user += boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1) - debut_temps_user;
temps_user += boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1) - debut_temps_user; // temps_user += boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1) - debut_temps_user;
}; // };
//
#endif //#endif
}; // };
// affichage // affichage
// si niveau = 1 ou plus, on a plus d'info pour le débug par exemple // si niveau = 1 ou plus, on a plus d'info pour le débug par exemple
void Temps_CPU_HZpp::Affiche(ostream & sort,int niveau) void Temps_CPU_HZpp::Affiche(ostream & sort,int niveau)
{ // on arrondi en ms { // on arrondi en ms
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST #ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST

View file

@ -155,10 +155,32 @@ class Temps_CPU_HZpp
// surcharge de l'operator d'ecriture // surcharge de l'operator d'ecriture
friend ostream & operator << (ostream & sort , const Temps_CPU_HZpp & a); friend ostream & operator << (ostream & sort , const Temps_CPU_HZpp & a);
private :
// VARIABLES PROTEGEES :
// def des variables du process
bool comptage_en_cours; // indique si oui ou non on est dans une phase de comptage
// microseconds temps_user;
nanoseconds temps_user;
// def des variables de début: au lieu d'utiliser un time_point et une duration
// j'utilise directement des microsecondes car sinon tout est en nanoseconde et
// il faut redéfinir un compteur en microsecondes: c'est une solution possible qui a été faite
// dans Chrono_GR.h mais je ne suis pas sûr que 1) cela soit indispensable, 2) que cela soit pérenne
// car j'ai été obligé de récupérer du code de boost et de l'adapter du coup c'est une usine dont je ne
// suis pas sûr de bien tout maîtriser donc j'utilise une solution plus simple
// microseconds debut_temps_user;
nanoseconds debut_temps_user;
// gestion schéma XML
static short int impre_schem_XML;
public : public :
// CONSTRUCTEURS : // CONSTRUCTEURS :
Temps_CPU_HZpp(); // par défaut, initialise à défaut // Temps_CPU_HZpp(); // par défaut, initialise à défaut
Temps_CPU_HZpp():
temps_user(0),debut_temps_user(0),comptage_en_cours(false)
{};
// constructeur de copie // constructeur de copie
Temps_CPU_HZpp(const Temps_CPU_HZpp& tps): Temps_CPU_HZpp(const Temps_CPU_HZpp& tps):
temps_user(tps.temps_user),debut_temps_user(tps.debut_temps_user) temps_user(tps.temps_user),debut_temps_user(tps.debut_temps_user)
@ -169,9 +191,46 @@ class Temps_CPU_HZpp
// --- METHODES PUBLIQUES : // --- METHODES PUBLIQUES :
// mise en route du comptage // mise en route du comptage
void Mise_en_route_du_comptage(); void Mise_en_route_du_comptage()
{
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST
if (!comptage_en_cours)
{ comptage_en_cours = true;
// on récup le temps depuis le début : c'est la seule qui marche pour le cumul
//high_resolution_clock
// -- pour le temps user
// boost::chrono::process_user_cpu_clock::duration tuti_1
// = boost::chrono::process_user_cpu_clock::now().time_since_epoch();
boost::chrono::high_resolution_clock::duration tuti_1
= boost::chrono::high_resolution_clock::now().time_since_epoch();
// on transforme en microseconde
// debut_temps_user = boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1);
debut_temps_user = boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1);
};
#endif
};
// arrêt du comptage et cumul // arrêt du comptage et cumul
void Arret_du_comptage(); void Arret_du_comptage()
{ // comptage
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST
if (comptage_en_cours)
{ comptage_en_cours = false;
// on récup le temps en nano depuis le début
// -- pour le temps user
// boost::chrono::process_user_cpu_clock::duration tuti_1
// = boost::chrono::process_user_cpu_clock::now().time_since_epoch();
boost::chrono::high_resolution_clock::duration tuti_1
= boost::chrono::high_resolution_clock::now().time_since_epoch();
// on transforme en microseconde et on incrémente
// temps_user += boost::chrono::duration_cast<boost::chrono::microseconds>(tuti_1) - debut_temps_user;
temps_user += boost::chrono::duration_cast<boost::chrono::nanoseconds>(tuti_1) - debut_temps_user;
};
#endif
};
// indique si oui ou non, on est en phase de comptage // indique si oui ou non, on est en phase de comptage
// permet de fermer un comptage en catastrophe, // permet de fermer un comptage en catastrophe,
bool Comptage_en_cours() const {return comptage_en_cours;}; bool Comptage_en_cours() const {return comptage_en_cours;};
@ -218,24 +277,6 @@ class Temps_CPU_HZpp
void SchemaXML_Temps_CPU_HZpp(ofstream& sort,const Enum_IO_XML enu) const ; void SchemaXML_Temps_CPU_HZpp(ofstream& sort,const Enum_IO_XML enu) const ;
private :
// VARIABLES PROTEGEES :
// def des variables du process
bool comptage_en_cours; // indique si oui ou non on est dans une phase de comptage
// microseconds temps_user;
nanoseconds temps_user;
// def des variables de début: au lieu d'utiliser un time_point et une duration
// j'utilise directement des microsecondes car sinon tout est en nanoseconde et
// il faut redéfinir un compteur en microsecondes: c'est une solution possible qui a été faite
// dans Chrono_GR.h mais je ne suis pas sûr que 1) cela soit indispensable, 2) que cela soit pérenne
// car j'ai été obligé de récupérer du code de boost et de l'adapter du coup c'est une usine dont je ne
// suis pas sûr de bien tout maîtriser donc j'utilise une solution plus simple
// microseconds debut_temps_user;
nanoseconds debut_temps_user;
// gestion schéma XML
static short int impre_schem_XML;
}; };