diff --git a/.gitignore b/.gitignore index f888394c0c21cc5552b0be1f4d3bb945249691ac..daafa3350a91d529b0f3d2673824a4aaed3d0e0f 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ examples/*/*.h5 examples/*/*.png examples/*/*.mp4 examples/*/*.txt -examples/*/*.dot +examples/*/dependency_graph_*.csv examples/*/restart/* examples/*/used_parameters.yml examples/*/unused_parameters.yml diff --git a/src/scheduler.c b/src/scheduler.c index 781c816524843f3932ff3faa493a897d754f34b7..b4e8e732e01d72c45e016c56d4ab74ad8ec6e5e1 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -113,55 +113,6 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta, atomic_inc(&s->completed_unlock_writes); } -/** - * @brief generate the dependency name for the tasks - * - * @param ta_type The #task type. - * @param ta_subtype The #task type. - * @param ta_name (return) The formatted string - */ -void scheduler_task_dependency_name(int ta_type, int ta_subtype, - char *ta_name) { - - /* Check input */ - if ((ta_type < 0) || (ta_type >= task_type_count)) - error("Unknown task type %i", ta_type); - - if ((ta_subtype < 0) || (ta_subtype >= task_subtype_count)) - error("Unknown task subtype %i with type %s", ta_subtype, - taskID_names[ta_type]); - - /* construct line */ - if (ta_subtype == task_subtype_none) - sprintf(ta_name, "%s", taskID_names[ta_type]); - else - sprintf(ta_name, "%s_%s", taskID_names[ta_type], - subtaskID_names[ta_subtype]); -} - -/** - * @brief Get the cluster name of a task. - * - * @param ta The #task - * @param cluster (output) The cluster name (should be allocated) - */ -void scheduler_get_cluster_name(const struct task *ta, char *cluster) { - strcpy(cluster, "None"); - if (ta->subtype == task_subtype_density) - strcpy(cluster, "Density"); - else if (ta->subtype == task_subtype_gradient) - strcpy(cluster, "Gradient"); - else if (ta->subtype == task_subtype_force) - strcpy(cluster, "Force"); - else if (ta->subtype == task_subtype_grav || - ta->type == task_type_grav_long_range || - ta->type == task_type_grav_mm || - ta->type == task_type_grav_mesh) - strcpy(cluster, "Gravity"); - else if (ta->subtype == task_subtype_stars_density) - strcpy(cluster, "Stars"); -} - /** * @brief compute the number of same dependencies * @@ -172,7 +123,8 @@ void scheduler_get_cluster_name(const struct task *ta, char *cluster) { * @return Number of dependencies */ int scheduler_get_number_relation(const struct scheduler *s, - const struct task *ta, const struct task *tb) { + const struct task *ta, + const struct task *tb) { int count = 0; @@ -184,11 +136,9 @@ int scheduler_get_number_relation(const struct scheduler *s, for (int j = 0; j < ta->nr_unlock_tasks; j++) { const struct task *tb_tmp = ta->unlock_tasks[j]; - if (ta->type == ta_tmp->type && - ta->subtype == ta_tmp->subtype && - tb->type == tb_tmp->type && - tb->subtype == tb_tmp->subtype) { - count += 1; + if (ta->type == ta_tmp->type && ta->subtype == ta_tmp->subtype && + tb->type == tb_tmp->type && tb->subtype == tb_tmp->subtype) { + count += 1; } } } @@ -234,7 +184,9 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { /* Write header */ fprintf(f, "# %s\n", git_revision()); - fprintf(f, "task_in,task_out,implicit_in,implicit_out,mpi_in,mpi_out,cluster_in,cluster_out,number_link\n"); + fprintf(f, + "task_in,task_out,implicit_in,implicit_out,mpi_in,mpi_out,cluster_in," + "cluster_out,number_link\n"); /* loop over all tasks */ for (int i = 0; i < s->nr_tasks; i++) { @@ -279,35 +231,34 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { /* Not written yet => write it */ if (!written) { - int count = scheduler_get_number_relation(s, ta, tb); + int count = scheduler_get_number_relation(s, ta, tb); /* text to write */ char ta_name[200]; char tb_name[200]; /* construct line */ - scheduler_task_dependency_name(ta->type, ta->subtype, ta_name); - scheduler_task_dependency_name(tb->type, tb->subtype, tb_name); + task_get_full_name(ta->type, ta->subtype, ta_name); + task_get_full_name(tb->type, tb->subtype, tb_name); - /* Check if MPI */ - int ta_mpi = 0; + /* Check if MPI */ + int ta_mpi = 0; if (ta->type == task_type_send || ta->type == task_type_recv) - ta_mpi = 1; + ta_mpi = 1; - int tb_mpi = 0; + int tb_mpi = 0; if (tb->type == task_type_send || tb->type == task_type_recv) - tb_mpi = 1; - - /* Get cluster name */ - char ta_cluster[20]; - scheduler_get_cluster_name(ta, ta_cluster); - char tb_cluster[20]; - scheduler_get_cluster_name(tb, tb_cluster); - - fprintf(f, "%s,%s,%i,%i,%i,%i,%s,%s,%i\n", - ta_name, tb_name, ta->implicit, tb->implicit, - ta_mpi, tb_mpi, ta_cluster, tb_cluster, count); + tb_mpi = 1; + + /* Get group name */ + char ta_cluster[20]; + char tb_cluster[20]; + task_get_group_name(ta, ta_cluster); + task_get_group_name(tb, tb_cluster); + fprintf(f, "%s,%s,%d,%d,%d,%d,%s,%s,%d\n", ta_name, tb_name, + ta->implicit, tb->implicit, ta_mpi, tb_mpi, ta_cluster, + tb_cluster, count); } } } diff --git a/src/task.c b/src/task.c index 3918dad3b713c6c226e5dacf3e38756910c1dd27..a902feed8ec7a7f4b6a4af462da8660100147d94 100644 --- a/src/task.c +++ b/src/task.c @@ -566,6 +566,72 @@ void task_print(const struct task *t) { t->nr_unlock_tasks, t->skip); } +/** + * @brief Get the group name of a task. + * + * This is used to group tasks with similar actions in the task dependency + * graph. + * + * @param t The #task. + * @param group (return) The group name (should be allocated) + */ +void task_get_group_name(const struct task *t, char *cluster) { + + if (t->type == task_type_grav_long_range || t->type == task_type_grav_mm || + t->type == task_type_grav_mesh) { + + strcpy(cluster, "Gravity"); + return; + } + + switch (t->subtype) { + case task_subtype_density: + strcpy(cluster, "Density"); + break; + case task_subtype_gradient: + strcpy(cluster, "Gradient"); + break; + case task_subtype_force: + strcpy(cluster, "Force"); + break; + case task_subtype_grav: + strcpy(cluster, "Gravity"); + break; + case task_subtype_stars_density: + strcpy(cluster, "Stars"); + break; + default: + strcpy(cluster, "None"); + break; + } +} + +/** + * @brief Generate the full name of a #task. + * + * @param type The #task type. + * @param subtype The #task type. + * @param name (return) The formatted string + */ +void task_get_full_name(enum task_types type, enum task_subtypes subtype, + char *name) { + +#ifdef SWIFT_DEBUG_CHECKS + /* Check input */ + if ((type < 0) || (type >= task_type_count)) + error("Unknown task type %i", type); + + if ((subtype < 0) || (subtype >= task_subtype_count)) + error("Unknown task subtype %i with type %s", subtype, taskID_names[type]); +#endif + + /* Full task name */ + if (subtype == task_subtype_none) + sprintf(name, "%s", taskID_names[type]); + else + sprintf(name, "%s_%s", taskID_names[type], subtaskID_names[subtype]); +} + #ifdef WITH_MPI /** * @brief Create global communicators for each of the subtasks. diff --git a/src/task.h b/src/task.h index 994b2b14c05965b71e877feac5cb9827a1d1b4bb..39ab2003933f738b5fd0149eee961ad887c3e407 100644 --- a/src/task.h +++ b/src/task.h @@ -203,6 +203,10 @@ float task_overlap(const struct task *ta, const struct task *tb); int task_lock(struct task *t); void task_do_rewait(struct task *t); void task_print(const struct task *t); +void task_get_full_name(enum task_types type, enum task_subtypes subtype, + char *name); +void task_get_group_name(const struct task *t, char *cluster); + #ifdef WITH_MPI void task_create_mpi_comms(void); #endif