Baseline.c 3.58 KB
Newer Older
iker_martin's avatar
iker_martin committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "../malleabilityStates.h"
#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);
void single_strat_children(int myId, int root, MPI_Comm *parents);


//--------------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
    single_strat_children(spawn_data.myId, spawn_data.root, child);
  }
  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;
  if(spawn_data.myId == spawn_data.root) rootBcast = MPI_ROOT;

  // WORK
  int spawn_err = MPI_Comm_spawn(spawn_data.cmd, MPI_ARGV_NULL, spawn_data.spawn_qty, spawn_data.mapping, spawn_data.root, comm, child, MPI_ERRCODES_IGNORE); 
  MPI_Comm_set_name(*child, "MPI_COMM_MALL_RESIZE");

  // END WORK

  if(spawn_err != MPI_SUCCESS) {
    printf("Error creating new set of %d procs.\n", spawn_data.spawn_qty);
  }
  MPI_Bcast(&spawn_data, 1, spawn_data.dtype, rootBcast, *child);

  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;

  if (spawn_data.myId == spawn_data.root) {
    spawn_err = baseline_spawn(spawn_data, MPI_COMM_SELF, child);

    port_name = (char *) malloc(MPI_MAX_PORT_NAME * sizeof(char));
    MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, spawn_data.root, 130, *child, MPI_STATUS_IGNORE);

    set_spawn_state(MALL_SPAWN_SINGLE_COMPLETED, spawn_data.spawn_is_async); // Indicate other processes to join root to end spawn procedure

  } else {
    port_name = malloc(1);
  }

  MPI_Comm_connect(port_name, MPI_INFO_NULL, spawn_data.root, spawn_data.comm, &newintercomm);

  if(spawn_data.myId == spawn_data.root)
    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
 */
void single_strat_children(int myId, int root, MPI_Comm *parents) {
  char *port_name;
  MPI_Comm newintercomm;

  if(myId == root) {
    port_name = (char *) malloc(MPI_MAX_PORT_NAME * sizeof(char));
    MPI_Open_port(MPI_INFO_NULL, port_name);
    MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, root, 130, *parents);
  } else {
    port_name = malloc(1);
  }

  MPI_Comm_accept(port_name, MPI_INFO_NULL, root, MPI_COMM_WORLD, &newintercomm);

  if(myId == root) {
    MPI_Close_port(port_name);
  }
  free(port_name);
  MPI_Comm_free(parents);
  *parents = newintercomm;
}