Merge.c 2.39 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "../malleabilityStates.h"
#include "Merge.h"
#include "Baseline.h"

//--------------PRIVATE DECLARATIONS---------------//
void merge_adapt_expand(MPI_Comm *child, int is_children_group);
void merge_adapt_shrink(int numC, MPI_Comm *child, MPI_Comm comm, int myId);

//--------------PUBLIC FUNCTIONS---------------//
int merge(Spawn_data spawn_data, MPI_Comm *child, int data_state) {
14
  MPI_Comm intercomm;
15
  int local_state;
16
  int is_children_group = 1;
17
18

  if(spawn_data.initial_qty > spawn_data.target_qty) { //Shrink
19
20
    if(data_state == MALL_DIST_COMPLETED) {
      merge_adapt_shrink(spawn_data.target_qty, child, spawn_data.comm, spawn_data.myId);
21
      local_state = MALL_SPAWN_ADAPTED;
22
    } else {
23
24
25
      local_state = MALL_SPAWN_ADAPT_POSTPONE;
    }
  } else { //Expand
26
27
    MPI_Comm_get_parent(&intercomm);
    is_children_group = intercomm == MPI_COMM_NULL ? 0:1;
28

29

30
31
    baseline(spawn_data, child);
    merge_adapt_expand(child, is_children_group);
32
    local_state = MALL_SPAWN_COMPLETED;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  }

  return local_state;
}

//--------------PRIVATE MERGE TYPE FUNCTIONS---------------//

/*
 * Se encarga de que el grupo de procesos resultante se 
 * encuentren todos en un intra comunicador, uniendo a
 * padres e hijos en un solo comunicador.
 *
 * Se llama antes de la redistribución de datos.
 *
 * TODO REFACTOR
 */
void merge_adapt_expand(MPI_Comm *child, int is_children_group) {
  MPI_Comm new_comm = MPI_COMM_NULL;

52
  MPI_Intercomm_merge(*child, is_children_group, &new_comm); //El que pone 0 va primero
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

  MPI_Comm_free(child); //POSIBLE ERROR?
  *child = new_comm;

  //*numP = numC; //TODO REFACTOR Llevar a otra parte -- Hacer solo si MALL_SPAWN_ADAPTED
  //if(*comm != MPI_COMM_WORLD && *comm != MPI_COMM_NULL) {
  //  MPI_Comm_free(comm);
  //}
}


/*
 * Se encarga de que el grupo de procesos resultante se
 * eliminen aquellos procesos que ya no son necesarios.
 * Los procesos eliminados se quedaran como zombies.
 *
 * Se llama una vez ha terminado la redistribución de datos.
 */
void merge_adapt_shrink(int numC, MPI_Comm *child, MPI_Comm comm, int myId) {
  int color = MPI_UNDEFINED;

  if(myId < numC) {
      color = 1;  
  }
  MPI_Comm_split(comm, color, myId, child);

  //TODO REFACTOR Llevar a otra parte -- Hacer solo si MALL_SPAWN_ADAPTED
  //if(*comm != MPI_COMM_WORLD && *comm != MPI_COMM_NULL)
  //  MPI_Comm_free(comm); //POSIBLE ERROR?
}