Baseline.c 3.37 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 "SpawnUtils.h"
8
#include "Strategy_Single.h"
9
#include "Strategy_Multiple.h"
10
#include "Strategy_Parallel.h"
11
#include "PortService.h"
12
13

//--------------PRIVATE DECLARATIONS---------------//
14
void baseline_parents(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *child);
15
void baseline_children(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *parents);
16

17
18
19
20
21
22
//--------------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
23
  Spawn_ports spawn_port;
24
  MPI_Comm intercomm;
25
  MPI_Comm_get_parent(&intercomm); //FIXME May be a problem for third reconf or more with only expansions
26
  init_ports(&spawn_port);
27

28
  if (intercomm == MPI_COMM_NULL) { // Parents path
29
    baseline_parents(spawn_data, &spawn_port, child);
30
  } else { // Children path
31
    baseline_children(spawn_data, &spawn_port, child);
32
  }
33

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

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

/*
 * Funcion utilizada por los padres para realizar la
 * creación de procesos.
 *
 */
45
void baseline_parents(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *child) {
46
47
48
  int i;
  MPI_Comm comm, *intercomms;

49
50
51
52
53
54
55
56
57
58
59
  #if MAM_DEBUG >= 3
    DEBUG_FUNC("Starting spawning of processes", mall->myId, mall->numP); fflush(stdout);
  #endif

  if (spawn_data.spawn_is_parallel) {
    // This spawn is quite different from the rest, as so
    // it takes care of everything related to spawning.
    parallel_strat_parents(spawn_data, spawn_port, child);
    return;
  }

60
61
62
63
64
65
66
67
68
69
70
71
72
  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));
  }

  for(i=0; i<spawn_data.total_spawns; i++) {
73
    mam_spawn(spawn_data.sets[i], comm, &intercomms[i]);
74
  }
75
76
77
  #if MAM_DEBUG >= 3
    DEBUG_FUNC("Sources have created the new processes. Performing additional actions if required.", mall->myId, mall->numP); fflush(stdout);
  #endif
78
79

  // TODO Improvement - Deactivate Multiple spawn before spawning if total_spawns == 1
80
  if(spawn_data.spawn_is_multiple) { multiple_strat_parents(spawn_data, spawn_port, comm, intercomms, child); }
81
82
83
84
85
86
87
88
  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); }
}

89

90
91
92
93
94
95
void baseline_children(Spawn_data spawn_data, Spawn_ports *spawn_port, MPI_Comm *parents) {
  if(spawn_data.spawn_is_parallel) {
    // This spawn is quite different from the rest, as so
    // it takes care of everything related to spawning.
    parallel_strat_children(spawn_data, spawn_port, parents);
    return;
96
97
  }

98
99
  if(spawn_data.spawn_is_multiple) { multiple_strat_children(parents, spawn_port); }
  if(spawn_data.spawn_is_single) { single_strat_children(parents, spawn_port); }
100
}