2010-02-13 5 views
5

J'ai besoin de MPI_Gatherv() un certain nombre de paires int/string. Disons que chaque paire ressemble à ceci:Passer des structures de longueur variable entre des processus MPI

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

Comment définir un type de données approprié MPI pour la paire?

+0

Utilisez 'char s [0];' pour le tableau de longueur variable, pas 'char s [1];'. – kennytm

+0

@KennyTM, s [0] donne "avertissement C4200: extension non standard utilisée: tableau de taille nulle en struct/union". – Constantin

+0

Ah MSVC. C99 est correctement pris en charge par gcc, mais pas par MSVC. – kennytm

Répondre

4

En bref, il est théoriquement impossible d'envoyer un message de taille variable et la recevoir dans un tampon de la taille parfaite. Vous devrez soit envoyer un premier message avec les tailles de chaque chaîne et ensuite un deuxième message avec les chaînes elles-mêmes, soit encoder ce métainfo dans la charge utile et utiliser un tampon de réception statique. Si vous ne devez envoyer qu'un seul message, je renoncerais à définir un type de données pour Pair: à la place, je créerais un type de données pour l'ensemble de la charge utile et déverserais toutes les données dans un paquet contigu, non typé. Ensuite, à la réception, vous pouvez itérer dessus, en allouant la quantité exacte d'espace nécessaire pour chaque chaîne et en la remplissant. Laissez-moi monter un diagramme ASCII pour illustrer. Ce serait votre charge utile:

| ..x1 .. | .._lang1 .. | .... chaîne1 .... | ..x2 .. | ..sllen2 .. | .string2. |. .x3 .. | ..s_len3 .. | ....... string3 ....... | ...

Vous envoyez le tout en une seule unité (par exemple un tableau de MPI_BYTE), alors le récepteur serait le déballer quelque chose comme ceci:

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

Notez cependant que cette solution ne fonctionne que si la représentation des données de nombres entiers et caractères est le même sur les systèmes d'envoi et de réception.

+0

Emballer tout dans un tampon contigu est ce que j'ai finalement décidé. Une chose à noter est que j'ai dû utiliser MPI_Gather() supplémentaire pour collecter les tailles de charge utile de chaque processus. Ces tailles de charge utile ont été utilisées pour calculer la taille du tampon recv et du vecteur de déplacement (http://www.mpi-forum.org/docs/mpi-11-html/node70.html). – Constantin

2

Je ne pense pas que vous puissiez faire tout ce que vous voulez avec MPI. Je suis un programmeur Fortran, alors supportez-moi si ma compréhension de C est un peu fragile. Vous voulez, semble-t-il, passer une structure de données composée de 1 int et 1 chaîne (que vous passez en passant l'emplacement du premier caractère de la chaîne) d'un processus à l'autre? Je pense que ce que vous devez faire est de passer une chaîne de longueur fixe - qui devrait, par conséquent, être aussi longue que l'une des chaînes que vous voulez vraiment passer. La zone de réception pour la collecte de ces cordes devra être suffisamment grande pour recevoir toutes les cordes ainsi que leurs longueurs.

Vous aurez probablement envie de déclarer un nouveau MPI pour votre type de données struct; vous pouvez ensuite les rassembler et, puisque les données recueillies comprennent la longueur de la chaîne, récupérer les parties utiles de la chaîne au niveau du récepteur.

Je ne suis pas certain à ce sujet, mais je n'ai jamais rencontré un message vraiment de longueur variable que vous semblez vouloir utiliser et il ne se sent sorte un-MPI-like. Mais c'est peut-être quelque chose qui a été implémenté dans la dernière version de MPI que je n'ai jamais trébuché, bien que regarder la documentation en ligne ne me semble pas le cas.

+0

J'espérais éviter de gaspiller de l'espace avec des tampons de longueur fixe. Une autre option possible à éviter est de représenter le tableau de paires len/chars avec 2 tableaux séparés: un de l'objectif et un des caractères. Merci quand même. – Constantin

+0

Mark, ça fait longtemps que je n'ai pas joué avec MPI, mais je suis à peu près sûr que vous êtes précis ici. Au moins pour 2005 MPI. –

1

Les implémentations MPI n'inspectent ni n'interprètent le contenu réel d'un message. Pourvu que vous connaissiez la taille de la structure de données, vous pouvez représenter cette taille dans un certain nombre de char ou d'int. L'implémentation MPI ne connaîtra pas ou ne se souciera pas des détails internes réels des données. Il y a quelques mises en garde ... l'expéditeur et le destinataire doivent s'entendre sur l'interprétation du contenu du message, et le tampon que vous fournissez du côté de l'envoi et du destinataire doit correspondre à un certain nombre définissable de caractères ou int.

Questions connexes