Baseline.c 3.52 KB
Newer Older
1
2
3
4
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "../malleabilityStates.h"
iker_martin's avatar
iker_martin committed
5
#include "../malleabilityDataStructures.h"
6
#include "Baseline.h"
7
#include "Spawn_state.h"
8
9
10

//--------------PRIVATE DECLARATIONS---------------//
int baseline_spawn(Spawn_data spawn_data, MPI_Comm comm, MPI_Comm *child);
11
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child);
iker_martin's avatar
iker_martin committed
12
void single_strat_children(MPI_Comm *parents);
13

14
15
16
17
18
19
20

//--------------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
21
22
  MPI_Comm intercomm;
  MPI_Comm_get_parent(&intercomm);
23

24
  if (intercomm == MPI_COMM_NULL) { // Parents path
25
26
    if (spawn_data.spawn_is_single) {
      single_strat_parents(spawn_data, child);
27
28
29
30
    } else {
      baseline_spawn(spawn_data, spawn_data.comm, child);
    }
  } else if(spawn_data.spawn_is_single) { // Children path
iker_martin's avatar
iker_martin committed
31
    single_strat_children(child);
32
33
34
35
36
37
38
39
40
41
42
  }
  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;
iker_martin's avatar
iker_martin committed
43
  if(mall->myId == mall->root) rootBcast = MPI_ROOT;
44

iker_martin's avatar
iker_martin committed
45
  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); 
46
  MPI_Comm_set_name(*child, "MPI_COMM_MALL_RESIZE");
47
48
49
50

  if(spawn_err != MPI_SUCCESS) {
    printf("Error creating new set of %d procs.\n", spawn_data.spawn_qty);
  }
iker_martin's avatar
iker_martin committed
51
52

  MAM_Comm_main_structures(rootBcast);
53
54
55
56
57
58
59
60

  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
 */
61
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child) {
62
63
64
65
  int spawn_err;
  char *port_name;
  MPI_Comm newintercomm;

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

    port_name = (char *) malloc(MPI_MAX_PORT_NAME * sizeof(char));
iker_martin's avatar
iker_martin committed
70
    MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, MPI_ANY_SOURCE, 130, *child, MPI_STATUS_IGNORE);
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();
74
75
76
77
  } else {
    port_name = malloc(1);
  }

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

iker_martin's avatar
iker_martin committed
80
  if(mall->myId == mall->root)
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
 */
iker_martin's avatar
iker_martin committed
95
void single_strat_children(MPI_Comm *parents) {
96
97
98
  char *port_name;
  MPI_Comm newintercomm;

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

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

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