Commit a539c1cc authored by iker_martin's avatar iker_martin
Browse files

Anadida maleabilidad asincrona y nuevo parametro para indicar como realizaran...

Anadida maleabilidad asincrona y nuevo parametro para indicar como realizaran la espera de transmision de datos asincronos los padres
parent 90aa227d
...@@ -37,6 +37,8 @@ static int handler(void* user, const char* section, const char* name, ...@@ -37,6 +37,8 @@ static int handler(void* user, const char* section, const char* name,
pconfig->sdr = atoi(value); pconfig->sdr = atoi(value);
} else if (MATCH("general", "ADR")) { } else if (MATCH("general", "ADR")) {
pconfig->adr = atoi(value); pconfig->adr = atoi(value);
} else if (MATCH("general", "AIB")) {
pconfig->aib = atoi(value);
} else if (MATCH("general", "time")) { } else if (MATCH("general", "time")) {
pconfig->general_time = atof(value); pconfig->general_time = atof(value);
...@@ -128,11 +130,11 @@ void free_config(configuration *user_config) { ...@@ -128,11 +130,11 @@ void free_config(configuration *user_config) {
* Imprime por salida estandar toda la informacion que contiene * Imprime por salida estandar toda la informacion que contiene
* la configuracion pasada como argumento * la configuracion pasada como argumento
*/ */
void print_config(configuration *user_config) { void print_config(configuration *user_config, int numP) {
if(user_config != NULL) { if(user_config != NULL) {
int i; int i;
printf("Config loaded: resizes=%d, matrix=%d, sdr=%d, adr=%d, time=%f\n", printf("Config loaded: resizes=%d, matrix=%d, sdr=%d, adr=%d, time=%f || NUMP=%d\n",
user_config->resizes, user_config->matrix_tam, user_config->sdr, user_config->adr, user_config->general_time); user_config->resizes, user_config->matrix_tam, user_config->sdr, user_config->adr, user_config->general_time, numP);
for(i=0; i<user_config->resizes; i++) { for(i=0; i<user_config->resizes; i++) {
printf("Resize %d: Iters=%d, Procs=%d, Factors=%f, Phy=%d\n", printf("Resize %d: Iters=%d, Procs=%d, Factors=%f, Phy=%d\n",
i, user_config->iters[i], user_config->procs[i], user_config->factors[i], user_config->phy_dist[i]); i, user_config->iters[i], user_config->procs[i], user_config->factors[i], user_config->phy_dist[i]);
...@@ -221,14 +223,14 @@ configuration *recv_config_file(int root, MPI_Comm intercomm) { ...@@ -221,14 +223,14 @@ configuration *recv_config_file(int root, MPI_Comm intercomm) {
* de la estructura de configuracion con una sola comunicacion. * de la estructura de configuracion con una sola comunicacion.
*/ */
void def_struct_config_file(configuration *config_file, MPI_Datatype *config_type) { void def_struct_config_file(configuration *config_file, MPI_Datatype *config_type) {
int i, counts = 6; int i, counts = 7;
int blocklengths[6] = {1, 1, 1, 1, 1, 1}; int blocklengths[7] = {1, 1, 1, 1, 1, 1, 1};
MPI_Aint displs[counts], dir; MPI_Aint displs[counts], dir;
MPI_Datatype types[counts]; MPI_Datatype types[counts];
// Rellenar vector types // Rellenar vector types
types[0] = types[1] = types[2] = types[3] = types[4] = MPI_INT; types[0] = types[1] = types[2] = types[3] = types[4] = types[5] = MPI_INT;
types[5] = MPI_FLOAT; types[6] = MPI_FLOAT;
// Rellenar vector displs // Rellenar vector displs
MPI_Get_address(config_file, &dir); MPI_Get_address(config_file, &dir);
...@@ -238,7 +240,8 @@ void def_struct_config_file(configuration *config_file, MPI_Datatype *config_typ ...@@ -238,7 +240,8 @@ void def_struct_config_file(configuration *config_file, MPI_Datatype *config_typ
MPI_Get_address(&(config_file->matrix_tam), &displs[2]); MPI_Get_address(&(config_file->matrix_tam), &displs[2]);
MPI_Get_address(&(config_file->sdr), &displs[3]); MPI_Get_address(&(config_file->sdr), &displs[3]);
MPI_Get_address(&(config_file->adr), &displs[4]); MPI_Get_address(&(config_file->adr), &displs[4]);
MPI_Get_address(&(config_file->general_time), &displs[5]); MPI_Get_address(&(config_file->aib), &displs[5]);
MPI_Get_address(&(config_file->general_time), &displs[6]);
for(i=0;i<counts;i++) displs[i] -= dir; for(i=0;i<counts;i++) displs[i] -= dir;
......
...@@ -8,6 +8,7 @@ typedef struct ...@@ -8,6 +8,7 @@ typedef struct
int resizes; int resizes;
int actual_resize; int actual_resize;
int matrix_tam, sdr, adr; int matrix_tam, sdr, adr;
int aib;
float general_time; float general_time;
int *iters, *procs, *phy_dist; int *iters, *procs, *phy_dist;
...@@ -17,7 +18,7 @@ typedef struct ...@@ -17,7 +18,7 @@ typedef struct
configuration *read_ini_file(char *file_name); configuration *read_ini_file(char *file_name);
void free_config(configuration *user_config); void free_config(configuration *user_config);
void print_config(configuration *user_config); void print_config(configuration *user_config, int numP);
// MPI Intercomm functions // MPI Intercomm functions
void send_config_file(configuration *config_file, int root, MPI_Comm intercomm); void send_config_file(configuration *config_file, int root, MPI_Comm intercomm);
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
int work(); int work();
void Sons_init(); void Sons_init();
int checkpoint(int iter); int checkpoint(int iter, int state, MPI_Request **comm_req);
void TC(int numS); void TC(int numS);
int start_redistribution(int numS, MPI_Request **comm_req);
int check_redistribution(int iter, MPI_Request **comm_req);
void iterate(double *matrix, int n); void iterate(double *matrix, int n);
void computeMatrix(double *matrix, int n); void computeMatrix(double *matrix, int n);
...@@ -21,11 +23,12 @@ typedef struct { ...@@ -21,11 +23,12 @@ typedef struct {
int myId; int myId;
int numP; int numP;
int grp; int grp;
int iter_start;
MPI_Comm children, parents; MPI_Comm children, parents;
char **argv; char **argv;
char *sync_array; char *sync_array, *async_array;
} group_data; } group_data;
configuration *config_file; configuration *config_file;
...@@ -39,10 +42,11 @@ int main(int argc, char *argv[]) { ...@@ -39,10 +42,11 @@ int main(int argc, char *argv[]) {
MPI_Comm_rank(MPI_COMM_WORLD, &myId); MPI_Comm_rank(MPI_COMM_WORLD, &myId);
group = malloc(1 * sizeof(group_data)); group = malloc(1 * sizeof(group_data));
group->myId = myId; group->myId = myId;
group->numP = numP; group->numP = numP;
group->grp = 0; group->grp = 0;
group->argv = argv; group->iter_start = 0;
group->argv = argv;
MPI_Comm_get_parent(&(group->parents)); MPI_Comm_get_parent(&(group->parents));
if(group->parents != MPI_COMM_NULL ) { // Si son procesos hijos deben comunicarse con las padres if(group->parents != MPI_COMM_NULL ) { // Si son procesos hijos deben comunicarse con las padres
...@@ -52,20 +56,22 @@ int main(int argc, char *argv[]) { ...@@ -52,20 +56,22 @@ int main(int argc, char *argv[]) {
if(config_file->sdr > 0) { if(config_file->sdr > 0) {
malloc_comm_array(&(group->sync_array), config_file->sdr , group->myId, group->numP); malloc_comm_array(&(group->sync_array), config_file->sdr , group->myId, group->numP);
} }
if(config_file->adr > 0) {
malloc_comm_array(&(group->async_array), config_file->adr , group->myId, group->numP);
}
} }
if(myId== ROOT) print_config(config_file); if(myId== ROOT) print_config(config_file, numP);
int res = work(); int res = work();
if(res) { // Ultimo set de procesos comprueba resultados if(res) { // Ultimo set de procesos muestra resultados
//RESULTADOS //RESULTADOS
} }
// free_config(config_file); //FIXME DESCOMENTAR free_config(config_file);
// free(group->sync_array); free(group->sync_array);
// free(group); free(group->async_array);
free(group);
MPI_Finalize(); MPI_Finalize();
return 0; return 0;
...@@ -83,26 +89,25 @@ int main(int argc, char *argv[]) { ...@@ -83,26 +89,25 @@ int main(int argc, char *argv[]) {
* comunicacion asincrona y realizar entonces la sincrona. * comunicacion asincrona y realizar entonces la sincrona.
*/ */
int work() { int work() {
int iter, maxiter; int iter, maxiter, state;
double *matrix; double *matrix;
MPI_Request *async_comm;
maxiter = config_file->iters[group->grp]; maxiter = config_file->iters[group->grp];
initMatrix(&matrix, config_file->matrix_tam); initMatrix(&matrix, config_file->matrix_tam);
for(iter=0; iter < maxiter; iter++) { for(iter=group->iter_start; iter < maxiter; iter++) {
iterate(matrix, config_file->matrix_tam); iterate(matrix, config_file->matrix_tam);
} }
checkpoint(iter); state = checkpoint(iter, MAL_COMM_UNINITIALIZED, &async_comm);
/* iter = 0;
iter = 0 while(state == MAL_ASYNC_PENDING) {
while(maxiter) { //FIXME AÑADIR VALOR
iterate(matrix, config_file->matrix_tam); iterate(matrix, config_file->matrix_tam);
iter++; iter++;
//check_async(iter); state = checkpoint(iter, state, &async_comm);
} }
*/
return 0; return 0;
} }
...@@ -115,59 +120,104 @@ int work() { ...@@ -115,59 +120,104 @@ int work() {
* *
* Si hay datos asincronos a transmitir, primero se comienza a * Si hay datos asincronos a transmitir, primero se comienza a
* transmitir estos y se termina la funcion. Se tiene que comprobar con * transmitir estos y se termina la funcion. Se tiene que comprobar con
* la funcion "??" que se han terminado de enviar //TODO * llamando a la función de nuevo que se han terminado de enviar //TODO
* *
* Si hay ademas datos sincronos a enviar, no se envian aun. * Si hay ademas datos sincronos a enviar, no se envian aun.
* *
* Si solo hay datos sincronos se envian tras la creacion de los procesos * Si solo hay datos sincronos se envian tras la creacion de los procesos
* y finalmente se desconectan los dos grupos de procesos. * y finalmente se desconectan los dos grupos de procesos.
*/ */
int checkpoint(int iter) { int checkpoint(int iter, int state, MPI_Request **comm_req) {
if(state == MAL_COMM_UNINITIALIZED) {
// Comprobar si se tiene que realizar un redimensionado
if(config_file->iters[group->grp] > iter || config_file->resizes == group->grp + 1) {return MAL_COMM_UNINITIALIZED;}
int numS = config_file->procs[group->grp +1];
TC(numS);
state = start_redistribution(numS, comm_req);
} else if(MAL_ASYNC_PENDING) {
state = check_redistribution(iter, comm_req);
}
// Comprobar si se tiene que realizar un redimensionado return state;
if(config_file->iters[group->grp] < iter) {return 0;} }
int numS = config_file->procs[group->grp +1]; /*
* Se encarga de realizar la creacion de los procesos hijos.
*/
void TC(int numS){
// Inicialización de la comunicación con SLURM
int dist = config_file->phy_dist[group->grp +1];
init_slurm_comm(group->argv, group->myId, numS, ROOT, dist, COMM_SPAWN_SERIAL);
TC(numS); // Esperar a que la comunicación y creación de procesos
// haya finalizado
int test = -1;
while(test != MPI_SUCCESS) {
test = check_slurm_comm(group->myId, ROOT, MPI_COMM_WORLD, &(group->children));
}
}
int start_redistribution(int numS, MPI_Request **comm_req) {
int rootBcast = MPI_PROC_NULL; int rootBcast = MPI_PROC_NULL;
if(group->myId == ROOT) rootBcast = MPI_ROOT; if(group->myId == ROOT) rootBcast = MPI_ROOT;
// Enviar a los hijos que grupo de procesos son // Enviar a los hijos que grupo de procesos son
MPI_Bcast(&(group->grp), 1, MPI_INT, rootBcast, group->children); MPI_Bcast(&(group->grp), 1, MPI_INT, rootBcast, group->children);
send_config_file(config_file, rootBcast, group->children); send_config_file(config_file, rootBcast, group->children);
if(config_file->adr > 0) { if(config_file->adr > 0) {
send_async(group->sync_array, config_file->sdr, group->myId, group->numP, ROOT, group->children, numS); send_async(group->async_array, config_file->adr, group->myId, group->numP, ROOT, group->children, numS, comm_req, config_file->aib);
} else if return MAL_ASYNC_PENDING;
}
if(config_file->sdr > 0) { if(config_file->sdr > 0) {
send_sync(group->sync_array, config_file->sdr, group->myId, group->numP, ROOT, group->children, numS); send_sync(group->sync_array, config_file->sdr, group->myId, group->numP, ROOT, group->children, numS);
} }
// Desconectar intercomunicador con los hijos // Desconectar intercomunicador con los hijos
MPI_Comm_disconnect(&(group->children)); MPI_Comm_disconnect(&(group->children));
//MPI_Comm_free(&(group->children));
return 1; return MAL_COMM_COMPLETED;
} }
/* int check_redistribution(int iter, MPI_Request **comm_req) {
* Se encarga de realizar la creacion de los procesos hijos. int completed, all_completed, test_err, iter_send;
*/ int numS = config_file->procs[group->grp +1];
void TC(int numS){ int rootBcast = MPI_PROC_NULL;
// Inicialización de la comunicación con SLURM MPI_Request *req_completed;
int dist = config_file->phy_dist[group->grp +1]; if(group->myId == ROOT) rootBcast = MPI_ROOT;
init_slurm_comm(group->argv, group->myId, numS, ROOT, dist, COMM_SPAWN_SERIAL);
// Esperar a que la comunicación y creación de procesos if(config_file->aib == MAL_USE_NORMAL) {
// haya finalizado req_completed = &(*comm_req)[0];
int test = -1; } else {
while(test != MPI_SUCCESS) { req_completed = &(*comm_req)[1];
test = check_slurm_comm(group->myId, ROOT, MPI_COMM_WORLD, &(group->children));
} }
test_err = MPI_Test(req_completed, &completed, MPI_STATUS_IGNORE);
if (test_err != MPI_SUCCESS && test_err != MPI_ERR_PENDING) {
printf("P%d aborting\n", group->myId);
MPI_Abort(MPI_COMM_WORLD, test_err);
}
MPI_Allreduce(&completed, &all_completed, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
if(!all_completed) return MAL_ASYNC_PENDING; // Continue only if asynchronous send has ended
iter_send = iter;
MPI_Bcast(&iter_send, 1, MPI_INT, rootBcast, group->children);
if(config_file->sdr > 0) {
send_sync(group->sync_array, config_file->sdr, group->myId, group->numP, ROOT, group->children, numS);
}
if(config_file->aib == MAL_USE_IBARRIER) {
MPI_Wait(&(*comm_req)[0], MPI_STATUS_IGNORE); // Indicar como completado el envio asincrono
}
// Desconectar intercomunicador con los hijos
MPI_Comm_disconnect(&(group->children));
free(*comm_req);
return MAL_COMM_COMPLETED;
} }
/* /*
...@@ -182,18 +232,19 @@ void Sons_init() { ...@@ -182,18 +232,19 @@ void Sons_init() {
MPI_Bcast(&(group->grp), 1, MPI_INT, ROOT, group->parents); MPI_Bcast(&(group->grp), 1, MPI_INT, ROOT, group->parents);
group->grp++; group->grp++;
config_file = recv_config_file(ROOT, group->parents); config_file = recv_config_file(ROOT, group->parents);
int numP_parents = config_file->procs[group->grp -1]; int numP_parents = config_file->procs[group->grp -1];
if(config_file->adr > 0) { // Recibir datos asincronos
recv_async(&(group->async_array), config_file->adr, group->myId, group->numP, ROOT, group->parents, numP_parents, config_file->aib);
MPI_Bcast(&(group->iter_start), 1, MPI_INT, ROOT, group->parents);
}
if(config_file->sdr > 0) { // Recibir datos sincronos if(config_file->sdr > 0) { // Recibir datos sincronos
recv_sync(&(group->sync_array), config_file->sdr, group->myId, group->numP, ROOT, group->parents, numP_parents); recv_sync(&(group->sync_array), config_file->sdr, group->myId, group->numP, ROOT, group->parents, numP_parents);
} }
// Desconectar intercomunicador con los hijos // Desconectar intercomunicador con los hijos
MPI_Comm_disconnect(&(group->parents)); MPI_Comm_disconnect(&(group->parents));
// MPI_Abort(MPI_COMM_WORLD, 0);
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <mpi.h> #include <mpi.h>
#include <string.h> #include <string.h>
#include "CommDist.h"
struct Dist_data { struct Dist_data {
int ini; //Primer elemento a enviar int ini; //Primer elemento a enviar
...@@ -22,12 +22,9 @@ struct Counts { ...@@ -22,12 +22,9 @@ struct Counts {
int *zero_arr; int *zero_arr;
}; };
void send_sync_arrays(struct Dist_data dist_data, char *array, int root, int numP_child, int idI, int idE, struct Counts counts); void send_sync_arrays(struct Dist_data dist_data, char *array, int root, int numP_child, int idI, int idE, struct Counts counts);
void recv_sync_arrays(struct Dist_data dist_data, char *array, int root, int numP_parents, int idI, int idE, struct Counts counts); void recv_sync_arrays(struct Dist_data dist_data, char *array, int root, int numP_parents, int idI, int idE, struct Counts counts);
void send_async_arrays(struct Dist_data dist_data, char *array, int root, int numP_child, int idI, int idE, struct Counts counts, MPI_Request *comm_req); void send_async_arrays(struct Dist_data dist_data, char *array, int root, int numP_child, int idI, int idE, struct Counts counts, MPI_Request *comm_req);
void recv_async_arrays(struct Dist_data dist_data, char *array, int root, int numP_parents, int idI, int idE, struct Counts counts, MPI_Request *comm_req); void recv_async_arrays(struct Dist_data dist_data, char *array, int root, int numP_parents, int idI, int idE, struct Counts counts, MPI_Request *comm_req);
...@@ -40,6 +37,23 @@ void freeCounts(struct Counts *counts); ...@@ -40,6 +37,23 @@ void freeCounts(struct Counts *counts);
void print_counts(struct Dist_data data_dist, int *xcounts, int *xdispls, int size, const char* name); void print_counts(struct Dist_data data_dist, int *xcounts, int *xdispls, int size, const char* name);
/*
* Reserva memoria para un vector de hasta "qty" elementos.
* Los "qty" elementos se disitribuyen entre los "numP" procesos
* que llaman a esta funcion.
*/
void malloc_comm_array(char **array, int qty, int myId, int numP) {
struct Dist_data dist_data;
get_dist(qty, myId, numP, &dist_data);
*array = malloc(dist_data.tamBl * sizeof(char));
int i;
for(i=0; i<dist_data.tamBl; i++) {
(*array)[i] = '!' + i + dist_data.ini;
}
// printf("P%d Tam %d String: %s\n", myId, dist_data.tamBl, *array);
}
//================================================================================ //================================================================================
//================================================================================ //================================================================================
...@@ -102,31 +116,12 @@ void recv_sync(char **array, int qty, int myId, int numP, int root, MPI_Comm int ...@@ -102,31 +116,12 @@ void recv_sync(char **array, int qty, int myId, int numP, int root, MPI_Comm int
getIds_intercomm(dist_data, numP_parents, &idS); // Obtener el rango de Ids de padres del que este proceso recibira datos getIds_intercomm(dist_data, numP_parents, &idS); // Obtener el rango de Ids de padres del que este proceso recibira datos
recv_sync_arrays(dist_data, *array, root, numP_parents, idS[0], idS[1], counts); recv_sync_arrays(dist_data, *array, root, numP_parents, idS[0], idS[1], counts);
printf("S%d Tam %d String: %s END\n", myId, dist_data.tamBl, *array); //printf("S%d Tam %d String: %s END\n", myId, dist_data.tamBl, *array);
freeCounts(&counts); freeCounts(&counts);
free(idS); free(idS);
} }
/*
* Reserva memoria para un vector de hasta "qty" elementos.
* Los "qty" elementos se disitribuyen entre los "numP" procesos
* que llaman a esta funcion.
*/
void malloc_comm_array(char **array, int qty, int myId, int numP) {
struct Dist_data dist_data;
get_dist(qty, myId, numP, &dist_data);
*array = malloc(dist_data.tamBl * sizeof(char));
int i;
for(i=0; i<dist_data.tamBl; i++) {
(*array)[i] = '!' + i + dist_data.ini;
}
printf("P%d Tam %d String: %s\n", myId, dist_data.tamBl, *array);
}
/* /*
* Envia a los hijos un vector que es redistribuido a los procesos * Envia a los hijos un vector que es redistribuido a los procesos
* hijos. Antes de realizar la comunicacion, cada proceso padre calcula sobre que procesos * hijos. Antes de realizar la comunicacion, cada proceso padre calcula sobre que procesos
...@@ -194,7 +189,7 @@ void recv_sync_arrays(struct Dist_data dist_data, char *array, int root, int num ...@@ -194,7 +189,7 @@ void recv_sync_arrays(struct Dist_data dist_data, char *array, int root, int num
* *
* El vector array no se modifica en esta funcion. * El vector array no se modifica en esta funcion.
*/ */
int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child, MPI_Request *comm_req) { int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child, MPI_Request **comm_req, int parents_wait) {
int rootBcast = MPI_PROC_NULL; int rootBcast = MPI_PROC_NULL;
int *idS = NULL; int *idS = NULL;
struct Counts counts; struct Counts counts;
...@@ -210,7 +205,18 @@ int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm inte ...@@ -210,7 +205,18 @@ int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm inte
getIds_intercomm(dist_data, numP_child, &idS); // Obtener rango de Id hijos a los que este proceso manda datos getIds_intercomm(dist_data, numP_child, &idS); // Obtener rango de Id hijos a los que este proceso manda datos
send_async_arrays(dist_data, array, rootBcast, numP_child, idS[0], idS[1], counts, comm_req); if(parents_wait == MAL_USE_NORMAL) {
*comm_req = (MPI_Request *) malloc(sizeof(MPI_Request));
*comm_req[0] = MPI_REQUEST_NULL;
send_async_arrays(dist_data, array, rootBcast, numP_child, idS[0], idS[1], counts, &(*comm_req[0]));
} else {
*comm_req = (MPI_Request *) malloc(2 * sizeof(MPI_Request));
(*comm_req)[0] = MPI_REQUEST_NULL;
(*comm_req)[1] = MPI_REQUEST_NULL;
send_async_arrays(dist_data, array, rootBcast, numP_child, idS[0], idS[1], counts, &((*comm_req)[1]));
MPI_Ibarrier(intercomm, &((*comm_req)[0]) );
}
freeCounts(&counts); freeCounts(&counts);
free(idS); free(idS);
...@@ -224,13 +230,16 @@ int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm inte ...@@ -224,13 +230,16 @@ int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm inte
* *
* El vector array se reserva dentro de la funcion y se devuelve en el mismo argumento. * El vector array se reserva dentro de la funcion y se devuelve en el mismo argumento.
* Tiene que ser liberado posteriormente por el usuario. * Tiene que ser liberado posteriormente por el usuario.
*
* El argumento "parents_wait" sirve para indicar si se usará la versión en la los padres
* espera a que terminen de enviar, o en la que esperan a que los hijos acaben de recibir.
*/ */
void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents) { void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents, int parents_wait) {
int *idS = NULL; int *idS = NULL;
int wait_err; int wait_err;
struct Counts counts; struct Counts counts;
struct Dist_data dist_data; struct Dist_data dist_data;
MPI_Request comm_req; MPI_Request comm_req, aux;
// Obtener distribución para este hijo // Obtener distribución para este hijo
get_dist(qty, myId, numP, &dist_data); get_dist(qty, myId, numP, &dist_data);
...@@ -244,16 +253,18 @@ void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm in ...@@ -244,16 +253,18 @@ void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm in
getIds_intercomm(dist_data, numP_parents, &idS); // Obtener el rango de Ids de padres del que este proceso recibira datos getIds_intercomm(dist_data, numP_parents, &idS); // Obtener el rango de Ids de padres del que este proceso recibira datos
recv_async_arrays(dist_data, *array, root, numP_parents, idS[0], idS[1], counts, &comm_req); recv_async_arrays(dist_data, *array, root, numP_parents, idS[0], idS[1], counts, &comm_req);
printf("S%d Tam %d String: %s END\n", myId, dist_data.tamBl, *array);
wait_err = MPI_Wait(&comm_req, MPI_STATUS_IGNORE); wait_err = MPI_Wait(&comm_req, MPI_STATUS_IGNORE);
if(wait_err != MPI_SUCCESS) { if(wait_err != MPI_SUCCESS) {
MPI_Abort(MPI_COMM_WORLD, wait_err); MPI_Abort(MPI_COMM_WORLD, wait_err);
} }
// TODO Indicar a los padres que los hijos han terminado?? if(parents_wait == MAL_USE_IBARRIER) {
MPI_Ibarrier(intercomm, &aux);
MPI_Wait(&aux, MPI_STATUS_IGNORE); //Es necesario comprobar que la comunicación ha terminado para desconectar los grupos de procesos
}
//printf("S%d Tam %d String: %s END\n", myId, dist_data.tamBl, *array);
freeCounts(&counts); freeCounts(&counts);
free(idS); free(idS);
} }
......
...@@ -3,13 +3,19 @@ ...@@ -3,13 +3,19 @@
#include <mpi.h> #include <mpi.h>
#include <string.h> #include <string.h>
#define MAL_COMM_COMPLETED 0
#define MAL_COMM_UNINITIALIZED 0
#define MAL_ASYNC_PENDING 1
#define MAL_USE_NORMAL 0
#define MAL_USE_IBARRIER 1
int send_sync(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child); int send_sync(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child);
void recv_sync(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents); void recv_sync(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents);
int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child, MPI_Request *comm_req); int send_async(char *array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_child, MPI_Request **comm_req, int parents_wait);
void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents); void recv_async(char **array, int qty, int myId, int numP, int root, MPI_Comm intercomm, int numP_parents, int parents_wait);
void malloc_comm_array(char **array, int qty, int myId, int numP); void malloc_comm_array(char **array, int qty, int myId, int numP);
...@@ -2,17 +2,6 @@ ...@@ -2,17 +2,6 @@
#SBATCH -N 2 #SBATCH -N 2
#module load gcc/6.4.0
#module load openmpi/1.10.7
#module load /home/martini/ejemplos_Mod/modulefiles/mpi/openmpi_aliaga_1_10_7
echo "OPENMPI"
#module load /home/martini/MODULES/modulefiles/openmpi4.1.0
#mpirun -mca btl_openib_allow_ib 1 -npernode 10 -np 20 ./batch5.out
echo "MPICH" echo "MPICH"
module load mpich-3.4.1-noucx module load mpich-3.4.1-noucx
#module load /home/martini/MODULES/modulefiles/mpich3.4 #module load /home/martini/MODULES/modulefiles/mpich3.4
...@@ -21,14 +10,4 @@ module load mpich-3.4.1-noucx ...@@ -21,14 +10,4 @@ module load mpich-3.4.1-noucx
mpirun -ppn 1 -np 2 ./a.out test.ini mpirun -ppn 1 -np 2 ./a.out test.ini
echo "END RUN"
echo "Intel"
#module load /home/martini/MODULES/modulefiles/intel64.module
#export I_MPI_OFI_PROVIDER=tcp
#export I_MPI_DEBUG=6
#export I_MPI_FABRICS=shm:ofi
#mpirun -print-all-exitcodes -np 2 --ppn 1 ./batch.out
#mpirun -genv I_MPI_FABRICS=shm:ofi -print-all-exitcodes -iface ib0 -np 16 ./batch4.out
#mpirun -genv I_MPI_FABRICS=shm:ofi -iface enp59s0f0 -np 20 ./batch4.out
[general] [general]
resizes=2 ; Numero de redistribuciones resizes=2 ; Numero de redistribuciones
matrix_tam=2000 ; Tamaño en bytes de la matriz de computo matrix_tam=2000 ; Tamaño en bytes de la matriz de computo
SDR=20 ; Tamaño en bytes a redistribuir de forma sincrona SDR=20 ; Tamaño en bytes a redistribuir de forma sincrona
ADR=10000 ; Tamaño en bytes a redistribuir de forma asincrona ADR=20 ; Tamaño en bytes a redistribuir de forma asincrona
time=0.5 ; Tiempo necesario para realizar una iteracion AIB=0 ; Indica si las redistribuciones asíncronas se consideran terminadas para los padres
; cuando terminan de enviar (0) o cuando terminan de recibir los valores (1)
time=0.5 ; Tiempo necesario para realizar una iteracion
[resize0] ; Grupo inicial(mpirun) - La aplicación no sigue el valor procs ni physical_dist [resize0] ; Grupo inicial(mpirun) - La aplicación no sigue el valor procs ni physical_dist
iters=5 ; Numero de iteraciones a realizar por este grupo iters=5 ; Numero de iteraciones a realizar por este grupo
...@@ -14,12 +16,12 @@ physical_dist=node ; Tipo de redistribución física de los procesos ...@@ -14,12 +16,12 @@ physical_dist=node ; Tipo de redistribución física de los procesos
[resize1] ; Grupo de hijos 1 [resize1] ; Grupo de hijos 1
iters=5 iters=5
procs=4 procs=4
factor=1.5 factor=0.5
physical_dist=node physical_dist=node
[resize2] ; Grupo de hijos 1 [resize2] ; Grupo de hijos 2
iters=5 iters=5
procs=8 procs=8
factor=2 factor=0.25
physical_dist=node physical_dist=node
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment