linear_reg.c 5.34 KB
Newer Older
1
2
#include <stdlib.h>
#include <stdio.h>
3
#include <math.h>
4
5
#include <mpi.h>
#include "Main_datatypes.h"
6
#include "../malleability/distribution_methods/block_distribution.h"
7
8
#include "linear_reg.h"

9
10
11
12
13

// Array for linear regression computation
// Cantidades                          10b 100b 1Kb   5Kb  10Kb   50Kb  100Kb   500Kb   1Mb      10Mb      100Mb
double LR_bytes_array[LR_ARRAY_TAM] = {10, 100, 1000, 5000,10000, 50000,100000, 500000, 1000000, 10000000, 100000000};

14
15
16
17
18
19
20
21
// Linear regression
// Y = a +bX
// Bytes = a +b(Time)
//
// X is the independent variable, which correlates to the Communication time
// Y is the dependent variable, which correlates to the number of bytes
//

22
23
24
25
26
27
28
29
30
void lr_avg_plus_diff(int tam, double *array, double *avg, double *diffs);

/*
 * Computes and returns the related Y value to a given linear regression
 */
void lr_calc_Y(double slope, double intercept, double x_value, int *y_result) {
  *y_result = (int) ceil(intercept + slope * x_value);
}

31
32
33
34
35
36

/*
 * Computes the slope and intercept for a given array of times
 * so users can calculate the number of bytes for a given time.
 *
 */
37
void lr_compute(int tam, double *bytes, double *times, double *slope, double *intercept) {
38
39
40
41
42
  int i;
  double avgX, avgY;
  double *diffsX, *diffsY;
  double SSxx, SSxy;

43
44
  diffsX = malloc(tam * sizeof(double));
  diffsY = malloc(tam * sizeof(double));
45
46
  SSxx = SSxy = 0;

47
48
  lr_avg_plus_diff(tam, times, &avgX, diffsX);
  lr_avg_plus_diff(tam, bytes, &avgY, diffsY);
49

50
  for(i=0; i<tam; i++) {
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    SSxx+= diffsX[i]*diffsX[i];
    SSxy+= diffsX[i]*diffsY[i];
  }
  *slope = SSxy / SSxx;
  *intercept = avgY - (*slope * avgX);
  
  free(diffsX);
  free(diffsY);
}

/*
 * Computes the average of an arrray and 
 * the difference of each element in respect to the average.
 *
 * Returns the average and an the difference of each element.
 */
67
void lr_avg_plus_diff(int tam, double *array, double *avg, double *diffs) {
68
69
  int i;
  double sum = 0;
70
  for(i=0; i<tam; i++) {
71
72
    sum+= array[i];
  }
73
  *avg = sum / tam;
74

75
  for(i=0; i<tam; i++) {
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    diffs[i]= *avg - array[i];
  }
}


//======================================================||
//======================================================||
//==================TIMES COMPUTATION===================||
//======================================================||
//======================================================||

/*
 * Obtains an array of times to perform a "Broadcast"
 * operation depending on a predifined set of number of bytes.
 */
91
92
93
94
void lr_times_bcast(int myId, int numP, int root, MPI_Comm comm, int loop_iters, double *times) {
  int i, j, n;
  double start_time;
  char *aux = NULL;
95
96
97
98
99

  for(i=0; i<LR_ARRAY_TAM; i++) {
    n = LR_bytes_array[i];
    aux = malloc(n * sizeof(char));

100
101
102
    for(j=0; j<loop_iters; j++) {
      MPI_Barrier(comm);
      start_time = MPI_Wtime();
103
      MPI_Bcast(aux, n, MPI_CHAR, root, comm);
104
      times[i*loop_iters+j] = MPI_Wtime() - start_time;
105
106
    }

107
108
109
110
111
112
113
114
115
116
117
118
119
    free(aux);
    aux = NULL;
  }
}


/*
 * Obtains an array of times to perform an "Allgatherv"
 * operation depending on a predifined set of number of bytes.
 */
void lr_times_allgatherv(int myId, int numP, int root, MPI_Comm comm, int loop_iters, double *times) {
  int i, j, n;
  double start_time;
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  char *aux = NULL, *aux_full = NULL;
  struct Dist_data dist_data;
  struct Counts counts;

  for(i=0; i<LR_ARRAY_TAM; i++) {
    n = LR_bytes_array[i];

    prepare_comm_allgatherv(numP, n, &counts);    
    get_block_dist(n, myId, numP, &dist_data);

    aux = malloc(dist_data.tamBl * sizeof(char));
    aux_full = malloc(n * sizeof(char));

    for(j=0; j<loop_iters; j++) {
      MPI_Barrier(comm);
      start_time = MPI_Wtime();
      MPI_Allgatherv(aux, dist_data.tamBl, MPI_CHAR, aux_full, counts.counts, counts.displs, MPI_CHAR, comm);
      times[i*loop_iters+j] = MPI_Wtime() - start_time;
    }
    
    freeCounts(&counts);
    free(aux);
    free(aux_full);
    aux_full = NULL;
    aux = NULL;
  }
}
147

148
149
150
151
152
153
154
155
/*
 * Obtains an array of times to perform an "Reduce"
 * operation depending on a predifined set of number of bytes.
 */
void lr_times_reduce(int myId, int numP, int root, MPI_Comm comm, int loop_iters, double *times) {
  int i, j, n;
  double start_time;
  char *aux = NULL, *aux_full = NULL;
156
157
158

  for(i=0; i<LR_ARRAY_TAM; i++) {
    n = LR_bytes_array[i];
159
160

    aux = malloc(n * sizeof(char));
161
162
163
164
165
    aux_full = malloc(n * sizeof(char));

    for(j=0; j<loop_iters; j++) {
      MPI_Barrier(comm);
      start_time = MPI_Wtime();
166
      MPI_Reduce(aux, aux_full, n, MPI_CHAR, MPI_MAX, root, comm);
167
      times[i*loop_iters+j] = MPI_Wtime() - start_time;
168
    }
169
    
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    free(aux);
    free(aux_full);
    aux_full = NULL;
    aux = NULL;
  }
}

/*
 * Obtains an array of times to perform an "Allreduce"
 * operation depending on a predifined set of number of bytes.
 */
void lr_times_allreduce(int myId, int numP, int root, MPI_Comm comm, int loop_iters, double *times) {
  int i, j, n;
  double start_time;
  char *aux = NULL, *aux_full = NULL;

  for(i=0; i<LR_ARRAY_TAM; i++) {
    n = LR_bytes_array[i];

    aux = malloc(n * sizeof(char));
    aux_full = malloc(n * sizeof(char));
191

192
193
194
195
196
197
198
    for(j=0; j<loop_iters; j++) {
      MPI_Barrier(comm);
      start_time = MPI_Wtime();
      MPI_Allreduce(aux, aux_full, n, MPI_CHAR, MPI_MAX, comm);
      times[i*loop_iters+j] = MPI_Wtime() - start_time;
    }
    
199
    free(aux);
200
201
202
    free(aux_full);
    aux_full = NULL;
    aux = NULL;
203
204
  }
}