In queste lezioni abbiamo approfondito il tema della divisione dei dati per affrontare il problema del Game of Life.
Abbiamo inoltre trattato le comunicazioni ASINCRONE in MPI.
Le funzioni Isend e Irecv istanziano un send e un receive non bloccanti. Prima di poter usare di nuovo il buffer di invio o poter leggere il i dati nel buffer di ricezione bisogna verificare che le operazioni siano andate a buon fine tramite le chiamate a MPI_Test, MPI_Wait, MPI_Waitall, MPI_Probe o MPI_Iprobe.
int flag;
MPI_Isend(&sendb,1,MPI_INT,dest,tag,MPI_COMM_WORLD,&request[1]);
MPI_Irecv(&receiveb,1,MPI_INT,dest,tag,com,&request[0]);
MPI_Test(&request[0],&flag,&status[0]);
{ int cc=0;
while(!flag)
{
cout << "aspetto il receive e lavoro "<< cc++ << endl;
MPI_Test(&request[0],&flag,&status[0]);
}}
cout << "L'esecuzione prosegue dopo i send e receive non bloccanti" << endl;
/* MPI_Wait è una chiamata BLOCCANTE
che in questo caso attende il completamento del SEND in alternativa Waitall attende TUTTE le richieste di comunicazione contenute nel vettore.*/
MPI_Wait(&request[1],&status[1]);
//MPI_Waitall(2,&request[0],&status[0]);
Se invece che usare il semplice Test o Wait volessimo avere informazioni più dettagliate su una comunicazione in arrivo dovremmo usare MPI_Probe (Bloccante) o MPI_Iprobe (non bloccante).
//MPI_Probe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status[0]); BLOCCANTE
MPI_Iprobe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&flag,&status[0]);
{ int cc=0;
while(!flag)
{
cout << "aspetto il receive e lavoro "<< cc++ << endl;
MPI_Iprobe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&flag,&status[0]);
}}
// con Get_count ottengo informazioni su quanti elementi ha il messaggio
MPI_Get_count(&status[0],MPI_INT,&count);
// Posso allocare il buffer di receive in base a questo e ricevere il messaggio
receiveb =(int*)malloc(count*sizeof(int));
MPI_Recv(receiveb,count,MPI_INT,status[0].MPI_SOURCE,tag,MPI_COMM_WORLD,&status[1]);
Le informazioni riguardo al tag ( MPI_TAG ), alla sorgente (MPI_SOUCE), ed errore ( MPI_ERROR ) del messaggio possono essere ottenute dalla struttura MPI_status. Altre informazioni possono essere introdotte in questa struttura dalle implementazioni ma sono fuori dallo standard.
Abbiamo inoltre trattato le comunicazioni ASINCRONE in MPI.
Le funzioni Isend e Irecv istanziano un send e un receive non bloccanti. Prima di poter usare di nuovo il buffer di invio o poter leggere il i dati nel buffer di ricezione bisogna verificare che le operazioni siano andate a buon fine tramite le chiamate a MPI_Test, MPI_Wait, MPI_Waitall, MPI_Probe o MPI_Iprobe.
int flag;
MPI_Isend(&sendb,1,MPI_INT,dest,tag,MPI_COMM_WORLD,&request[1]);
MPI_Irecv(&receiveb,1,MPI_INT,dest,tag,com,&request[0]);
MPI_Test(&request[0],&flag,&status[0]);
{ int cc=0;
while(!flag)
{
cout << "aspetto il receive e lavoro "<< cc++ << endl;
MPI_Test(&request[0],&flag,&status[0]);
}}
cout << "L'esecuzione prosegue dopo i send e receive non bloccanti" << endl;
/* MPI_Wait è una chiamata BLOCCANTE
che in questo caso attende il completamento del SEND in alternativa Waitall attende TUTTE le richieste di comunicazione contenute nel vettore.*/
MPI_Wait(&request[1],&status[1]);
//MPI_Waitall(2,&request[0],&status[0]);
Se invece che usare il semplice Test o Wait volessimo avere informazioni più dettagliate su una comunicazione in arrivo dovremmo usare MPI_Probe (Bloccante) o MPI_Iprobe (non bloccante).
//MPI_Probe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status[0]); BLOCCANTE
MPI_Iprobe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&flag,&status[0]);
{ int cc=0;
while(!flag)
{
cout << "aspetto il receive e lavoro "<< cc++ << endl;
MPI_Iprobe(MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&flag,&status[0]);
}}
// con Get_count ottengo informazioni su quanti elementi ha il messaggio
MPI_Get_count(&status[0],MPI_INT,&count);
// Posso allocare il buffer di receive in base a questo e ricevere il messaggio
receiveb =(int*)malloc(count*sizeof(int));
MPI_Recv(receiveb,count,MPI_INT,status[0].MPI_SOURCE,tag,MPI_COMM_WORLD,&status[1]);
Le informazioni riguardo al tag ( MPI_TAG ), alla sorgente (MPI_SOUCE), ed errore ( MPI_ERROR ) del messaggio possono essere ottenute dalla struttura MPI_status. Altre informazioni possono essere introdotte in questa struttura dalle implementazioni ma sono fuori dallo standard.