Skip to content

Commit e180f0c

Browse files
committed
Solution for posix I/O where everyone writes
1 parent c3bbb7d commit e180f0c

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <errno.h>
5+
#include <mpi.h>
6+
7+
#define DATASIZE 64
8+
#define WRITER_ID 0
9+
10+
void single_writer(int, int *, int);
11+
void many_writers(int, int *, int);
12+
13+
14+
int main(int argc, char *argv[])
15+
{
16+
int my_id, ntasks, i, localsize;
17+
int *localvector;
18+
19+
MPI_Init(&argc, &argv);
20+
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
21+
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
22+
23+
if (ntasks > 64) {
24+
fprintf(stderr, "Datasize (64) should be divisible by number "
25+
"of tasks.\n");
26+
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
27+
}
28+
29+
if (DATASIZE % ntasks != 0) {
30+
fprintf(stderr, "Datasize (64) should be divisible by number "
31+
"of tasks.\n");
32+
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
33+
}
34+
35+
localsize = DATASIZE / ntasks;
36+
localvector = (int *) malloc(localsize * sizeof(int));
37+
38+
for (i = 0; i < localsize; i++) {
39+
localvector[i] = i + 1 + localsize * my_id;
40+
}
41+
42+
many_writers(my_id, localvector, localsize);
43+
44+
free(localvector);
45+
46+
MPI_Finalize();
47+
return 0;
48+
}
49+
50+
void single_writer(int my_id, int *localvector, int localsize)
51+
{
52+
FILE *fp;
53+
int *fullvector;
54+
55+
fullvector = (int *) malloc(DATASIZE * sizeof(int));
56+
57+
MPI_Gather(localvector, localsize, MPI_INT, fullvector, localsize,
58+
MPI_INT, WRITER_ID, MPI_COMM_WORLD);
59+
60+
if (my_id == WRITER_ID) {
61+
if ((fp = fopen("singlewriter.dat", "wb")) == NULL) {
62+
fprintf(stderr, "Error: %d (%s)\n", errno, strerror(errno));
63+
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
64+
} else {
65+
fwrite(fullvector, sizeof(int), DATASIZE, fp);
66+
fclose(fp);
67+
printf("Wrote %d elements to file singlewriter.dat\n", DATASIZE);
68+
}
69+
}
70+
71+
free(fullvector);
72+
}
73+
74+
void many_writers(int my_id, int *localvector, int localsize)
75+
{
76+
FILE *fp;
77+
char filename[64];
78+
79+
sprintf(filename, "manywriters-%d.dat", my_id);
80+
81+
if ((fp = fopen(filename, "wb")) == NULL) {
82+
fprintf(stderr, "Error: %d (%s)\n", errno, strerror(errno));
83+
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
84+
} else {
85+
fwrite(localvector, sizeof(int), localsize, fp);
86+
fclose(fp);
87+
printf("Wrote %d elements to file manywriters-%d.dat\n", localsize,
88+
my_id);
89+
}
90+
}
91+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
program pario
2+
use mpi
3+
use, intrinsic :: iso_fortran_env, only : error_unit, output_unit
4+
implicit none
5+
6+
integer, parameter :: datasize = 64, writer_id = 0
7+
integer :: rc, my_id, ntasks, localsize, i
8+
integer, dimension(:), allocatable :: localvector
9+
integer, dimension(datasize) :: fullvector
10+
11+
call mpi_init(rc)
12+
call mpi_comm_size(mpi_comm_world, ntasks, rc)
13+
call mpi_comm_rank(mpi_comm_world, my_id, rc)
14+
15+
if (ntasks > 64) then
16+
write(error_unit, *) 'Maximum number of tasks is 64!'
17+
call mpi_abort(MPI_COMM_WORLD, -1, rc)
18+
end if
19+
20+
if (mod(datasize, ntasks) /= 0) then
21+
write(error_unit,*) 'Datasize (64) should be divisible by number of tasks'
22+
call mpi_abort(MPI_COMM_WORLD, -1, rc)
23+
end if
24+
25+
localsize = datasize / ntasks
26+
allocate(localvector(localsize))
27+
28+
localvector = [(i + my_id * localsize, i=1,localsize)]
29+
30+
call many_writers()
31+
32+
deallocate(localvector)
33+
call mpi_finalize(rc)
34+
35+
contains
36+
37+
subroutine single_writer()
38+
implicit none
39+
40+
call mpi_gather(localvector, localsize, mpi_integer, fullvector, &
41+
& localsize, mpi_integer, writer_id, mpi_comm_world, rc)
42+
if (my_id == writer_id) then
43+
open(10, file='singlewriter.dat', status='replace', form='unformatted', &
44+
& access='stream')
45+
write(10, pos=1) fullvector
46+
close (10)
47+
write(output_unit,'(A,I0,A)') 'Wrote ', size(fullvector), &
48+
& ' elements to file singlewriter.dat'
49+
end if
50+
end subroutine single_writer
51+
52+
subroutine many_writers()
53+
implicit none
54+
character(len=85) :: filename
55+
56+
write(filename, '(A,I0,A)') 'manywriters-', my_id, '.dat'
57+
58+
open(my_id+10, file=filename, status='replace', form='unformatted', &
59+
& access='stream')
60+
write(my_id+10, pos=1) localvector
61+
close (my_id+10)
62+
write(output_unit,'(A,I0,A,A)') 'Wrote ', size(localvector), &
63+
& ' elements to file ', filename
64+
end subroutine many_writers
65+
66+
end program pario

0 commit comments

Comments
 (0)