/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*
*/
#ifndef MPIR_GROUP_H_INCLUDED
#define MPIR_GROUP_H_INCLUDED
/*---------------------------------------------------------------------------
* Groups are *not* a major data structure in MPICH-2. They are provided
* only because they are required for the group operations (e.g.,
* MPI_Group_intersection) and for the scalable RMA synchronization
*---------------------------------------------------------------------------*/
/* This structure is used to implement the group operations such as
MPI_Group_translate_ranks */
typedef struct MPII_Group_pmap_t {
int lpid; /* local process id, from VCONN */
int next_lpid; /* Index of next lpid (in lpid order) */
int flag; /* marker, used to implement group operations */
} 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
The processes in the group of 'MPI_COMM_WORLD' have lpid values 0 to 'size'-1,
where 'size' is the size of 'MPI_COMM_WORLD'. Processes created by
'MPI_Comm_spawn' or 'MPI_Comm_spawn_multiple' or added by 'MPI_Comm_attach'
or
'MPI_Comm_connect'
are numbered greater than 'size - 1' (on the calling process). See the
discussion of LocalPID values.
Note that when dynamic process creation is used, the pids are `not` unique
across the universe of connected MPI processes. This is ok, as long as
pids are interpreted `only` on the process that owns them.
Only for MPI-1 are the lpid''s equal to the `global` pids. The local pids
can be thought of as a reference not to the remote process itself, but
how the remote process can be reached from this process. We may want to
have a structure 'MPID_Lpid_t' that contains information on the remote
process, such as (for TCP) the hostname, ip address (it may be different if
multiple interfaces are supported; we may even want plural ip addresses for
stripping communication), and port (or ports). For shared memory connected
processes, it might have the address of a remote queue. The lpid number
is an index into a table of 'MPID_Lpid_t'''s that contain this (device- and
method-specific) information.
Module:
Group-DS
S*/
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
};
/* NOTE-G1: is_local_dense_monotonic will be true iff the group meets the
* following criteria:
* 1) the lpids are all in the range [0,size-1], i.e. a subset of comm world
* 2) the pids are sequentially numbered in increasing order, without any gaps,
* stride, or repetitions
*
* This additional information allows us to handle the common case (insofar as
* group ops are common) for MPI_Group_translate_ranks where group2 is
* group_of(MPI_COMM_WORLD), or some simple subset. This is an important use
* case for many MPI tool libraries, such as Scalasca.
*/
extern MPIR_Object_alloc_t MPIR_Group_mem;
/* Preallocated group objects */
#define MPIR_GROUP_N_BUILTIN 1
extern MPIR_Group MPIR_Group_builtin[MPIR_GROUP_N_BUILTIN];
extern MPIR_Group MPIR_Group_direct[];
/* Object for empty group */
extern MPIR_Group *const MPIR_Group_empty;
#define MPIR_Group_add_ref(_group) \
do { MPIR_Object_add_ref(_group); } while (0)
#define MPIR_Group_release_ref(_group, _inuse) \
do { MPIR_Object_release_ref(_group, _inuse); } while (0)
int MPIR_Group_create(int, MPIR_Group **);
int MPIR_Group_release(MPIR_Group * group_ptr);
int MPIR_Group_compare_impl(MPIR_Group * group_ptr1, MPIR_Group * group_ptr2, int *result);
int MPIR_Group_difference_impl(MPIR_Group * group_ptr1, MPIR_Group * group_ptr2,
MPIR_Group ** new_group_ptr);
int MPIR_Group_excl_impl(MPIR_Group * group_ptr, int n, const int *ranks,
MPIR_Group ** new_group_ptr);
int MPIR_Group_free_impl(MPIR_Group * group_ptr);
int MPIR_Group_incl_impl(MPIR_Group * group_ptr, int n, const int *ranks,
MPIR_Group ** new_group_ptr);
int MPIR_Group_intersection_impl(MPIR_Group * group_ptr1, MPIR_Group * group_ptr2,
MPIR_Group ** new_group_ptr);
int MPIR_Group_range_excl_impl(MPIR_Group * group_ptr, int n, int ranges[][3],
MPIR_Group ** new_group_ptr);
int MPIR_Group_range_incl_impl(MPIR_Group * group_ptr, int n, int ranges[][3],
MPIR_Group ** new_group_ptr);
int MPIR_Group_translate_ranks_impl(MPIR_Group * group_ptr1, int n, const int *ranks1,
MPIR_Group * group_ptr2, int *ranks2);
int MPIR_Group_union_impl(MPIR_Group * group_ptr1, MPIR_Group * group_ptr2,
MPIR_Group ** new_group_ptr);
int MPIR_Group_check_subset(MPIR_Group * group_ptr, MPIR_Comm * comm_ptr);
int MPIR_Group_init(void);
/* internal functions */
void MPII_Group_setup_lpid_list(MPIR_Group *);
#endif /* MPIR_GROUP_H_INCLUDED */