diff --git a/src/task.c b/src/task.c index 4769aa6605ee58b30bb56b7f59755a6cfdd93017..e9404ab00df4f757f49d6d186f28dc40c49cfa01 100644 --- a/src/task.c +++ b/src/task.c @@ -59,7 +59,7 @@ const char *subtaskID_names[task_type_count] = {"none", "density", "force", /** * @brief Computes the overlap between the parts array of two given cells. */ -size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { +size_t task_cell_overlap_part(const struct cell *ci, const struct cell *cj) { if (ci == NULL || cj == NULL) return 0; if (ci->parts <= cj->parts && ci->parts + ci->count >= cj->parts + cj->count) { @@ -71,6 +71,95 @@ size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { return 0; } +/** + * @brief Computes the overlap between the gparts array of two given cells. + */ +size_t task_cell_overlap_gpart(const struct cell *ci, const struct cell *cj) { + if (ci == NULL || cj == NULL) return 0; + if (ci->gparts <= cj->gparts && + ci->gparts + ci->gcount >= cj->gparts + cj->gcount) { + return cj->gcount; + } else if (cj->gparts <= ci->gparts && + cj->gparts + cj->gcount >= ci->gparts + ci->gcount) { + return ci->gcount; + } + return 0; +} + +/** + * @brief Returns the #task_actions for a given task. + * + * @param t The #task. + */ +enum task_actions task_acts_on(const struct task *t) { + + switch (t->type) { + + case task_type_none: + return task_action_none; + break; + + case task_type_sort: + case task_type_ghost: + return task_action_part; + break; + + case task_type_self: + case task_type_pair: + case task_type_sub_self: + case task_type_sub_pair: + switch (t->subtype) { + + case task_subtype_density: + case task_subtype_force: + return task_action_part; + break; + + case task_subtype_grav: + return task_action_gpart; + break; + + default: + error("Unknow task_action for task"); + return task_action_none; + break; + } + break; + + case task_type_init: + case task_type_drift: + case task_type_kick: + case task_type_kick_fixdt: + case task_type_send: + case task_type_recv: + return task_action_all; + break; + + case task_type_grav_gather_m: + case task_type_grav_fft: + case task_type_grav_mm: + case task_type_grav_up: + return task_action_multipole; + break; + + case task_type_grav_external: + return task_action_gpart; + break; + + case task_type_part_sort: + case task_type_gpart_sort: + case task_type_split_cell: + case task_type_rewait: + return task_action_none; + break; + + default: + error("Unknow task_action for task"); + return task_action_none; + break; + } +} + /** * @brief Compute the Jaccard similarity of the data used by two * different tasks. @@ -79,29 +168,63 @@ size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { * @param tb The second #task. */ float task_overlap(const struct task *ta, const struct task *tb) { + + if (ta == NULL || tb == NULL) return 0.f; + + const enum task_actions ta_act = task_acts_on(ta); + const enum task_actions tb_act = task_acts_on(tb); + /* First check if any of the two tasks are of a type that don't use cells. */ - if (ta == NULL || tb == NULL || ta->type == task_type_none || - ta->type == task_type_part_sort || ta->type == task_type_gpart_sort || - ta->type == task_type_split_cell || ta->type == task_type_rewait || - tb->type == task_type_none || tb->type == task_type_part_sort || - tb->type == task_type_gpart_sort || tb->type == task_type_split_cell || - tb->type == task_type_rewait) - return 0.0f; - - /* Compute the union of the cell data. */ - size_t size_union = 0; - if (ta->ci != NULL) size_union += ta->ci->count; - if (ta->cj != NULL) size_union += ta->cj->count; - if (tb->ci != NULL) size_union += tb->ci->count; - if (tb->cj != NULL) size_union += tb->cj->count; - - /* Compute the intersection of the cell data. */ - const size_t size_intersect = - task_cell_overlap(ta->ci, tb->ci) + task_cell_overlap(ta->ci, tb->cj) + - task_cell_overlap(ta->cj, tb->ci) + task_cell_overlap(ta->cj, tb->cj); - - return ((float)size_intersect) / (size_union - size_intersect); + if (ta_act == task_action_none || tb_act == task_action_none) return 0.f; + + const int ta_part = (ta_act == task_action_part || ta_act == task_action_all); + const int ta_gpart = + (ta_act == task_action_gpart || ta_act == task_action_all); + const int tb_part = (tb_act == task_action_part || tb_act == task_action_all); + const int tb_gpart = + (tb_act == task_action_gpart || tb_act == task_action_all); + + /* In the case where both tasks act on parts */ + if (ta_part && tb_part) { + + /* Compute the union of the cell data. */ + size_t size_union = 0; + if (ta->ci != NULL) size_union += ta->ci->count; + if (ta->cj != NULL) size_union += ta->cj->count; + if (tb->ci != NULL) size_union += tb->ci->count; + if (tb->cj != NULL) size_union += tb->cj->count; + + /* Compute the intersection of the cell data. */ + const size_t size_intersect = task_cell_overlap_part(ta->ci, tb->ci) + + task_cell_overlap_part(ta->ci, tb->cj) + + task_cell_overlap_part(ta->cj, tb->ci) + + task_cell_overlap_part(ta->cj, tb->cj); + + return ((float)size_intersect) / (size_union - size_intersect); + } + + /* In the case where both tasks act on gparts */ + else if (ta_gpart && tb_gpart) { + + /* Compute the union of the cell data. */ + size_t size_union = 0; + if (ta->ci != NULL) size_union += ta->ci->gcount; + if (ta->cj != NULL) size_union += ta->cj->gcount; + if (tb->ci != NULL) size_union += tb->ci->gcount; + if (tb->cj != NULL) size_union += tb->cj->gcount; + + /* Compute the intersection of the cell data. */ + const size_t size_intersect = task_cell_overlap_gpart(ta->ci, tb->ci) + + task_cell_overlap_gpart(ta->ci, tb->cj) + + task_cell_overlap_gpart(ta->cj, tb->ci) + + task_cell_overlap_gpart(ta->cj, tb->cj); + + return ((float)size_intersect) / (size_union - size_intersect); + } + + /* Else, no overlap */ + return 0.f; } /** diff --git a/src/task.h b/src/task.h index 581af55e561fb61fad788c78c20ccc986c27821b..ee49568b143282b9e3025f6d2bc81ded04ffee41 100644 --- a/src/task.h +++ b/src/task.h @@ -70,6 +70,16 @@ enum task_subtypes { task_subtype_count }; +/* The kind of action the task perform */ +enum task_actions { + task_action_none, + task_action_part, + task_action_gpart, + task_action_all, + task_action_multipole, + task_action_count +}; + extern const char *subtaskID_names[]; /* Data of a task. */ @@ -102,5 +112,6 @@ int task_lock(struct task *t); void task_print_mask(unsigned int mask); void task_print_submask(unsigned int submask); void task_do_rewait(struct task *t); +enum task_actions task_acts_on(const struct task *t); #endif /* SWIFT_TASK_H */