MPI-IO/fr: Difference between revisions
(Created page with "=== Opérations par déplacements ===") |
(Created page with "En utilisant les vues, chaque processus peut ''voir'' une section du fichier, comme si c'était le fichier en entier. De cette manière, il n'est plus nécessaire de calculer...") |
||
Line 61: | Line 61: | ||
=== Utiliser les vues === | === Utiliser les vues === | ||
En utilisant les vues, chaque processus peut ''voir'' une section du fichier, comme si c'était le fichier en entier. De cette manière, il n'est plus nécessaire de calculer les déplacements dans le fichier en fonction du rang du processus. Une fois la vue définie, il est beaucoup plus simple d'effectuer des opérations sur le fichier sans craindre d'entrer en conflit avec les opérations effectuées par les autres processus. On définit une vue à l'aide de la fonction [http://www.open-mpi.org/doc/current/man3/MPI_File_set_view.3.php MPI_File_set_view]. Voici un programme identique à celui de l'exemple précédent, mais en utilisant les vues. | |||
{{ | {{ | ||
File | File |
Revision as of 16:21, 11 March 2020
Partie du standard MPI-2, MPI-IO est une famille de routines MPI qui permet l'enregistrement d'opérations parallèles de lecture et d'écriture. Le principal avantage de MPI-IO est qu'il permet, de manière simple et efficace, de lire et d'écrire des données réparties sur plusieurs processus, vers un seul fichier commun à tous les processus. Ceci s'avère particulièrement utile lorsque les données manipulées sont des vecteurs ou des matrices découpés de manière structurée entre les différents processus. Le présent document donne quelques indications à propos de l'utilisation de MPI-IO et des références vers des documents plus complets
Utilisation
Opérations par déplacements
The simplest way to perform parallel read and write operations is to use offsets. Each process can read from or write to the file with a defined offset. This can be done in two operations (MPI_File_seek followed by MPI_File_read or by MPI_File_write), or even in a single operation (MPI_File_read_at or MPI_File_write_at). Usually the offset is computed as a function of the process rank.
#include <mpi.h>
#define BLOCKSIZE 80
#define NBRBLOCKS 32
int main(int argc, char** argv) {
MPI_File f;
char* filename = "testmpi.txt";
char buffer[TAILLEBLOC];
int rank, size;
int i;
/* MPI Initialization */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* Buffer initialization */
memset(buffer, 'a'+rank, BLOCKSIZE);
buffer[BLOCKSIZE - 1] = '\n';
MPI_File_open(MPI_COMM_WORLD, filename, (MPI_MODE_WRONLY | MPI_MODE_CREATE), MPI_INFO_NULL, &f);
/* Write data alternating between the processes: aabbccddaabbccdd... */
MPI_File_seek(f, rank*BLOCKSIZE, MPI_SEEK_SET); /* Go to position rank * BLOCKSIZE */
for (i=0; i<NBRBLOCKS; ++i) {
MPI_File_write(f, buffer, BLOCKSIZE, MPI_CHAR, MPI_STATUS_IGNORE);
/* Advance (size-1)*BLOCKSIZE bytes */
MPI_File_seek(f, (size-1)*BLOCKSIZE, MPI_SEEK_CUR);
}
MPI_File_close(&f);
MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &f);
/* Read data in a serial fashion for each process. Each process reads: aabbccdd */
for (i=0; i<NBRBLOCKS; ++i) {
MPI_File_read_at(f, rank*i*NBRBLOCKS*BLOCKSIZE, buffer, BLOCKSIZE, MPI_CHAR, MPI_STATUS_IGNORE);
}
MPI_File_close(&f);
MPI_Finalize();
return 0;
}
Utiliser les vues
En utilisant les vues, chaque processus peut voir une section du fichier, comme si c'était le fichier en entier. De cette manière, il n'est plus nécessaire de calculer les déplacements dans le fichier en fonction du rang du processus. Une fois la vue définie, il est beaucoup plus simple d'effectuer des opérations sur le fichier sans craindre d'entrer en conflit avec les opérations effectuées par les autres processus. On définit une vue à l'aide de la fonction MPI_File_set_view. Voici un programme identique à celui de l'exemple précédent, mais en utilisant les vues.
#include <stdio.h>
#include <mpi.h>
#define BLOCKSIZE 80
#define NBRBLOCKS 32
int main(int argc, char** argv) {
MPI_File f;
MPI_Datatype type_intercomp;
MPI_Datatype type_contiguous;
char* filename = "testmpi.txt";
char buffer[BLOCKSIZE];
int rank, size;
int i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* Buffer initialization */
memset(buffer, 'a'+rank, BLOCKSIZE);
buffer[BLOCKSIZE - 1] = '\n';
MPI_File_open(MPI_COMM_WORLD,
filename,
(MPI_MODE_WRONLY | MPI_MODE_CREATE),
MPI_INFO_NULL,
&f);
/* Write data alternating between the processes: aabbccddaabbccdd... */
MPI_Type_contiguous(BLOCKSIZE, MPI_CHAR, &type_intercomp);
MPI_Type_commit(&type_intercomp);
for (i=0; i<NBRBLOCKS; ++i) {
MPI_File_set_view(f, rank*BLOCKSIZE+i*size*BLOCKSIZE, MPI_CHAR, type_intercomp, "native", MPI_INFO_NULL);
MPI_File_write(f, buffer, BLOCKSIZE, MPI_CHAR, MPI_STATUS_IGNORE);
}
MPI_File_close(&f);
MPI_File_open(MPI_COMM_WORLD,
filename,
MPI_MODE_RDONLY,
MPI_INFO_NULL,
&f);
/* Read data in a serial fashion for each process. Each process reads: aabbccdd */
MPI_Type_contiguous(NBRBLOCKS*BLOCKSIZE, MPI_CHAR, &type_contiguous);
MPI_Type_commit(&type_contiguous);
MPI_File_set_view(f, rank*NBRBLOCKS*BLOCKSIZE, MPI_CHAR, type_contiguous, "native", MPI_INFO_NULL);
for (i=0; i<NBRBLOCKS; ++i) {
MPI_File_read(f, buffer, BLOCKSIZE, MPI_CHAR, MPI_STATUS_IGNORE);
}
MPI_File_close(&f);
MPI_Finalize();
return 0;
}
Warning! Some file systems do not support file locks. Consequently some operations are not possible, in particular using views on disjoint file sections.