2004-01-10 01:09:51 +03:00
|
|
|
/*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-01-10 11:20:15 +03:00
|
|
|
#ifndef LAM_COMMUNICATOR_H
|
|
|
|
#define LAM_COMMUNICATOR_H
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "lfc/lam_object.h"
|
2004-03-19 03:00:09 +03:00
|
|
|
#include "errhandler/errhandler.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "threads/mutex.h"
|
|
|
|
#include "util/output.h"
|
2004-01-11 03:13:22 +03:00
|
|
|
#include "mpi.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "group/group.h"
|
|
|
|
#include "mca/coll/coll.h"
|
2004-04-17 00:54:48 +04:00
|
|
|
#include "mca/topo/topo.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "lfc/lam_hash_table.h"
|
2004-03-26 23:02:42 +03:00
|
|
|
#include "attribute/attribute.h"
|
2004-02-06 07:20:13 +03:00
|
|
|
|
2004-02-13 16:56:55 +03:00
|
|
|
extern lam_class_t lam_communicator_t_class;
|
|
|
|
|
2004-03-26 23:02:42 +03:00
|
|
|
#define LAM_COMM_INTER 0x00000001
|
|
|
|
#define LAM_COMM_CART 0x00000002
|
|
|
|
#define LAM_COMM_GRAPH 0x00000004
|
|
|
|
#define LAM_COMM_NAMEISSET 0x00000008
|
|
|
|
#define LAM_COMM_ISFREED 0x00000010
|
2004-02-13 16:56:55 +03:00
|
|
|
|
2004-04-21 04:16:05 +04:00
|
|
|
/* some utility #defines */
|
|
|
|
#define LAM_COMM_IS_INTER(comm) ((comm)->c_flags & LAM_COMM_INTER)
|
|
|
|
#define LAM_COMM_IS_INTRA(comm) (!((comm)->c_flags & LAM_COMM_INTER))
|
|
|
|
#define LAM_COMM_IS_CART(comm) ((comm)->c_flags & LAM_COMM_CART)
|
|
|
|
#define LAM_COMM_IS_GRAPH(comm) ((comm)->c_flags & LAM_COMM_GRAPH)
|
|
|
|
|
2004-03-26 23:02:42 +03:00
|
|
|
/* modes reqquired for accquiring the new comm-id */
|
|
|
|
#define LAM_COMM_INTRA_INTRA 0x00000020
|
|
|
|
#define LAM_COMM_INTRA_INTER 0x00000040
|
|
|
|
#define LAM_COMM_INTER_INTRA 0x00000080
|
|
|
|
#define LAM_COMM_INTER_INTER 0x00000100
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-03-26 23:02:42 +03:00
|
|
|
struct lam_communicator_t {
|
|
|
|
lam_object_t c_base;
|
|
|
|
char c_name[MPI_MAX_OBJECT_NAME];
|
|
|
|
uint32_t c_contextid;
|
|
|
|
int c_my_rank;
|
|
|
|
uint32_t c_flags; /* flags, e.g. intercomm,
|
|
|
|
topology, etc. */
|
|
|
|
|
|
|
|
lam_group_t *c_local_group;
|
|
|
|
lam_group_t *c_remote_group;
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-01-10 11:20:15 +03:00
|
|
|
/* Attributes */
|
2004-03-26 23:02:42 +03:00
|
|
|
lam_hash_table_t *c_keyhash;
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-04-21 04:16:05 +04:00
|
|
|
int c_cube_dim; /**< inscribing cube dimension */
|
|
|
|
|
2004-04-17 00:54:48 +04:00
|
|
|
/* Hooks for topo module to hang things */
|
|
|
|
mca_topo_1_0_0_t c_topo; /**< structure of function pointers */
|
|
|
|
mca_topo_comm_t *c_topo_comm; /**<structure containing information
|
|
|
|
*about the topology */
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-03-19 03:00:09 +03:00
|
|
|
/* index in Fortran <-> C translation array */
|
|
|
|
|
|
|
|
int c_f_to_c_index;
|
|
|
|
|
2004-03-19 09:12:43 +03:00
|
|
|
/* Error handling. This field does not have the "c_" prefix so
|
|
|
|
that the LAM_ERRHDL_* macros can find it, regardless of whether
|
|
|
|
it's a comm, window, or file. */
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-03-19 09:12:43 +03:00
|
|
|
lam_errhandler_t *error_handler;
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-01-10 11:20:15 +03:00
|
|
|
/* Hooks for PML to hang things */
|
2004-01-14 20:40:12 +03:00
|
|
|
struct mca_pml_comm_t* c_pml_comm;
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-01-10 11:20:15 +03:00
|
|
|
/* Hooks for collectives to hang things */
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-01-12 00:32:57 +03:00
|
|
|
mca_coll_1_0_0_t c_coll;
|
2004-01-10 11:20:15 +03:00
|
|
|
struct mca_coll_comm_t* c_coll_comm;
|
2004-01-10 20:05:04 +03:00
|
|
|
};
|
|
|
|
typedef struct lam_communicator_t lam_communicator_t;
|
2004-01-10 01:09:51 +03:00
|
|
|
|
2004-01-11 02:12:43 +03:00
|
|
|
|
2004-03-17 00:56:19 +03:00
|
|
|
/**
|
|
|
|
* is this a valid communicator
|
|
|
|
*/
|
|
|
|
static inline int lam_comm_invalid(lam_communicator_t* comm)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2004-03-03 19:44:41 +03:00
|
|
|
/**
|
|
|
|
* rank w/in the communicator
|
|
|
|
*/
|
|
|
|
static inline int lam_comm_rank(lam_communicator_t* comm)
|
|
|
|
{
|
|
|
|
return comm->c_my_rank;
|
|
|
|
}
|
2004-03-12 01:02:01 +03:00
|
|
|
/**
|
|
|
|
* size of the communicator
|
|
|
|
*/
|
|
|
|
static inline int lam_comm_size(lam_communicator_t* comm)
|
|
|
|
{
|
2004-03-26 23:02:42 +03:00
|
|
|
return comm->c_local_group->grp_proc_count;
|
2004-03-12 01:02:01 +03:00
|
|
|
}
|
|
|
|
|
2004-03-26 23:02:42 +03:00
|
|
|
/**
|
|
|
|
* size of the remote group for inter-communicators.
|
|
|
|
* returns zero for an intra-communicator
|
|
|
|
*/
|
|
|
|
static inline int lam_comm_remote_size(lam_communicator_t* comm)
|
|
|
|
{
|
|
|
|
if ( comm->c_flags & LAM_COMM_INTER )
|
|
|
|
return comm->c_remote_group->grp_proc_count;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
2004-03-03 19:44:41 +03:00
|
|
|
|
2004-01-11 02:12:43 +03:00
|
|
|
/* return pointer to communicator associated with context id cid,
|
|
|
|
* No error checking is done*/
|
2004-01-12 21:47:12 +03:00
|
|
|
static inline lam_communicator_t *lam_comm_lookup(uint32_t cid)
|
2004-01-11 02:12:43 +03:00
|
|
|
{
|
|
|
|
/* array of pointers to communicators, indexed by context ID */
|
2004-03-12 01:02:01 +03:00
|
|
|
extern lam_pointer_array_t lam_mpi_communicators;
|
|
|
|
return (lam_communicator_t*)lam_pointer_array_get_item(&lam_mpi_communicators, cid);
|
2004-01-11 02:12:43 +03:00
|
|
|
}
|
|
|
|
|
2004-03-17 00:56:19 +03:00
|
|
|
static inline lam_proc_t* lam_comm_peer_lookup(lam_communicator_t* comm, int peer_id)
|
2004-01-12 21:47:12 +03:00
|
|
|
{
|
2004-02-13 08:38:24 +03:00
|
|
|
#if LAM_ENABLE_DEBUG
|
2004-02-12 01:55:06 +03:00
|
|
|
if(peer_id >= comm->c_remote_group->grp_proc_count) {
|
2004-01-29 01:52:51 +03:00
|
|
|
lam_output(0, "lam_comm_lookup_peer: invalid peer index (%d)", peer_id);
|
2004-01-12 21:47:12 +03:00
|
|
|
return (lam_proc_t *) NULL;
|
2004-01-29 01:52:51 +03:00
|
|
|
}
|
2004-01-12 21:47:12 +03:00
|
|
|
#endif
|
2004-02-12 01:55:06 +03:00
|
|
|
return comm->c_remote_group->grp_proc_pointers[peer_id];
|
2004-01-12 21:47:12 +03:00
|
|
|
}
|
|
|
|
|
2004-03-17 00:56:19 +03:00
|
|
|
static inline bool lam_comm_peer_invalid(lam_communicator_t* comm, int peer_id)
|
|
|
|
{
|
|
|
|
if(peer_id < 0 || peer_id >= comm->c_remote_group->grp_proc_count) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-04-21 04:16:05 +04:00
|
|
|
static inline int lam_cube_dim(int nprocs) {
|
|
|
|
int dim;
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
if (1 > nprocs) return LAM_ERROR;
|
2004-04-22 00:55:54 +04:00
|
|
|
for(dim = 0, size = 1; size < (size_t)nprocs; ++dim, size <<= 1);
|
2004-04-21 04:16:05 +04:00
|
|
|
|
|
|
|
return dim;
|
|
|
|
}
|
2004-03-17 00:56:19 +03:00
|
|
|
|
2004-02-06 07:20:13 +03:00
|
|
|
|
2004-02-05 04:52:56 +03:00
|
|
|
#if defined(c_plusplus) || defined(__cplusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialise MPI_COMM_WORLD and MPI_COMM_SELF
|
|
|
|
*/
|
2004-02-13 16:56:55 +03:00
|
|
|
int lam_comm_init(void);
|
|
|
|
int lam_comm_link_function(void);
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* extract the local group from a communicator
|
|
|
|
*/
|
2004-03-28 18:24:43 +04:00
|
|
|
int lam_comm_group ( lam_communicator_t *comm, lam_group_t **group );
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* create a communicator based on a group
|
|
|
|
*/
|
2004-03-28 18:24:43 +04:00
|
|
|
int lam_comm_create ( lam_communicator_t* comm, lam_group_t *group,
|
|
|
|
lam_communicator_t** newcomm );
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* split a communicator based on color and key. Parameters
|
|
|
|
* are identical to the MPI-counterpart of the function.
|
|
|
|
*
|
|
|
|
* @param comm: input communicator
|
|
|
|
* @param color
|
|
|
|
* @param key
|
|
|
|
*
|
|
|
|
* @
|
|
|
|
*/
|
2004-03-28 18:24:43 +04:00
|
|
|
int lam_comm_split ( lam_communicator_t *comm, int color, int key,
|
|
|
|
lam_communicator_t** newcomm );
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* free a communicator
|
|
|
|
*/
|
2004-03-28 18:24:43 +04:00
|
|
|
int lam_comm_free ( lam_communicator_t **comm );
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* allocate a new communicator structure
|
|
|
|
* @param local_group_size
|
|
|
|
* @param remote_group_size
|
|
|
|
*
|
|
|
|
* this routine allocates the structure, the according local and
|
|
|
|
* remote groups, the proc-arrays in the local and remote group.
|
|
|
|
* It furthermore sets the fortran index correctly,
|
|
|
|
* and sets all other elements to zero.
|
|
|
|
*/
|
|
|
|
lam_communicator_t* lam_comm_allocate ( int local_group_size,
|
|
|
|
int remote_group_size );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* allocate new communicator ID
|
|
|
|
* @param mode: combination of input and output communicator
|
|
|
|
* LAM_COMM_INTRA_INTRA, LAM_COMM_INTRA_INTER,
|
|
|
|
* LAM_COMM_INTER_INTRA, LAM_COMM_INTER_INTER
|
|
|
|
*
|
|
|
|
* This routine has to be thread safe in the final version.
|
|
|
|
*/
|
2004-03-28 18:24:43 +04:00
|
|
|
int lam_comm_nextcid (lam_communicator_t* comm, int mode);
|
2004-03-26 23:02:42 +03:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* shut down the communicator infrastructure.
|
|
|
|
*/
|
|
|
|
int lam_comm_finalize (void);
|
2004-02-05 04:52:56 +03:00
|
|
|
#if defined(c_plusplus) || defined(__cplusplus)
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-01-10 01:09:51 +03:00
|
|
|
#endif /* LAM_COMMUNICATOR_H */
|