]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Commentaires
authorrahuel <rahuel@opencascade.com>
Fri, 25 Jan 2008 14:53:50 +0000 (14:53 +0000)
committerrahuel <rahuel@opencascade.com>
Fri, 25 Jan 2008 14:53:50 +0000 (14:53 +0000)
src/ParaMEDMEM/MPI_AccessDEC.cxx

index d72df99d9af4cde5ce43a20044dd6659a433c402..39f284df1c9f0dee025be4a67f87f9e9922c3f9b 100644 (file)
@@ -374,6 +374,60 @@ int MPI_AccessDEC::AllToAllv( void* sendbuf, int* sendcounts, int* sdispls,
   return sts ;
 }
 
+/*
+MPI_AccessDEC et la gestion des SendBuffers :
+=============================================
+
+. Comme dans les communications collectives on n'envoie que des
+  parties du meme buffer à chaque process "target", il faut s'assurer
+  en asynchrone que toutes ces parties sont disponibles pour
+  pouvoir liberer le buffer.
+
+. On suppose que ces buffers ont ete alloues avec un new double[]
+
+. La structure SendBuffStruct permet de conserver l'adresse du buffer
+  et de gerer un compteur de references de ce buffer. Elle comporte
+  aussi MPI_Datatype pour pouvoir faire un delete [] (double *) ...
+  lorsque le compteur est null.
+
+. La map _MapOfSendBuffers etablit la correspondance entre chaque
+  RequestId obtenu de MPI_Access->ISend(...) et un SendBuffStruct
+  pour chaque "target" d'une partie du buffer.
+
+. Tout cela ne concerne que les envois asynchrones. En synchrone,
+  on detruit senbuf juste apres l'avoir transmis.
+*/
+
+/*
+MPI_AccessDEC et la gestion des RecvBuffers :
+=============================================
+
+S'il n'y a pas d'interpolation, rien de particulier n'est fait.
+
+Avec interpolation pour chaque target :
+---------------------------------------
+. On a _TimeMessages[target] qui est un vecteur de TimesMessages.
+  On en a 2 dans notre cas avec une interpolation lineaire qui
+  contiennent le time(t0)/deltatime precedent et le dernier
+  time(t1)/deltatime.
+
+. On a _DataMessages[target] qui est un vecteur de DatasMessages
+  On en a 2 dans notre cas avec une interpolation lineaire qui
+  contiennent les donnees obtenues par Recv au time(t0)/deltatime
+  precedent et au dernier time(t1)/deltatime.
+
+. Au temps _t(t*) du processus courrant on effectue l'interpolation
+  entre les valeurs des 2 DatasMessages que l'on rend dans la
+  partie de recvbuf correspondant au target pourvu que t0 < t* <= t1.
+
+. Par suite de la difference des "deltatimes" entre process, on
+  peut avoir t0 < t1 < t* auquel cas on aura une extrapolation.
+
+. Les vecteurs _OutOfTime, _DataMessagesRecvCount et _DataMessagesType
+  contiennent pour chaque target true si t* > dernier t1, recvcount et
+  MPI_Datatype pour finaliser la gestion des messages a la fin.
+*/
+
 /*!
 Send a TimeMessage to all targets of IntraCommunicator
 Receive the TimeMessages from targets of IntraCommunicator if necessary.
@@ -452,7 +506,7 @@ int MPI_AccessDEC::AllToAllTime( void* sendbuf, int sendcount , MPI_Datatype sen
     }
   }
 
-//CheckTime + DoRecv
+//CheckTime + DoRecv + DoInterp
   if ( recvbuf && recvcount ) {
     for ( target = 0 ; target < _GroupSize ; target++ ) {
        int recvsize = recvcount*_MPIAccess->Extent( recvtype ) ;
@@ -519,6 +573,22 @@ int MPI_AccessDEC::AllToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
     CheckSent() ;
   }
 
+/*
+. DoSend :
+  + On cree un TimeMessage (voir cette structure dans MPI_Access).
+  + Si l'on est en asynchrone on cree deux structures SendBuffStruct
+    aSendTimeStruct et aSendDataStruct que l'on remplit.
+  + On remplit la structure aSendTimeMessage avec time/deltatime du
+    process courant. "deltatime" doit etre nul s'il s'agit du dernier
+    pas de temps.
+  + Puis pour chaque "target", on envoie le TimeMessage et la partie
+    de sendbuf concernee par ce target.
+  + Si l'on est en asynchrone, on incremente le compteur et on ajoute
+    a _MapOfSendBuffers aSendTimeStruct et aSendDataStruct avec les
+    identifieurs SendTimeRequestId et SendDataRequestId recus de
+    MPI_Access->Send(...).
+  + Et enfin si l'on est en synchrone, on detruit les SendMessages.
+*/
 //DoSend : Time + SendBuff
   SendBuffStruct * aSendTimeStruct = NULL ;
   SendBuffStruct * aSendDataStruct = NULL ;
@@ -604,7 +674,18 @@ int MPI_AccessDEC::AllToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
     }
   }
 
-//CheckTime + DoRecv
+/*
+. CheckTime + DoRecv + DoInterp
+  + Pour chaque target on appelle CheckTime
+  + Si on a un TimeInterpolator et si le message temps du target
+    n'est pas le premier, on appelle l'interpolateur qui stocke
+    ses resultats dans la partie du buffer de reception qui
+    correspond au "target".
+  + Sinon, on recopie les donnees recues pour ce premier pas de
+    temps dans la partie du buffer de reception qui correspond au
+    "target".
+*/
+//CheckTime + DoRecv + DoInterp
   if ( recvbuf ) {
     for ( target = 0 ; target < _GroupSize ; target++ ) {
        if ( recvcounts[target] ) {
@@ -670,6 +751,39 @@ int MPI_AccessDEC::AllToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
   return sts ;
 }
 
+/*
+. CheckTime(recvcount , recvtype , target , UntilEnd)
+  + Au depart, on lit le premier "Message-temps" dans
+    &(*_TimeMessages)[target][1] et le premier message de donnees
+    dans le buffer alloue (*_DataMessages)[target][1].
+  + Par convention deltatime des messages temps est nul si c'est le
+    dernier.
+  + Boucle while : _t(t*) est le temps courant du processus.
+    "tant que _t(t*) est superieur au temps du "target"
+     (*_TimeMessages)[target][1].time et que
+     (*_TimeMessages)[target][1].deltatime n'est pas nul",
+    ainsi en fin de boucle on aura :
+     _t(t*) <= (*_TimeMessages)[target][1].time avec
+     _t(t*) > (*_TimeMessages)[target][0].time
+    ou bien on aura le dernier message temps du "target".
+  + S'il s'agit de la finalisation des receptions des messages
+    temps et donnees (UntilEnd vaut true), on effectue la
+    boucle jusqu'a ce que l'on trouve
+    (*_TimeMessages)[target][1].deltatime nul.
+  + Dans la boucle :
+    On recopie le dernier message temps dans le message temps
+      precedent et on lit le message temps suivant.
+    On detruit le buffer de donnees du temps precedent.
+    On recopie le pointeur du dernier buffer de donnees dans
+      le precedent.
+    On alloue un nouveau dernier buffer de donnees
+      (*_DataMessages)[target][1] et on lit les donnees
+      correspondantes dans ce buffer.
+  + Si le temps courant du process est plus grand que le dernier
+    temps (*_TimeMessages)[target][1].time du target, on donne
+    la valeur true a (*_OutOfTime)[target].
+    (*_TimeMessages)[target][1].deltatime est alors nul.
+*/
 int MPI_AccessDEC::CheckTime( int recvcount , MPI_Datatype recvtype , int target ,
                               bool UntilEnd ) {
 //                              int target , bool &OutOfTime ) {
@@ -759,6 +873,22 @@ int MPI_AccessDEC::CheckTime( int recvcount , MPI_Datatype recvtype , int target
   //cout << endl ;
   return sts ;
 }
+
+/*
+. CheckSent() :
+  + appelle SendRequestIds de MPI_Access afin d'obtenir tous les
+    RequestIds d'envoi de messages a tous les "targets".
+  + Pour chaque RequestId, appelle Test de MPI_Access pour savoir
+    si le buffer est libre (flag = true). Lorsqu'il s'agit du
+    FinalCheckSent, on appelle Wait au lieu de Test.
+  + Si le buffer est libre, on decremente le compteur de la
+    structure SendBuffStruct obtenue avec _MapOfSendBuffers.
+    (voir MPI_AccessDEC et la gestion des SendBuffers ci-dessus)
+  + Si le compteur est nul on detruit le TimeMessage ou le
+    SendBuffer en fonction du DataType.
+  + Puis on detruit la structure SendBuffStruct avant de supprimer
+    (erase) cet item de _MapOfSendBuffers
+*/
 int MPI_AccessDEC::CheckSent(bool WithWait) {
   int sts = MPI_SUCCESS ;
   int flag = WithWait ;