2010-02-13 7 views
5

Ich brauche MPI_Gatherv() eine Anzahl von Int/String-Paaren. Nehmen wir an, jedes Paar sieht so aus:Struktur mit variabler Länge zwischen MPI-Prozessen übergeben

struct Pair { 
    int x; 
    unsigned s_len; 
    char s[1]; // variable-length string of s_len chars 
}; 

Wie definiere ich einen passenden MPI-Datentyp für Pair?

+0

Verwenden Sie 'char s [0];' für das Array variabler Länge, nicht 'char s [1];'. – kennytm

+0

@KennyTM, s [0] gibt "Warnung C4200: nicht standardmäßige Erweiterung verwendet: Null-Array in Struct/Union". – Constantin

+0

Ah MSVC. C99 wird von gcc, aber nicht von MSVC unterstützt. – kennytm

Antwort

4

Kurz gesagt, es ist theoretisch unmöglich, eine Nachricht variabler Größe zu senden und sie in einem Puffer der perfekten Größe zu empfangen. Sie müssen entweder eine erste Nachricht mit den Größen jeder Zeichenfolge und dann eine zweite Nachricht mit den Zeichenfolgen selbst senden oder das Metainfo in die Nutzdaten codieren und einen statischen Empfangspuffer verwenden.

Wenn Sie nur eine Nachricht senden müssen, dann würde ich verzichten, einen Datentyp für Pair zu definieren: stattdessen würde ich einen Datentyp für die gesamte Nutzlast erstellen und alle Daten in einem zusammenhängenden, nicht typisierten Paket ablegen. Dann könnten Sie am empfangenden Ende darüber iterieren, indem Sie den genauen Platzbedarf für jeden String zuweisen und ihn auffüllen. Lassen Sie mich ein ASCII-Diagramm zur Veranschaulichung aufstellen. Dies wäre Ihre Nutzlast:

| ..x1 .. | ..s_len1 .. | .... string1 .... | ..x2 .. | ..s_len2 .. | .string2. |. .x3 .. | ..s_len3 .. | ....... string3 ....... | ...

Sie senden das Ganze als eine Einheit (zB ein Array von MPI_BYTE), dann würde der Empfänger es so etwas wie dieses entpacken:

while (buffer is not empty) 
{ 
    read x; 
    read s_len; 
    allocate s_len characters; 
    move s_len characters from buffer to allocated space; 
} 

ist jedoch zu beachten, dass diese Lösung nur, wenn die Datendarstellung von Zahlen und Zeichen funktioniert genauso auf den Sende- und Empfangssystemen.

+0

Packen alles in zusammenhängendem Puffer ist, was ich endlich beschlossen. Eine Sache zu beachten ist, dass ich zusätzliche MPI_Gather() verwenden musste, um Payload-Größen von jedem Prozess zu sammeln. Diese Nutzlastgrößen wurden verwendet, um die Größe des recv-Puffers und des Verschiebungsvektors zu berechnen (http://www.mpi-forum.org/docs/mpi-11-html/node70.html). – Constantin

2

Ich glaube nicht, dass Sie mit MPI ganz das machen können, was Sie wollen. Ich bin ein Fortran-Programmierer, also ertragen Sie mit mir, wenn mein Verständnis von C ein wenig wackelig ist. Sie wollen, so scheint es, eine Datenstruktur übergeben, die aus 1 int und 1 string besteht (die Sie weitergeben, indem Sie den Ort des ersten Zeichens in der string übergeben) von einem Prozess zum anderen? Ich denke, was Sie tun müssen, ist eine Zeichenfolge fester Länge zu übergeben - die daher so lang sein müsste wie eine der Zeichenfolgen, die Sie wirklich übergeben möchten. Der Empfangsbereich für das Sammeln dieser Saiten muss groß genug sein, um alle Saiten zusammen mit ihren Längen aufzunehmen.

Wahrscheinlich möchten Sie einen neuen MPI-Datentyp für Ihre Strukturen deklarieren; Sie können diese dann sammeln und, da die gesammelten Daten die Länge der Zeichenfolge enthalten, die nützlichen Teile der Zeichenfolge beim Empfänger wiederherstellen.

Ich bin mir nicht sicher, aber ich habe noch nie wirklich variable Nachrichtenlängen gefunden, wie Sie scheinen wollen, und es fühlt sich un-MPI-ähnlich an. Aber es könnte etwas sein, das in der neuesten Version von MPI implementiert wurde, über das ich noch nie gestolpert bin, obwohl es bei der Online-Dokumentation nicht so aussieht.

+0

Ich hoffte zu vermeiden, Platz mit Puffern fester Länge zu verschwenden. Eine weitere mögliche Option, die vermieden werden sollte, ist das Darstellen eines Arrays von len/chars-Paaren mit zwei separaten Arrays: eines von lens und eines von chars. Danke trotzdem. – Constantin

+0

Mark, es ist eine Weile her, seit ich mit MPI gespielt habe, aber ich bin mir ziemlich sicher, dass du hier genau bist. Zumindest für ca. 2005 MPI. –

1

MPI-Implementierungen untersuchen oder interpretieren den tatsächlichen Inhalt einer Nachricht nicht. Sofern Sie die Größe der Datenstruktur kennen, können Sie diese Größe in einer bestimmten Anzahl von Char- oder Int-Werten darstellen. Die MPI-Implementierung wird die tatsächlichen internen Details der Daten nicht kennen oder sich darum kümmern.

Es gibt ein paar Vorbehalte ... sowohl der Sender als auch der Empfänger müssen sich auf die Interpretation der Nachrichteninhalte einigen, und der auf der sendenden und empfangenden Seite bereitgestellte Puffer muss in eine definierbare Anzahl von Zeichen passen Int's.

Verwandte Themen