From aea99331e716d84d57a5272a5599212556c979e1 Mon Sep 17 00:00:00 2001 From: rahuel Date: Mon, 28 Jan 2008 13:01:34 +0000 Subject: [PATCH] Elements de rapport de prestation --- src/ParaMEDMEM/BASICS_JR | 339 +++++++++++++++++++++++++++++ src/ParaMEDMEM/README_JR | 449 +++++++++++++++++++++++++++++++++++++++ src/ParaMEDMEM/TODO_JR | 50 +++++ 3 files changed, 838 insertions(+) create mode 100644 src/ParaMEDMEM/BASICS_JR create mode 100644 src/ParaMEDMEM/README_JR create mode 100644 src/ParaMEDMEM/TODO_JR diff --git a/src/ParaMEDMEM/BASICS_JR b/src/ParaMEDMEM/BASICS_JR new file mode 100644 index 000000000..af82fda16 --- /dev/null +++ b/src/ParaMEDMEM/BASICS_JR @@ -0,0 +1,339 @@ + +Le document de specification : +============================== + +Globalement le document de specification correspond a +l'implementation qui a ete faite avec : + +. Transport-ParaMEDMEM qui a ete enrichi avec la classe MPI_Access + +. Presentation-ParaMEDMEM qui a ete enrichi avec la classe + MPI_AccessDEC + + +La conception correspondant a cette specification est restee +la meme : + +. MPI_Access gere pour un ProcessorGroup (IntraCommunicator) : + - Les structures MPI_Request et MPI_Status + - La valeur des "tags" MPI + - Les requetes d'ecritures et de lectures asynchrones + - Les communications en "Point a Point" [I]Send, [I]Recv ainsi + que [I]SendRecv. + - A la difference de l'API MPI [I]SendRecv ne concerne qu'un + seul et meme "target". + - Les controles de communications asynchrones Wait, Test, + WaitAll, TestAll, [I]Probe, Cancel et CancelAll. + - Comme c'etait demande seules les methodes "utiles" ont ete + implementees. + - Les appels a [I]Send ou a [I]Recv avec des sendbuff/recvbuff + de valeur NULL ou avec des sendcount/recvcount de valeur + nulle sont ignores. + - Les methodes de communications collectives ne sont pas + implementees dans MPI_Access. + - Les deux methodes "Cancel" concernent soit un IRecv deja + soumis soit un message en attente (sans IRecv deja soumis). + Elles regroupent les differents appels de l'API MPI + necessaires (IProbe, IRecv, Wait, Test_Canceled ...). + +. MPI_AccessDEC utilise les services de MPI_Access pour un + ProcessorGroup (IntraCommunicator) et gere : + - Les communications collectives en "Point a Point". + (AllToAll[v] synchrone ou asynchrone). + - Les temps et l'interpolation + - Les [I]Send avec leurs buffers (delete []) + - Les [I]Recv + - La finalisation des envois et receptions de messages dans + le destructeur afin qu'il n'y ait plus de message en attente + et afin de liberer les buffers + + +MPI_Access et "tags" (ou "MPITags") : +===================================== + +. Le constructeur permet optionnellement de fixer une plage de tags + a utiliser : [BaseTag , MaxTag]. + Par defaut c'est [ 0 , MPI_TAG_UB], MPI_TAG_UB etant la valeur + maximum d'une implementation de MPI (valeur minimum 32767 + soit 2**15-1). Sur awa avec l'implementation lam MPI_TAG_UB + vaut 7353944. La norme MPI specifie que cette valeur doit + etre la meme dans les process demarres avec mpirun. + Dans le cas de l'usage simultane du meme IntraCommunicator + dans un meme process (ou de plusieurs IntraCommunicator + d'intersection non nulle) cela peut eviter toute ambiguite + et aider au debug. + +. Dans MPI_Access les tags sont constitues de deux parties + (#define ModuloTag 10) : + + Le dernier digit decimal correspond au MPI_DataType ( 1 pour + les messages "temps", 2 pour MPI_INT et 3 pour MPI_DOUBLE) + + La valeur des autres digits correspond a une numerotation + circulaire des messages. + + Un message "temps" et le message de donnees associe ont le + meme numero de message (mais des types et donc des tags + differents). + +. Pour un envoi de message d'un process "source" vers un process + "target", on dispose de _SendMPITag[target] dans le process + source (il contient le dernier "tag" utilise pour l'envoi de + messages vers le process target). + Et dans le process "target" qui recoit ce message, on dispose + de _RecvMPITag[source] (il contient le dernier "tag" utilise + pour la reception de messages du process source). + Naturellement d'apres la norme MPI les valeurs de ces tags sont + les memes. + + +MPI_Access et "RequestIds" : +============================ + +. ATTENTION : Dans le document de specification, la distinction + n'est pas faite clairement entre les "MPITags" (voir ci-dessus) + qui sont un argument des appels a MPI et les "RequestIds" qui + ne concernent pas les appels MPI. Ces "RequestIds" figurent + en effet sous le nom de tag comme argument d'entree/sortie dans l'API + de MPI_Access decrite dans le document de specification. Mais + dans l'implementation on a bien le nom RequestId (ou bien + RecvRequestId/SendRequestId). + +. Lors de la soumission d'une requete d'ecriture ou de lecture MPI + via MPI_Access, on obtient un identifieur "RequestId". + Cet identifieur "RequestId" correspond a une structure RequestStruct + de MPI_Access a laquelle on accede avec la map + "_MapOfRequestStruct". + Cette structure RequestStruct permet de gerer MPI_Request et + MPI_Status * de MPI et permet d'obtenir des informations sur + la requete : target, send/recv, tag, [a]synchrone, type, outcount. + +. C'est cet identifieur qui peut etre utilise pour controler une + requete asynchrone via MPI_Access : Wait, Test, Probe, etc... + +. En pratique "RequestId" est simplement un entier de l'intervalle + [0 , 2**32-1]. Il y a uniquement un compteur cyclique global + aussi bien pour les [I]Send que pour les [I]Recv. + +. Ces "RequestIds" et leur structures associees facilitent les + communications asynchrones. + Par exemple on a mpi_access->Wait( int RequestId ) + au lieu de MPI_Wait(MPI_Request *request, MPI_Status *status) + avec gestion de status. + +. L'API de MPI_Access peut fournir les "SendRequestIds" d'un "target", + les "RecvRequestIds" d'un "source" ou bien les "SendRequestIds" de + tous les "targets" ou les "RecvRequestIds" de tous les "sources". + Cela permet d'eviter leur gestion au niveau de Presentation-ParaMEDMEM. + + +MPI_AccessDEC : +=============== + +. Comme la classe DEC, il est base sur local_group et distant_group + ce qui forme un MPI_union_group et donc un IntraCommunicator. + +. Il permet de choisir le mode synchrone ou asynchrone (par defaut). + Le meme programme peut fonctionner en synchrone ou en asynchrone + sans devoir etre modifie. + +. Il permet de choisir un mode d'interpolation (actuellement + uniquement une interpolation lineaire) ou bien un mode sans + interpolation (par defaut). Ceci pour les communications collectives. + Avec interpolation les communications collectives transmettent et + recoivent un message "temps" en plus des donnees. + +. Il implemente AllToAll[v] en "Point a Point" avec ou sans interpolation. + +. Il gere les buffers d'envoi de messages. Il les detruit donc + lorsqu'ils sont disponibles. + +. Il cree et utilise MPI_Access. + + +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. + + +Etapes des communications collectives de MPI_AccessDEC : +======================================================== + +AllToAll[v] : Les arguments sont les memes que dans MPI sauf MPI_Comm +------------- inutile (deja connu de MPI_AccessDEC et MPI_Access). + + Si on a un TimeInterpolator, appel de AllToAll[v]Time. + + Sinon, on appelle CheckSent pour les echanges + asynchrones (voir ci-apres) et on appelle SendRecv + pour chaque "target". + +AllToAll[v]Time : +----------------- + +. 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 + +. 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. + +. 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. + +. 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". + + +Presentation-ParaMEDMEM : +========================= + +. Des modifications mineures ont ete effectuees dans Presentation-ParaMEDMEM + afin de pouvoir utiliser ces nouvelles fonctionnalites. Il n'y + a surtout pas eu de bouleversement destabilisateur. L'ancien + mode de fonctionnement reste naturellement disponible. + +. Cela repose sur trois nouvelles options creees avec registerOption + dans le constructeur de IntersectionDEC : + + Asynchronous : true ou false (par defaut) + + TimeInterpolation : WithoutTimeInterp (par defaut) ou LinearTimeInterp + typedef enum{WithoutTimeInterp,LinearTimeInterp} TimeInterpolationMethod; + dans MPI_AccessDEC.hxx + + AllToAllMethod : Native (par defaut) ou PointToPoint + typedef enum{Native,PointToPoint} AllToAllMethod; + dans MxN_Mapping.hxx + +. Le choix des options se fait avec le Data Exchange Channel : + + ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group); + + dec.setOption("Asynchronous",true); + + dec.setOption("TimeInterpolation",LinearTimeInterp); + + dec.setOption("AllToAllMethod",PointToPoint); + +. Dans dec.synchronize(), + + on cree un objet InterpolationMatrix + qui lui-meme cree un objet MxN_Mapping + qui lui-meme cree maintenant un objet MPI_AccessDEC + + on transmet a MxN_Mapping via l'InterpolationMatrix l'option + choisie de AllToAllMethod + + on transmet a MPI_AccessDEC les valeurs des options Asynchronous + et TimeInterpolation : methodes Asynchronous et + SetTimeInterpolator de MPI_AccessDEC. + +. ParaMEDMEM::IntersectionDEC comporte maintenant une surcharge des + methodes recvData() et sendData() : + + void IntersectionDEC::recvData( double time ) qui appelle + SetTime(time) de MPI_AccessDEC et + recvData() + + void IntersectionDEC::sendData( double time , double deltatime ) + qui appelle + SetTime(time,deltatime) de MPI_AccessDEC et + sendData() + +. recvData() et sendData() de ParaMEDMEM::IntersectionDEC + appellent multiply et transposeMultiply de l'InterpolationMatrix + qui appellent sendRecv et reverseSendRecv de MxN_Mapping + qui appellent comm_interface.allToAllV en mode "Native" + ou bien MPI_AccessDEC::AllToAllv en mode "PointToPoint" + diff --git a/src/ParaMEDMEM/README_JR b/src/ParaMEDMEM/README_JR new file mode 100644 index 000000000..95e64288c --- /dev/null +++ b/src/ParaMEDMEM/README_JR @@ -0,0 +1,449 @@ + +Mon password : ata_turk + +CVS : +===== + +Branche : BR_MEDPARA : MED_SRC +setenv CVSROOT :pserver:rahuel@cvs.opencascade.com:/home/server/cvs/MED +cvs login +password : rahuel + + +Repertoires : +============= + +Sources : /home/rahuel/MEDPARAsynch +Construction sur awa : /data/tmpawa/rahuel/MEDPARAsynch/MED_Build +Intallation sur awa : /data/tmpawa/rahuel/MEDPARAsynch/MED_Install + + +Environnement : +=============== + +source /home/rahuel/MEDPARAsynch/env_products.csh + +On utilise : +/data/tmpawa/vb144235/valgrind-3.2.1/valgrind_install/bin +/data/tmpawa/adam/Salome3/V3_2_7_AWA_OCC/Python-2.4.1 +/data/tmpawa/vb144235/med_231_install +/data/tmpawa2/adam/omniORB/omniORB-4.0.7 +/data/tmpawa/vb144235/lam_install +/data/tmpawa/vb144235/cppunit_install +/data/tmpawa/vb144235/fvm_install_lam +/data/tmpawa/vb144235/bft_install +/home/rahuel/MEDPARAsynch/ICoCo +/data/tmpawa2/adam/Salome3/V3_2_0_maintainance/KERNEL/KERNEL_INSTALL + + +Build_Configure et Configure : +============================== + +MEDMEM est en "stand-alone" sans KERNEL ni IHM. + +cd $MED_BUILD_DIR +${MED_SRC_DIR}/build_configure --without-kernel --without-ihm +rm ${MED_SRC_DIR}/adm_local_without_kernel/adm_local_without_kernel +rm -fR $MED_BUILD_DIR/adm_local_without_kernel/adm_local_without_kernel + +cd $MED_BUILD_DIR +${MED_SRC_DIR}/configure --without-kernel --without-ihm --with-lam=/data/tmpawa/vb144235/lam_install --prefix=${MED_ROOT_DIR} --with-med2=/data/tmpawa/vb144235/med_231_install --with-python=/data/tmpawa/adam/Salome3/V3_2_7_AWA_OCC/Python-2.4.1 --with-cppunit=/data/tmpawa/vb144235/cppunit_install --with-cppunit_inc=/data/tmpawa/vb144235/cppunit_install/include --with-fvm=/data/tmpawa/vb144235/fvm_install_lam +rm ${MED_SRC_DIR}/adm_local_without_kernel/adm_local_without_kernel +rm -fR $MED_BUILD_DIR/adm_local_without_kernel/adm_local_without_kernel + + +Construction : +============== + +cd $MED_BUILD_DIR +make +make install + +Problemes de construction : +=========================== + +Liste des fichiers modifies et differents de la base CVS pour pouvoir +effectuer la construction et l'installation : + +M MED_SRC/configure.in.base : +----------------------------- +CHECK_MPICH +CHECK_LAM +CHECK_OPENMPI mis en commentaire (redefinit le resultat de CHECK_LAM) +CHECK_CPPUNIT a ete ajoute + +M MED_SRC/adm_local_without_kernel/unix/config_files/check_lam.m4 : +------------------------------------------------------------------- +Debugs pour trouver la bonne configuration de LAM + +M MED_SRC/src/INTERP_KERNEL/Makefile.in : +----------------------------------------- +Problemes de construction des tests + +M MED_SRC/src/ParaMEDMEM/Makefile.in : +-------------------------------------- +. Construction de libParaMEDMEM.a pour gcov (link statique) +. Ajout d'options de compilations : -fprofile-arcs -ftest-coverage -pg (gcov) ==> + instrumentation du code + +C MED_SRC/src/ParaMEDMEM/Test/Makefile.in : +------------------------------------------- +. Construction de libParaMEDMEMTest.a pour gcov (link statique) +. Ajout d'options de compilations : -fprofile-arcs -ftest-coverage -pg (gcov) ==> + instrumentation du code +. Prise en compte de $(MED_WITH_KERNEL) avec : + ifeq ($(MED_WITH_KERNEL),yes) + LDFLAGSFORBIN += $(LDFLAGS) -lm $(MED2_LIBS) $(HDF5_LIBS) $(MPI_LIBS) \ + -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -lmed_V2_1 -lparamed -lmedmem \ + ${KERNEL_LDFLAGS} -lSALOMELocalTrace -lSALOMEBasics \ + $(CPPUNIT_LIBS) \ + -lParaMEDMEMTest + endif + ifeq ($(MED_WITH_KERNEL),no) + LDFLAGSFORBIN += $(LDFLAGS) -lm $(MED2_LIBS) $(HDF5_LIBS) $(MPI_LIBS) \ + -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -lmed_V2_1 -lparamed -linterpkernel -lmedmem \ + ${KERNEL_LDFLAGS} ${FVM_LIBS} ${CPPUNIT_LIBS} -L/data/tmpawa/vb144235/bft_install/lib -lbft\ + -lParaMEDMEMTest + endif + +M MED_SRC/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx : +-------------------------------------------------- +Mise en commentaire du test manquant : +CPPUNIT_TEST(testNonCoincidentDEC_3D); + +U MED_SRC/src/ParaMEDMEM/Test/ParaMEDMEMTest_NonCoincidentDEC.cxx : +------------------------------------------------------------------- +Manque dans CVS + +Pour forcer la reconstruction des tests : +========================================= + +cd $MED_BUILD_DIR +rm src/ParaMEDMEM/*o +rm src/ParaMEDMEM/*.la +rm src/ParaMEDMEM/test_* +rm src/ParaMEDMEM/.libs/* +rm src/ParaMEDMEM/Test/*o +rm src/ParaMEDMEM/Test/*.la +rm src/ParaMEDMEM/Test/.libs/* +rm core.* +rm vgcore.* +cd $MED_BUILD_DIR/src/ParaMEDMEM/Test +make +make install +cd $MED_BUILD_DIR + + +Probleme avec lam : +=================== + +jr[1175]> mpirun -np 5 -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM +21508 TestParaMEDMEM running on n0 (o) +21509 TestParaMEDMEM running on n0 (o) +21510 TestParaMEDMEM running on n0 (o) +21511 TestParaMEDMEM running on n0 (o) +21512 TestParaMEDMEM running on n0 (o) +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +----------------------------------------------------------------------------- +The selected RPI failed to initialize during MPI_INIT. This is a +fatal error; I must abort. + +This occurred on host awa (n0). +The PID of failed process was 21508 (MPI_COMM_WORLD rank: 0) +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- +One of the processes started by mpirun has exited with a nonzero exit +code. This typically indicates that the process finished in error. +If your process did not finish in error, be sure to include a "return +0" or "exit(0)" in your C code before exiting the application. + +PID 21510 failed on node n0 (127.0.0.1) with exit status 1. +----------------------------------------------------------------------------- +jr[1176]> + + +Contournement du probleme lam : +=============================== + +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + + +Valgrind : +========== +. Les tests avec valgrind indiquent des erreurs dans MPI_Init et + MPI_Finalize ainsi que dans des programmes appeles "below main". +. De plus on obtient un "Segmentation Violation" accompagne d'un + fichier "vgcore.*" (plantage de valgrind) +. Mais on a " All heap blocks were freed -- no leaks are possible." + et on n'a aucune erreur de malloc/free new/delete dans ParaMEDMEM et + dans les tests. + +. Cependant si on execute les tests sans valgrind, il n'y a pas + d'erreur ni de fichier "core.*". + + +Tests avec CPPUNIT de $MED_BUILD_DIR/src/ParaMEDMEM/Test : +========================================================== + +L'appel a MPI_Init n'est fait qu'une seule fois. +Il est suivi par l'execution de toute la suite des tests regroupes +dans les trois executables TestParaMEDMEM, TestMPIAccessDEC et +TestMPIAccess +On a enfin un seul appel a MPI_Finalize. + +Si un des tests d'une suite de tests comporte une anomalie cela +peut avoir des implications sur l'execution des tests suivants. + +Lors de la mise au point de la suite de tests de TestMPIAccessDEC +cela etait le cas : il restait des messages postes dans lam mais +non lus. Le test suivant s'executait de plus en plus lentement +sans donner d'erreur (probleme difficile a identifier). + + +Lancement des tests de TestParaMEDMEM avec CPPUNIT et TotalView (option -tv) : +============================================================================== + +mpirun -np 5 -ssi rpi tcp C -tv -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + +Il arrive qu'on ne puisse pas utiliser totalview par manque de +license. + + + +Lancement des tests de TestParaMEDMEM avec CPPUNIT et Valgrind avec "memory leaks" : +==================================================================================== + +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestParaMEDMEM + + +Lancement des tests fonctionnels de MPI_AccessDEC avec CPPUNIT : +================================================================ + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccessDEC + + +Lancement des tests unitaires de MPI_Access avec CPPUNIT : +========================================================== + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccess + + +TestMPIAccess/TestMPIAccessDEC/TestParaMEDMEM et gcov : +======================================================= + +Les resultats sont dans les repertoires suivants de $MED_BUILD_DIR/src/ParaMEDMEM/Test : +------------- + + TestParaMEDMEM-gcov/ + TestMPIAccessDEC-gcov/ + TestMPIAccess-gcov/ + +Je n'y ai pas trouve d'anomalies. + +compilation : -fprofile-arcs -ftest-coverage +------------- + +$MED_BUILD_DIR/src/ParaMEDMEM/makefile.in : LIB=libparamedar.a \ +------------------------------------------- libparamed.la + +$MED_BUILD_DIR/src/ParaMEDMEM/Test/makefile.in : LIB = libParaMEDMEMTestar.a \ +------------------------------------------------ libParaMEDMEMTest.la + +links statiques manuels : +------------------------- + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestMPIAccess TestMPIAccess.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestMPIAccessDEC TestMPIAccessDEC.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestParaMEDMEM TestParaMEDMEM.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +Ne pas oublier le make install apres ... + +execution et gcov : +------------------- + +Pour pouvoir traiter les .cxx de ${MED_BUILD_DIR}/src/ParaMEDMEM et de +${MED_BUILD_DIR}/src/ParaMEDMEM/Test, on execute deux fois gcov. + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccess + +gcov TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ + test_MPI_Access_Cyclic_Send_Recv.cxx \ + test_MPI_Access_SendRecv.cxx \ + test_MPI_Access_ISend_IRecv.cxx \ + test_MPI_Access_Cyclic_ISend_IRecv.cxx \ + test_MPI_Access_ISendRecv.cxx \ + test_MPI_Access_Probe.cxx \ + test_MPI_Access_IProbe.cxx \ + test_MPI_Access_Cancel.cxx \ + test_MPI_Access_Send_Recv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length_1.cxx \ + test_MPI_Access_Time.cxx \ + test_MPI_Access_Time_0.cxx \ + test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ + ../MPI_Access.cxx +gcov -o ../ TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ + test_MPI_Access_Cyclic_Send_Recv.cxx \ + test_MPI_Access_SendRecv.cxx \ + test_MPI_Access_ISend_IRecv.cxx \ + test_MPI_Access_Cyclic_ISend_IRecv.cxx \ + test_MPI_Access_ISendRecv.cxx \ + test_MPI_Access_Probe.cxx \ + test_MPI_Access_IProbe.cxx \ + test_MPI_Access_Cancel.cxx \ + test_MPI_Access_Send_Recv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length_1.cxx \ + test_MPI_Access_Time.cxx \ + test_MPI_Access_Time_0.cxx \ + test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ + ../MPI_Access.cxx + + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccessDEC + +gcov TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ + test_AllToAllvDEC.cxx \ + test_AllToAllTimeDEC.cxx \ + test_AllToAllvTimeDEC.cxx \ + test_AllToAllvTimeDoubleDEC.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx +gcov -o ../ TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ + test_AllToAllvDEC.cxx \ + test_AllToAllTimeDEC.cxx \ + test_AllToAllvTimeDEC.cxx \ + test_AllToAllvTimeDoubleDEC.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + +gcov TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ + ParaMEDMEMTest_MPIProcessorGroup.cxx \ + ParaMEDMEMTest_BlockTopology.cxx \ + ParaMEDMEMTest_IntersectionDEC.cxx \ + ../BlockTopology.cxx \ + ../ComponentTopology.cxx \ + ../DEC.cxx \ + ../ElementLocator.cxx \ + ../InterpolationMatrix.cxx \ + ../IntersectionDEC.cxx \ + ../MPIProcessorGroup.cxx \ + ../MxN_Mapping.cxx \ + ../ParaFIELD.cxx \ + ../ParaMESH.cxx \ + ../ParaSUPPORT.cxx \ + ../ProcessorGroup.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + +gcov -o ../ TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ + ParaMEDMEMTest_MPIProcessorGroup.cxx \ + ParaMEDMEMTest_BlockTopology.cxx \ + ParaMEDMEMTest_IntersectionDEC.cxx \ + ../BlockTopology.cxx \ + ../ComponentTopology.cxx \ + ../DEC.cxx \ + ../ElementLocator.cxx \ + ../InterpolationMatrix.cxx \ + ../IntersectionDEC.cxx \ + ../MPIProcessorGroup.cxx \ + ../MxN_Mapping.cxx \ + ../ParaFIELD.cxx \ + ../ParaMESH.cxx \ + ../ParaSUPPORT.cxx \ + ../ProcessorGroup.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + + + + + +Lancement des tests unitaires sans CPPUNIT : +============================================ + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Send_Recv + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cyclic_Send_Recv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_SendRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cyclic_ISend_IRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISendRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Probe + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_IProbe + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cancel + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Send_Recv_Length + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_Length + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_Length_1 + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Time + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Time_0 2 1 + + +#AllToAllDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllDEC 1 + + +#AllToAllvDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvDEC 1 + + +#AllToAllTimeDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllTimeDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllTimeDEC 1 + + +#AllToAllvTimeDEC +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 0 1 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 0 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 1 + + + +#AllToAllvTimeDoubleDEC +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDoubleDEC 0 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDoubleDEC 1 + + + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_BottleNeck + diff --git a/src/ParaMEDMEM/TODO_JR b/src/ParaMEDMEM/TODO_JR new file mode 100644 index 000000000..de2318d54 --- /dev/null +++ b/src/ParaMEDMEM/TODO_JR @@ -0,0 +1,50 @@ + +MPI_Access : +============ + +. Creer des methodes [I]SendRecv en point a point avec un "target" + pour le Send et un "target" pour le Recv comme le SendRecv MPI. + +. Ne pas creer de structure RequestStruct en mode synchrone. + + +MPI_AccessDEC : +=============== + +. AllToAll, AllToAllv, AllToAllTime et AllToAllvTime comportent + des sequences de code semblables qui pourraient etre regroupees + sans que cela nuise a la lisibilite du code. + +. En mode asynchrone, il n'y a pas de controle d'engorgement des + messages envoyes dans CheckSent(). Il est vrai qu'en pratique + une synchronisation des temps est faite dans AllToAllTime et + AllToAllvTime. Mais ce probleme pourrait se produire avec + AllToAll et AllToAllv. Il serait possible de fixer un nombre + maximum de messages envoyes et "en cours" et de le comparer avec + le nombre de requetes rendu par MPI_Access. En cas de depassement + de ?n?*UnionGroupSize par exemple, CheckSent pourrait fonctionner + en mode "WithWait". Ce qui ferait qu'on apellerait Wait au lieu de Test. + +. Meme si le prototype d'interpolateur comporte des parametres + int nStepBefore et int nStepAfter, le codage actuel considere + qu'on n'a que nStepBefore=1 et nStepAfter=1. + Ainsi on a (*_TimeMessages)[target][0] et (*_TimeMessages)[target][1] + ainsi que &(*_DataMessages)[target][0] et &(*_DataMessages)[target][1]. + +. Les champs nStepBefore et nStepAfter correspondent a un maximum + requis. On devrait avoir les champs correspondants qui valent les + nombres disponibles a un moment donne. + +. Il existe un champs OutOfTime qui n'est pas utilise actuellement. + Il faudrait definir son usage et le transmettre sans doute à + l'interpolateur. Actuellement, L'interpolateur lineaire effectue une + extrapolation si OutOfTime vaut true. + +. Dans CheckTime, on alloue et detruit les (*_DataMessages)[target][] + alors qu'on pourrait considerer que pour un "target" donne, les + recvcount sont constants pendant toute la boucle de temps. Ainsi + on n'allouerait les buffers qu'une fois au depart et ils ne seraient + liberes qu'a la fin. + + + -- 2.39.2