Baseline.c 3.58 KB
Newer Older
1
2
3
4
5
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "../malleabilityStates.h"
#include "Baseline.h"
6
#include "Spawn_state.h"
7
8
9

//--------------PRIVATE DECLARATIONS---------------//
int baseline_spawn(Spawn_data spawn_data, MPI_Comm comm, MPI_Comm *child);
10
11
12
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child);
void single_strat_children(int myId, int root, MPI_Comm *parents);

13
14
15
16
17
18
19

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

23
  if (intercomm == MPI_COMM_NULL) { // Parents path
24
25
    if (spawn_data.spawn_is_single) {
      single_strat_parents(spawn_data, child);
26
27
28
29
    } else {
      baseline_spawn(spawn_data, spawn_data.comm, child);
    }
  } else if(spawn_data.spawn_is_single) { // Children path
30
    single_strat_children(spawn_data.myId, spawn_data.root, child);
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  }
  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); 
47
  MPI_Comm_set_name(*child, "MPI_COMM_MALL_RESIZE");
48
  // END WORK
49
50
51
52
53
54
55
56
57
58
59
60
61

  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
 */
62
int single_strat_parents(Spawn_data spawn_data, MPI_Comm *child) {
63
64
65
66
67
68
69
70
71
72
  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);

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

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  } 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
 */
96
void single_strat_children(int myId, int root, MPI_Comm *parents) {
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  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;
}