2017-11-18 2 views
0

Ich versuche, mit 2D-Arrays und MPI_Scatterv arbeiten. Als ich MPI_Scatterv nennen bekomme ichC - Segmentierung Fehler mit Scatterv mit dynamischen 2D-Array

================================================================================ 
    = BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES 
    = PID 5790 RUNNING AT ubuntu 
    = EXIT CODE: 139 
    = CLEANING UP REMAINING PROCESSES 
    = YOU CAN IGNORE THE BELOW CLEANUP MESSAGES 
    ================================================================================ 
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11) 
This typically refers to a problem with your application. 
Please see the FAQ page for debugging suggestions 

Wenn ich C99 2D-Arrays verwenden, es funktioniert, aber nicht mit malloc. Ich möchte wissen, wo ich mit malloc falsch liege. Ich kann nicht linearisierte 2D-Array verwenden, so kann ich nicht Array erstellen wie array[i*columns+j]

Hier ein Testprogramm ist:

int **alloc2d(int n, int m) { 
     int i; 
     int **array = malloc(n * sizeof(int*)); 
     array[0] = malloc(n * m * sizeof(int)); 
     for(i = 1; i < n; i++) 
      array[i] = array[i-1] + m; 
     return array; 
} 

int *genSendc(int dim, int numprocs) { 
    int* sendc = (int*)malloc(sizeof(int)*numprocs); 
    int i; 
    int subsize = dim/numprocs; 
    for(i=0; i<numprocs; ++i) 
     sendc[i] = subsize; 
    for(i=0; i<dim-subsize*numprocs; ++i) 
     sendc[i]+=1; 
    return sendc; 
} 

int *genDispl(int numprocs, int*sendc) { 
    int* displ = (int*)malloc(sizeof(int)*numprocs); 
    int i; 
    displ[0]=0; 
    for(i=1; i<numprocs; ++i) 
     displ[i] = displ[i-1]+sendc[i-1]; 
    return displ; 
} 

int main(int argc, char *argv[]){ 
    int numprocs, rank, i, j, N=5, M=4; 
    int* displMat, *sendcMat; 
    int **txMatrix, **rxMatrix; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 

    sendcMat = genSendc(N, numprocs); 
    for(i=0; i<numprocs; ++i) 
     sendcMat[i] *= M; 
    displMat = genDispl(numprocs, sendcMat); 

    rxMatrix = alloc2d(sendcMat[rank]/M, M); 
    if (rank == 0) { 
     srand(time(NULL)); 
     txMatrix = alloc2d(N, M); 
     for (i=0; i < N; ++i) 
      for(j=0; j < M; ++j) 
       txMatrix [i][j] = (rand() % 10)+1; 
    } 

    MPI_Scatterv(&txMatrix[0][0], sendcMat, displMat, MPI_INT, &rxMatrix[0][0], sendcMat[rank], MPI_INT, 0, MPI_COMM_WORLD); 

    MPI_Finalize(); 
} 

Wenn ich rxMatrix nach MPI_Scatterv, das Programm druckt RANG0 Untermatrix drucken und dann stürzt es mit Segmentierungsfehler ab. Wo liege ich falsch?

+0

können Sie eine [mcve] ohne MPI-Aufrufe erstellen? –

+1

* "sendcMat' und' displMat' sind korrekt eingestellt. "* Wahrscheinlich nicht. Zeig uns. Nur ein [mcve] macht diese Frage beantwortbar. – Zulan

+0

bearbeitet mit vollständigen Informationen erforderlich, um es auszuführen – TheEnigmist

Antwort

0

Dieser Ausdruck ruft undefiniertes Verhalten auf, wenn txMatrix nicht ordnungsgemäß initialisiert wird.

&txMatrix[0][0] 

Während das erste Argument MPI_Scatterv auf Nicht-root inkonsequent ist stuft *, nur den Ausdruck der Bewertung eines segfault verursachen kann. Verwenden Sie einfach ein if/else für root/nonroot und übergeben Sie NULL für Letzteres.

*: zumindest nach dem Standard habe ich gesehen, dass dies in MPI-Implementierungen abgehört wird.

+0

Auch mit TxMatrix = NULL funktioniert es nicht. Ich muss es mit alloc2d zuweisen, um Scatter arbeiten zu lassen! Ich weiß nicht warum, ich lehrte TxMatrix wird nur von Root-Prozessor verwendet ... – TheEnigmist

Verwandte Themen