Skip to content

Commit

Permalink
group: refactor MPIR_Group
Browse files Browse the repository at this point in the history
* add option to use stride to describe group composition
* remove the linked list design
  • Loading branch information
hzhou committed Dec 10, 2024
1 parent 4a577f1 commit 19292d6
Show file tree
Hide file tree
Showing 4 changed files with 317 additions and 631 deletions.
102 changes: 66 additions & 36 deletions src/include/mpir_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@
* MPI_Group_intersection) and for the scalable RMA synchronization
*---------------------------------------------------------------------------*/

/* Abstract the integer type for lpid (process id). It is possible to use 32-bit
* in principle, but 64-bit is simpler since we can trivially combine
* (world_idx, world_rank).
*/
typedef uint64_t MPIR_Lpid;

/* This structure is used to implement the group operations such as
MPI_Group_translate_ranks */
/* note: next_lpid (with idx_of_first_lpid in MPIR_Group) gives a linked list
* in a sorted lpid ascending order */
typedef struct MPII_Group_pmap_t {
MPIR_Lpid lpid; /* local process id, from VCONN */
int next_lpid; /* Index of next lpid (in lpid order) */
} MPII_Group_pmap_t;

/* Any changes in the MPIR_Group structure must be made to the
predefined value in MPIR_Group_builtin for MPI_GROUP_EMPTY in
src/mpi/group/grouputil.c */
/*S
MPIR_Group - Description of the Group data structure
Expand Down Expand Up @@ -60,22 +42,75 @@ typedef struct MPII_Group_pmap_t {
Group-DS
S*/

/* Abstract the integer type for lpid (process id). It is possible to use 32-bit
* in principle, but 64-bit is simpler since we can trivially combine
* (world_idx, world_rank).
*/
typedef uint64_t MPIR_Lpid;

struct MPIR_Pmap {
int size; /* same as group->size, duplicate here so Pmap is logically complete */
bool use_map;
union {
MPIR_Lpid *map;
struct {
MPIR_Lpid offset;
MPIR_Lpid stride;
MPIR_Lpid blocksize;
} stride;
} u;
};

MPL_STATIC_INLINE_PREFIX MPIR_Lpid MPIR_Pmap_rank_to_lpid(struct MPIR_Pmap *pmap, int rank)
{
if (rank >= 0 && rank < pmap->size) {
return MPI_UNDEFINED;
}

if (pmap->use_map) {
return pmap->u.map[rank];
} else {
MPIR_Lpid i_blk = rank / pmap->u.stride.blocksize;
MPIR_Lpid r_blk = rank % pmap->u.stride.blocksize;
return pmap->u.stride.offset + i_blk * pmap->u.stride.stride + r_blk;
}
}

MPL_STATIC_INLINE_PREFIX int MPIR_Pmap_lpid_to_rank(struct MPIR_Pmap *pmap, MPIR_Lpid lpid)
{
if (pmap->use_map) {
/* linear search */
for (int rank = 0; rank < pmap->size; rank++) {
if (pmap->u.map[rank] == lpid) {
return rank;
}
}
return MPI_UNDEFINED;
} else {
lpid -= pmap->u.stride.offset;
MPIR_Lpid i_blk = lpid / pmap->u.stride.stride;
MPIR_Lpid r_blk = lpid % pmap->u.stride.stride;

if (r_blk >= pmap->u.stride.blocksize) {
return MPI_UNDEFINED;
}

int rank = i_blk * pmap->u.stride.blocksize + r_blk;
if (rank >= 0 && rank < pmap->size) {
return rank;
} else {
return MPI_UNDEFINED;
}
}
}

struct MPIR_Group {
MPIR_OBJECT_HEADER; /* adds handle and ref_count fields */
int size; /* Size of a group */
int rank; /* rank of this process relative to this
* group */
int idx_of_first_lpid;
MPII_Group_pmap_t *lrank_to_lpid; /* Array mapping a local rank to local
* process number */
int is_local_dense_monotonic; /* see NOTE-G1 */

/* We may want some additional data for the RMA syncrhonization calls */
/* Other, device-specific information */
#ifdef MPID_DEV_GROUP_DECL
MPID_DEV_GROUP_DECL
#endif
MPIR_Session * session_ptr; /* Pointer to session to which this group belongs */
int rank; /* rank of this process relative to this group */
struct MPIR_Pmap pmap;
MPIR_Session *session_ptr; /* Pointer to session to which this group belongs */
};

/* NOTE-G1: is_local_dense_monotonic will be true iff the group meets the
Expand Down Expand Up @@ -104,10 +139,8 @@ extern MPIR_Group *const MPIR_Group_empty;
#define MPIR_Group_release_ref(_group, _inuse) \
do { MPIR_Object_release_ref(_group, _inuse); } while (0)

void MPII_Group_setup_lpid_list(MPIR_Group *);
int MPIR_Group_check_valid_ranks(MPIR_Group *, const int[], int);
int MPIR_Group_check_valid_ranges(MPIR_Group *, int[][3], int);
void MPIR_Group_setup_lpid_pairs(MPIR_Group *, MPIR_Group *);
int MPIR_Group_create(int, MPIR_Group **);
int MPIR_Group_release(MPIR_Group * group_ptr);

Expand All @@ -122,7 +155,4 @@ int MPIR_Group_check_subset(MPIR_Group * group_ptr, MPIR_Comm * comm_ptr);
void MPIR_Group_set_session_ptr(MPIR_Group * group_ptr, MPIR_Session * session_out);
int MPIR_Group_init(void);

/* internal functions */
void MPII_Group_setup_lpid_list(MPIR_Group *);

#endif /* MPIR_GROUP_H_INCLUDED */
3 changes: 0 additions & 3 deletions src/mpi/comm/comm_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ int MPII_Comm_create_calculate_mapping(MPIR_Group * group_ptr,
* exactly the same as the ranks in comm world.
*/

/* we examine the group's lpids in both the intracomm and non-comm_world cases */
MPII_Group_setup_lpid_list(group_ptr);

/* Optimize for groups contained within MPI_COMM_WORLD. */
if (comm_ptr->comm_kind == MPIR_COMM_KIND__INTRACOMM) {
int wsize;
Expand Down
Loading

0 comments on commit 19292d6

Please sign in to comment.