"Codes/MaM/MAM_Types.c" did not exist on "0a5e948bad8364b4778ee642d2be1902f597c633"
Baseline.c 3.52 KB
Newer Older
iker_martin's avatar
iker_martin committed
1
2
3
4
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "../malleabilityStates.h"
5
#include "../malleabilityDataStructures.h"
iker_martin's avatar
iker_martin committed
6
7
8
9
10
11
#include "Baseline.h"
#include "Spawn_state.h"

//--------------PRIVATE DECLARATIONS---------------//
int baseline_spawn(Spawn_data spawn_data, MPI_Comm comm, MPI_Comm *child);
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child);
12
void single_strat_children(MPI_Comm *parents);
iker_martin's avatar
iker_martin committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


//--------------PUBLIC FUNCTIONS---------------//
/*
 * Metodo basico para la creacion de procesos. Crea en total
 * spawn_data.spawn_qty procesos.
 */
int baseline(Spawn_data spawn_data, MPI_Comm *child) { //TODO Tratamiento de errores
  MPI_Comm intercomm;
  MPI_Comm_get_parent(&intercomm);

  if (intercomm == MPI_COMM_NULL) { // Parents path
    if (spawn_data.spawn_is_single) {
      single_strat_parents(spawn_data, child);
    } else {
      baseline_spawn(spawn_data, spawn_data.comm, child);
    }
  } else if(spawn_data.spawn_is_single) { // Children path
31
    single_strat_children(child);
iker_martin's avatar
iker_martin committed
32
  }
33

iker_martin's avatar
iker_martin committed
34
35
36
37
38
39
40
41
42
43
  return MALL_SPAWN_COMPLETED;
}

//--------------PRIVATE FUNCTIONS---------------//
/*
 * Crea un grupo de procesos segun la configuracion indicada por la funcion
 * "processes_dist()".
 */
int baseline_spawn(Spawn_data spawn_data, MPI_Comm comm, MPI_Comm *child) {
  int rootBcast = MPI_PROC_NULL;
44
  if(mall->myId == mall->root) rootBcast = MPI_ROOT;
iker_martin's avatar
iker_martin committed
45

46
  int spawn_err = MPI_Comm_spawn(mall->name_exec, MPI_ARGV_NULL, spawn_data.spawn_qty, spawn_data.mapping, mall->root, comm, child, MPI_ERRCODES_IGNORE); 
iker_martin's avatar
iker_martin committed
47
48
49
50
51
  MPI_Comm_set_name(*child, "MPI_COMM_MALL_RESIZE");

  if(spawn_err != MPI_SUCCESS) {
    printf("Error creating new set of %d procs.\n", spawn_data.spawn_qty);
  }
52
  MAM_Comm_main_structures(rootBcast);
iker_martin's avatar
iker_martin committed
53
54
55
56
57
58
59
60
61
62
63
64
65

  return spawn_err;
}

/* 
 * Si la variable "type" es 1, la creación es con la participación de todo el grupo de padres
 * Si el valor es diferente, la creación es solo con la participación del proceso root
 */
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child) {
  int spawn_err;
  char *port_name;
  MPI_Comm newintercomm;

66
  if (mall->myId == mall->root) {
iker_martin's avatar
iker_martin committed
67
68
69
    spawn_err = baseline_spawn(spawn_data, MPI_COMM_SELF, child);

    port_name = (char *) malloc(MPI_MAX_PORT_NAME * sizeof(char));
70
    MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, MPI_ANY_SOURCE, 130, *child, MPI_STATUS_IGNORE);
iker_martin's avatar
iker_martin committed
71
72

    set_spawn_state(MALL_SPAWN_SINGLE_COMPLETED, spawn_data.spawn_is_async); // Indicate other processes to join root to end spawn procedure
73
    wakeup_completion();
iker_martin's avatar
iker_martin committed
74
75
76
77
  } else {
    port_name = malloc(1);
  }

78
  MPI_Comm_connect(port_name, MPI_INFO_NULL, mall->root, spawn_data.comm, &newintercomm);
iker_martin's avatar
iker_martin committed
79

80
  if(mall->myId == mall->root)
iker_martin's avatar
iker_martin committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    MPI_Comm_free(child);
  free(port_name);
  *child = newintercomm;

  return spawn_err;
}

/*
 * Conectar grupo de hijos con grupo de padres
 * Devuelve un intercomunicador para hablar con los padres
 *
 * Solo se utiliza cuando la creación de los procesos ha sido
 * realizada por un solo proceso padre
 */
95
void single_strat_children(MPI_Comm *parents) {
iker_martin's avatar
iker_martin committed
96
97
98
  char *port_name;
  MPI_Comm newintercomm;

99
  if(mall->myId == mall->root) {
iker_martin's avatar
iker_martin committed
100
101
    port_name = (char *) malloc(MPI_MAX_PORT_NAME * sizeof(char));
    MPI_Open_port(MPI_INFO_NULL, port_name);
102
    MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, mall->root_parents, 130, *parents);
iker_martin's avatar
iker_martin committed
103
104
105
106
  } else {
    port_name = malloc(1);
  }

107
  MPI_Comm_accept(port_name, MPI_INFO_NULL, mall->root, MPI_COMM_WORLD, &newintercomm);
iker_martin's avatar
iker_martin committed
108

109
  if(mall->myId == mall->root) {
iker_martin's avatar
iker_martin committed
110
111
112
113
114
115
    MPI_Close_port(port_name);
  }
  free(port_name);
  MPI_Comm_free(parents);
  *parents = newintercomm;
}