cout << "End of MPI_Access::~MPI_Access" << _MyRank << " this " << this << endl ;
}
+/*
+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.
+*/
+
int MPI_Access::NewRequest( MPI_Datatype datatype, int tag , int destsourcerank ,
bool fromsourcerank , bool asynchronous ) {
RequestStruct *mpiaccessstruct = new RequestStruct;
return _Request ;
}
+/*
+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.
+*/
int MPI_Access::NewSendTag( MPI_Datatype datatype, int destrank , int method ,
bool asynchronous, int &RequestId ) {
int tag ;
}
int MPI_Access::WaitAny(int count, int *array_of_RequestIds, int &RequestId) {
- int status ;
+ int status = MPI_ERR_OTHER ;
+ RequestId = -1 ;
+ cout << "MPI_Access::WaitAny not yet implemented" << endl ;
return status ;
}
int MPI_Access::TestAny(int count, int *array_of_RequestIds, int &RequestId,
int &flag) {
- int status ;
+ int status = MPI_ERR_OTHER ;
+ RequestId = -1 ;
+ flag = 0 ;
+ cout << "MPI_Access::TestAny not yet implemented" << endl ;
return status ;
}
int MPI_Access::WaitSome(int count, int *array_of_RequestIds, int outcount,
int *outarray_of_RequestIds) {
- int status ;
+ int status = MPI_ERR_OTHER ;
+ RequestId = -1 ;
+ cout << "MPI_Access::WaitSome not yet implemented" << endl ;
return status ;
}
int MPI_Access::TestSome(int count, int *array_of_RequestIds, int outcounts,
int *outarray_of_RequestIds) {
- int status ;
+ int status = MPI_ERR_OTHER ;
+ RequestId = -1 ;
+ cout << "MPI_Access::TestSome not yet implemented" << endl ;
return status ;
}