Commit afb37003 authored by iker_martin's avatar iker_martin
Browse files

Pequenyo refactor en IO codes. Ahora se permite elegir la precision de tiempos...

Pequenyo refactor en IO codes. Ahora se permite elegir la precision de tiempos globales XOR tiempos iteraciones
parent 897b6adb
......@@ -31,10 +31,10 @@ static int handler(void* user, const char* section, const char* name,
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
if (MATCH("general", "Total_Resizes")) {
pconfig->n_resizes = atoi(value) + 1;
pconfig->n_resizes = strtoul(value, NULL, 10) + 1;
user_functions->resizes_f(pconfig);
} else if (MATCH("general", "Total_Stages")) {
pconfig->n_stages = atoi(value);
pconfig->n_stages = strtoul(value, NULL, 10);
user_functions->stages_f(pconfig);
} else if (MATCH("general", "Granularity")) {
pconfig->granularity = atoi(value);
......@@ -42,6 +42,8 @@ static int handler(void* user, const char* section, const char* name,
pconfig->sdr = atoi(value);
} else if (MATCH("general", "ADR")) { // TODO Refactor a nombre manual
pconfig->adr = atoi(value);
} else if (MATCH("general", "Rigid")) {
pconfig->rigid_times = atoi(value);
// Iter stage
} else if (MATCH(stage_name, "Stage_Type")) {
......
......@@ -13,37 +13,16 @@ void def_results_type(results_data *results, int resizes, MPI_Datatype *results_
//======================================================||
//======================================================||
//TODO Generalizar ambas funciones en una sola
/*
* Envia una estructura de resultados al grupo de procesos al que se
* enlaza este grupo a traves del intercomunicador pasado como argumento.
* Comunica una estructura de resultados a todos los procesos del comunicador
* a traves de un tipo derivado.
*
* Esta funcion tiene que ser llamada por todos los procesos del mismo grupo
* e indicar cual es el proceso raiz que se encargara de enviar los
* resultados al otro grupo.
* Si se llama con un intercommunicador, el grupo de procesos que envia los datos
* tiene que indicar en el proceso raiz el valor "MPI_ROOT" para "root" y el resto
* de ese grupo el valor "MPI_PROC_NULL". Los procesos del otro grupo tienen que
* indicar el Id del proceso raiz que ha puesto "MPI_ROOT".
*/
void send_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm) {
MPI_Datatype results_type;
// Obtener un tipo derivado para enviar todos los
// datos escalares con una sola comunicacion
def_results_type(results, resizes, &results_type);
MPI_Bcast(results, 1, results_type, root, intercomm);
//Liberar tipos derivados
MPI_Type_free(&results_type);
}
/*
* Recibe una estructura de resultados desde otro grupo de procesos
* y la devuelve. La memoria de la estructura se tiene que reservar con antelacion
* con la función "init_results_data".
*
* Esta funcion tiene que ser llamada por todos los procesos del mismo grupo
* e indicar cual es el proceso raiz del otro grupo que se encarga de enviar
* los resultados a este grupo.
*/
void recv_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm) {
void comm_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm) {
MPI_Datatype results_type;
// Obtener un tipo derivado para enviar todos los
......
......@@ -20,8 +20,7 @@ typedef struct {
double wasted_time; // Time spent recalculating iter stages
} results_data;
void send_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm);
void recv_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm);
void comm_results(results_data *results, int root, size_t resizes, MPI_Comm intercomm);
void set_results_post_reconfig(results_data *results, int grp, int sdr, int adr);
void reset_results_index(results_data *results);
......
......@@ -14,6 +14,8 @@
int work();
double iterate(int async_comm);
double iterate_relaxed(double *time, double *times_stages);
double iterate_rigid(double *time, double *times_stages);
void init_group_struct(char *argv[], int argc, int myId, int numP);
void init_application();
......@@ -223,24 +225,22 @@ int work() {
/*
* Simula la ejecucción de una iteración de computo en la aplicación
* que dura al menos un tiempo de "time" segundos.
* que dura al menos un tiempo determinado por la suma de todas las
* etapas definidas en la configuracion.
*/
double iterate(int async_comm) {
double start_time, start_time_stage, actual_time, *times_stages_aux;
double time, *times_stages_aux;
size_t i;
double aux = 0;
times_stages_aux = malloc(config_file->n_stages * sizeof(double));
start_time = MPI_Wtime();
for(i=0; i < config_file->n_stages; i++) {
start_time_stage = MPI_Wtime();
aux+= process_stage(*config_file, config_file->stages[i], *group, comm);
times_stages_aux[i] = MPI_Wtime() - start_time_stage;
if(config_file->rigid_times) {
iterate_relaxed(&time, times_stages_aux);
} else {
iterate_rigid(&time, times_stages_aux);
}
actual_time = MPI_Wtime(); // Guardar tiempos
// Se esta realizando una redistribucion de datos asincrona
if(async_comm == MALL_DIST_PENDING || async_comm == MALL_SPAWN_PENDING || async_comm == MALL_SPAWN_SINGLE_PENDING) {
// TODO Que diferencie entre ambas en el IO
......@@ -250,7 +250,7 @@ double iterate(int async_comm) {
if(results->iter_index == results->iters_size) { // Aumentar tamaño de ambos vectores de resultados
realloc_results_iters(results, config_file->n_stages, results->iters_size + 100);
}
results->iters_time[results->iter_index] = actual_time - start_time;
results->iters_time[results->iter_index] = time;
for(i=0; i < config_file->n_stages; i++) {
results->stage_times[i][results->iter_index] = times_stages_aux[i];
}
......@@ -261,6 +261,50 @@ double iterate(int async_comm) {
return aux;
}
/*
* Performs an iteration. The gathered times for iterations
* and stages could be imprecise in order to ensure the
* global execution time is precise.
*/
double iterate_relaxed(double *time, double *times_stages) {
size_t i;
double start_time, start_time_stage, aux=0;
start_time = MPI_Wtime();
for(i=0; i < config_file->n_stages; i++) {
start_time_stage = MPI_Wtime();
aux+= process_stage(*config_file, config_file->stages[i], *group, comm);
times_stages[i] = MPI_Wtime() - start_time_stage;
}
*time = MPI_Wtime() - start_time; // Guardar tiempos
return aux;
}
/*
* Performs an iteration. The gathered times for iterations
* and stages are ensured to be precise but the global
* execution time could be imprecise.
*/
double iterate_rigid(double *time, double *times_stages) {
size_t i;
double start_time, start_time_stage, aux=0;
MPI_Barrier(comm);
start_time = MPI_Wtime();
for(i=0; i < config_file->n_stages; i++) {
start_time_stage = MPI_Wtime();
aux+= process_stage(*config_file, config_file->stages[i], *group, comm);
MPI_Barrier(comm);
times_stages[i] = MPI_Wtime() - start_time_stage;
}
*time = MPI_Wtime() - start_time; // Guardar tiempos
return aux;
}
//======================================================||
//======================================================||
//=============INIT/FREE/PRINT FUNCTIONS================||
......
......@@ -54,6 +54,7 @@ typedef struct
{
size_t n_resizes, n_stages;
size_t actual_resize, actual_stage;
int rigid_times;
int granularity, sdr, adr;
double latency_m, bw_m;
......
......@@ -273,14 +273,14 @@ void recv_config_file(int root, MPI_Comm intercomm, configuration **config_file_
* de la estructura de configuracion con una sola comunicacion.
*/
void def_struct_config_file(configuration *config_file, MPI_Datatype *config_type) {
int i, counts = 7;
int blocklengths[7] = {1, 1, 1, 1, 1, 1, 1};
int i, counts = 8;
int blocklengths[8] = {1, 1, 1, 1, 1, 1, 1, 1};
MPI_Aint displs[counts], dir;
MPI_Datatype types[counts];
// Rellenar vector types
types[0] = types[1] = types[2] = types[3] = types[4] = MPI_INT;
types[5] = types[6] = MPI_DOUBLE;
types[0] = types[1] = types[2] = types[3] = types[4] = types[5] = MPI_INT;
types[6] = types[7] = MPI_DOUBLE;
// Rellenar vector displs
MPI_Get_address(config_file, &dir);
......@@ -290,8 +290,9 @@ void def_struct_config_file(configuration *config_file, MPI_Datatype *config_typ
MPI_Get_address(&(config_file->granularity), &displs[2]);
MPI_Get_address(&(config_file->sdr), &displs[3]);
MPI_Get_address(&(config_file->adr), &displs[4]);
MPI_Get_address(&(config_file->latency_m), &displs[5]);
MPI_Get_address(&(config_file->bw_m), &displs[6]);
MPI_Get_address(&(config_file->rigid_times), &displs[5]);
MPI_Get_address(&(config_file->latency_m), &displs[6]);
MPI_Get_address(&(config_file->bw_m), &displs[7]);
for(i=0;i<counts;i++) displs[i] -= dir;
......
......@@ -479,7 +479,7 @@ void Children_init() {
}
// Guardar los resultados de esta transmision
recv_results(mall_conf->results, mall->root, mall_conf->config_file->n_resizes, mall->intercomm);
comm_results(mall_conf->results, mall->root, mall_conf->config_file->n_resizes, mall->intercomm);
if(!is_intercomm) {
if(mall->thread_comm != MPI_COMM_WORLD) MPI_Comm_free(&(mall->thread_comm));
if(mall->comm != MPI_COMM_WORLD) MPI_Comm_free(&(mall->comm));
......@@ -656,7 +656,7 @@ int end_redistribution() {
}
}
send_results(mall_conf->results, rootBcast, mall_conf->config_file->n_resizes, mall->intercomm);
comm_results(mall_conf->results, rootBcast, mall_conf->config_file->n_resizes, mall->intercomm);
local_state = MALL_DIST_COMPLETED;
if(!is_intercomm) { // Merge Spawn
......
......@@ -4,6 +4,7 @@ Total_Stages=4
Granularity=100000
SDR=1000.0
ADR=0.0
Rigid=1
; end [general]
[stage0]
Stage_Type=0
......
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