Memory leak in MPI_File_read_at - c

i'm writing a C/MPI program that making many processes read from a data file.
When using the standard functions from stdio (fopen, fread, fseek) everything goes well. The problem that i can't go beyond 4 Go offsets. So i used MPI-IO functions to read a big file and at this moment memory doesn't liberate well.
In fact i read a buffer, i process it then i free the allocated memory. The memory usage per process is perfect but the global memory usage doesn't stop increasing. I don't have this problem by just replacing mpi_file_read at by fread.
there is my code :
double CPUtime(){ return ((double) clock())/CLOCKS_PER_SEC;}int main(int argc, char* argv []){
if(argc != 5) {
printf("\t[Dictionary file] [Dictionary] [Input file] [Buffer size]\n");
exit(0);
}
char* sInput = malloc (sizeof(char)*maxLength);
char* sOutput = malloc (sizeof(char)*maxLength);
char* compl = malloc (sizeof(char)*maxLength);
char* sDictionaryFileName = argv[1];
char* sDictionaryName = argv[2];
char* filename = argv[3];
int Mbuffer = atoi(argv[4]);
int maxBuffer = Mbuffer*1024*1024;
int over = 10000;
int rank,numprocess;
long int offset;
char* buffer;
char* opbuffer;
double tstart=CPUtime();
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
/* mpi version */
/* open the file*/
MPI_File fh;
int err;
err = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
if (err != MPI_SUCCESS) {
char errstr[MPI_MAX_ERROR_STRING];
int errlen;
MPI_Error_string(err, errstr, &errlen);
printf("Error at opening file %s (%s)\n",filename,errstr);
MPI_Finalize();
exit(1);
}
// get offsets and buffer size
MPI_Offset sfile;
MPI_File_get_size(fh,&sfile);
MPI_Status status;
/* C version */
/*FILE* fh;
long int sfile;
fh =fopen( filename,"rb");
if (fh==NULL) {
printf("Error at opening file %s\n",filename);
exit(1);
}
// get offsets and buffer size
fseek(fh, 0L, SEEK_END);
sfile = ftell(fh);
fseek(fh, 0L, SEEK_SET);*/
MPI_Comm_size( MPI_COMM_WORLD, &numprocess );
/* number of iterations */
long int data_size = (long int)(sfile/(numprocess));
int nbIter = data_size/maxBuffer;
if(nbIter<=1){
nbIter = 1;
maxBuffer = data_size;
}
/* offsets */
offset = data_size*(rank);
long int cursor = offset;
char* header;
if(rank==0){
FILE* fh;
fh =fopen( filename,"rb");
if (fh==NULL) {
printf("Error at opening file %s\n",filename);
exit(1);
}
/* read the header and broadcast it */
header = malloc(sizeof(char)*1000);
fgets(header,1000,fh);
fclose(fh);
//broadcast header
int sndHeader = strlen(header);
//cursor+=sndHeader;
int process_counter;
for(process_counter=1;process_counter<numprocess;process_counter++){
int ierr = MPI_Send(&sndHeader, 1, MPI_INT, process_counter, 42,MPI_COMM_WORLD);
if (ierr != MPI_SUCCESS) {
int errclass,resultlen;
char err_buffer[MPI_MAX_ERROR_STRING];
MPI_Error_class(ierr,&errclass);
if (errclass== MPI_ERR_RANK) {
fprintf(stderr,"Invalid rank used in MPI send call\n");
MPI_Error_string(ierr,err_buffer,&resultlen);
fprintf(stderr,err_buffer);
MPI_Finalize();
}
}
MPI_Send(header, sndHeader, MPI_CHAR, process_counter, 43, MPI_COMM_WORLD);
}
}
else{
/* receive the header */
int sizeofHeader;
MPI_Status s ;
MPI_Recv(&sizeofHeader,1,MPI_INT,0,42,MPI_COMM_WORLD,&s);
header = malloc (sizeof(char)*sizeofHeader+1);
MPI_Recv(header,sizeofHeader,MPI_CHAR,0,43,MPI_COMM_WORLD,&s);
}
/* Synchronization barrier */
MPI_Barrier(MPI_COMM_WORLD);
int count;
opbuffer = malloc(sizeof(char)*maxBuffer);
/* C version */
//fseek(fh,cursor,SEEK_SET);
for(count=0;count<nbIter;count++){
if(count==0 && rank==numprocess-1){ //init ring
//send the token to p0
int token=1;
MPI_Send(&token,sizeof(int),MPI_INT,0,55,MPI_COMM_WORLD);
}
//recv
int token;
int sender;
if(rank==0)
sender = numprocess-1;
else
sender=rank-1;
MPI_Status s;
MPI_Recv(&token,sizeof(int),MPI_INT,sender,55,MPI_COMM_WORLD,&s);
fflush(stdout);printf("P%d got the token at %G\n",rank,CPUtime());
//read
double start=CPUtime();
/*double readtime;
double sread=CPUtime();//read time*/
//read
if(token==1){
/* MPI version */
int err=MPI_File_read_at(fh, cursor,opbuffer, sizeof(char)*maxBuffer, MPI_CHAR, &status);
if(err!=MPI_SUCCESS){
/*char errstr[MPI_MAX_ERROR_STRING];
int errlen;
MPI_Error_string(err, errstr, &errlen);
printf("Error reading file %s (%s)\n",filename,errstr);*/
MPI_Finalize();
exit(0);
}
/* C version of read */
/*int k=fread(opbuffer,sizeof(char),maxBuffer,fh);
if(k==0)
perror("fread");*/
cursor+=maxBuffer;
buffer=opbuffer;
}
else{
printf("Error token!\n");
token=1;
}
//printf("P%d readtime=%G\n",rank,CPUtime()-sread);
//Isend
int next = (rank+1)%numprocess;
MPI_Send(&token,sizeof(int),MPI_INT,next,55,MPI_COMM_WORLD);
/* start processing*/
/* end processing */
}
free(opbuffer);
int er=MPI_File_close(&fh);
if(er!=MPI_SUCCESS){
printf("Error closing file\n");
MPI_Finalize();
exit(1);
}
MPI_Finalize();
printf("Global time : %G\n",CPUtime()-tstart);
return 0;
}
If any one have any idea of what is it i would apprciate that.
Thank you.

It's probably that you're never calling MPI_File_close. That will cause intermediate operations on the file to leak. Note that you should also close it under the error condition if(err!=MPI_SUCCESS) if you really want to write clean code.

Related

Signal code: Address not mapped (1) how should I define a variable dynamically to avoid it?

I have the following code - it is an image filter, but in this case I am not using the convolution part - which fails with the error from the title, when using scatter. I think that the error is in the receiver buffer, but can not figure out why:
#include "utils.h"
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdint.h>
#include <mpi.h>
typedef char pixel_t[3];
typedef struct image_s {
pixel_t *data_in,
*data_out;
size_t width, height;
} image_t;
#define DIE_MPI(msg) do { \
fprintf(stderr, "FAILURE: %s\n", msg); \
exit(EXIT_FAILURE); \
} while(0)
char *g_progname;
static inline void usage(void) {
fprintf(stderr, "USAGE: %s [filename [x y]]\n", g_progname);
exit(0);
}
void img_load(const char* filename, const size_t width, const size_t height, image_t* img)
{
FILE* fsrc = fopen(filename, "r");
if (!fsrc)
FATAL("fopen");
fseek(fsrc, 0, SEEK_END);
size_t sz = ftell(fsrc);
fseek(fsrc, 0, SEEK_SET);
img->data_in = XMALLOC(sz);
img->data_out = XMALLOC(sz);
img->width = width;
img->height = height;
memset(img->data_in, 0UL, sz);
memset(img->data_out, 0UL, sz);
size_t n_bytes = fread(img->data_in, 1, sz, fsrc);
printf("Read %u. Expected %u bytes\n", n_bytes, sz);
if (n_bytes < sz) {
fprintf(stderr, "Read fewer bytes than expected: %u/%u\n", n_bytes, sz);
}
if (feof(fsrc)) {
printf("Finished reading %s\n", filename);
clearerr(fsrc);
}
fclose(fsrc);
}
int main(int argc, char* argv[])
{
int err = MPI_Init(&argc, &argv);
if (err) DIE_MPI("MPI_Init");
int size = 0;
err = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (err) DIE_MPI("MPI_Comm_size");
int rank = 0;
err = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (err) DIE_MPI("MPI_Comm_rank");
uint32_t X = 512,
Y = 512;
char* filename = NULL;
g_progname = argv[0];
switch(argc) {
case 4:
X = strtoul(argv[3], NULL, 0);
Y = strtoul(argv[2], NULL, 0);
case 2:
filename = argv[1];
break;
case 1:
filename = "lena_color.data";
X = 512;
Y = 512;
break;
default:
usage();
}
pixel_t *bitmap_in;
bitmap_in = malloc(X * Y * sizeof(pixel_t));
image_t img;
if(rank==0)
{
printf("Processing %s...\n", filename);
img_load(filename, X, Y, &img);
}
MPI_Scatter(img, X*Y*sizeof(pixel_t), MPI_CHAR, bitmap_in, X*Y*sizeof(pixel_t), MPI_CHAR, 0, MPI_COMM_WORLD);
err = MPI_Finalize();
if (err) DIE("MPI_Finalize");
return err;
}
To sum up the problem, I have a mapping trouble with either the sending buffer or the receiving buffer. I have tried adding more space to the memory allocated on the receiving buffer but it did not solved it. Another cause could be that I am sending more memory than the allocated in the structure image_t, but I do not think so, because it should be twice as big as the size that I am trying to send.
Perhaps I am missing something with my conclusions, as I am still learning c and MPI.
The error was not in the definition of the variable itself, but in the call to the variable in the MPI_Scatter(), there is no need to put "&var" in the MPI_Scatter(), you should just put "var"

After reading a file, integers are set to arbitrarily large values

I'm facing a very odd issue when trying to read a file in C.
I've parsed a file path via a command line argument, and gotten the size using the stat() function, and this works fine. However, after I read the file, all of my integers become arbitrarily large, and I cannot for the life of me figure out why!
Here is the relevant code from my main function:
int main( int argc, char *argv[] ) {
char *filepath = argv[1];
startaddress = strtol(argv[2], &endptra, 16);
endaddress = strtol(argv[3], &endptrb, 16);
int filesize = getfilesize(filepath);
printf("Filesize is %d\n", filesize);
unsigned char *mem = malloc( filesize );
printf("Filesize here is %d\n", filesize);
int size2 = filesize;
int test3 = 18;
printf("Size 2 set to %d\n", size2);
printf("Test 3 set to %d\n", test3);
// READ FILE
loadimage(filepath, &mem, filesize);
printf("Right after load image, file size is %d\n", filesize);
printf("%s\n", strerror(errno));
printf("Filesize is %d\n", filesize);
printf("size2: %d\n", size2);
printf("test3: %d\n", test3);
exit(0);
}
"getfilesize" is a relatively simple function that appears to work well:
int getfilesize(char *path) {
struct stat sbuffer;
int filesize = 0;
filesize = stat(path, &sbuffer);
if (filesize == -1) {
return 0;
} else {
return sbuffer.st_size;
}
}
Here is the loadimage function:
int loadimage(char *path, unsigned char *mem[], int size) {
int fdin, retval;
unsigned char buf[2048];
int nread;
printf("Path is: %s\n", path);
printf("Size is: %d\n", size);
fdin = open(path, O_RDONLY);
printf("fdin: %d\n", fdin);
if(fdin == -1) {
die(strerror( errno ));
}
int count = 0;
nread = read(fdin, buf, 2048);
for(; count < nread; count++) {
mem[count] = &buf[count];
}
if(nread == -1) {
die(strerror( errno ));
}
retval = close(fdin);
printf("Size is now %d\n", size);
return 1;
}
And this is the output of the result:
Filesize is 39
Filesize here is 39
Size 2 set to 39
Test 3 set to 18
Path is: test_file.txt
Size is: 39
fdin: 3
Size is now 39
Right after load image, file size is 32765
Success
Filesize is 32765
size2: 1418855892
test3: 32765
This is baffling to me and I cannot figure it out! It's confusing that even integers that I don't pass to the function are being modified as well. I'm assuming there's some sort of memory overflow happening somewhere, but I'm not used to working in the file system in C.
Thanks!
It seems to me that the problem is here:
int loadimage(char *path, unsigned char *mem[], int size) {
The mem argument should be just a pointer, or just an array, but not both. Aside from that, you're doing the same with the buf local variable, you're dereferencing it more than once when you use it (however that case might be harmless, I'm not sure). loadimage() should be:
int loadimage(char *path, unsigned char *mem, int size) {
int fdin, retval;
unsigned char buf[2048];
int nread;
printf("Path is: %s\n", path);
printf("Size is: %d\n", size);
fdin = open(path, O_RDONLY);
printf("fdin: %d\n", fdin);
if(fdin == -1) {
die(strerror( errno ));
}
int count = 0;
nread = read(fdin, buf, 2048);
for(; count < nread; count++) {
mem[count] = buf[count]; //no need for derefencing
}
if(nread == -1) {
die(strerror( errno ));
}
retval = close(fdin);
printf("Size is now %d\n", size);
return 1;
}
then, when calling it, do not dereference mem:
loadimage(filepath, mem, filesize);
Sorry, I don't have time so I haven't compiled it, but you get the idea, most probably that's the problem.

Sending .amr files to SIM900 over serial in c

I'm trying to send .amr files from my desktop to a SIM900 GSM module over UART.
I'm using teuniz's RS232 library.
I do the initialisation using AT commands and then read the file into a buffer and write it to the UART using the RS232_SendByte() library function byte-by-byte, but it doesn't seem to work.
I send the following AT commands:
AT+CFSINIT
AT+CFSWFILE=\"audio.amr\",0,6694,13000 # After which I get the CONNECT message from the SIM900 module
# Here's where I send the file
AT+CFSGFIS=\"audio.amr\"
Here's my code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "rs232.h"
char *readFile(char *filename, int *size) {
char *source = NULL;
FILE *fp = fopen(filename, "rb");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { return NULL; }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
if(!source) return NULL;
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { return NULL; }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
free(source);
return NULL;
} else {
source[newLen++] = 0; /* Just to be safe. */
}
*size = bufsize;
}
fclose(fp);
}
return source;
}
int main(int argc, char *argv[])
{
int ret = 0, cport_nr = 2, bdrate=38400;
char data[2000] = {0};
if(RS232_OpenComport(cport_nr, bdrate)) {
printf("Can not open comport\n");
ret = -1;
goto END;
}
int size;
unsigned char *filebuf = readFile("audio.amr", &size);
if (!filebuf) {
ret = -1;
goto END_1;
}
/* Initialization */
RS232_cputs(cport_nr, "AT");
RS232_cputs(cport_nr, "AT+CFSINIT");
sleep(1);
RS232_cputs(cport_nr, "AT+CFSWFILE=\"audio.amr\",0,6694,13000");
/* Wait for CONNECT */
sleep(2);
printf("Sending file of size: %d\n", size);
int i;
for (i = 0; i < size; ++i) {
putchar(filebuf[i]);
RS232_SendByte(cport_nr, filebuf[i]);
}
free(filebuf);
sleep(1);
/* Check if file transferred right */
RS232_cputs(cport_nr, "AT+CFSGFIS=\"audio.amr\"");
END_1:
RS232_CloseComport(cport_nr);
END:
return ret;
}
EDIT 1
Normally, the procedure to send a file to SIM900 using AT commands would be as documented here:
AT+CFSINIT # Initialize flash; Response is OK
AT+CFSWFILE=<filename>,<writeMode>,<fileSize>,<InputTime> # Write file with these parameter; Response is CONNECT; So this is when I start sending the file
Here's where I send the file. If it worked and the sent file size matched the <filesize> sent in the above command, SIM900 must respond with OK, which it doesn't. :(
AT+CFSGFIS=<filename> # Gives the file size on flash. This gives me an error since the file didn't upload correctly.
This leads me to beleive there's something wrong with my program. I'm reading the file in binary mode. And the size reported is exacty the same as I specify in the AT+CFSWFILE=<filename>,<writeMode>,<fileSize>,<InputTime> command.

C progam to play audio file in Linux crackels at end

On Ubuntu Linux I have written a c program based on the Libao example program to open audio wave file and play. It works fine but at the end after finish playing there is crackling high pitch noise. Here is the code which I modified mt libao example. How can I fix it? Please help
#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>
#define BUF_SIZE 4096
int main(int argc, char **argv)
{
ao_device *device;
ao_sample_format format;
int default_driver;
char *buffer;
int buf_size;
int sample;
FILE *fp;
float freq = 440.0;
int i;
/* -- Initialize -- */
fprintf(stderr, "libao example program\n");
ao_initialize();
/* -- Setup for default driver -- */
default_driver = ao_default_driver_id();
memset(&format, 0, sizeof(format));
format.bits = 16;
format.channels = 2;
format.rate = 44100;
format.byte_format = AO_FMT_LITTLE;
/* -- Open driver -- */
// device = ao_open_live(default_driver, &format, NULL /* no options */);
device = ao_open_live(default_driver, &format, NULL /* no options */);
if (device == NULL) {
fprintf(stderr, "Error opening device.\n");
return 1;
}
fp = fopen("nc.wav", "rb");
if (fp == NULL) {
fprintf(stderr, "Unable to open file \n");
return;
}
fseek(fp, 0, SEEK_END);
unsigned long fileLen = ftell(fp);
fseek(fp, 0, SEEK_SET);
//Allocate memory
buffer=(char *)malloc(fileLen+1);
if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(fp);
return;
}
fread(buffer, fileLen, 1, fp);
fclose(fp);
ao_play(device, buffer, buf_size);
/* -- Close and shutdown -- */
ao_close(device);
ao_shutdown();
return (0);
}
The buf_size variable is passed to ao_play without being initialized, and the crackles most likely occur because it is playing past the end of the sample buffer into random memory.
Depending on your compiler settings, the compiler can warn you about uninitialized variables bugs like this (gcc only does it when optimizations are turned on, via the -Wuninitialized or -Wall settings).

MPI Point to Point Communication to Collective Communication: MPI_Scatterv Trouble

I am working on a project of converting a Point to Point Communication to a Collective Communication.
Essentially, what I would like to do is use MPI_Scatterv instead of MPI_Send and MPI_Recv. What I am having trouble determining is the correct arguments for Scatterv.
Here is the function that I am working in:
void read_block_vector (
char *s, /* IN - File name */
void **v, /* OUT - Subvector */
MPI_Datatype dtype, /* IN - Element type */
int *n, /* OUT - Vector length */
MPI_Comm comm) /* IN - Communicator */
{
int datum_size; /* Bytes per element */
int i;
FILE *infileptr; /* Input file pointer */
int local_els; /* Elements on this proc */
MPI_Status status; /* Result of receive */
int id; /* Process rank */
int p; /* Number of processes */
int x; /* Result of read */
datum_size = get_size (dtype);
MPI_Comm_size(comm, &p);
MPI_Comm_rank(comm, &id);
/* Process p-1 opens file, determines number of vector
elements, and broadcasts this value to the other
processes. */
if (id == (p-1)) {
infileptr = fopen (s, "r");
if (infileptr == NULL) *n = 0;
else fread (n, sizeof(int), 1, infileptr);
}
MPI_Bcast (n, 1, MPI_INT, p-1, comm);
if (! *n) {
if (!id) {
printf ("Input file '%s' cannot be opened\n", s);
fflush (stdout);
}
}
/* Block mapping of vector elements to processes */
local_els = BLOCK_SIZE(id,p,*n);
/* Dynamically allocate vector. */
*v = my_malloc (id, local_els * datum_size);
if (id == (p-1)) {
for (i = 0; i < p-1; i++) {
x = fread (*v, datum_size, BLOCK_SIZE(i,p,*n),
infileptr);
MPI_Send (*v, BLOCK_SIZE(i,p,*n), dtype, i, DATA_MSG,
comm);
}
x = fread (*v, datum_size, BLOCK_SIZE(id,p,*n),
infileptr);
fclose (infileptr);
} else {
MPI_Recv (*v, BLOCK_SIZE(id,p,*n), dtype, p-1, DATA_MSG,
comm, &status);
}
// My Attempt at making this collective communication:
if(id == (p-1))
{
x = fread(*v,datum_size,*n,infileptr);
for(i = 0; i < p; i++)
{
size[i] = BLOCK_SIZE(i,p,*n);
}
//x = fread(*v,datum_size,BLOCK_SIZE(id, p, *n),infileptr);
fclose(infileptr);
}
MPI_Scatterv(v,send_count,send_disp, dtype, storage, size[id], dtype, p-1, comm);
}
Any help would be appreciated.
Thank you
It's easier for people to answer your question if you post a small, self-contained, reproducible example.
For the Scatterv, you need to provide the list of counts to send to each process, which appears to be your size[] array, and the displacements within the data to send out. The mechanics of Scatter vs Scatterv are described in some detail in this answer. Trying to infer what all your variables and un-supplied functions/macros do, the example below scatters a file out to the processes.
But also note that if you're doing this, it's not much harder to actually use MPI-IO to coordinate the file access directly, avoiding the need to have one process read all of the data in the first place. Code for that is also supplied.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv) {
int id, p;
int *block_size;
int datasize = 0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
block_size = malloc(p * sizeof(int));
for (int i=0; i<p; i++) {
block_size[i] = i + 1;
datasize += block_size[i];
}
/* create file for reading */
if (id == p-1) {
char *data = malloc(datasize * sizeof(char));
for (int i=0; i<datasize; i++)
data[i] = 'a' + i;
FILE *f = fopen("data.dat","wb");
fwrite(data, sizeof(char), datasize, f);
fclose(f);
printf("Initial data: ");
for (int i=0; i<datasize; i++)
printf("%c", data[i]);
printf("\n");
free(data);
}
if (id == 0) printf("---Using MPI-Scatterv---\n");
/* using scatterv */
int local_els = block_size[id];
char *v = malloc ((local_els + 1) * sizeof(char));
char *all;
int *counts, *disps;
counts = malloc(p * sizeof(int));
disps = malloc(p * sizeof(int));
/* counts.. */
for(int i = 0; i < p; i++)
counts[i] = block_size[i];
/* and displacements (where the data starts within the send buffer) */
disps[0] = 0;
for(int i = 1; i < p; i++)
disps[i] = disps[i-1] + counts[i-1];
if(id == (p-1))
{
all = malloc(datasize*sizeof(char));
FILE *f = fopen("data.dat","rb");
int x = fread(all,sizeof(char),datasize,f);
fclose(f);
}
MPI_Scatterv(all, counts, disps, MPI_CHAR, v, local_els, MPI_CHAR, p-1, MPI_COMM_WORLD);
if (id == (p-1)) {
free(all);
}
v[local_els] = '\0';
printf("[%d]: %s\n", id, v);
/* using MPI I/O */
fflush(stdout);
MPI_Barrier(MPI_COMM_WORLD); /* only for syncing output to screen */
if (id == 0) printf("---Using MPI-IO---\n");
for (int i=0; i<local_els; i++)
v[i] = 'X';
/* create the file layout - the subarrays within the 1d array of data */
MPI_Datatype myview;
MPI_Type_create_subarray(1, &datasize, &local_els, &(disps[id]),
MPI_ORDER_C, MPI_CHAR, &myview);
MPI_Type_commit(&myview);
MPI_File mpif;
MPI_Status status;
MPI_File_open(MPI_COMM_WORLD, "data.dat", MPI_MODE_RDONLY, MPI_INFO_NULL, &mpif);
MPI_File_set_view(mpif, (MPI_Offset)0, MPI_CHAR, myview, "native", MPI_INFO_NULL);
MPI_File_read_all(mpif, v, local_els, MPI_CHAR, &status);
MPI_File_close(&mpif);
MPI_Type_free(&myview);
v[local_els] = '\0';
printf("[%d]: %s\n", id, v);
free(v);
free(counts);
free(disps);
MPI_Finalize();
return 0;
}
Running this gives (output re-ordered for clarity)
$ mpirun -np 6 ./foo
Initial data: abcdefghijklmnopqrstu
---Using MPI-Scatterv---
[0]: a
[1]: bc
[2]: def
[3]: ghij
[4]: klmno
[5]: pqrstu
---Using MPI-IO---
[0]: a
[1]: bc
[2]: def
[3]: ghij
[4]: klmno
[5]: pqrstu

Resources