MAM_Configuration.c 14.9 KB
Newer Older
1
2
#include "MAM_Configuration.h"
#include "MAM_Init_Configuration.h"
3
#include "MAM_DataStructures.h"
4
5
6
7
8
#include <limits.h>

typedef struct {
    unsigned int *value, default_value;
    int config_max_length;
iker_martin's avatar
iker_martin committed
9
10
11
12
    union {
      int (*set_config_simple)(unsigned int, unsigned int *);
      int (*set_config_complex)(unsigned int);
    };
13
14
15
16
17
18
    char *env_name;
} mam_config_setting_t;

int MAM_I_set_method(unsigned int new_method, unsigned int *method);
int MAM_I_set_spawn_strat(unsigned int strategy, unsigned int *strategies);
int MAM_I_set_red_strat(unsigned int strategy, unsigned int *strategies);
iker_martin's avatar
iker_martin committed
19
int MAM_I_set_target_number(unsigned int new_numC);
20

21
int MAM_I_configuration_get_defaults();
22

23
int MAM_I_contains_strat(unsigned int comm_strategies, unsigned int strategy);
24
25
26
int MAM_I_add_strat(unsigned int *comm_strategies, unsigned int strategy);
int MAM_I_remove_strat(unsigned int *comm_strategies, unsigned int strategy);

iker_martin's avatar
iker_martin committed
27
mam_config_setting_t configSettings[] = { 
28
    {NULL, MAM_SPAWN_MERGE, MAM_METHODS_SPAWN_LEN, {.set_config_simple = MAM_I_set_method }, MAM_SPAWN_METHOD_ENV},
iker_martin's avatar
iker_martin committed
29
    {NULL, MAM_STRAT_SPAWN_CLEAR, MAM_STRATS_SPAWN_LEN, {.set_config_simple = MAM_I_set_spawn_strat }, MAM_SPAWN_STRATS_ENV},
30
31
    {NULL, MAM_PHY_DIST_COMPACT, MAM_METHODS_PHYSICAL_DISTRIBUTION_LEN, {.set_config_simple = MAM_I_set_method }, MAM_PHYSICAL_DISTRIBUTION_METHOD_ENV},
    {NULL, MAM_RED_BASELINE, MAM_METHODS_RED_LEN, {.set_config_simple = MAM_I_set_method }, MAM_RED_METHOD_ENV},
iker_martin's avatar
iker_martin committed
32
    {NULL, MAM_STRAT_RED_CLEAR, MAM_STRATS_RED_LEN, {.set_config_simple = MAM_I_set_red_strat }, MAM_RED_STRATS_ENV},
33

iker_martin's avatar
iker_martin committed
34
    {NULL, 1, INT_MAX, {.set_config_complex = MAM_I_set_target_number }, MAM_NUM_TARGETS_ENV}
35
36
};

37
unsigned int masks_spawn[] = {MAM_STRAT_CLEAR_VALUE, MAM_MASK_PTHREAD, MAM_MASK_SPAWN_SINGLE, MAM_MASK_SPAWN_INTERCOMM, MAM_MASK_SPAWN_MULTIPLE, MAM_MASK_SPAWN_PARALLEL};
38
unsigned int masks_red[] = {MAM_STRAT_CLEAR_VALUE, MAM_MASK_PTHREAD, MAM_MASK_RED_WAIT_SOURCES, MAM_MASK_RED_WAIT_TARGETS};
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

/**
 * @brief Set configuration parameters for MAM.
 *
 * This function allows setting various configuration parameters for MAM
 * such as spawn method, spawn strategies, spawn physical distribution, 
 * redistribution method, and red strategies.
 *
 * @param spawn_method The spawn method reconfiguration.
 * @param spawn_strategies The spawn strategies reconfiguration.
 * @param spawn_dist The spawn physical distribution method reconfiguration.
 * @param red_method The redistribution method reconfiguration.
 * @param red_strategies The redesitribution strategy for reconfiguration.
 */
void MAM_Set_configuration(int spawn_method, int spawn_strategies, int spawn_dist, int red_method, int red_strategies) {
  int i, aux;
  int aux_array[] = {spawn_method, spawn_strategies, spawn_dist, red_method, red_strategies};
56
  if(state > MAM_I_NOT_STARTED) return;
57
58
59
60
61
62

  mam_config_setting_t *config = NULL;
  for (i = 0; i < MAM_KEY_COUNT-1; i++) { //FIXME Numero magico para no cambiar num_targets
    aux = aux_array[i];
    config = &configSettings[i];
    if (0 <= aux && aux < config->config_max_length) {
iker_martin's avatar
iker_martin committed
63
64
65
66
67
      if(i == MAM_NUM_TARGETS) {
        config->set_config_complex(aux);
      } else {
        config->set_config_simple(aux, config->value);
      }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    } 
  }
}

/*
 * @brief Set the configuration value for a specific key in MAM.
 *
 * Modifies the configuration value associated with the given key
 * to the specified "required" value. The final value set is returned in the
 * "provided" parameter.
 *
 * @param key       The key for which the configuration value is to be modified.
 * @param required  The required value to set for the specified key.
 * @param provided  Pointer to an integer where the final value set will be stored.
 *                  This parameter is updated with the actual value after modification.
 *                  For strategy keys the value is "MAM_STRATS_ADDED" if "required" has 
 *                  been added, or "MAM_STRATS_MODIFIED" if multiple strategies of the
 *                  key have been modified.
 */
void MAM_Set_key_configuration(int key, int required, int *provided) {
  int i, aux;

  if(provided == NULL) provided = &aux;
91
92
  *provided = MAM_DENIED;
  if(required < 0 || state > MAM_I_NOT_STARTED) return;
93
94

  mam_config_setting_t *config = NULL;
95
  for (i = 0; i < MAM_KEY_COUNT; i++) { //FIXME A for is not needed -- Check if key < MAM_KEY_COUNT and then just use key as index
96
97
98
99
100
101
102
103
    if (key == i) {
      config = &configSettings[i];
      break;
    }
  }

  if (config != NULL) {
    if (required < config->config_max_length) {
iker_martin's avatar
iker_martin committed
104
105
106
107
108
      if(i == MAM_NUM_TARGETS) {
        *provided = config->set_config_complex(required);
      } else {
        *provided = config->set_config_simple(required, config->value);
      }
109
110
111
112
113
114
115
116
    } else {*provided = *(config->value); }
  } else { printf("MAM: Key %d does not exist\n", key); }
}

/*
 * Retorna si una estrategia aparece o no
 */
int MAM_Contains_strat(int key, unsigned int strategy, int *result) {
117
118
  int strategies, aux = MAM_OK;
  unsigned int len = 0, mask;
119
120
121

  switch(key) {
    case MAM_SPAWN_STRATEGIES:
122
123
124
      strategies = mall_conf->spawn_strategies;
      mask = masks_spawn[strategy];
      len = MAM_STRATS_SPAWN_LEN;
125
126
      break;
    case MAM_RED_STRATEGIES:
127
128
129
      strategies = mall_conf->red_strategies;
      mask = masks_red[strategy];
      len = MAM_STRATS_RED_LEN;
130
131
      break;
    default:
132
      aux = MAM_DENIED;
133
134
135
      break;
  }

136
137
138
139
  if(aux == MAM_OK && strategy < len) {
    aux = MAM_I_contains_strat(strategies, mask);
  } else {
    aux = 0;
140
141
142
143
144
145
146
147
148
149
150
  }

  if(result != NULL) *result = aux;
  return aux;
}

/*
 * //TODO
 * Tiene que ser llamado despues de setear la config
 */
int MAM_Set_target_number(unsigned int numC){
iker_martin's avatar
iker_martin committed
151
  return MAM_I_set_target_number(numC);
152
153
}

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

/*
 * //TODO
 * Tiene que ser llamado fuera de reconfig
 */
void MAM_Use_valgrind(int flag) {
  if(state > MAM_I_NOT_STARTED) return;

  mall_conf->external_usage = flag ? MAM_USE_VALGRIND: 0;
  #if MAM_DEBUG
    if(mall->myId == mall->root && flag) DEBUG_FUNC("Settled Valgrind Wrapper", mall->myId, mall->numP); fflush(stdout);
  #endif
}

/*
 * //TODO
 * Tiene que ser llamado fuera de reconfig
 */
void MAM_Use_extrae(int flag) {
  if(state > MAM_I_NOT_STARTED) return;

  mall_conf->external_usage = flag ? MAM_USE_EXTRAE: 0;
  #if MAM_DEBUG
    if(mall->myId == mall->root && flag) DEBUG_FUNC("Settled Extrae Wrapper", mall->myId, mall->numP); fflush(stdout);
  #endif
}

181
182
183
184
185
186
187
188
189
190
191
192
//======================================================||
//===============MAM_INIT FUNCTIONS=====================||
//======================================================||
//======================================================||

void MAM_Init_configuration() {
  if(mall == NULL || mall_conf == NULL) {
    printf("MAM FATAL ERROR: Setting initial config without previous mallocs\n");
    fflush(stdout);
    MPI_Abort(MPI_COMM_WORLD, -50);
  }

193
194
195
196
  mall_conf->spawn_method = MAM_STRAT_CLEAR_VALUE;
  mall_conf->spawn_strategies = MAM_STRAT_CLEAR_VALUE;
  mall_conf->red_method = MAM_STRAT_CLEAR_VALUE;
  mall_conf->red_strategies = MAM_STRAT_CLEAR_VALUE;
197
  mall_conf->external_usage = 0;
198

199
200
201
202
203
204
205
  configSettings[MAM_SPAWN_METHOD].value = &mall_conf->spawn_method;
  configSettings[MAM_SPAWN_STRATEGIES].value = &mall_conf->spawn_strategies;
  configSettings[MAM_PHYSICAL_DISTRIBUTION].value = &mall_conf->spawn_dist;
  configSettings[MAM_RED_METHOD].value = &mall_conf->red_method;
  configSettings[MAM_RED_STRATEGIES].value = &mall_conf->red_strategies;
}

206
void MAM_Set_initial_configuration() {
207
208
  int not_filled = 1;
  
209
  not_filled = MAM_I_configuration_get_defaults();
210
211
212
213
214
215
  if(not_filled) {
    if(mall->myId == mall->root) printf("MAM WARNING: Starting configuration not set\n");
    fflush(stdout);
    MPI_Abort(mall->comm, -50);
  }

216
  #if MAM_DEBUG >= 2
217
218
219
220
221
222
223
    if(mall->myId == mall->root) {
      DEBUG_FUNC("Initial configuration settled", mall->myId, mall->numP); 
      fflush(stdout); 
    }
  #endif
}

224
void MAM_Check_configuration() {
225
  int global_internodes;
226
  if(mall->numC == mall->numP) { // Migrate
227
    MAM_Set_key_configuration(MAM_SPAWN_METHOD, MAM_SPAWN_BASELINE, NULL);
228
229
  }

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  // BEGIN ADDED FOR DMR
  char *tmp = getenv(MAM_SPAWN_METHOD_ENV);
  int tmp_value = mall_conf->spawn_method;
  if(tmp != NULL) {
    tmp_value = atoi(tmp);
  }
  if(mall_conf->spawn_method != (size_t) tmp_value) {
    MAM_Set_key_configuration(MAM_SPAWN_METHOD, tmp_value, NULL);
  }
  if(!MAM_Contains_strat(MAM_SPAWN_STRATEGIES, MAM_STRAT_SPAWN_PARALLEL, NULL)
        &&  mall_conf->spawn_method == MAM_SPAWN_MERGE) {
      MAM_I_set_spawn_strat(MAM_STRAT_SPAWN_PARALLEL, &mall_conf->spawn_strategies);
  }
  // END ADDED FOR DMR

245
  MPI_Allreduce(&mall->internode_group, &global_internodes, 1, MPI_INT, MPI_MAX, mall->comm);
246
247
248
  if((MAM_Contains_strat(MAM_SPAWN_STRATEGIES, MAM_STRAT_SPAWN_MULTIPLE, NULL)
  || MAM_Contains_strat(MAM_SPAWN_STRATEGIES, MAM_STRAT_SPAWN_PARALLEL, NULL) )
  && global_internodes) { // Remove internode MPI_COMM_WORLDs
249
    MAM_Set_key_configuration(MAM_SPAWN_METHOD, MAM_SPAWN_BASELINE, NULL);
250
251
  }

252
  if(mall_conf->spawn_method == MAM_SPAWN_MERGE) {
253
254
255
    if(MAM_I_contains_strat(mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM)) {
      MAM_I_remove_strat(&mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM);
    }
256
    // FIXME This should not be required to be removed for that case...
257
258
259
    if(mall->numP > mall->numC && MAM_I_contains_strat(mall_conf->spawn_strategies, MAM_MASK_SPAWN_SINGLE)) {
      MAM_I_remove_strat(&mall_conf->spawn_strategies, MAM_MASK_SPAWN_SINGLE);
    }
iker_martin's avatar
iker_martin committed
260
  }
261
  if(mall_conf->red_method == MAM_RED_RMA_LOCK || mall_conf->red_method == MAM_RED_RMA_LOCKALL) {
iker_martin's avatar
iker_martin committed
262
    if(MAM_I_contains_strat(mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM)) {
263
264
      MAM_I_remove_strat(&mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM);
    }
iker_martin's avatar
iker_martin committed
265
266
    if(!MAM_I_contains_strat(mall_conf->red_strategies, MAM_MASK_RED_WAIT_TARGETS) &&
       !MAM_I_contains_strat(mall_conf->red_strategies, MAM_MASK_PTHREAD)) {
267
268
269
      MAM_I_set_red_strat(MAM_STRAT_RED_WAIT_TARGETS, &mall_conf->red_strategies);
    }
  }
iker_martin's avatar
iker_martin committed
270
271
272
273
274
275
276
277
278

  #if MAM_DEBUG >= 2
    if(mall->myId == mall->root) {
      DEBUG_FUNC("MaM configuration", mall->myId, mall->numP); 
      printf("Spawn M=%d S=%d D=%d Redist M=%d S=%d\n", 
            mall_conf->spawn_method, mall_conf->spawn_strategies, mall_conf->spawn_dist, mall_conf->red_method, mall_conf->red_strategies);
      fflush(stdout);
    }
  #endif
279
}
280
281
282
283
284
285
286

//======================================================||
//================PRIVATE FUNCTIONS=====================||
//======================================================||
//======================================================||


287
int MAM_I_configuration_get_defaults() {
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  size_t i;
  int set_value;
  char *tmp = NULL;
  
  mam_config_setting_t *config = NULL;
  for (i = 0; i < MAM_KEY_COUNT; i++) {
    config = &configSettings[i];
    tmp = getenv(config->env_name);

    if(tmp != NULL) {
      set_value = atoi(tmp);
    } else {
      set_value = config->default_value;
    }

    if (0 <= set_value && set_value < config->config_max_length) {
iker_martin's avatar
iker_martin committed
304
305
306
307
308
      if(i == MAM_NUM_TARGETS) {
        config->set_config_complex(set_value);
      } else {
        config->set_config_simple(set_value, config->value);
      }
309
310
311
312
313
314
315
316
317
318
319
320
    }
    tmp = NULL;
  }
  return 0;
}


int MAM_I_set_method(unsigned int new_method, unsigned int *method) {
  *method = new_method;
  return *method;
}

321
//TODO Se podría hacer un par de arrays o dict para obtener la mascara sin un switch
322
323
324
325
326
327
328
329
330
331
332
333
334
335
int MAM_I_set_spawn_strat(unsigned int strategy, unsigned int *strategies) {
  int result = 0;
  int strat_removed = 0;

  switch(strategy) {
    case MAM_STRAT_SPAWN_CLEAR:
      *strategies = MAM_STRAT_CLEAR_VALUE;
      result = MAM_STRATS_MODIFIED;
      break;
    case MAM_STRAT_SPAWN_PTHREAD:
      result = MAM_I_add_strat(strategies, MAM_MASK_PTHREAD);
      break;
    case MAM_STRAT_SPAWN_SINGLE:
      result = MAM_I_add_strat(strategies, MAM_MASK_SPAWN_SINGLE);
336
337
338
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_SPAWN_PARALLEL);
      }
339
      break;
340
341
342
    case MAM_STRAT_SPAWN_INTERCOMM:
      result = MAM_I_add_strat(strategies, MAM_MASK_SPAWN_INTERCOMM);
      break;
343
344
    case MAM_STRAT_SPAWN_MULTIPLE:
      result = MAM_I_add_strat(strategies, MAM_MASK_SPAWN_MULTIPLE);
345
346
347
348
349
350
351
352
353
354
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_SPAWN_PARALLEL);
      }
      break;
    case MAM_STRAT_SPAWN_PARALLEL:
      result = MAM_I_add_strat(strategies, MAM_MASK_SPAWN_PARALLEL);
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_SPAWN_MULTIPLE);
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_SPAWN_SINGLE);
      }
355
      break;
356
357
    default:
      //Unkown strategy
358
      result = MAM_DENIED;
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
      break;
  }

  if(strat_removed) {
    result = MAM_STRATS_MODIFIED;
  }
  return result;
}

int MAM_I_set_red_strat(unsigned int strategy, unsigned int *strategies) {
  int result = 0;
  int strat_removed = 0;

  switch(strategy) {
    case MAM_STRAT_RED_CLEAR:
      *strategies = MAM_STRAT_CLEAR_VALUE;
      result = MAM_STRATS_MODIFIED;
      break;
377
    case MAM_STRAT_RED_PTHREAD: //TODO - IMPROVEMENT - This could be done with a single operation instead of 3.
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
      result = MAM_I_add_strat(strategies, MAM_MASK_PTHREAD);
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_RED_WAIT_SOURCES);
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_RED_WAIT_TARGETS);
      }
      break;
    case MAM_STRAT_RED_WAIT_SOURCES:
      result = MAM_I_add_strat(strategies, MAM_MASK_RED_WAIT_SOURCES);
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_RED_WAIT_TARGETS);
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_PTHREAD);
      }
      break;
    case MAM_STRAT_RED_WAIT_TARGETS:
      result = MAM_I_add_strat(strategies, MAM_MASK_RED_WAIT_TARGETS);
      if(result == MAM_STRATS_ADDED) {
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_RED_WAIT_SOURCES);
        strat_removed += MAM_I_remove_strat(strategies, MAM_MASK_PTHREAD);
      }
      break;
    default:
      //Unkown strategy
400
      result = MAM_DENIED;
401
402
403
404
405
406
407
408
409
      break;
  }

  if(strat_removed) {
    result = MAM_STRATS_MODIFIED;
  }
  return result;
}

iker_martin's avatar
iker_martin committed
410
int MAM_I_set_target_number(unsigned int new_numC) {
411
  if(state > MAM_I_NOT_STARTED || new_numC == 0) return MAM_DENIED;
412
413
414
415
416

  mall->numC = (int) new_numC;
  return new_numC;
}

417

418
419
420
/*
 * Returns 1 if strategy is applied, 0 otherwise
 */
421
422
int MAM_I_contains_strat(unsigned int comm_strategies, unsigned int strategy) {
  return comm_strategies & strategy;
423
424
425
}

int MAM_I_add_strat(unsigned int *comm_strategies, unsigned int strategy) {
426
  if(MAM_I_contains_strat(*comm_strategies, strategy)) return MAM_OK;
427
428
429
430
431
  *comm_strategies |= strategy;
  return MAM_STRATS_ADDED;
}

int MAM_I_remove_strat(unsigned int *comm_strategies, unsigned int strategy) {
432
  if(!MAM_I_contains_strat(*comm_strategies, strategy)) return MAM_OK;
433
434
435
  *comm_strategies &= ~strategy;
  return MAM_STRATS_MODIFIED;
}