Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <stdio.h> // printf
#include <stdlib.h> // EXIT_SUCCESS
#include <mpi.h>
#include "prng_shared.h"
int main(int argc, char* argv[]) {
int seed;
int N;
int i;
int number_of_workers;
int N_per_worker;
int my_process_id;
double *seq;
double *my_seq;
// initialize MPI sybsystem
MPI_Init(&argc,&argv);
// get number of available processes, and a unique id for this process
MPI_Comm_rank(MPI_COMM_WORLD, &my_process_id);
MPI_Comm_size(MPI_COMM_WORLD, &number_of_workers);
// get parameters from command line arguments
read_arguments(&seed, &N, argc, argv);
// get number of workers and this workers id
MPI_Comm_rank(MPI_COMM_WORLD, &my_process_id);
MPI_Comm_size(MPI_COMM_WORLD, &number_of_workers);
// exit if work cannot be divided equally among workers
if ( (N % number_of_workers) != 0 ) {
printf("Cannot equally divide %d numbers by %d workers \n", N, number_of_workers);
exit(EXIT_FAILURE);
}
// calculate numbers to be generated by each process
N_per_worker = N / number_of_workers;
// allocate and array to hold N_per_worker random numbers
my_seq = malloc(N_per_worker * sizeof(double));
// exit if allocation fails
if (my_seq == NULL) {
printf("Cannot allocate space for %d numbers\n", N_per_worker);
exit(EXIT_FAILURE);
}
// adjust seed so that each process creates a different number sequence
seed = seed + my_process_id;
// generate N_per_worker random numbers and save them in the array
// please remember that each process will have its own memory context
for (i=0; i<N_per_worker; i++) {
my_seq[i] = (double)rand_r(&seed) / (double)RAND_MAX;
}
// in the following step, sequences from all workers will be gathered on
// the main process. in order to do that, memory space to accommodate all
// the numbers have to be allocated
if (my_process_id == 0) {
seq = malloc(N * sizeof(double));
// exit if allocation fails
if (seq == NULL) {
printf("Cannot allocate space for %d numbers\n", N);
exit(EXIT_FAILURE);
}
}
// everyone (including the main process) will send N_per_worker numbers from
// their my_seq buffer to the seq buffer in the main process, using different offsets
MPI_Gather(my_seq, N_per_worker, MPI_DOUBLE, seq, N_per_worker, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// print the generated random numbers, showing 8 digits after the decimal point
// this step will only be executed in the main process
if(my_process_id == 0) {
for (i=0; i<N; i++) {
printf("%10.8lf\n", seq[i]);
}
}
// cleanly terminate MPI subsystem
MPI_Finalize();
return EXIT_SUCCESS;
}