2017-04-04 4 views
0

Ich programmiere mit MPI und C und ich verwende den Root-Rang, um Daten aus einer Datei zu lesen und sie dann auf die verbleibenden Ränge zu verteilen. Mein MPI_Scatter funktioniert gut und ich drucke die Werte aus, um sicherzustellen, dass sie korrekt sind (und sie sind). Mein Problem ist, dass ich nach dem Zuordnen von Strukturen Fehler bei dem Versuch, auf sie zuzugreifen, von anderen Rängen als dem Root-Rang trennen.MPI_Scatter() gefolgt von malloc ergibt einen segfault

pr_graph * graph = malloc(sizeof(*graph)); 
    .... 

    MPI_Scatter(verticesCountArray, 1, MPI_INT, &(graph->nvtxs), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 
    MPI_Scatter(edgesCountArray, 1, MPI_INT, &(graph->nedges), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 

    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     // graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 

Und meine Ausgabe lautet:

2 4 
    2 4 
    2 4 

Was ist richtig. Aber wenn ich die kommentierte Zeile auskommentiere, bekomme ich:

2 4 
    2 4 
    [phi01:07170] *** Process received signal *** 
    [phi01:07170] Signal: Segmentation fault (11) 
    [phi01:07170] Signal code: (128) 
    [phi01:07170] Failing at address: (nil) 
    [phi01:07170] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f5740503390] 
    [phi01:07170] [ 1] ./pagerank[0x401188] 
    [phi01:07170] [ 2] ./pagerank[0x400c73] 
    [phi01:07170] [ 3] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f5740149830] 
    [phi01:07170] [ 4] ./pagerank[0x400ce9] 
    [phi01:07170] *** End of error message *** 
    -------------------------------------------------------------------------- 
    mpirun noticed that process rank 1 with PID 7170 on node phi01 exited on signal 11 (Segmentation fault). 

Das bedeutet, dass nur Rang 0 auf die zugewiesene Struktur zugreifen konnte. Kann mir jemand auf warum hinweisen? Vielen Dank!

EDIT:

für die beiden recvbuffers in beliebigen Werten Anstecken segfault nicht und druckt die korrekten Werte aus. Es scheint, dass der Fehler in der Verwendung von MPI_Scatter() wurzelt.

graph->nvtxs = 2; 
    graph->nedges = 4; 
    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 
+0

Willkommen bei StackOverflow. Bitte geben Sie eine [MCVE] an. Ansonsten ist es unmöglich, Ihnen beim Debuggen zu helfen. Es hilft auch sehr, wenn Sie Ihre eigenen Bemühungen zeigen, um die Situation zu debuggen. – Zulan

+0

Hallo und danke! :) Dieser Code ist so minimal, wie ich es machen könnte. Der ursprüngliche Quellcode beträgt etwa 500 Zeilen. Das "..." im Code ist, wo ich die Datei mit dem Rang 0 lese und meine zwei Arrays (jeweils mit der Größe numProcesses) fülle, daher fand ich es wirklich irrelevant, sie einzuschließen. Ich arbeite nun seit 6 Stunden an diesem Bug und habe es schließlich geschafft, das Problem auf diese 10 Codezeilen zu beschränken. Ich bin ratlos, was ich als nächstes versuchen soll, deshalb kam ich hierher:/Ich habe diesen Fehler reproduziert, indem ich irgendwelche Werte für meine zwei Arrays anschliesse, ohne sie aus einer Datei zu lesen, und ich habe immer noch das gleiche Problem. –

Antwort

0

Ich fand eine Lösung für das Problem. Ich poste es zuerst und versuche dann zu verstehen, warum es funktioniert.

pr_int * nvtxs = malloc(sizeof(pr_int)); 
    pr_int * nedges = malloc(sizeof(pr_int)); 

    MPI_Scatter(verticesCountArray, 1, MPI_INT, &(nvtxs), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 
    MPI_Scatter(edgesCountArray, 1, MPI_INT, &(nedges), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 

    graph->nvtxs = nvtxs; 
    graph->nedges = nedges; 
    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 

Ich glaube, ich habe keine tatsächlichen Puffer (Zeiger) für den Empfang, nur normale Variablen. Sie wurden möglicherweise während des Aufrufs von malloc in Zeiger (Adresswerte) konvertiert, und deshalb könnte die Größe der Struktur verrückt gewesen sein. Ich bin mir immer noch nicht sicher, warum ich die Werte drucken konnte, oder sogar wie Rang 0 ohne Probleme funktionierte. Irgendwelche Ideen würden sehr geschätzt werden! Vielen Dank!