Ho la seguente situazione: Ho scritto alcuni brevi codici di test MPI per scoprire quale combinazione di operazioni di invio e ricezione funziona meglio nel mio codice.C++: errore di corruzione del puntatore strano
Il codice funziona perfettamente sul mio computer (testato con 8 processi), ma non appena eseguo il cluster su cui sto lavorando, ottengo un enorme errore di output di un puntatore danneggiato o doppiamente liberato, questo è l'output: http://pastebin.com/pXTRSf89
Quello che sto facendo nel mio codice è il seguente: chiamo la mia funzione di comunicazione 100K volte e misurare l'ora. Questa funzione è mostrata sotto. Quello che ho scoperto, è che l'errore si verifica sempre nella stessa iterazione (da qualche parte intorno a 6K). Il processorID segnalato cambia tuttavia. L'iterazione è la stessa anche se uso 64 proc anziché 8. Il problema è: non ho assolutamente idea, cosa potrebbe esserci di sbagliato, specialmente perché non ci sono puntatori liberati o assegnati.
void communicateGrid(int level, real* grid, const Subdomain& subdomain, std::vector<TimeMap>& tm_) {
tm_[level]["CommGrid"].start();
MPI_Status status[2];
MPI_Request request[2];
// x
MPI_Isend(&grid[getIndexInner(level, 1, 1, 1) + innerGridpoints_[level][0] - numOuterGridpoints_[level]], 1, mpiTypes_[level * 4 + 1], subdomain.upperNeighbors[0], 0, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndexInner(level, 1, 1, 1)], 1, mpiTypes_[level * 4 + 1], subdomain.lowerNeighbors[0], 1, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndexInner(level, 1,1,1) + innerGridpoints_[level][0]], 1, mpiTypes_[level * 4 + 1], subdomain.upperNeighbors[0], 1, MPI_COMM_WORLD, &status[0]);
MPI_Recv(&grid[getIndexInner(level, 1,1,1) - numOuterGridpoints_[level]], 1, mpiTypes_[level * 4 + 1], subdomain.lowerNeighbors[0], 0, MPI_COMM_WORLD, &status[1]);
//y
MPI_Isend(&grid[getIndex(level, 0, innerGridpoints_[level][1], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.upperNeighbors[1], 2, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndex(level, 0, numOuterGridpoints_[level], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.lowerNeighbors[1], 3, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndex(level, 0, innerGridpoints_[level][1] + numOuterGridpoints_[level], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.upperNeighbors[1], 3, MPI_COMM_WORLD, &status[0]);
MPI_Recv(grid, 1, mpiTypes_[level * 4 + 2], subdomain.lowerNeighbors[1], 2, MPI_COMM_WORLD, &status[1]);
// z
MPI_Isend(&grid[getIndex(level, 0, 0, innerGridpoints_[level][2])], 1, mpiTypes_[level * 4 + 3], subdomain.upperNeighbors[2], 4, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndex(level, 0, 0, numOuterGridpoints_[level])], 1, mpiTypes_[level * 4 + 3], subdomain.lowerNeighbors[2], 5, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndex(level, 0, 0, numOuterGridpoints_[level] + innerGridpoints_[level][2])], 1, mpiTypes_[level * 4 + 3], subdomain.upperNeighbors[2], 5, MPI_COMM_WORLD, &status[0]);
MPI_Recv(grid, 1, mpiTypes_[level * 4 + 3], subdomain.lowerNeighbors[2], 4, MPI_COMM_WORLD, &status[1]);
tm_[level]["CommGrid"].stop();
}
mpiTypes_ è una variabile globale di tipo MPI_Datatype *, innerGridpoints_ e numOuterGridpoints_ sono globali così (so che questo non è un buon stile di codifica, ma ho preso solo per i tempi). Sono abbastanza sicuro che i miei tipi di dati siano corretti, poiché funzionano in un'altra configurazione delle funzioni di comunicazione (ad esempio Irecv seguita da Send).
Nota finale: ho appena provato a eseguire questo con un solo processo. Poi il seguente errore ha accaduto:
Rank 0 [Lun 22 Apr 02:11:23 2013] [c0-0c1s3n0] Fatal error in PMPI_Isend: Errore MPI interno !, errore di stack: PMPI_Isend (148): MPI_Isend (buf = 0x2aaaab7b531c, count = 1, dtype = USER, dest = 0, tag = 1, MPI_COMM_WORLD, request = 0x7fffffffb4d4) failed (unknown)(): Errore MPI interno! _pmiu_daemon (SIGCHLD): [NID 00070] [c0-0c1s3n0] [Lun 22 Apr 02:11:23 2013] PE RANK segnale 0 uscita abortito
Ancora una volta, questo è successo solo sul cluster, ma ha lavorato su la mia macchina
Sono felice per qualsiasi cosa potrei controllare o dove potrebbe essere l'errore! Grazie
Quale marca di CPU funziona e quale marca di CPU non funziona? – Patashu
Mi chiedo se i tuoi suggerimenti non finiscano mai per indicare blocchi di dati che non dovrebbero. Quando fai cose come '& grid [getIndex (livello, 0, 0, numOuterGridpoints_ [livello] + innerGridpoints_ [livello] [2])]', c'è qualche possibilità che punti ad un blocco che non è tuo? Oppure potrebbe esserci una perdita di memoria nella funzione che stai chiamando ... è la stessa identica versione di compilatore/librerie su entrambe le macchine? – Floris
getIndex e getInnerIndex sono solo funzioni di indice incorporate, poiché la griglia è una matrice 3d, dovrebbero andare bene. Il mio PC è un Intel i5, compilato con gcc 4.6.0 (sistema Mac): il cluster è una macchina Cray con CPU Opteron. Ho provato ma il compilatore PGI standard così come il gcc (versione 4.6.3) – Chris