a924b4a7f4
the shared object when it is compiled with the Sun Studio C compiler. Depends on where the extern variables that are included in the headers were initialized, there can be instances wheter there is no storage allocated for the variables and therefore the symbols may or may not be defined when the debugger tries to dlopen this message queue dll. This commit was SVN r18685.
777 строки
29 KiB
C
777 строки
29 KiB
C
/*
|
|
* Copyright (c) 2007-2008 Cisco, Inc. All rights resereved.
|
|
* Copyright (c) 2004-2007 The University of Tennessee and The University
|
|
* of Tennessee Research Foundation. All rights
|
|
* reserved.
|
|
* Copyright (c) 2008 Sun Microsystems, Inc. All rights resereved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
/**********************************************************************
|
|
* Copyright (C) 2000-2004 by Etnus, LLC.
|
|
* Copyright (C) 1999 by Etnus, Inc.
|
|
* Copyright (C) 1997-1998 Dolphin Interconnect Solutions Inc.
|
|
*
|
|
* Permission is hereby granted to use, reproduce, prepare derivative
|
|
* works, and to redistribute to others.
|
|
*
|
|
* DISCLAIMER
|
|
*
|
|
* Neither Dolphin Interconnect Solutions, Etnus LLC, nor any of their
|
|
* employees, makes any warranty express or implied, or assumes any
|
|
* legal liability or responsibility for the accuracy, completeness,
|
|
* or usefulness of any information, apparatus, product, or process
|
|
* disclosed, or represents that its use would not infringe privately
|
|
* owned rights.
|
|
*
|
|
* This code was written by
|
|
* James Cownie: Dolphin Interconnect Solutions. <jcownie@dolphinics.com>
|
|
* Etnus LLC <jcownie@etnus.com>
|
|
**********************************************************************/
|
|
|
|
#include "ompi_config.h"
|
|
|
|
#if defined(HAVE_STRING_H)
|
|
#include <string.h>
|
|
#endif /* defined(HAVE_STRING_H) */
|
|
#if defined(HAVE_STDLIB_H)
|
|
#include <stdlib.h>
|
|
#endif /* defined(HAVE_STDLIB_H) */
|
|
|
|
#include "ompi/mca/pml/base/pml_base_request.h"
|
|
#include "mpihandles_interface.h"
|
|
#include "ompi_mpihandles_dll_defs.h"
|
|
#include "ompi/communicator/communicator.h"
|
|
#include "ompi/group/group.h"
|
|
|
|
|
|
#define OPAL_ALIGN(x,a,t) (((x)+((t)(a)-1)) & ~(((t)(a)-1)))
|
|
|
|
/* Globals that the debugger expects to find in the DLL */
|
|
#if defined(WORDS_BIGENDIAN)
|
|
char mpidbg_dll_is_big_endian = 1;
|
|
#else
|
|
char mpidbg_dll_is_big_endian = 0;
|
|
#endif
|
|
char mpidbg_dll_bitness = (char) (sizeof(void*) * 8);
|
|
enum mpidbg_comm_capabilities_t mpidbg_comm_capabilities = 0;
|
|
struct mpidbg_name_map_t *mpidbg_comm_name_map = NULL;
|
|
enum mpidbg_errhandler_capabilities_t mpidbg_errhandler_capabilities = 0;
|
|
struct mpidbg_name_map_t *mpidbg_errhandler_name_map = NULL;
|
|
enum mpidbg_request_capabilities_t mpidbg_request_capabilities = 0;
|
|
struct mpidbg_name_map_t *mpidbg_request_name_map = NULL;
|
|
enum mpidbg_status_capabilities_t mpidbg_status_capabilities = 0;
|
|
struct mpidbg_name_map_t *mpidbg_status_name_map = NULL;
|
|
|
|
#if defined(__SUNPRO_C)
|
|
/*
|
|
* These symbols are defined here because of the different way compilers
|
|
* may handle extern definitions. The particular case that is causing
|
|
* problems is when there is an extern variable that is accessed in a
|
|
* static inline function. For example, here is the code we often see in
|
|
* a header file.
|
|
*
|
|
* extern int request_complete;
|
|
* static inline check_request(void) {
|
|
* request_complete = 1;
|
|
* }
|
|
*
|
|
* If this code exists in a header file and gets included in a source
|
|
* file, then some compilers expect to have request_complete defined
|
|
* somewhere even if request_complete is never referenced and
|
|
* check_request is never called. Other compilers do not need them defined
|
|
* if they are never referenced in the source file. Therefore, to handle
|
|
* cases like the above with compilers that require the symbol (like
|
|
* Sun Studio) we add in these definitions here.
|
|
*/
|
|
size_t ompi_request_completed;
|
|
opal_condition_t ompi_request_cond;
|
|
size_t ompi_request_waiting;
|
|
opal_mutex_t ompi_request_lock;
|
|
opal_mutex_t opal_event_lock;
|
|
uint32_t opal_progress_recursion_depth_counter;
|
|
int opal_progress_spin_count;
|
|
volatile int32_t opal_progress_thread_count;
|
|
bool opal_mutex_check_locks;
|
|
bool opal_uses_threads;
|
|
#endif /* defined(__SUNPRO_C) */
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
/* Small helper function: allocate a map of a given length */
|
|
static struct mpidbg_name_map_t *alloc_map(mqs_image *image, int len)
|
|
{
|
|
mpi_image_info *i_info = (mpi_image_info *) mqs_get_image_info(image);
|
|
struct mpidbg_name_map_t *m = NULL;
|
|
|
|
if (NULL != i_info) {
|
|
m = mqs_malloc(len * sizeof(struct mpidbg_name_map_t));
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
/* Small helper function: look up a symbol, and if we find it, put it
|
|
in a map entry */
|
|
static void fill_map(mqs_image *image,
|
|
char *public_name, char *private_name,
|
|
struct mpidbg_name_map_t *map)
|
|
{
|
|
mqs_taddr_t value;
|
|
mpi_image_info *i_info = (mpi_image_info *) mqs_get_image_info(image);
|
|
|
|
if (NULL != i_info) {
|
|
map->map_name = strdup(public_name);
|
|
if (NULL != private_name) {
|
|
if (mqs_ok == mqs_find_symbol(image, private_name, &value)) {
|
|
map->map_handle = value;
|
|
return;
|
|
}
|
|
} else {
|
|
map->map_handle = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
printf("OMPI MPI handles DLL: fill_map: Unable to find symbol: %s\n",
|
|
private_name);
|
|
}
|
|
|
|
/* Helper function to lookup MPI attributes and fill an
|
|
mpidbg_attribute_pair_t array with their keys/values */
|
|
static int fill_attributes(int *num_attrs,
|
|
struct mpidbg_attribute_pair_t **attrs,
|
|
mqs_taddr_t table)
|
|
{
|
|
/* JMS fill me in */
|
|
return mqs_ok;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
int mpidbg_init_once(const mqs_basic_callbacks *cb)
|
|
{
|
|
mqs_basic_entrypoints = cb;
|
|
printf("mpidbg_init_once\n");
|
|
return MPIDBG_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
/* Returns the fixed value */
|
|
int mpidbg_interface_version_compatibility(void)
|
|
{
|
|
printf("mpidbg_interface_version_compatibility\n");
|
|
return MPIDBG_INTERFACE_VERSION;
|
|
}
|
|
|
|
|
|
/* Returns a string specific to OMPI */
|
|
char *mpidbg_version_string(void)
|
|
{
|
|
printf("mpidbg_version_string\n");
|
|
return "Open MPI handle interpretation support for parallel"
|
|
" debuggers compiled on " __DATE__;
|
|
}
|
|
|
|
|
|
/* So the debugger can tell what interface width the library was
|
|
compiled with */
|
|
int mpidbg_dll_taddr_width(void)
|
|
{
|
|
printf("mpidbg_dll_taddr_width\n");
|
|
return sizeof(mqs_taddr_t);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
/* Once-per-image setup */
|
|
int mpidbg_init_per_image(mqs_image *image, const mqs_image_callbacks *icb,
|
|
struct mpidbg_handle_info_t *handle_types)
|
|
{
|
|
char **message;
|
|
mpi_image_info *i_info =
|
|
(mpi_image_info *) mqs_malloc(sizeof(mpi_image_info));
|
|
printf("mpidbg_init_per_image\n");
|
|
|
|
if (NULL == i_info) {
|
|
printf("mpidbg_init_per_image: malloc failed!\n");
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
|
|
memset((void *)i_info, 0, sizeof(mpi_image_info));
|
|
/* Before we do *ANYTHING* else */
|
|
i_info->image_callbacks = icb;
|
|
|
|
/* Nothing extra (yet) */
|
|
i_info->extra = NULL;
|
|
|
|
/* Save the info */
|
|
mqs_put_image_info(image, (mqs_image_info *)i_info);
|
|
|
|
/* Fill in the OMPI type information */
|
|
if (mqs_ok != ompi_fill_in_type_info(image, message)) {
|
|
printf("mpidbg_init_per_image: failed to get all type info\n");
|
|
return MPIDBG_ERR_NOT_SUPPORTED;
|
|
}
|
|
|
|
/* Fill in the handle_types struct with our types */
|
|
/* JMS: "MPI_Aint" is a typedef -- is that enough? (the actual
|
|
type is a #define, so it's not easy to put into the
|
|
mqs_find_type call as a string) */
|
|
handle_types->hi_c_aint = mqs_find_type(image, "MPI_Aint", mqs_lang_c);
|
|
/* JMS: these ompi types are just the "foo" types; but OMPI MPI
|
|
types are all "foo*"'s -- is this right? If this is wrong, I
|
|
*suspect* that something like the following may be right:
|
|
|
|
handle_types->hi_c_comm = mqs_find_type(image, "ompi_communicator_t*", mqs_lang_c);
|
|
|
|
Need to confirm this with the DDT guys...
|
|
*/
|
|
handle_types->hi_c_comm = i_info->ompi_communicator_t.type;
|
|
handle_types->hi_c_datatype = i_info->ompi_datatype_t.type;
|
|
handle_types->hi_c_errhandler =
|
|
mqs_find_type(image, "ompi_errhandler_t", mqs_lang_c);
|
|
handle_types->hi_c_file =
|
|
mqs_find_type(image, "ompi_file_t", mqs_lang_c);
|
|
handle_types->hi_c_group = i_info->ompi_group_t.type;
|
|
handle_types->hi_c_info =
|
|
mqs_find_type(image, "ompi_info_t", mqs_lang_c);
|
|
/* JMS: "MPI_Offset" is a typedef (see comment about MPI_Aint above) */
|
|
handle_types->hi_c_offset =
|
|
mqs_find_type(image, "MPI_Offset", mqs_lang_c);
|
|
handle_types->hi_c_op =
|
|
mqs_find_type(image, "ompi_op_t", mqs_lang_c);
|
|
handle_types->hi_c_request = i_info->ompi_request_t.type;
|
|
handle_types->hi_c_status = i_info->ompi_status_public_t.type;
|
|
handle_types->hi_c_win =
|
|
mqs_find_type(image, "ompi_win_t", mqs_lang_c);
|
|
|
|
/* MPI::Aint is a typedef to MPI_Aint */
|
|
handle_types->hi_cxx_aint = handle_types->hi_cxx_aint;
|
|
handle_types->hi_cxx_comm =
|
|
mqs_find_type(image, "MPI::Comm", mqs_lang_cplus);
|
|
handle_types->hi_cxx_intracomm =
|
|
mqs_find_type(image, "MPI::Intracomm", mqs_lang_cplus);
|
|
handle_types->hi_cxx_intercomm =
|
|
mqs_find_type(image, "MPI::Intercomm", mqs_lang_cplus);
|
|
handle_types->hi_cxx_graphcomm =
|
|
mqs_find_type(image, "MPI::Graphcomm", mqs_lang_cplus);
|
|
handle_types->hi_cxx_cartcomm =
|
|
mqs_find_type(image, "MPI::Cartcomm", mqs_lang_cplus);
|
|
handle_types->hi_cxx_datatype =
|
|
mqs_find_type(image, "MPI::Datatype", mqs_lang_cplus);
|
|
handle_types->hi_cxx_errhandler =
|
|
mqs_find_type(image, "MPI::Errhandler", mqs_lang_cplus);
|
|
handle_types->hi_cxx_file =
|
|
mqs_find_type(image, "MPI::File", mqs_lang_cplus);
|
|
handle_types->hi_cxx_group =
|
|
mqs_find_type(image, "MPI::Group", mqs_lang_cplus);
|
|
handle_types->hi_cxx_info =
|
|
mqs_find_type(image, "MPI::Info", mqs_lang_cplus);
|
|
/* MPI::Offset is a typedef to MPI_Offset */
|
|
handle_types->hi_cxx_offset = handle_types->hi_c_offset;
|
|
handle_types->hi_cxx_op =
|
|
mqs_find_type(image, "MPI::Op", mqs_lang_cplus);
|
|
handle_types->hi_cxx_request =
|
|
mqs_find_type(image, "MPI::Request", mqs_lang_cplus);
|
|
handle_types->hi_cxx_prequest =
|
|
mqs_find_type(image, "MPI::Prequest", mqs_lang_cplus);
|
|
handle_types->hi_cxx_grequest =
|
|
mqs_find_type(image, "MPI::Grequest", mqs_lang_cplus);
|
|
handle_types->hi_cxx_status =
|
|
mqs_find_type(image, "MPI::Status", mqs_lang_cplus);
|
|
handle_types->hi_cxx_win =
|
|
mqs_find_type(image, "MPI::Win", mqs_lang_cplus);
|
|
|
|
/* Tell the debuger what capabilities we have */
|
|
mpidbg_comm_capabilities =
|
|
MPIDBG_COMM_CAP_BASIC |
|
|
MPIDBG_COMM_CAP_STRING_NAMES |
|
|
MPIDBG_COMM_CAP_FREED_HANDLE |
|
|
MPIDBG_COMM_CAP_FREED_OBJECT;
|
|
mpidbg_errhandler_capabilities =
|
|
MPIDBG_ERRH_CAP_BASIC |
|
|
MPIDBG_ERRH_CAP_STRING_NAMES |
|
|
MPIDBG_ERRH_CAP_FREED_HANDLE |
|
|
MPIDBG_ERRH_CAP_FREED_OBJECT;
|
|
mpidbg_request_capabilities =
|
|
MPIDBG_REQUEST_CAP_BASIC;
|
|
mpidbg_status_capabilities =
|
|
MPIDBG_STATUS_CAP_BASIC;
|
|
|
|
/* All done */
|
|
printf("mpidbg_init_per_image: init succeeded -- ready!\n");
|
|
return MPIDBG_SUCCESS;
|
|
}
|
|
|
|
|
|
/* This image is now dead; free all the state associated with it */
|
|
void mpidbg_finalize_per_image(mqs_image *image, mqs_image_info *info)
|
|
{
|
|
mpi_image_info *i_info = (mpi_image_info *)info;
|
|
|
|
printf("mpidbg_finalize_per_image\n");
|
|
if (NULL != i_info->extra) {
|
|
mqs_free(i_info->extra);
|
|
}
|
|
mqs_free(info);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
/* Setup information needed for a specific process. The debugger
|
|
* assumes that this will hang something onto the process, if nothing
|
|
* is attached to it, then TV will believe that this process has no
|
|
* message queue information.
|
|
*/
|
|
int mpidbg_init_per_process(mqs_process *process,
|
|
const mqs_process_callbacks *pcb,
|
|
struct mpidbg_handle_info_t *handle_types)
|
|
{
|
|
mqs_image *image;
|
|
mpi_image_info *i_info;
|
|
|
|
/* Extract the addresses of the global variables we need and save
|
|
them away */
|
|
mpi_process_info *p_info =
|
|
(mpi_process_info *) mqs_malloc(sizeof(mpi_process_info));
|
|
printf("mpidbg_init_per_process\n");
|
|
|
|
if (NULL == p_info) {
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
|
|
/* Setup the callbacks first */
|
|
p_info->process_callbacks = pcb;
|
|
|
|
/* Nothing extra (yet) */
|
|
p_info->extra = NULL;
|
|
|
|
/* Now we can get the rest of the info */
|
|
image = mqs_get_image(process);
|
|
i_info = (mpi_image_info *) mqs_get_image_info(image);
|
|
|
|
/* Get process info sizes */
|
|
mqs_get_type_sizes (process, &p_info->sizes);
|
|
|
|
/* Save the info */
|
|
mqs_put_process_info(process, (mqs_process_info *) p_info);
|
|
|
|
/* Fill in pre-defined MPI handle name mappings (because OMPI uses
|
|
#define's for the pre-defined names, such as "#define
|
|
MPI_COMM_WORLD &ompi_mpi_comm_world"). */
|
|
/* Communicators */
|
|
mpidbg_comm_name_map = alloc_map(image, 4);
|
|
if (NULL != mpidbg_comm_name_map) {
|
|
int i = 0;
|
|
fill_map(image, "MPI_COMM_WORLD", "ompi_mpi_comm_world",
|
|
&mpidbg_comm_name_map[i++]);
|
|
fill_map(image, "MPI_COMM_SELF", "ompi_mpi_comm_self",
|
|
&mpidbg_comm_name_map[i++]);
|
|
fill_map(image, "MPI_COMM_NULL", "ompi_mpi_comm_null",
|
|
&mpidbg_comm_name_map[i++]);
|
|
|
|
/* Sentinel value */
|
|
mpidbg_comm_name_map[i].map_name = NULL;
|
|
}
|
|
|
|
/* Error handlers */
|
|
mpidbg_errhandler_name_map = alloc_map(image, 4);
|
|
if (NULL != mpidbg_errhandler_name_map) {
|
|
int i = 0;
|
|
fill_map(image, "MPI_ERRORS_ARE_FATAL", "ompi_mpi_errors_are_fatal",
|
|
&mpidbg_errhandler_name_map[i++]);
|
|
fill_map(image, "MPI_ERRORS_RETURN", "ompi_mpi_errors_return",
|
|
&mpidbg_errhandler_name_map[i++]);
|
|
fill_map(image, "MPI_ERRHANDLER_NULL", "ompi_mpi_errhandler_null",
|
|
&mpidbg_errhandler_name_map[i++]);
|
|
/* MPI::ERRORS_THROW_EXCEPTIONS exists as a symbol in OMPI; no
|
|
need to alias it here */
|
|
|
|
/* Sentinel value */
|
|
mpidbg_errhandler_name_map[i].map_name = NULL;
|
|
}
|
|
|
|
/* Requests */
|
|
mpidbg_request_name_map = alloc_map(image, 2);
|
|
if (NULL != mpidbg_request_name_map) {
|
|
int i = 0;
|
|
fill_map(image, "MPI_REQUEST_NULL", "ompi_request_null",
|
|
&mpidbg_request_name_map[i++]);
|
|
|
|
/* Sentinel value */
|
|
mpidbg_request_name_map[i].map_name = NULL;
|
|
}
|
|
|
|
/* Statuses */
|
|
mpidbg_status_name_map = alloc_map(image, 2);
|
|
if (NULL != mpidbg_status_name_map) {
|
|
int i = 0;
|
|
fill_map(image, "MPI_STATUS_IGNORE", NULL,
|
|
&mpidbg_status_name_map[i++]);
|
|
|
|
/* Sentinel value */
|
|
mpidbg_status_name_map[i].map_name = NULL;
|
|
}
|
|
|
|
/* All done */
|
|
return MPIDBG_SUCCESS;
|
|
}
|
|
|
|
|
|
/* This process is now done; free all the state associated with it */
|
|
void mpidbg_finalize_per_process(mqs_process *process, mqs_process_info *info)
|
|
{
|
|
mpi_process_info *p_info = (mpi_process_info *)info;
|
|
|
|
printf("mpidbg_finalize_per_process\n");
|
|
if (NULL != p_info->extra) {
|
|
mqs_free(p_info->extra);
|
|
}
|
|
mqs_free(info);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
int mpidbg_comm_query(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t c_comm, struct mpidbg_comm_info_t **info)
|
|
{
|
|
int flags;
|
|
mpi_image_info *i_info = (mpi_image_info*) image_info;
|
|
mpi_process_info *p_info = (mpi_process_info*) process_info;
|
|
mqs_taddr_t group, topo, keyhash;
|
|
|
|
/* Get the comm name */
|
|
|
|
*info = mqs_malloc(sizeof(struct mpidbg_comm_info_t));
|
|
if (NULL == *info) {
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
/* JMS temporarily zero everything out. Remove this when we fill
|
|
in all the fields */
|
|
memset(*info, 0, sizeof(struct mpidbg_comm_info_t));
|
|
(*info)->comm_c_handle = c_comm;
|
|
|
|
printf("mpidbg_comm_query: %p\n", (void*) c_comm);
|
|
mqs_fetch_data(process, c_comm + i_info->ompi_communicator_t.offset.c_name,
|
|
MPIDBG_MAX_OBJECT_NAME, (*info)->comm_name);
|
|
|
|
/* Get this process' rank in the comm */
|
|
(*info)->comm_rank = ompi_fetch_int(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_my_rank,
|
|
p_info);
|
|
|
|
/* Analyze the flags on the comm */
|
|
flags = ompi_fetch_int(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_flags,
|
|
p_info);
|
|
(*info)->comm_bitflags = 0;
|
|
if (MPI_PROC_NULL == (*info)->comm_rank) {
|
|
/* This communicator is MPI_COMM_NULL */
|
|
(*info)->comm_rank = (*info)->comm_size = 0;
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_COMM_NULL;
|
|
} else if (0 != (flags & OMPI_COMM_INTER)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_INTERCOMM;
|
|
} else {
|
|
if (0 != (flags & OMPI_COMM_CART)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_CARTESIAN;
|
|
} else if (0 != (flags & OMPI_COMM_GRAPH)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_GRAPH;
|
|
}
|
|
}
|
|
if (0 != (flags & OMPI_COMM_ISFREED)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_FREED_HANDLE;
|
|
}
|
|
if (0 != (flags & OMPI_COMM_INTRINSIC)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_PREDEFINED;
|
|
}
|
|
if (0 != (flags & OMPI_COMM_INVALID)) {
|
|
(*info)->comm_bitflags |= MPIDBG_COMM_INFO_FREED_OBJECT;
|
|
}
|
|
|
|
/* Look up the local group */
|
|
group = ompi_fetch_pointer(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_local_group,
|
|
p_info);
|
|
(*info)->comm_rank = ompi_fetch_int(process,
|
|
group + i_info->ompi_group_t.offset.grp_my_rank,
|
|
p_info);
|
|
(*info)->comm_num_local_procs = ompi_fetch_int(process,
|
|
group + i_info->ompi_group_t.offset.grp_proc_count,
|
|
p_info);
|
|
|
|
/* Fill in the comm_size with the size of the local group. We'll
|
|
override below if this is an intercommunicator. */
|
|
(*info)->comm_size = (*info)->comm_num_local_procs;
|
|
|
|
/* JMS fill this in: waiting to decide between mpidbg_process_t
|
|
and mqs_process_location */
|
|
(*info)->comm_local_procs = NULL;
|
|
|
|
/* Look up the remote group (if relevant) */
|
|
if (0 != (flags & OMPI_COMM_INTER)) {
|
|
group = ompi_fetch_pointer(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_remote_group,
|
|
p_info);
|
|
(*info)->comm_num_remote_procs = ompi_fetch_int(process,
|
|
group + i_info->ompi_group_t.offset.grp_proc_count,
|
|
p_info);
|
|
(*info)->comm_size = (*info)->comm_num_remote_procs;
|
|
|
|
/* JMS fill this in: waiting to decide between
|
|
mpidbg_process_t and mqs_process_location */
|
|
(*info)->comm_remote_procs = NULL;
|
|
} else {
|
|
(*info)->comm_num_remote_procs = 0;
|
|
(*info)->comm_remote_procs = NULL;
|
|
}
|
|
|
|
/* Fill in cartesian/graph info, if relevant. The cartesian and
|
|
graph data is just slightly different from each other; it's
|
|
[slightly] easier (and less confusing!) to have separate
|
|
retrieval code blocks. */
|
|
topo = ompi_fetch_pointer(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_topo_comm,
|
|
p_info);
|
|
if (0 != topo &&
|
|
0 != ((*info)->comm_bitflags & MPIDBG_COMM_INFO_CARTESIAN)) {
|
|
int i, ndims, tmp;
|
|
mqs_taddr_t dims, periods;
|
|
|
|
/* Alloc space for copying arrays */
|
|
(*info)->comm_cart_num_dims = ndims =
|
|
ompi_fetch_int(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_ndims_or_nnodes,
|
|
p_info);
|
|
(*info)->comm_cart_dims = mqs_malloc(ndims * sizeof(int));
|
|
if (NULL == (*info)->comm_cart_dims) {
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
(*info)->comm_cart_periods = mqs_malloc(ndims * sizeof(int8_t));
|
|
if (NULL == (*info)->comm_cart_periods) {
|
|
mqs_free((*info)->comm_cart_dims);
|
|
(*info)->comm_cart_dims = NULL;
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
|
|
/* Retrieve the dimension and periodic description data from
|
|
the two arrays on the image's communicator */
|
|
dims = ompi_fetch_pointer(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_dims_or_index,
|
|
p_info);
|
|
periods = ompi_fetch_pointer(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_periods_or_edges,
|
|
p_info);
|
|
|
|
for (i = 0; i < ndims; ++i) {
|
|
(*info)->comm_cart_dims[i] =
|
|
ompi_fetch_int(process, dims + (sizeof(int) * i), p_info);
|
|
tmp = ompi_fetch_int(process, periods + (sizeof(int) * i), p_info);
|
|
(*info)->comm_cart_periods[i] = (int8_t) tmp;
|
|
printf("mpidbg: cart comm: dimension %d: (length %d, periodic: %d)\n", i, (*info)->comm_cart_dims[i], tmp);
|
|
}
|
|
} else if (0 != topo &&
|
|
0 != ((*info)->comm_bitflags & MPIDBG_COMM_INFO_GRAPH)) {
|
|
int i, nnodes;
|
|
mqs_taddr_t index, edges;
|
|
|
|
/* Alloc space for copying the indexes */
|
|
(*info)->comm_graph_num_nodes = nnodes =
|
|
ompi_fetch_int(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_ndims_or_nnodes,
|
|
p_info);
|
|
(*info)->comm_graph_index = mqs_malloc(nnodes * sizeof(int));
|
|
if (NULL == (*info)->comm_graph_index) {
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
|
|
/* Retrieve the index data */
|
|
index = ompi_fetch_pointer(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_dims_or_index,
|
|
p_info);
|
|
for (i = 0; i < nnodes; ++i) {
|
|
(*info)->comm_graph_index[i] =
|
|
ompi_fetch_int(process, index + (sizeof(int) * i), p_info);
|
|
}
|
|
|
|
/* Allocate space for the edges */
|
|
(*info)->comm_graph_edges = mqs_malloc((*info)->comm_graph_index[(*info)->comm_graph_num_nodes - 1] * sizeof(int));
|
|
if (NULL == (*info)->comm_graph_edges) {
|
|
mqs_free((*info)->comm_graph_index);
|
|
(*info)->comm_graph_index = NULL;
|
|
return MPIDBG_ERR_NO_MEM;
|
|
}
|
|
|
|
/* Retrieve the edge data */
|
|
edges = ompi_fetch_pointer(process,
|
|
topo + i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_periods_or_edges,
|
|
p_info);
|
|
for (i = 0;
|
|
i < (*info)->comm_graph_index[(*info)->comm_graph_num_nodes - 1];
|
|
++i) {
|
|
(*info)->comm_graph_edges[i] =
|
|
ompi_fetch_int(process, edges + (sizeof(int) * i), p_info);
|
|
}
|
|
}
|
|
|
|
/* Fortran handle */
|
|
(*info)->comm_fortran_handle =
|
|
ompi_fetch_int(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_f_to_c_index,
|
|
p_info);
|
|
printf("mpdbg: comm fortran handle: %d\n", (*info)->comm_fortran_handle);
|
|
|
|
/* Fill in attributes */
|
|
keyhash = ompi_fetch_pointer(process,
|
|
c_comm + i_info->ompi_communicator_t.offset.c_keyhash,
|
|
p_info);
|
|
fill_attributes(&((*info)->comm_num_attrs), &((*info)->comm_attrs),
|
|
keyhash);
|
|
|
|
/* JMS temporary */
|
|
(*info)->comm_num_pending_requests = MPIDBG_ERR_NOT_SUPPORTED;
|
|
(*info)->comm_pending_requests = NULL;
|
|
(*info)->comm_num_derived_windows = MPIDBG_ERR_NOT_SUPPORTED;
|
|
(*info)->comm_derived_windows = NULL;
|
|
(*info)->comm_num_derived_files = MPIDBG_ERR_NOT_SUPPORTED;
|
|
(*info)->comm_derived_files = NULL;
|
|
|
|
return MPIDBG_SUCCESS;
|
|
}
|
|
|
|
int mpidbg_comm_f2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t f77_comm, mqs_taddr_t *c_comm)
|
|
{
|
|
mqs_taddr_t comm_list;
|
|
mpi_image_info *i_info = (mpi_image_info *) image_info;
|
|
mpi_process_info *p_info = (mpi_process_info*) process_info;
|
|
|
|
mqs_find_symbol(image, "ompi_mpi_communicators", &comm_list);
|
|
if (mqs_ok != ompi_fetch_opal_pointer_array_item(process, comm_list,
|
|
p_info, f77_comm,
|
|
c_comm) ||
|
|
NULL == c_comm) {
|
|
printf("mpidbg_comm_f2c: %lu -> not found\n",
|
|
(long unsigned int) f77_comm);
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
printf("mpidbg_comm_f2c: %lu -> %lu\n",
|
|
(long unsigned int) f77_comm, (long unsigned int) c_comm);
|
|
return MPIDBG_SUCCESS;
|
|
}
|
|
|
|
int mpidbg_comm_cxx2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t cxx_comm,
|
|
enum mpidbg_comm_info_bitmap_t comm_type,
|
|
mqs_taddr_t *c_comm)
|
|
{
|
|
/* David tells me that any type of communicator (MPI::Comm,
|
|
MPI::Intracomm, etc.) should have the offset to the mpi_comm
|
|
member in the same place. */
|
|
printf("mpidbg_comm_cxx2c: %p\n", (void*) cxx_comm);
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
int mpidbg_errhandler_query(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t c_errhandler,
|
|
struct mpidbg_errhandler_info_t **info)
|
|
{
|
|
printf("mpidbg_errhandler_query: %p\n", (void*) c_errhandler);
|
|
printf("mpidbg_errhandler_query: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_errhandler_f2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t f77_errhandler, mqs_taddr_t *c_errhandler)
|
|
{
|
|
printf("mpidbg_errhandler_f2c: %lu\n", (long unsigned int) f77_errhandler);
|
|
printf("mpidbg_errhandler_f2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_errhandler_cxx2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t cxx_errhandler,
|
|
mqs_taddr_t *c_errhandler)
|
|
{
|
|
printf("mpidbg_errhandler_cxx2c: %p\n", (void*) cxx_errhandler);
|
|
printf("mpidbg_errhandler_cxx2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
int mpidbg_request_query(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t c_request,
|
|
struct mpidbg_request_info_t **info)
|
|
{
|
|
printf("mpidbg_request_query: %p\n", (void*) c_request);
|
|
printf("mpidbg_request_query: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_request_f2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t f77_request, mqs_taddr_t *c_request)
|
|
{
|
|
printf("mpidbg_request_f2c: %lu\n", (long unsigned int) f77_request);
|
|
printf("mpidbg_request_f2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_request_cxx2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t cxx_request,
|
|
enum mpidbg_request_info_bitmap_t request_type,
|
|
mqs_taddr_t *c_request)
|
|
{
|
|
printf("mpidbg_request_cxx2c: %p\n", (void*) cxx_request);
|
|
printf("mpidbg_request_cxx2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
int mpidbg_status_query(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t c_status,
|
|
struct mpidbg_status_info_t **info)
|
|
{
|
|
printf("mpidbg_status_query: %p\n", (void*) c_status);
|
|
printf("mpidbg_status_query: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_status_f2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t f77_status, mqs_taddr_t *c_status)
|
|
{
|
|
printf("mpidbg_status_f2c: %lu\n", (long unsigned int) f77_status);
|
|
printf("mpidbg_status_f2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|
|
|
|
int mpidbg_status_cxx2c(mqs_image *image, mqs_image_info *image_info,
|
|
mqs_process *process, mqs_process_info *process_info,
|
|
mqs_taddr_t cxx_status,
|
|
mqs_taddr_t *c_status)
|
|
{
|
|
printf("mpidbg_status_cxx2c: %p\n", (void*) cxx_status);
|
|
printf("mpidbg_status_cxx2c: not [yet] found\n");
|
|
return MPIDBG_ERR_NOT_FOUND;
|
|
}
|