292d185c30
- Use opal hash table instead of list for group lookup. - Code cleanup/refactoring. Group cache is now a part of the proc_group. Signed-off-by: Alex Mikheev <alexm@mellanox.com>
324 строки
9.4 KiB
C
324 строки
9.4 KiB
C
/*
|
|
* Copyright (c) 2013-2018 Mellanox Technologies, Inc.
|
|
* All rights reserved.
|
|
* Copyright (c) 2016 Research Organization for Information Science
|
|
* and Technology (RIST). All rights reserved.
|
|
* Copyright (c) 2017 Cisco Systems, Inc. All rights reserved
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
#ifndef OSHMEM_PROC_PROC_H
|
|
#define OSHMEM_PROC_PROC_H
|
|
|
|
#include "oshmem_config.h"
|
|
#include "oshmem/types.h"
|
|
#include "oshmem/constants.h"
|
|
|
|
#include "opal/class/opal_list.h"
|
|
#include "opal/util/proc.h"
|
|
#include "opal/dss/dss_types.h"
|
|
#include "opal/mca/hwloc/hwloc-internal.h"
|
|
|
|
#include "orte/types.h"
|
|
#include "orte/runtime/orte_globals.h"
|
|
|
|
#include "ompi/proc/proc.h"
|
|
#include "ompi/communicator/communicator.h"
|
|
|
|
#include "oshmem/mca/scoll/scoll.h"
|
|
#include "oshmem/runtime/runtime.h"
|
|
#include "oshmem/shmem/shmem_api_logger.h"
|
|
|
|
BEGIN_C_DECLS
|
|
|
|
/* ******************************************************************** */
|
|
|
|
struct oshmem_group_t;
|
|
|
|
#define OSHMEM_PE_INVALID (-1)
|
|
|
|
/* This struct will be copied into the padding field of an ompi_proc_t
|
|
* so the size of oshmem_proc_data_t must be less or equal than
|
|
* OMPI_PROC_PADDING_SIZE */
|
|
struct oshmem_proc_data_t {
|
|
char * transport_ids;
|
|
int num_transports;
|
|
};
|
|
|
|
typedef struct oshmem_proc_data_t oshmem_proc_data_t;
|
|
|
|
#define OSHMEM_PROC_DATA(proc) \
|
|
((oshmem_proc_data_t *)(proc)->padding)
|
|
|
|
/**
|
|
* Group of Open SHMEM processes structure
|
|
*
|
|
* Set of processes used in collective operations.
|
|
*/
|
|
struct oshmem_group_t {
|
|
opal_object_t base;
|
|
int id; /**< index in global array */
|
|
int my_pe;
|
|
int proc_count; /**< number of processes in group */
|
|
int is_member; /* true if my_pe is part of the group, participate in collectives */
|
|
struct ompi_proc_t **proc_array; /**< list of pointers to ompi_proc_t structures
|
|
for each process in the group */
|
|
opal_list_t peer_list;
|
|
|
|
/* Collectives module interface and data */
|
|
mca_scoll_base_group_scoll_t g_scoll;
|
|
ompi_communicator_t* ompi_comm;
|
|
};
|
|
typedef struct oshmem_group_t oshmem_group_t;
|
|
OSHMEM_DECLSPEC OBJ_CLASS_DECLARATION(oshmem_group_t);
|
|
|
|
OSHMEM_DECLSPEC extern oshmem_group_t* oshmem_group_all;
|
|
OSHMEM_DECLSPEC extern oshmem_group_t* oshmem_group_self;
|
|
OSHMEM_DECLSPEC extern oshmem_group_t* oshmem_group_null;
|
|
|
|
|
|
/* ******************************************************************** */
|
|
|
|
/**
|
|
* Initialize the OSHMEM process subsystem
|
|
*
|
|
* Initialize the Open SHMEM process subsystem. This function will
|
|
* query the run-time environment and build a list of the proc
|
|
* instances in the current pe set. The local information not
|
|
* easily determined by the run-time ahead of time (architecture and
|
|
* hostname) will be published during this call.
|
|
*
|
|
* @note While an ompi_proc_t will exist with mostly valid information
|
|
* for each process in the pe set at the conclusion of this
|
|
* call, some information will not be immediately available. This
|
|
* includes the architecture and hostname, which will be available by
|
|
* the conclusion of the stage gate.
|
|
*
|
|
* @retval OSHMEM_SUCESS System successfully initialized
|
|
* @retval OSHMEM_ERROR Initialization failed due to unspecified error
|
|
*/
|
|
OSHMEM_DECLSPEC int oshmem_proc_init(void);
|
|
|
|
/**
|
|
* Finalize the OSHMEM Process subsystem
|
|
*
|
|
* Finalize the Open SHMEM process subsystem. This function will
|
|
* release all memory created during the life of the application,
|
|
* including all ompi_proc_t structures.
|
|
*
|
|
* @retval OSHMEM_SUCCESS System successfully finalized
|
|
*/
|
|
OSHMEM_DECLSPEC int oshmem_proc_finalize(void);
|
|
|
|
/**
|
|
* Returns a pointer to the local process
|
|
*
|
|
* Returns a pointer to the local process. Unlike oshmem_proc_self(),
|
|
* the reference count on the local proc instance is not modified by
|
|
* this function.
|
|
*
|
|
* @return Pointer to the local process structure
|
|
*/
|
|
static inline ompi_proc_t *oshmem_proc_local(void)
|
|
{
|
|
return (ompi_proc_t *)ompi_proc_local_proc;
|
|
}
|
|
|
|
/**
|
|
* Returns the proc instance for a given name
|
|
*
|
|
* Returns the proc instance for the specified process name. The
|
|
* reference count for the proc instance is not incremented by this
|
|
* function.
|
|
*
|
|
* @param[in] name The process name to look for
|
|
*
|
|
* @return Pointer to the process instance for \c name
|
|
*/
|
|
static inline ompi_proc_t *oshmem_proc_for_find(const orte_process_name_t name)
|
|
{
|
|
return (ompi_proc_t *)ompi_proc_for_name(name);
|
|
}
|
|
|
|
static inline ompi_proc_t *oshmem_proc_find(int pe)
|
|
{
|
|
orte_process_name_t name;
|
|
|
|
name.jobid = ORTE_PROC_MY_NAME->jobid;
|
|
name.vpid = pe;
|
|
return oshmem_proc_for_find(name);
|
|
}
|
|
|
|
static inline int oshmem_proc_pe(ompi_proc_t *proc)
|
|
{
|
|
return (proc ? (int) ((orte_process_name_t*)&proc->super.proc_name)->vpid : -1);
|
|
}
|
|
|
|
#define OSHMEM_PROC_JOBID(PROC) (((orte_process_name_t*)&((PROC)->super.proc_name))->jobid)
|
|
#define OSHMEM_PROC_VPID(PROC) (((orte_process_name_t*)&((PROC)->super.proc_name))->vpid)
|
|
|
|
/**
|
|
* Initialize the OSHMEM process predefined groups
|
|
*
|
|
* Initialize the Open SHMEM process predefined groups. This function will
|
|
* query the run-time environment and build a list of the proc
|
|
* instances in the current pe set. The local information not
|
|
* easily determined by the run-time ahead of time (architecture and
|
|
* hostname) will be published during this call.
|
|
*
|
|
* @note This is primarily used once during SHMEM setup.
|
|
*
|
|
* @retval OSHMEM_SUCESS System successfully initialized
|
|
* @retval OSHMEM_ERROR Initialization failed due to unspecified error
|
|
*/
|
|
OSHMEM_DECLSPEC int oshmem_proc_group_init(void);
|
|
|
|
/**
|
|
* Finalize the OSHMEM process predefined groups
|
|
*
|
|
* @retval OSHMEM_SUCESS System successfully initialized
|
|
* @retval OSHMEM_ERROR Initialization failed due to unspecified error
|
|
*/
|
|
OSHMEM_DECLSPEC int oshmem_proc_group_finalize(void);
|
|
|
|
/**
|
|
* Release collectives used by the groups. The function
|
|
* must be called prior to the oshmem_proc_group_finalize()
|
|
*/
|
|
OSHMEM_DECLSPEC void oshmem_proc_group_finalize_scoll(void);
|
|
|
|
/**
|
|
* Create processes group.
|
|
*
|
|
* Returns the list of known proc instances located in this group.
|
|
*
|
|
* @param[in] pe_start The lowest PE in the active set.
|
|
* @param[in] pe_stride The log (base 2) of the stride between consecutive
|
|
* PEs in the active set.
|
|
* @param[in] pe_size The number of PEs in the active set.
|
|
*
|
|
* @return Array of pointers to proc instances in the current
|
|
* known universe, or NULL if there is an internal failure.
|
|
*/
|
|
OSHMEM_DECLSPEC oshmem_group_t *oshmem_proc_group_create(int pe_start,
|
|
int pe_stride,
|
|
int pe_size);
|
|
|
|
/**
|
|
* same as above but abort on failure
|
|
*/
|
|
static inline oshmem_group_t *
|
|
oshmem_proc_group_create_nofail(int pe_start, int pe_stride, int pe_size)
|
|
{
|
|
oshmem_group_t *group;
|
|
|
|
group = oshmem_proc_group_create(pe_start, pe_stride, pe_size);
|
|
if (NULL == group) {
|
|
goto fatal;
|
|
}
|
|
return group;
|
|
|
|
fatal:
|
|
SHMEM_API_ERROR("Failed to create group (%d,%d,%d)",
|
|
pe_start, pe_stride, pe_size);
|
|
oshmem_shmem_abort(-1);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* Destroy processes group.
|
|
*
|
|
*/
|
|
OSHMEM_DECLSPEC void oshmem_proc_group_destroy(oshmem_group_t* group);
|
|
|
|
static inline ompi_proc_t *oshmem_proc_group_all(int pe)
|
|
{
|
|
return oshmem_group_all->proc_array[pe];
|
|
}
|
|
|
|
static inline ompi_proc_t *oshmem_proc_group_find(oshmem_group_t* group,
|
|
int pe)
|
|
{
|
|
int i = 0;
|
|
ompi_proc_t* proc = NULL;
|
|
|
|
if (OPAL_LIKELY(group)) {
|
|
if (OPAL_LIKELY(group == oshmem_group_all)) {
|
|
/* To improve performance use direct index. It is feature of oshmem_group_all */
|
|
proc = group->proc_array[pe];
|
|
} else {
|
|
for (i = 0; i < group->proc_count; i++) {
|
|
if (pe == oshmem_proc_pe(group->proc_array[i])) {
|
|
proc = group->proc_array[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
orte_process_name_t name;
|
|
|
|
name.jobid = ORTE_PROC_MY_NAME->jobid;
|
|
name.vpid = pe;
|
|
proc = oshmem_proc_for_find(name);
|
|
}
|
|
|
|
return proc;
|
|
}
|
|
|
|
static inline int oshmem_proc_group_find_id(oshmem_group_t* group, int pe)
|
|
{
|
|
int i = 0;
|
|
int id = -1;
|
|
|
|
if (group) {
|
|
for (i = 0; i < group->proc_count; i++) {
|
|
if (pe == oshmem_proc_pe(group->proc_array[i])) {
|
|
id = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
static inline int oshmem_proc_group_is_member(oshmem_group_t *group)
|
|
{
|
|
return group->is_member;
|
|
}
|
|
|
|
static inline int oshmem_num_procs(void)
|
|
{
|
|
return (oshmem_group_all ?
|
|
oshmem_group_all->proc_count : (int)opal_list_get_size(&ompi_proc_list));
|
|
}
|
|
|
|
static inline int oshmem_my_proc_id(void)
|
|
{
|
|
return oshmem_group_self->my_pe;
|
|
}
|
|
|
|
static inline int oshmem_get_transport_id(int pe)
|
|
{
|
|
ompi_proc_t *proc;
|
|
|
|
proc = oshmem_proc_group_find(oshmem_group_all, pe);
|
|
|
|
return (int) OSHMEM_PROC_DATA(proc)->transport_ids[0];
|
|
}
|
|
|
|
static inline int oshmem_get_transport_count(int pe)
|
|
{
|
|
ompi_proc_t *proc;
|
|
proc = oshmem_proc_group_find(oshmem_group_all, pe);
|
|
return OSHMEM_PROC_DATA(proc)->num_transports;
|
|
}
|
|
|
|
END_C_DECLS
|
|
|
|
#endif /* OSHMEM_PROC_PROC_H */
|