2016-04-17 27 views
0

Ich versuche, eine MPI_Scatter mit Eigen Matrix mit folgenden zu implementieren:MPI_Scatter: Scatter Eigen Matrix

// get pointer to samples 
double *X = prob.x; 
// map the samples into the matrix object 
MatrixXd globaldata = Map<MatrixXd>(X, dims, nsmp); 
MatrixXd localdata; 
int size, rank; 

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

if (rank == 0) { 
    printf("Processor %d has data before Scatter \n", rank); 
    cout << globaldata<<endl<<endl; 
} 

MPI_Scatter(globaldata.data(), 1, MPI_DOUBLE, &localdata, 1, MPI_DOUBLE, 0, 
     MPI_COMM_WORLD); 

printf("Processor %d has data \n", rank); 
cout << localdata << endl; 

Der Ausgang des MatrixXd Global ist:

 -1   -1   -1   -1 
-0.997455 -0.996032 -0.998472 -0.996154 
    -0.94402 -0.912698 -0.966387 -0.915385 
-0.974555 -0.960317 -0.984721 -0.961538 
    -0.46056 -0.0753968 -0.676089 0.423077 
     1   1   1   1 

Dann versuche ich, die Eigen Matrix zu zerstreuen Gloaldata mit

MPI_Scatter(globaldata.data(), 1, MPI_DOUBLE, &localdata, 1, MPI_DOUBLE, 0, 
      MPI_COMM_WORLD); 

Allerdings denke ich nicht oben ist richtig. Wie kann ich die obige Eigenmatrix Spalte für Spalte streuen, so dass, wenn ich zum Beispiel mpirun -np 4 ./mpitest laufen lasse ich jede Spalte der Eigenmatrix auf jeden Prozess abgebildet oder die 2 auf jeden Prozess abgebildet, wenn np 2 ist? Sind der send_datatype und der recv_datatype i-e MPI_DOUBLE korrekt?

Antwort

2

In MPI_Scatter ist die Anzahl (die Sie als 1 haben) die Anzahl der Elemente, die an jeden Prozess gesendet werden. Um die Matrix gleichmäßig auf "Größen" -Prozesse zu verteilen, müssen Sie die Anzahl auf 16/Größe setzen (für Ihr 4x4-Matrix-Beispiel).

Dies beruht auf der Tatsache, dass alle Daten in der Matrix als ein zusammenhängender Speicherblock gespeichert werden - Sie müssen prüfen, ob dies für MatrixXd-Typen der Fall ist, obwohl ich annehmen würde, dass dies zutrifft.

Ob die Verteilung Zeilen oder Spalten verteilt, hängt wiederum von Ihrer Speicherreihenfolge ab. Bei Standard-C-Arrays würden Sie bei 4 Prozessen eine separate Zeile an jeden Prozess und nicht an eine Spalte senden. Eigen scheint jedoch standardmäßig auf den Spaltenhauptspeicher (Standard für Fortran, aber nicht für C) zu verweisen, was dann bedeuten würde, dass Sie ganze Spalten senden.

+0

Wenn ich MatrixXd nicht verwende und nur X verwende, funktioniert es immer noch nicht. X ist ein Array der Größe 4 * 6. Ich versuchte mit \t \t MPI_Scatter (& X, 4, MPI_DOUBLE, & X1, 4, MPI_DOUBLE, 0, \t MPI_COMM_WORLD); wo X1 auch als Doppel * X1 deklariert wird; Ich laufe mit mpirun -np 4 ./test. Es gibt mir Segmentierungsfehler. – srai

0

Sie müssen Speicherplatz für den Empfangspuffer reservieren. Wenn Sie eine Variable einfach als Double * definieren, wird kein Speicher reserviert, so dass Sie einen Fehler erhalten. Ich denke, das gleiche gilt für Ihr ursprüngliches Beispiel - localdata ist definiert, aber es sieht so aus, als wäre kein Speicherplatz zugewiesen.

den Code zum Laufen zu bringen, könnten Sie versuchen:

double X1[24]; // This is more storage than you need but its safe 
... 
MPI_Scatter(X, 4,MPI_DOUBLE, X1, 4, MPI_DOUBLE, 0, MPI_COMM_WORLD) 

Obwohl der Fehler in MPI_Scatter auftritt, ich glaube, die Ursache des Problems ist, dass einige Verwirrung hier zwischen Zeigern und Zuordnen Arrays gibt.