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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <mpi.h>
#include "vec.h"
int main (int argc, char* argv[]) {
MPI_Init (&argc, &argv);
// MPI_COMM_WORLD is the default communicator that contains all ranks
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
char node_name[MPI_MAX_PROCESSOR_NAME];
int node_name_len;
MPI_Get_processor_name(node_name,&node_name_len);
// make sure we are not running on a login node!
if ((strcmp(node_name,"tinkercliffs1") == 0) ||
(strcmp(node_name,"tinkercliffs2") == 0)) {
printf ("error : running on login node %s!\n",node_name);
return 1;
}
// read the filename from the command line
if (argc < 4) {
printf ("command usage: %s %s %s %s\n",argv[0],"filename","num_pairs","seed");
return 1;
}
char* filename = argv[1];
int num_pairs = atoi(argv[2]);
// seed the random number generator using command line seed
srandom(atoi(argv[3]));
// open the text file for reading
FILE* fptr;
fptr = fopen(filename,"r");
// need to check for null
if (fptr == 0) {
printf ("Error opening data file %s.\n",filename);
exit(1);
}
// read the number of points and the dimension of each point
int num_points, dim;
if (fscanf(fptr,"%*c %d %d",&num_points, &dim) != 2) {
printf ("error reading the number of points and the dimension\n");
return 1;
}
// Read vectors from stdin and store them in a 2d array
double* data = (double*)malloc(num_points*dim*sizeof(double));
if (data == NULL) {
printf ("malloc return NULL pointer!\n");
return 1;
}
for (int i=0;i<num_points;i++) {
if (vec_read_file(fptr,data+i*dim,dim) != dim) {
printf ("error reading the next point from the file %s\n",filename);
return 1;
}
}
// close the data file
fclose(fptr);
// start the timer
double start_time, end_time;
start_time = MPI_Wtime();
// find the approximate extreme pair
double max_dist_sq = 0;
int pairs_checked = 0;
int extreme[2];
for (int p=0;p<num_pairs;p++) {
int i = random() % num_points;
int j = random() % num_points;
double dist_sq = vec_dist_sq(data+i*dim,data+j*dim,dim);
pairs_checked += 1;
if (dist_sq > max_dist_sq) {
max_dist_sq = dist_sq;
extreme[0] = i;
extreme[1] = j;
}
}
// all nonzero ranks send their approximate extreme pair to rank 0
if (rank == 0) {
MPI_Status status;
int rank_extreme[2];
int rank_pairs_checked;
for (int src=1;src<size;src++) {
MPI_Recv(&rank_pairs_checked,1,MPI_INT,src,0,MPI_COMM_WORLD,&status);
pairs_checked += rank_pairs_checked;
MPI_Recv(rank_extreme,2,MPI_INT,src,0,MPI_COMM_WORLD,&status);
int i = rank_extreme[0];
int j = rank_extreme[1];
double dist_sq = vec_dist_sq(data+i*dim,data+j*dim,dim);
if (dist_sq > max_dist_sq) {
max_dist_sq = dist_sq;
extreme[0] = rank_extreme[0];
extreme[1] = rank_extreme[1];
}
}
} else {
int dest = 0;
MPI_Send(&pairs_checked,1,MPI_INT,dest,0,MPI_COMM_WORLD);
MPI_Send(extreme,2,MPI_INT,dest,0,MPI_COMM_WORLD);
}
// stop the timer
end_time = MPI_Wtime();
// output the results
if (rank == 0) {
printf ("elapsed time = %.4f seconds\n",end_time-start_time);
printf ("pairs checked = %d\n",pairs_checked);
printf ("Approximate Extreme Distance = %.2f\n",sqrt(max_dist_sq));
printf ("Approximate Extreme Pair = %d %d\n",extreme[0],extreme[1]);
}
// free memory allocated for dataset
free(data);
MPI_Finalize();
}