MAM_Configuration.c 11.5 KB
Newer Older
1
2
3
4
5
6
7
8
#include "MAM_Configuration.h"
#include "MAM_Init_Configuration.h"
#include "malleabilityDataStructures.h"
#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
28
29
30
31
32
mam_config_setting_t configSettings[] = { 
    {NULL, MALL_SPAWN_MERGE, MAM_METHODS_SPAWN_LEN, {.set_config_simple = MAM_I_set_method }, MAM_SPAWN_METHOD_ENV},
    {NULL, MAM_STRAT_SPAWN_CLEAR, MAM_STRATS_SPAWN_LEN, {.set_config_simple = MAM_I_set_spawn_strat }, MAM_SPAWN_STRATS_ENV},
    {NULL, MALL_DIST_COMPACT, MAM_METHODS_PHYSICAL_DISTRIBUTION_LEN, {.set_config_simple = MAM_I_set_method }, MAM_PHYSICAL_DISTRIBUTION_METHOD_ENV},
    {NULL, MALL_RED_BASELINE, MAM_METHODS_RED_LEN, {.set_config_simple = MAM_I_set_method }, MAM_RED_METHOD_ENV},
    {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
38
unsigned int masks_spawn[] = {MAM_STRAT_CLEAR_VALUE, MAM_MASK_PTHREAD, MAM_MASK_SPAWN_SINGLE, MAM_MASK_SPAWN_INTERCOMM};
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
56
57
58
59
60
61
62

/**
 * @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};
  if(state > MALL_NOT_STARTED) return;

  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
91
92
93
94
95
96
97
98
99
100
101
102
103
    } 
  }
}

/*
 * @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;
  *provided = MALL_DENIED;
  if(required < 0 || state > MALL_NOT_STARTED) return;

  mam_config_setting_t *config = NULL;
  for (i = 0; i < MAM_KEY_COUNT; i++) {
    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
132
133
134
135
      break;
    default:
      aux = MALL_DENIED;
      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
}

//======================================================||
//===============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);
  }

  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;
}

173
void MAM_Set_initial_configuration() {
174
175
  int not_filled = 1;
  
176
  not_filled = MAM_I_configuration_get_defaults();
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  if(not_filled) {
    if(mall->myId == mall->root) printf("MAM WARNING: Starting configuration not set\n");
    fflush(stdout);
    MPI_Abort(mall->comm, -50);
  }

  #if USE_MAL_DEBUG >= 2
    if(mall->myId == mall->root) {
      DEBUG_FUNC("Initial configuration settled", mall->myId, mall->numP); 
      fflush(stdout); 
    }
  #endif
}

191
void MAM_Check_configuration() {
iker_martin's avatar
iker_martin committed
192
193
194
195
196
  if(mall_conf->spawn_method == MALL_SPAWN_MERGE && MAM_I_contains_strat(mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM)) {
    MAM_I_remove_strat(&mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM);
  }
  if(mall_conf->red_method == MALL_RED_RMA_LOCK || mall_conf->red_method == MALL_RED_RMA_LOCKALL) {
    if(MAM_I_contains_strat(mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM)) {
197
198
      MAM_I_remove_strat(&mall_conf->spawn_strategies, MAM_MASK_SPAWN_INTERCOMM);
    }
iker_martin's avatar
iker_martin committed
199
200
    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)) {
201
202
203
204
205
206
207
208
      MAM_I_set_red_strat(MAM_STRAT_RED_WAIT_TARGETS, &mall_conf->red_strategies);
    }
  }

  if(mall->numC == mall->numP) { // Migrate
    MAM_Set_key_configuration(MAM_SPAWN_METHOD, MALL_SPAWN_BASELINE, NULL);
  }
}
209
210
211
212
213
214
215

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


216
int MAM_I_configuration_get_defaults() {
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  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
233
234
235
236
237
      if(i == MAM_NUM_TARGETS) {
        config->set_config_complex(set_value);
      } else {
        config->set_config_simple(set_value, config->value);
      }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    }
    tmp = NULL;
  }
  return 0;
}


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

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);
      break;
265
266
267
    case MAM_STRAT_SPAWN_INTERCOMM:
      result = MAM_I_add_strat(strategies, MAM_MASK_SPAWN_INTERCOMM);
      break;
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    default:
      //Unkown strategy
      result = MALL_DENIED;
      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;
289
    case MAM_STRAT_RED_PTHREAD: //TODO - IMPROVEMENT - This could be done with a single operation instead of 3.
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
      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
      result = MALL_DENIED;
      break;
  }

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

iker_martin's avatar
iker_martin committed
322
int MAM_I_set_target_number(unsigned int new_numC) {
323
324
325
326
327
328
  if(state > MALL_NOT_STARTED || new_numC == 0) return MALL_DENIED;

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

329

330
331
332
/*
 * Returns 1 if strategy is applied, 0 otherwise
 */
333
334
int MAM_I_contains_strat(unsigned int comm_strategies, unsigned int strategy) {
  return comm_strategies & strategy;
335
336
337
}

int MAM_I_add_strat(unsigned int *comm_strategies, unsigned int strategy) {
338
  if(MAM_I_contains_strat(*comm_strategies, strategy)) return MAM_OK;
339
340
341
342
343
  *comm_strategies |= strategy;
  return MAM_STRATS_ADDED;
}

int MAM_I_remove_strat(unsigned int *comm_strategies, unsigned int strategy) {
344
  if(!MAM_I_contains_strat(*comm_strategies, strategy)) return MAM_OK;
345
346
347
  *comm_strategies &= ~strategy;
  return MAM_STRATS_MODIFIED;
}