1
1
openmpi/oshmem/runtime/runtime.h

204 строки
7.0 KiB
C

/*
* Copyright (c) 2013 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/**
* @file
*
* Interface into the SHMEM portion of the Open SHMEM Run Time Environment
*/
#ifndef OSHMEM_SHMEM_RUNTIME_H
#define OSHMEM_SHMEM_RUNTIME_H
#include "oshmem_config.h"
#include "opal/class/opal_list.h"
#include "opal/class/opal_hash_table.h"
#include "orte/runtime/orte_globals.h"
BEGIN_C_DECLS
/* Global variables and symbols for the SHMEM layer */
/** Is oshmem initialized? */
OSHMEM_DECLSPEC extern bool oshmem_shmem_initialized;
/** Has oshmem been aborted **/
OSHMEM_DECLSPEC extern bool oshmem_shmem_aborted;
/** Do we have multiple threads? */
OSHMEM_DECLSPEC extern bool oshmem_mpi_thread_multiple;
/** Thread level requested to \c MPI_Init_thread() */
OSHMEM_DECLSPEC extern int oshmem_mpi_thread_requested;
/** Thread level provided by Open MPI */
OSHMEM_DECLSPEC extern int oshmem_mpi_thread_provided;
/** Identifier of the main thread */
OSHMEM_DECLSPEC extern struct opal_thread_t *oshmem_mpi_main_thread;
/*
* SHMEM_Init_thread constants
*/
enum {
SHMEM_THREAD_SINGLE,
SHMEM_THREAD_FUNNELED,
SHMEM_THREAD_SERIALIZED,
SHMEM_THREAD_MULTIPLE
};
/** Bitflags to be used for the modex exchange for the various thread
* levels. Required to support heterogeneous environments */
#define OSHMEM_THREADLEVEL_SINGLE_BF 0x00000001
#define OSHMEM_THREADLEVEL_FUNNELED_BF 0x00000002
#define OSHMEM_THREADLEVEL_SERIALIZED_BF 0x00000004
#define OSHMEM_THREADLEVEL_MULTIPLE_BF 0x00000008
#define OSHMEM_THREADLEVEL_SET_BITFLAG(threadlevelin,threadlevelout) { \
if ( SHMEM_THREAD_SINGLE == threadlevelin ) { \
threadlevelout |= OSHMEM_THREADLEVEL_SINGLE_BF; \
} else if ( SHMEM_THREAD_FUNNELED == threadlevelin ) { \
threadlevelout |= OSHMEM_THREADLEVEL_FUNNELED_BF; \
} else if ( SHMEM_THREAD_SERIALIZED == threadlevelin ) { \
threadlevelout |= OSHMEM_THREADLEVEL_SERIALIZED_BF; \
} else if ( SHMEM_THREAD_MULTIPLE == threadlevelin ) { \
threadlevelout |= OSHMEM_THREADLEVEL_MULTIPLE_BF; \
}}
#define OSHMEM_THREADLEVEL_IS_MULTIPLE(threadlevel) (threadlevel & OSHMEM_THREADLEVEL_MULTIPLE_BF)
/** In ompi_mpi_init: the lists of Fortran 90 mathing datatypes.
* We need these lists and hashtables in order to satisfy the new
* requirements introduced in MPI 2-1 Sect. 10.2.5,
* MPI_TYPE_CREATE_F90_xxxx, page 295, line 47.
*/
extern opal_hash_table_t ompi_mpi_f90_integer_hashtable;
extern opal_hash_table_t ompi_mpi_f90_real_hashtable;
extern opal_hash_table_t ompi_mpi_f90_complex_hashtable;
/** version string of ompi */
OSHMEM_DECLSPEC extern const char ompi_version_string[];
/**
* Initialize the Open SHMEM environment
*
* @param argc argc, typically from main() (IN)
* @param argv argv, typically from main() (IN)
* @param requested Thread support that is requested (IN)
* @param provided Thread support that is provided (OUT)
*
* @returns OSHMEM_SUCCESS if successful
* @returns Error code if unsuccessful
*
* Intialize all support code needed for SHMEM applications. This
* function should only be called by SHMEM applications (including
* singletons). If this function is called, ompi_init() and
* ompi_rte_init() should *not* be called.
*
* It is permissable to pass in (0, NULL) for (argc, argv).
*/
int oshmem_shmem_init(int argc, char **argv, int requested, int *provided);
/**
* Finalize the Open SHMEM environment
*
* @returns OSHMEM_SUCCESS if successful
* @returns Error code if unsuccessful
*
*/
int oshmem_shmem_finalize(void);
/**
* Abort SHMEM processes
*/
OSHMEM_DECLSPEC int oshmem_shmem_abort(int errcode);
/**
* Exchange initial info between processes
*/
OSHMEM_DECLSPEC int oshmem_shmem_exchange_allgather(void *buf, int buf_size);
OSHMEM_DECLSPEC int oshmem_shmem_exchange_bcast(void *buf, int buf_size, int root);
/**
* Register OSHMEM specific runtime parameters
*/
OSHMEM_DECLSPEC int oshmem_shmem_register_params(void);
#if OSHMEM_PARAM_CHECK == 1
#define RUNTIME_CHECK_ERROR(format, ...) \
do { \
fprintf(stderr, "[%s]%s[%s:%d:%s] ", \
orte_process_info.nodename, \
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), \
__FILE__, __LINE__, __func__); \
fprintf(stderr, format, ## __VA_ARGS__); \
} while(0);
/**
* Check if SHMEM API generates internal error return code
* Note: most API does not return error code
*/
#define RUNTIME_CHECK_RC(x) \
if (OPAL_UNLIKELY(OSHMEM_SUCCESS != (x))) \
{ \
RUNTIME_CHECK_ERROR("Internal error is appeared rc = %d\n", (x)); \
}
/**
* Check if we called start_pes() and passed initialization phase
*/
#define RUNTIME_CHECK_INIT() \
if (OPAL_UNLIKELY(!oshmem_shmem_initialized)) \
{ \
RUNTIME_CHECK_ERROR("SHMEM is not initialized\n"); \
oshmem_shmem_abort(-1); \
}
/**
* Check if we target PE is valid
*/
#define RUNTIME_CHECK_PE(x) \
if (OPAL_UNLIKELY(((x) < 0) || \
((int)(x) > (int)(orte_process_info.num_procs - 1)))) \
{ \
RUNTIME_CHECK_ERROR("Target PE #%d is not in valid range\n", (x)); \
oshmem_shmem_abort(-1); \
}
/**
* Check if required address is in symmetric address space
*/
#include "oshmem/mca/memheap/memheap.h"
#define RUNTIME_CHECK_ADDR(x) \
if (OPAL_UNLIKELY(!MCA_MEMHEAP_CALL(is_symmetric_addr((unsigned long)(x))))) \
{ \
RUNTIME_CHECK_ERROR("Required address %p is not in symmetric space\n", (x)); \
oshmem_shmem_abort(-1); \
}
#define RUNTIME_CHECK_WITH_MEMHEAP_SIZE(x) \
if (OPAL_UNLIKELY((long)(x) > MCA_MEMHEAP_CALL(size))) \
{ \
RUNTIME_CHECK_ERROR("Requested (%ld)bytes and it exceeds symmetric space size (%ld)bytes\n", (long)(x), MCA_MEMHEAP_CALL(size)); \
}
#else
#define RUNTIME_CHECK_RC(x) (x = x)
#define RUNTIME_CHECK_INIT()
#define RUNTIME_CHECK_PE(x)
#define RUNTIME_CHECK_ADDR(x)
#endif /* OSHMEM_PARAM_CHECK */
END_C_DECLS
#endif /* OSHMEM_SHMEM_RUNTIME_H */