Baseline.c 3.4 KB
Newer Older
1
2
3
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
4
5
#include "../MAM_Constants.h"
#include "../MAM_DataStructures.h"
6
#include "Baseline.h"
7
#include "Strategy_Single.h"
8
#include "Strategy_Multiple.h"
9
#include "PortService.h"
10
11

//--------------PRIVATE DECLARATIONS---------------//
12
int baseline_spawn(Spawn_set spawn_set, MPI_Comm comm, MPI_Comm *child);
13
void baseline_parents(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *child);
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
  Spawn_ports spawn_port;
22
  MPI_Comm intercomm;
23
  MPI_Comm_get_parent(&intercomm); //FIXME May be a problem for third reconf or more with only expansions
24
  init_ports(&spawn_port);
25

26
  if (intercomm == MPI_COMM_NULL) { // Parents path
27
    baseline_parents(spawn_data, &spawn_port, child);
28
  } else { // Children path
29
    if(spawn_data.spawn_is_multiple) { multiple_strat_children(child, &spawn_port); }
30
    if(spawn_data.spawn_is_single) { single_strat_children(child, &spawn_port); }
31
  }
32

33
  free_ports(&spawn_port);
34
  return MAM_I_SPAWN_COMPLETED;
35
36
37
}

//--------------PRIVATE FUNCTIONS---------------//
38
39
40
41
42
43

/*
 * Funcion utilizada por los padres para realizar la
 * creación de procesos.
 *
 */
44
void baseline_parents(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *child) {
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  int i;
  MPI_Comm comm, *intercomms;

  if (spawn_data.spawn_is_single && mall->myId != mall->root) {
    single_strat_parents(spawn_data, child);
    return;
  }

  comm = spawn_data.spawn_is_single ? MPI_COMM_SELF : spawn_data.comm;
  MPI_Bcast(&spawn_data.total_spawns, 1, MPI_INT, mall->root, comm);
  intercomms = (MPI_Comm*) malloc(spawn_data.total_spawns * sizeof(MPI_Comm)); 
  if(mall->myId != mall->root) {
    spawn_data.sets = (Spawn_set *) malloc(spawn_data.total_spawns * sizeof(Spawn_set));
  }

60
61
62
  #if MAM_DEBUG >= 3
    DEBUG_FUNC("Starting spawning of processes", mall->myId, mall->numP); fflush(stdout);
  #endif
63
64
65
  for(i=0; i<spawn_data.total_spawns; i++) {
    baseline_spawn(spawn_data.sets[i], comm, &intercomms[i]);
  }
66
67
68
  #if MAM_DEBUG >= 3
    DEBUG_FUNC("Sources have created the new processes. Performing additional actions if required.", mall->myId, mall->numP); fflush(stdout);
  #endif
69
70

  // TODO Improvement - Deactivate Multiple spawn before spawning if total_spawns == 1
71
  if(spawn_data.spawn_is_multiple) { multiple_strat_parents(spawn_data, spawn_port, comm, intercomms, child); }
72
73
74
75
76
77
78
79
  else { *child = intercomms[0]; } 

  if(spawn_data.spawn_is_single) { single_strat_parents(spawn_data, child); }

  free(intercomms);
  if(mall->myId != mall->root) { free(spawn_data.sets); }
}

80
/*
81
82
83
84
 * Funcion basica encargada de la creacion de procesos.
 * Crea un set de procesos segun la configuracion obtenida
 * en ProcessDist.c
 * Devuelve en "child" el intercomunicador que se conecta a los hijos.
85
 */
86
int baseline_spawn(Spawn_set spawn_set, MPI_Comm comm, MPI_Comm *child) {
87
  int rootBcast = MPI_PROC_NULL;
iker_martin's avatar
iker_martin committed
88
  if(mall->myId == mall->root) rootBcast = MPI_ROOT;
89

90
  int spawn_err = MPI_Comm_spawn(spawn_set.cmd, MPI_ARGV_NULL, spawn_set.spawn_qty, spawn_set.mapping, mall->root, comm, child, MPI_ERRCODES_IGNORE); 
91
92

  if(spawn_err != MPI_SUCCESS) {
93
    printf("Error creating new set of %d procs.\n", spawn_set.spawn_qty);
94
  }
95
  MAM_Comm_main_structures(*child, rootBcast);
96
97

  return spawn_err;
98
}