|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2005 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Fixme: include the mpichconf.h file? */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Allow fprintf in debug statements */
|
|
Packit Service |
c5cf8c |
/* style: allow:fprintf:5 sig:0 */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <stdint.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* #define DEBUG_MPIDBG_DLL 1 */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Define this to have the code print out details of its list traversal
|
|
Packit Service |
c5cf8c |
action. This is primarily for use with dbgstub.c and the test programs
|
|
Packit Service |
c5cf8c |
such as tvtest.c */
|
|
Packit Service |
c5cf8c |
/* #define DEBUG_LIST_ITER */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Define this to have the code print out its operation to a file.
|
|
Packit Service |
c5cf8c |
This may be used to help understand how the debugger is using this
|
|
Packit Service |
c5cf8c |
interface */
|
|
Packit Service |
c5cf8c |
/* #define DEBUG_MPIDBG_LOGGING */
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_MPIDBG_LOGGING
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
FILE *debugfp = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static void initLogFile(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (!debugfp) {
|
|
Packit Service |
c5cf8c |
debugfp = fopen("mpich-dbg-interface-log.txt", "w");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
/* no-op definition */
|
|
Packit Service |
c5cf8c |
#define initLogFile()
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* MPIR_dll_name is defined in dbg_init.c; it must be part of the target image,
|
|
Packit Service |
c5cf8c |
not the debugger interface */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* mpi_interface.h defines the interface to the debugger. This interface
|
|
Packit Service |
c5cf8c |
is the same for any MPI implementation, for a given debugger
|
|
Packit Service |
c5cf8c |
(a more precise name might be mpi_tv_interface.h) */
|
|
Packit Service |
c5cf8c |
#include "mpi_interface.h"
|
|
Packit Service |
c5cf8c |
/* mpich_dll_defs.h defines the structures for a particular MPI
|
|
Packit Service |
c5cf8c |
implementation (MPICH in this case) */
|
|
Packit Service |
c5cf8c |
#include "mpich_dll_defs.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* style: allow:strncpy:1 sig:0 */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Local variables for this package */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static const mqs_basic_callbacks *mqs_basic_entrypoints = 0;
|
|
Packit Service |
c5cf8c |
static int host_is_big_endian = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Error values. */
|
|
Packit Service |
c5cf8c |
enum {
|
|
Packit Service |
c5cf8c |
err_silent_failure = mqs_first_user_code,
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
err_no_current_communicator,
|
|
Packit Service |
c5cf8c |
err_bad_request,
|
|
Packit Service |
c5cf8c |
err_no_store,
|
|
Packit Service |
c5cf8c |
err_all_communicators,
|
|
Packit Service |
c5cf8c |
err_group_corrupt,
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
err_failed_qhdr,
|
|
Packit Service |
c5cf8c |
err_unexpected,
|
|
Packit Service |
c5cf8c |
err_posted,
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
err_failed_queue,
|
|
Packit Service |
c5cf8c |
err_first,
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Internal structure we hold for each communicator */
|
|
Packit Service |
c5cf8c |
typedef struct communicator_t {
|
|
Packit Service |
c5cf8c |
struct communicator_t *next;
|
|
Packit Service |
c5cf8c |
group_t *group; /* Translations */
|
|
Packit Service |
c5cf8c |
int context_id; /* To catch changes */
|
|
Packit Service |
c5cf8c |
int recvcontext_id; /* May also be needed for
|
|
Packit Service |
c5cf8c |
* matchine */
|
|
Packit Service |
c5cf8c |
int present;
|
|
Packit Service |
c5cf8c |
mqs_communicator comm_info; /* Info needed at the higher level */
|
|
Packit Service |
c5cf8c |
} communicator_t;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Internal functions used only by routines in this package */
|
|
Packit Service |
c5cf8c |
static void mqs_free_communicator_list(struct communicator_t *comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int communicators_changed(mqs_process * proc);
|
|
Packit Service |
c5cf8c |
static int rebuild_communicator_list(mqs_process * proc);
|
|
Packit Service |
c5cf8c |
static int compare_comms(const void *a, const void *b);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static group_t *find_or_create_group(mqs_process * proc, mqs_tword_t np, mqs_taddr_t table);
|
|
Packit Service |
c5cf8c |
static int translate(group_t * this, int idx);
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
static int reverse_translate(group_t * this, int idx);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
static void group_decref(group_t * group);
|
|
Packit Service |
c5cf8c |
static communicator_t *find_communicator(mpich_process_info * p_info,
|
|
Packit Service |
c5cf8c |
mqs_taddr_t comm_base, int recv_ctx);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Many of the services used by this file are performed by calling
|
|
Packit Service |
c5cf8c |
* functions executed by the debugger. In other words, these are routines
|
|
Packit Service |
c5cf8c |
* that the debugger must export to this package. To make it easy to
|
|
Packit Service |
c5cf8c |
* identify these functions as well as to make their use simple,
|
|
Packit Service |
c5cf8c |
* we use macros that start with dbgr_xxx (for debugger). These
|
|
Packit Service |
c5cf8c |
* function pointers are set early in the initialization phase.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Note: to avoid any changes to the mpi_interface.h file, the fields in
|
|
Packit Service |
c5cf8c |
* the structures that contain the function pointers have not been
|
|
Packit Service |
c5cf8c |
* renamed dbgr_xxx and continue to use their original mqs_ prefix.
|
|
Packit Service |
c5cf8c |
* Using the dbgr_ prefix for the debugger-provided callbacks was done to
|
|
Packit Service |
c5cf8c |
* make it more obvious whether the debugger or the MPI interface DLL is
|
|
Packit Service |
c5cf8c |
* responsible for providing the function.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#define dbgr_malloc (mqs_basic_entrypoints->mqs_malloc_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_free (mqs_basic_entrypoints->mqs_free_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_prints (mqs_basic_entrypoints->mqs_eprints_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_put_image_info (mqs_basic_entrypoints->mqs_put_image_info_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_get_image_info (mqs_basic_entrypoints->mqs_get_image_info_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_put_process_info (mqs_basic_entrypoints->mqs_put_process_info_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_get_process_info (mqs_basic_entrypoints->mqs_get_process_info_fp)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* These macros *RELY* on the function already having set up the conventional
|
|
Packit Service |
c5cf8c |
* local variables i_info or p_info.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#define dbgr_find_type (i_info->image_callbacks->mqs_find_type_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_field_offset (i_info->image_callbacks->mqs_field_offset_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_get_type_sizes (i_info->image_callbacks->mqs_get_type_sizes_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_find_function (i_info->image_callbacks->mqs_find_function_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_find_symbol (i_info->image_callbacks->mqs_find_symbol_fp)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define dbgr_get_image (p_info->process_callbacks->mqs_get_image_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_get_global_rank (p_info->process_callbacks->mqs_get_global_rank_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_fetch_data (p_info->process_callbacks->mqs_fetch_data_fp)
|
|
Packit Service |
c5cf8c |
#define dbgr_target_to_host (p_info->process_callbacks->mqs_target_to_host_fp)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Routines to access data within the process */
|
|
Packit Service |
c5cf8c |
static mqs_taddr_t fetch_pointer(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info);
|
|
Packit Service |
c5cf8c |
static mqs_tword_t fetch_int(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info);
|
|
Packit Service |
c5cf8c |
static mqs_tword_t fetch_int16(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Startup calls
|
|
Packit Service |
c5cf8c |
These three routines are the first ones invoked by the debugger; they
|
|
Packit Service |
c5cf8c |
are used to ensure that the debug interface library is a known version.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_version_compatibility(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return MQS_INTERFACE_COMPATIBILITY;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
const char *mqs_version_string(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return "MPICH message queue support for MPICH " MPICH_VERSION " compiled on " __DATE__;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Allow the debugger to discover the size of an address type */
|
|
Packit Service |
c5cf8c |
int mqs_dll_taddr_width(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return sizeof(mqs_taddr_t);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Initialization
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
The function mqs_setup_basic_callbacks is used by the debugger to
|
|
Packit Service |
c5cf8c |
inform the routines in this file of the addresses of functions that
|
|
Packit Service |
c5cf8c |
it may call in the debugger.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
The function mqs_setup_image creates the image structure (local to this
|
|
Packit Service |
c5cf8c |
file) and tell the debugger about it
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
The function mqs_image_has_queues initializes the image structure.
|
|
Packit Service |
c5cf8c |
Much of the information that is saved in the image structure is information
|
|
Packit Service |
c5cf8c |
about the relative offset to data within an MPICH data structure.
|
|
Packit Service |
c5cf8c |
These offsets allow the debugger to retrieve information about the
|
|
Packit Service |
c5cf8c |
MPICH structures. The debugger routine dbgr_find_type is used to
|
|
Packit Service |
c5cf8c |
find information on an named type, and dbgr_field_offset is used
|
|
Packit Service |
c5cf8c |
to get the offset of a named field within a type.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
The function mqs_setup_process(process, callbacks) creates a private
|
|
Packit Service |
c5cf8c |
process information structure and stores a pointer to it in process
|
|
Packit Service |
c5cf8c |
(using dbgr_put_process_info). The use of a routine to store this
|
|
Packit Service |
c5cf8c |
value rather than passing an address to the process structure is
|
|
Packit Service |
c5cf8c |
done to give the debugger control over any operation that might store
|
|
Packit Service |
c5cf8c |
into the debuggers memory (instead, we'll use put_xxx_info).
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
The function mqs_process_has_queues ??
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void mqs_setup_basic_callbacks(const mqs_basic_callbacks * cb)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int t = 1;
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
host_is_big_endian = (*(char *) &t) != 1;
|
|
Packit Service |
c5cf8c |
mqs_basic_entrypoints = cb;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
Allocate and setup the basic image data structure. Also
|
|
Packit Service |
c5cf8c |
save the callbacks provided by the debugger; these will be used
|
|
Packit Service |
c5cf8c |
to access information about the image. This memory may be recovered
|
|
Packit Service |
c5cf8c |
with mqs_destroy_image_info.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_setup_image(mqs_image * image, const mqs_image_callbacks * icb)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_malloc(sizeof(mpich_image_info));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!i_info)
|
|
Packit Service |
c5cf8c |
return err_no_store;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
memset((void *) i_info, 0, sizeof(mpich_image_info));
|
|
Packit Service |
c5cf8c |
i_info->image_callbacks = icb; /* Before we do *ANYTHING* */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Tell the debugger to associate i_info with image */
|
|
Packit Service |
c5cf8c |
dbgr_put_image_info(image, (mqs_image_info *) i_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Setup information needed to access the queues. If successful, return
|
|
Packit Service |
c5cf8c |
* mqs_ok. If not, return an erro rcode. Also set the message pointer
|
|
Packit Service |
c5cf8c |
* with an explanatory message if there is a problem; otherwise, set it
|
|
Packit Service |
c5cf8c |
* to NULL.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* This routine is where much of the information specific to an MPI
|
|
Packit Service |
c5cf8c |
* implementation is used. In particular, the names of the structures
|
|
Packit Service |
c5cf8c |
* internal to an implementation and their fields are used here.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* FIXME: some of this information is specific to particular devices.
|
|
Packit Service |
c5cf8c |
* For example, the message queues are defined by the device. How do
|
|
Packit Service |
c5cf8c |
* we export this information? Should the queue code itself be responsible
|
|
Packit Service |
c5cf8c |
* for this (either by calling a routine in the image, using
|
|
Packit Service |
c5cf8c |
* dbgr_find_function (?) or by having the queue implementation provide a
|
|
Packit Service |
c5cf8c |
* separate file that can be included here to get the necessary information.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_image_has_queues(mqs_image * image, const char **message)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Default failure message ! */
|
|
Packit Service |
c5cf8c |
*message = "The symbols and types in the MPICH library used by TotalView\n"
|
|
Packit Service |
c5cf8c |
"to extract the message queues are not as expected in\n"
|
|
Packit Service |
c5cf8c |
"the image '%s'\n"
|
|
Packit Service |
c5cf8c |
"No message queue display is possible.\n"
|
|
Packit Service |
c5cf8c |
"This is probably an MPICH version or configuration problem.";
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Force in the file containing our wait-for-debugger function, to ensure
|
|
Packit Service |
c5cf8c |
* that types have been read from there before we try to look them up.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
dbgr_find_function(image, (char *) "MPII_Wait_for_debugger", mqs_lang_c, NULL);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Find the various global variables and structure definitions
|
|
Packit Service |
c5cf8c |
* that describe the communicator and message queue structures for
|
|
Packit Service |
c5cf8c |
* the MPICH implementation */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* First, the communicator information. This is in two parts:
|
|
Packit Service |
c5cf8c |
* MPIR_All_Communicators - a structure containing the head of the
|
|
Packit Service |
c5cf8c |
* list of all active communicators. The type is MPIR_Comm_list.
|
|
Packit Service |
c5cf8c |
* The communicators themselves are of type MPIR_Comm.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_type *cl_type = dbgr_find_type(image, (char *) "MPIR_Comm_list",
|
|
Packit Service |
c5cf8c |
mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (cl_type) {
|
|
Packit Service |
c5cf8c |
i_info->sequence_number_offs = dbgr_field_offset(cl_type, (char *) "sequence_number");
|
|
Packit Service |
c5cf8c |
i_info->comm_head_offs = dbgr_field_offset(cl_type, (char *) "head");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_type *co_type = dbgr_find_type(image, (char *) "MPIR_Comm", mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (co_type) {
|
|
Packit Service |
c5cf8c |
i_info->comm_name_offs = dbgr_field_offset(co_type, (char *) "name");
|
|
Packit Service |
c5cf8c |
i_info->comm_next_offs = dbgr_field_offset(co_type, (char *) "comm_next");
|
|
Packit Service |
c5cf8c |
i_info->comm_rsize_offs = dbgr_field_offset(co_type, (char *) "remote_size");
|
|
Packit Service |
c5cf8c |
i_info->comm_rank_offs = dbgr_field_offset(co_type, (char *) "rank");
|
|
Packit Service |
c5cf8c |
i_info->comm_context_id_offs = dbgr_field_offset(co_type, (char *) "context_id");
|
|
Packit Service |
c5cf8c |
i_info->comm_recvcontext_id_offs =
|
|
Packit Service |
c5cf8c |
dbgr_field_offset(co_type, (char *) "recvcontext_id");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Now the receive queues. The receive queues contain MPIR_Request
|
|
Packit Service |
c5cf8c |
* objects, and the various fields are within types in that object.
|
|
Packit Service |
c5cf8c |
* To simplify the eventual access, we compute all offsets relative to the
|
|
Packit Service |
c5cf8c |
* request. This means diving into the types that make of the
|
|
Packit Service |
c5cf8c |
* request definition */
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_type *req_type = dbgr_find_type(image, (char *) "MPIR_Request", mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (req_type) {
|
|
Packit Service |
c5cf8c |
int dev_offs;
|
|
Packit Service |
c5cf8c |
dev_offs = dbgr_field_offset(req_type, (char *) "dev");
|
|
Packit Service |
c5cf8c |
i_info->req_status_offs = dbgr_field_offset(req_type, (char *) "status");
|
|
Packit Service |
c5cf8c |
i_info->req_cc_offs = dbgr_field_offset(req_type, (char *) "cc");
|
|
Packit Service |
c5cf8c |
if (dev_offs >= 0) {
|
|
Packit Service |
c5cf8c |
mqs_type *dreq_type = dbgr_find_type(image, (char *) "MPIDI_Request",
|
|
Packit Service |
c5cf8c |
mqs_lang_c);
|
|
Packit Service |
c5cf8c |
i_info->req_dev_offs = dev_offs;
|
|
Packit Service |
c5cf8c |
if (dreq_type) {
|
|
Packit Service |
c5cf8c |
int loff, match_offs;
|
|
Packit Service |
c5cf8c |
loff = dbgr_field_offset(dreq_type, (char *) "next");
|
|
Packit Service |
c5cf8c |
i_info->req_next_offs = dev_offs + loff;
|
|
Packit Service |
c5cf8c |
loff = dbgr_field_offset(dreq_type, (char *) "user_buf");
|
|
Packit Service |
c5cf8c |
i_info->req_user_buf_offs = dev_offs + loff;
|
|
Packit Service |
c5cf8c |
loff = dbgr_field_offset(dreq_type, (char *) "user_count");
|
|
Packit Service |
c5cf8c |
i_info->req_user_count_offs = dev_offs + loff;
|
|
Packit Service |
c5cf8c |
loff = dbgr_field_offset(dreq_type, (char *) "datatype");
|
|
Packit Service |
c5cf8c |
i_info->req_datatype_offs = dev_offs + loff;
|
|
Packit Service |
c5cf8c |
match_offs = dbgr_field_offset(dreq_type, (char *) "match");
|
|
Packit Service |
c5cf8c |
if (match_offs >= 0) {
|
|
Packit Service |
c5cf8c |
mqs_type *match_type =
|
|
Packit Service |
c5cf8c |
dbgr_find_type(image, (char *) "MPIDI_Message_match", mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (match_type) {
|
|
Packit Service |
c5cf8c |
int parts_offs = dbgr_field_offset(match_type, (char *) "parts");
|
|
Packit Service |
c5cf8c |
if (parts_offs >= 0) {
|
|
Packit Service |
c5cf8c |
mqs_type *parts_type =
|
|
Packit Service |
c5cf8c |
dbgr_find_type(image, (char *) "MPIDI_Message_match_parts_t",
|
|
Packit Service |
c5cf8c |
mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (parts_type) {
|
|
Packit Service |
c5cf8c |
int moff;
|
|
Packit Service |
c5cf8c |
moff = dbgr_field_offset(parts_type, (char *) "tag");
|
|
Packit Service |
c5cf8c |
i_info->req_tag_offs = dev_offs + match_offs + moff;
|
|
Packit Service |
c5cf8c |
moff = dbgr_field_offset(parts_type, (char *) "rank");
|
|
Packit Service |
c5cf8c |
i_info->req_rank_offs = dev_offs + match_offs + moff;
|
|
Packit Service |
c5cf8c |
moff = dbgr_field_offset(parts_type, (char *) "context_id");
|
|
Packit Service |
c5cf8c |
i_info->req_context_id_offs = dev_offs + match_offs + moff;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Send queues use a separate system */
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_type *sreq_type = dbgr_find_type(image, (char *) "MPIR_Sendq", mqs_lang_c);
|
|
Packit Service |
c5cf8c |
if (sreq_type) {
|
|
Packit Service |
c5cf8c |
i_info->sendq_next_offs = dbgr_field_offset(sreq_type, (char *) "next");
|
|
Packit Service |
c5cf8c |
i_info->sendq_tag_offs = dbgr_field_offset(sreq_type, (char *) "tag");
|
|
Packit Service |
c5cf8c |
i_info->sendq_rank_offs = dbgr_field_offset(sreq_type, (char *) "rank");
|
|
Packit Service |
c5cf8c |
i_info->sendq_context_id_offs = dbgr_field_offset(sreq_type, (char *) "context_id");
|
|
Packit Service |
c5cf8c |
i_info->sendq_req_offs = dbgr_field_offset(sreq_type, (char *) "sreq");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* mqs_setup_process initializes the process structure.
|
|
Packit Service |
c5cf8c |
* The memory allocated by this routine (and routines that modify this
|
|
Packit Service |
c5cf8c |
* structure) is freed with mqs_destroy_process_info
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_setup_process(mqs_process * process, const mqs_process_callbacks * pcb)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* Extract the addresses of the global variables we need and save
|
|
Packit Service |
c5cf8c |
* them away */
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_malloc(sizeof(mpich_process_info));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (p_info) {
|
|
Packit Service |
c5cf8c |
mqs_image *image;
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_info->process_callbacks = pcb;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Now we can get the rest of the info ! */
|
|
Packit Service |
c5cf8c |
image = dbgr_get_image(process);
|
|
Packit Service |
c5cf8c |
i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Library starts at zero, so this ensures we go look to start with */
|
|
Packit Service |
c5cf8c |
p_info->communicator_sequence = -1;
|
|
Packit Service |
c5cf8c |
/* We have no communicators yet */
|
|
Packit Service |
c5cf8c |
p_info->communicator_list = NULL;
|
|
Packit Service |
c5cf8c |
/* Ask the debugger to initialize the structure that contains
|
|
Packit Service |
c5cf8c |
* the sizes of basic items (short, int, long, long long, and
|
|
Packit Service |
c5cf8c |
* void *) */
|
|
Packit Service |
c5cf8c |
dbgr_get_type_sizes(process, &p_info->sizes);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Tell the debugger to associate p_info with process */
|
|
Packit Service |
c5cf8c |
dbgr_put_process_info(process, (mqs_process_info *) p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
return err_no_store;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int mqs_process_has_queues(mqs_process * proc, char **msg)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
mqs_image *image = dbgr_get_image(proc);
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t head_ptr;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Don't bother with a pop up here, it's unlikely to be helpful */
|
|
Packit Service |
c5cf8c |
*msg = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Check first for the communicator list */
|
|
Packit Service |
c5cf8c |
if (dbgr_find_symbol(image, (char *) "MPIR_All_communicators", &p_info->commlist_base) !=
|
|
Packit Service |
c5cf8c |
mqs_ok)
|
|
Packit Service |
c5cf8c |
return err_all_communicators;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Check for the receive and send queues */
|
|
Packit Service |
c5cf8c |
if (dbgr_find_symbol(image, (char *) "MPID_Recvq_posted_head_ptr", &head_ptr) != mqs_ok)
|
|
Packit Service |
c5cf8c |
return err_posted;
|
|
Packit Service |
c5cf8c |
p_info->posted_base = fetch_pointer(proc, head_ptr, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (dbgr_find_symbol(image, (char *) "MPID_Recvq_unexpected_head_ptr", &head_ptr) != mqs_ok)
|
|
Packit Service |
c5cf8c |
return err_unexpected;
|
|
Packit Service |
c5cf8c |
p_info->unexpected_base = fetch_pointer(proc, head_ptr, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Send queues are optional */
|
|
Packit Service |
c5cf8c |
if (dbgr_find_symbol(image, (char *) "MPIR_Sendq_head", &p_info->sendq_base) == mqs_ok) {
|
|
Packit Service |
c5cf8c |
p_info->has_sendq = 1;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
p_info->has_sendq = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This routine is called by the debugger to map an error code into a
|
|
Packit Service |
c5cf8c |
printable string */
|
|
Packit Service |
c5cf8c |
const char *mqs_dll_error_string(int errcode)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
switch (errcode) {
|
|
Packit Service |
c5cf8c |
case err_silent_failure:
|
|
Packit Service |
c5cf8c |
return "";
|
|
Packit Service |
c5cf8c |
case err_no_current_communicator:
|
|
Packit Service |
c5cf8c |
return "No current communicator in the communicator iterator";
|
|
Packit Service |
c5cf8c |
case err_bad_request:
|
|
Packit Service |
c5cf8c |
return "Attempting to setup to iterate over an unknown queue of operations";
|
|
Packit Service |
c5cf8c |
case err_no_store:
|
|
Packit Service |
c5cf8c |
return "Unable to allocate store";
|
|
Packit Service |
c5cf8c |
case err_group_corrupt:
|
|
Packit Service |
c5cf8c |
return
|
|
Packit Service |
c5cf8c |
"Could not read a communicator's group from the process (probably a store corruption)";
|
|
Packit Service |
c5cf8c |
case err_unexpected:
|
|
Packit Service |
c5cf8c |
return "Failed to find symbol MPID_Recvq_unexpected_head_ptr";
|
|
Packit Service |
c5cf8c |
case err_posted:
|
|
Packit Service |
c5cf8c |
return "Failed to find symbol MPID_Recvq_posted_head_ptr";
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return "Unknown error code";
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Queue Display
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Communicator list.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* To avoid problems that might be caused by having the list of communicators
|
|
Packit Service |
c5cf8c |
* change in the process that is being debugged, the communicator access
|
|
Packit Service |
c5cf8c |
* routines make an internal copy of the communicator list.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* update_communicator_list makes a copy of the list of currently active
|
|
Packit Service |
c5cf8c |
* communicators and stores it in the mqs_process structure.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_update_communicator_list(mqs_process * proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (communicators_changed(proc))
|
|
Packit Service |
c5cf8c |
return rebuild_communicator_list(proc);
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* These three routines (setup_communicator_iterator, get_communicator,
|
|
Packit Service |
c5cf8c |
* and next_communicator) provide a way to access each communicator in the
|
|
Packit Service |
c5cf8c |
* list that is initialized by update_communicator_list.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_setup_communicator_iterator(mqs_process * proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Start at the front of the list again */
|
|
Packit Service |
c5cf8c |
p_info->current_communicator = p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
/* Reset the operation iterator too */
|
|
Packit Service |
c5cf8c |
p_info->next_msg = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return p_info->current_communicator == NULL ? mqs_end_of_list : mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int mqs_get_communicator(mqs_process * proc, mqs_communicator * comm)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (p_info->current_communicator) {
|
|
Packit Service |
c5cf8c |
*comm = p_info->current_communicator->comm_info;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
return err_no_current_communicator;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int mqs_next_communicator(mqs_process * proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_info->current_communicator = p_info->current_communicator->next;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return (p_info->current_communicator != NULL) ? mqs_ok : mqs_end_of_list;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Iterate over the queues attached to the current communicator. */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Forward references for routines used to implement the operations */
|
|
Packit Service |
c5cf8c |
static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pending_operation * res);
|
|
Packit Service |
c5cf8c |
static int fetch_receive(mqs_process * proc, mpich_process_info * p_info,
|
|
Packit Service |
c5cf8c |
mqs_pending_operation * res, int look_for_user_buffer);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int mqs_setup_operation_iterator(mqs_process * proc, int op)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
/* mqs_image * image = dbgr_get_image (proc); */
|
|
Packit Service |
c5cf8c |
/* mpich_image_info *i_info =
|
|
Packit Service |
c5cf8c |
(mpich_image_info *)dbgr_get_image_info (image); */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_info->what = (mqs_op_class) op;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
switch (op) {
|
|
Packit Service |
c5cf8c |
case mqs_pending_sends:
|
|
Packit Service |
c5cf8c |
if (!p_info->has_sendq)
|
|
Packit Service |
c5cf8c |
return mqs_no_information;
|
|
Packit Service |
c5cf8c |
else {
|
|
Packit Service |
c5cf8c |
p_info->next_msg = p_info->sendq_base;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* The address on the receive queues is the address of a pointer to
|
|
Packit Service |
c5cf8c |
* the head of the list. */
|
|
Packit Service |
c5cf8c |
case mqs_pending_receives:
|
|
Packit Service |
c5cf8c |
p_info->next_msg = p_info->posted_base;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
case mqs_unexpected_messages:
|
|
Packit Service |
c5cf8c |
p_info->next_msg = p_info->unexpected_base;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
default:
|
|
Packit Service |
c5cf8c |
return err_bad_request;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Fetch the next operation on the current communicator, from the
|
|
Packit Service |
c5cf8c |
selected queue. Since MPICH does not (normally) use separate queues
|
|
Packit Service |
c5cf8c |
for each communicator, we must compare the queue items with the
|
|
Packit Service |
c5cf8c |
current communicator.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int mqs_next_operation(mqs_process * proc, mqs_pending_operation * op)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
switch (p_info->what) {
|
|
Packit Service |
c5cf8c |
case mqs_pending_receives:
|
|
Packit Service |
c5cf8c |
return fetch_receive(proc, p_info, op, 1);
|
|
Packit Service |
c5cf8c |
case mqs_unexpected_messages:
|
|
Packit Service |
c5cf8c |
return fetch_receive(proc, p_info, op, 0);
|
|
Packit Service |
c5cf8c |
case mqs_pending_sends:
|
|
Packit Service |
c5cf8c |
return fetch_send(proc, p_info, op);
|
|
Packit Service |
c5cf8c |
default:
|
|
Packit Service |
c5cf8c |
return err_bad_request;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Clean up routines
|
|
Packit Service |
c5cf8c |
* These routines free any memory allocated when the process or image
|
|
Packit Service |
c5cf8c |
* structures were allocated.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void mqs_destroy_process_info(mqs_process_info * mp_info)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) mp_info;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Need to handle the communicators and groups too */
|
|
Packit Service |
c5cf8c |
mqs_free_communicator_list(p_info->communicator_list);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
dbgr_free(p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void mqs_destroy_image_info(mqs_image_info * info)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
dbgr_free(info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Internal Routine
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* These routine know about the internal structure of the MPI implementation.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the next entry in the current receive queue (posted or unexpected) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int fetch_receive(mqs_process * proc, mpich_process_info * p_info,
|
|
Packit Service |
c5cf8c |
mqs_pending_operation * res, int look_for_user_buffer)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_image *image = dbgr_get_image(proc);
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
communicator_t *comm = p_info->current_communicator;
|
|
Packit Service |
c5cf8c |
int16_t wanted_context = comm->recvcontext_id;
|
|
Packit Service |
c5cf8c |
mqs_taddr_t base = fetch_pointer(proc, p_info->next_msg, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_LIST_ITER
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
fprintf(debugfp, "fetch receive base = %x, comm= %x, context = %d\n",
|
|
Packit Service |
c5cf8c |
base, comm, wanted_context);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
while (base != 0) {
|
|
Packit Service |
c5cf8c |
/* Check this entry to see if the context matches */
|
|
Packit Service |
c5cf8c |
int16_t actual_context = fetch_int16(proc, base + i_info->req_context_id_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_LIST_ITER
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
fprintf(debugfp, "fetch receive msg context = %d\n", actual_context);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
if (actual_context == wanted_context) {
|
|
Packit Service |
c5cf8c |
/* Found a request for this communicator */
|
|
Packit Service |
c5cf8c |
int tag = fetch_int(proc, base + i_info->req_tag_offs, p_info);
|
|
Packit Service |
c5cf8c |
int rank = fetch_int16(proc, base + i_info->req_rank_offs, p_info);
|
|
Packit Service |
c5cf8c |
int is_complete = fetch_int(proc, base + i_info->req_cc_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t user_buffer = fetch_pointer(proc, base + i_info->req_user_buf_offs, p_info);
|
|
Packit Service |
c5cf8c |
int user_count = fetch_int(proc, base + i_info->req_user_count_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Return -1 for ANY_TAG or ANY_SOURCE */
|
|
Packit Service |
c5cf8c |
res->desired_tag = (tag >= 0) ? tag : -1;
|
|
Packit Service |
c5cf8c |
res->desired_local_rank = (rank >= 0) ? rank : -1;
|
|
Packit Service |
c5cf8c |
res->desired_global_rank = -1; /* Convert to rank in comm world,
|
|
Packit Service |
c5cf8c |
* if valid (in mpi-2, may
|
|
Packit Service |
c5cf8c |
* not be available) */
|
|
Packit Service |
c5cf8c |
res->desired_length = user_count; /* Count, not bytes */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
res->tag_wild = (tag < 0);
|
|
Packit Service |
c5cf8c |
res->buffer = user_buffer;
|
|
Packit Service |
c5cf8c |
/* We don't know the rest of these */
|
|
Packit Service |
c5cf8c |
res->system_buffer = 0;
|
|
Packit Service |
c5cf8c |
res->actual_local_rank = rank;
|
|
Packit Service |
c5cf8c |
res->actual_global_rank = -1;
|
|
Packit Service |
c5cf8c |
res->actual_tag = tag;
|
|
Packit Service |
c5cf8c |
res->actual_length = -1;
|
|
Packit Service |
c5cf8c |
res->extra_text[0][0] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
res->status = (is_complete != 0) ? mqs_st_pending : mqs_st_complete;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Don't forget to step the queue ! */
|
|
Packit Service |
c5cf8c |
p_info->next_msg = base + i_info->req_next_offs;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Try the next one */
|
|
Packit Service |
c5cf8c |
base = fetch_pointer(proc, base + i_info->req_next_offs, p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
while (base != 0) { /* Well, there's a queue, at least ! */
|
|
Packit Service |
c5cf8c |
mqs_tword_t actual_context = fetch_int16(proc, base + i_info->context_id_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (actual_context == wanted_context) { /* Found a good one */
|
|
Packit Service |
c5cf8c |
mqs_tword_t tag = fetch_int(proc, base + i_info->tag_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t tagmask = fetch_int(proc, base + i_info->tagmask_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t lsrc = fetch_int(proc, base + i_info->lsrc_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t srcmask = fetch_int(proc, base + i_info->srcmask_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t ptr = fetch_pointer(proc, base + i_info->ptr_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Fetch the fields from the MPIR_RHANDLE */
|
|
Packit Service |
c5cf8c |
int is_complete = fetch_int(proc, ptr + i_info->is_complete_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t buf = fetch_pointer(proc, ptr + i_info->buf_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t len = fetch_int(proc, ptr + i_info->len_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t count = fetch_int(proc, ptr + i_info->count_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* If we don't have start, then use buf instead... */
|
|
Packit Service |
c5cf8c |
mqs_taddr_t start;
|
|
Packit Service |
c5cf8c |
if (i_info->start_offs < 0)
|
|
Packit Service |
c5cf8c |
start = buf;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
start = fetch_pointer(proc, ptr + i_info->start_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Hurrah, we should now be able to fill in all the necessary fields in the
|
|
Packit Service |
c5cf8c |
* result !
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
res->status = is_complete ? mqs_st_complete : mqs_st_pending; /* We can't discern matched */
|
|
Packit Service |
c5cf8c |
if (srcmask == 0) {
|
|
Packit Service |
c5cf8c |
res->desired_local_rank = -1;
|
|
Packit Service |
c5cf8c |
res->desired_global_rank = -1;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
res->desired_local_rank = lsrc;
|
|
Packit Service |
c5cf8c |
res->desired_global_rank = translate(comm->group, lsrc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
res->tag_wild = (tagmask == 0);
|
|
Packit Service |
c5cf8c |
res->desired_tag = tag;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (look_for_user_buffer) {
|
|
Packit Service |
c5cf8c |
res->system_buffer = 0;
|
|
Packit Service |
c5cf8c |
res->buffer = buf;
|
|
Packit Service |
c5cf8c |
res->desired_length = len;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
res->system_buffer = 1;
|
|
Packit Service |
c5cf8c |
/* Correct an oddity. If the buffer length is zero then no buffer
|
|
Packit Service |
c5cf8c |
* is allocated, but the descriptor is left with random data.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
if (count == 0)
|
|
Packit Service |
c5cf8c |
start = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
res->buffer = start;
|
|
Packit Service |
c5cf8c |
res->desired_length = count;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (is_complete) { /* Fill in the actual results, rather than what we were looking for */
|
|
Packit Service |
c5cf8c |
mqs_tword_t mpi_source = fetch_int(proc, ptr + i_info->MPI_SOURCE_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t mpi_tag = fetch_int(proc, ptr + i_info->MPI_TAG_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
res->actual_length = count;
|
|
Packit Service |
c5cf8c |
res->actual_tag = mpi_tag;
|
|
Packit Service |
c5cf8c |
res->actual_local_rank = mpi_source;
|
|
Packit Service |
c5cf8c |
res->actual_global_rank = translate(comm->group, mpi_source);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Don't forget to step the queue ! */
|
|
Packit Service |
c5cf8c |
p_info->next_msg = base + i_info->next_offs;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} else { /* Try the next one */
|
|
Packit Service |
c5cf8c |
base = fetch_pointer(proc, base + i_info->next_offs, p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
p_info->next_msg = 0;
|
|
Packit Service |
c5cf8c |
return mqs_end_of_list;
|
|
Packit Service |
c5cf8c |
} /* fetch_receive */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the next entry in the send queue, if there is one. The assumption is
|
|
Packit Service |
c5cf8c |
that the MPI implementation is quiescent while these queue probes are
|
|
Packit Service |
c5cf8c |
taking place, so we can simply keep track of the location of the "next"
|
|
Packit Service |
c5cf8c |
entry. (in the next_msg field) */
|
|
Packit Service |
c5cf8c |
static int fetch_send(mqs_process * proc, mpich_process_info * p_info, mqs_pending_operation * res)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mqs_image *image = dbgr_get_image(proc);
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
communicator_t *comm = p_info->current_communicator;
|
|
Packit Service |
c5cf8c |
int wanted_context = comm->context_id;
|
|
Packit Service |
c5cf8c |
mqs_taddr_t base = fetch_pointer(proc, p_info->next_msg, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!p_info->has_sendq)
|
|
Packit Service |
c5cf8c |
return mqs_no_information;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_LIST_ITER
|
|
Packit Service |
c5cf8c |
if (base) {
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
fprintf(debugf, "comm ptr = %p, comm context = %d\n", comm, comm->context_id);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* Say what operation it is. We can only see non blocking send operations
|
|
Packit Service |
c5cf8c |
* in MPICH. Other MPI systems may be able to show more here.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* FIXME: handle size properly (declared as 64 in mpi_interface.h) */
|
|
Packit Service |
c5cf8c |
strncpy((char *) res->extra_text[0], "Non-blocking send", 20);
|
|
Packit Service |
c5cf8c |
res->extra_text[1][0] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (base != 0) {
|
|
Packit Service |
c5cf8c |
/* Check this entry to see if the context matches */
|
|
Packit Service |
c5cf8c |
int actual_context = fetch_int16(proc, base + i_info->sendq_context_id_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (actual_context == wanted_context) {
|
|
Packit Service |
c5cf8c |
/* Fill in some of the fields */
|
|
Packit Service |
c5cf8c |
mqs_tword_t target = fetch_int(proc, base + i_info->sendq_rank_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t tag = fetch_int(proc, base + i_info->sendq_tag_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t length = 0;
|
|
Packit Service |
c5cf8c |
mqs_taddr_t data = 0;
|
|
Packit Service |
c5cf8c |
mqs_taddr_t sreq = fetch_pointer(proc, base + i_info->sendq_req_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t is_complete = fetch_int(proc, sreq + i_info->req_cc_offs, p_info);
|
|
Packit Service |
c5cf8c |
data = fetch_pointer(proc, sreq + i_info->req_user_buf_offs, p_info);
|
|
Packit Service |
c5cf8c |
length = fetch_int(proc, sreq + i_info->req_user_count_offs, p_info);
|
|
Packit Service |
c5cf8c |
/* mqs_tword_t complete=0; */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_LIST_ITER
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
fprintf(debugpf, "sendq entry = %p, rank off = %d, tag off = %d, context = %d\n",
|
|
Packit Service |
c5cf8c |
base, i_info->sendq_rank_offs, i_info->sendq_tag_offs, actual_context);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Ok, fill in the results */
|
|
Packit Service |
c5cf8c |
res->status = (is_complete != 0) ? mqs_st_pending : mqs_st_complete;
|
|
Packit Service |
c5cf8c |
res->actual_local_rank = res->desired_local_rank = target;
|
|
Packit Service |
c5cf8c |
res->actual_global_rank = res->desired_global_rank = translate(comm->group, target);
|
|
Packit Service |
c5cf8c |
res->tag_wild = 0;
|
|
Packit Service |
c5cf8c |
res->actual_tag = res->desired_tag = tag;
|
|
Packit Service |
c5cf8c |
res->desired_length = res->actual_length = length;
|
|
Packit Service |
c5cf8c |
res->system_buffer = 0;
|
|
Packit Service |
c5cf8c |
res->buffer = data;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Don't forget to step the queue ! */
|
|
Packit Service |
c5cf8c |
p_info->next_msg = base + i_info->sendq_next_offs;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Try the next one */
|
|
Packit Service |
c5cf8c |
base = fetch_pointer(proc, base + i_info->sendq_next_offs, p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
while (base != 0) { /* Well, there's a queue, at least ! */
|
|
Packit Service |
c5cf8c |
/* Check if it's one we're interested in ? */
|
|
Packit Service |
c5cf8c |
mqs_taddr_t commp = fetch_pointer(proc, base + i_info->db_comm_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t next = base + i_info->db_next_offs;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (commp == comm->comm_info.unique_id) { /* Found one */
|
|
Packit Service |
c5cf8c |
mqs_tword_t target = fetch_int(proc, base + i_info->db_target_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t tag = fetch_int(proc, base + i_info->db_tag_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t length = fetch_int(proc, base + i_info->db_byte_length_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t data = fetch_pointer(proc, base + i_info->db_data_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t shandle = fetch_pointer(proc, base + i_info->db_shandle_offs, p_info);
|
|
Packit Service |
c5cf8c |
mqs_tword_t complete = fetch_int(proc, shandle + i_info->is_complete_offs, p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Ok, fill in the results */
|
|
Packit Service |
c5cf8c |
res->status = complete ? mqs_st_complete : mqs_st_pending; /* We can't discern matched */
|
|
Packit Service |
c5cf8c |
res->actual_local_rank = res->desired_local_rank = target;
|
|
Packit Service |
c5cf8c |
res->actual_global_rank = res->desired_global_rank = translate(comm->group, target);
|
|
Packit Service |
c5cf8c |
res->tag_wild = 0;
|
|
Packit Service |
c5cf8c |
res->actual_tag = res->desired_tag = tag;
|
|
Packit Service |
c5cf8c |
res->desired_length = res->actual_length = length;
|
|
Packit Service |
c5cf8c |
res->system_buffer = 0;
|
|
Packit Service |
c5cf8c |
res->buffer = data;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_info->next_msg = next;
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
base = fetch_pointer(proc, next, p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_info->next_msg = 0;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
return mqs_end_of_list;
|
|
Packit Service |
c5cf8c |
} /* fetch_send */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Communicator */
|
|
Packit Service |
c5cf8c |
static int communicators_changed(mqs_process * proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
mqs_image *image = dbgr_get_image(proc);
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
mqs_tword_t new_seq = fetch_int(proc,
|
|
Packit Service |
c5cf8c |
p_info->commlist_base + i_info->sequence_number_offs,
|
|
Packit Service |
c5cf8c |
p_info);
|
|
Packit Service |
c5cf8c |
int res = (new_seq != p_info->communicator_sequence);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Save the sequence number for next time */
|
|
Packit Service |
c5cf8c |
p_info->communicator_sequence = new_seq;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return res;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/***********************************************************************
|
|
Packit Service |
c5cf8c |
* Find a matching communicator on our list. We check the recv context
|
|
Packit Service |
c5cf8c |
* as well as the address since the communicator structures may be
|
|
Packit Service |
c5cf8c |
* being re-allocated from a free list, in which case the same
|
|
Packit Service |
c5cf8c |
* address will be re-used a lot, which could confuse us.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static communicator_t *find_communicator(mpich_process_info * p_info,
|
|
Packit Service |
c5cf8c |
mqs_taddr_t comm_base, int recv_ctx)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
communicator_t *comm = p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (; comm; comm = comm->next) {
|
|
Packit Service |
c5cf8c |
if (comm->comm_info.unique_id == comm_base && comm->recvcontext_id == recv_ctx)
|
|
Packit Service |
c5cf8c |
return comm;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
} /* find_communicator */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is the comparison function used in the qsort call in
|
|
Packit Service |
c5cf8c |
rebuild_communicator_list */
|
|
Packit Service |
c5cf8c |
static int compare_comms(const void *a, const void *b)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
communicator_t *ca = *(communicator_t **) a;
|
|
Packit Service |
c5cf8c |
communicator_t *cb = *(communicator_t **) b;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return cb->recvcontext_id - ca->recvcontext_id;
|
|
Packit Service |
c5cf8c |
} /* compare_comms */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int rebuild_communicator_list(mqs_process * proc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
mpich_process_info *p_info = (mpich_process_info *) dbgr_get_process_info(proc);
|
|
Packit Service |
c5cf8c |
mqs_image *image = dbgr_get_image(proc);
|
|
Packit Service |
c5cf8c |
mpich_image_info *i_info = (mpich_image_info *) dbgr_get_image_info(image);
|
|
Packit Service |
c5cf8c |
mqs_taddr_t comm_base = fetch_pointer(proc,
|
|
Packit Service |
c5cf8c |
p_info->commlist_base + i_info->comm_head_offs,
|
|
Packit Service |
c5cf8c |
p_info);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
communicator_t **commp;
|
|
Packit Service |
c5cf8c |
int commcount = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Iterate over the list in the process comparing with the list
|
|
Packit Service |
c5cf8c |
* we already have saved. This is n**2, because we search for each
|
|
Packit Service |
c5cf8c |
* communicator on the existing list. I don't think it matters, though
|
|
Packit Service |
c5cf8c |
* because there aren't that many communicators to worry about, and
|
|
Packit Service |
c5cf8c |
* we only ever do this if something changed.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
while (comm_base) {
|
|
Packit Service |
c5cf8c |
/* We do have one to look at, so extract the info */
|
|
Packit Service |
c5cf8c |
int recv_ctx = fetch_int16(proc, comm_base + i_info->comm_recvcontext_id_offs, p_info);
|
|
Packit Service |
c5cf8c |
int send_ctx = fetch_int16(proc, comm_base + i_info->comm_context_id_offs, p_info);
|
|
Packit Service |
c5cf8c |
communicator_t *old = find_communicator(p_info, comm_base, recv_ctx);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
const char *name = "--unnamed--";
|
|
Packit Service |
c5cf8c |
char namebuffer[64];
|
|
Packit Service |
c5cf8c |
/* In MPICH, the name is preallocated and of size MPI_MAX_OBJECT_NAME */
|
|
Packit Service |
c5cf8c |
if (dbgr_fetch_data(proc, comm_base + i_info->comm_name_offs, 64,
|
|
Packit Service |
c5cf8c |
namebuffer) == mqs_ok && namebuffer[0] != 0) {
|
|
Packit Service |
c5cf8c |
name = namebuffer;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (old) {
|
|
Packit Service |
c5cf8c |
old->present = 1; /* We do want this communicator */
|
|
Packit Service |
c5cf8c |
strncpy(old->comm_info.name, name, sizeof(old->comm_info.name)); /* Make sure the name is up to date,
|
|
Packit Service |
c5cf8c |
* it might have changed and we can't tell.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
mqs_taddr_t group_base = fetch_pointer(proc, comm_base + i_info->lrank_to_grank_offs,
|
|
Packit Service |
c5cf8c |
p_info);
|
|
Packit Service |
c5cf8c |
int np = fetch_int(proc, comm_base + i_info->comm_rsize_offs, p_info);
|
|
Packit Service |
c5cf8c |
group_t *g = find_or_create_group(proc, np, group_base);
|
|
Packit Service |
c5cf8c |
communicator_t *nc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
if (!g)
|
|
Packit Service |
c5cf8c |
return err_group_corrupt;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
nc = (communicator_t *) dbgr_malloc(sizeof(communicator_t));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Save the results */
|
|
Packit Service |
c5cf8c |
nc->next = p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
p_info->communicator_list = nc;
|
|
Packit Service |
c5cf8c |
nc->present = 1;
|
|
Packit Service |
c5cf8c |
nc->group = g;
|
|
Packit Service |
c5cf8c |
nc->context_id = send_ctx;
|
|
Packit Service |
c5cf8c |
nc->recvcontext_id = recv_ctx;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
strncpy(nc->comm_info.name, name, sizeof(nc->comm_info.name));
|
|
Packit Service |
c5cf8c |
nc->comm_info.unique_id = comm_base;
|
|
Packit Service |
c5cf8c |
nc->comm_info.size = np;
|
|
Packit Service |
c5cf8c |
nc->comm_info.local_rank = fetch_int(proc, comm_base + i_info->comm_rank_offs, p_info);
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG_LIST_ITER
|
|
Packit Service |
c5cf8c |
initLogFile();
|
|
Packit Service |
c5cf8c |
fprintf(debugfp,
|
|
Packit Service |
c5cf8c |
"Adding communicator %p, send context=%d, recv context=%d, size=%d, name=%s\n",
|
|
Packit Service |
c5cf8c |
comm_base, send_ctx, recv_ctx, np, name);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
nc->comm_info.local_rank = reverse_translate(g, dbgr_get_global_rank(proc));
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* Step to the next communicator on the list */
|
|
Packit Service |
c5cf8c |
comm_base = fetch_pointer(proc, comm_base + i_info->comm_next_offs, p_info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Now iterate over the list tidying up any communicators which
|
|
Packit Service |
c5cf8c |
* no longer exist, and cleaning the flags on any which do.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
commp = &p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (; *commp; commp = &(*commp)->next) {
|
|
Packit Service |
c5cf8c |
communicator_t *comm = *commp;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (comm->present) {
|
|
Packit Service |
c5cf8c |
comm->present = 0;
|
|
Packit Service |
c5cf8c |
commcount++;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* It needs to be deleted */
|
|
Packit Service |
c5cf8c |
*commp = comm->next; /* Remove from the list */
|
|
Packit Service |
c5cf8c |
group_decref(comm->group); /* Group is no longer referenced from here */
|
|
Packit Service |
c5cf8c |
dbgr_free(comm);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (commcount) {
|
|
Packit Service |
c5cf8c |
/* Sort the list so that it is displayed in some semi-sane order. */
|
|
Packit Service |
c5cf8c |
communicator_t **comm_array =
|
|
Packit Service |
c5cf8c |
(communicator_t **) dbgr_malloc(commcount * sizeof(communicator_t *));
|
|
Packit Service |
c5cf8c |
communicator_t *comm = p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < commcount; i++, comm = comm->next)
|
|
Packit Service |
c5cf8c |
comm_array[i] = comm;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Do the sort */
|
|
Packit Service |
c5cf8c |
qsort(comm_array, commcount, sizeof(communicator_t *), compare_comms);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Re build the list */
|
|
Packit Service |
c5cf8c |
p_info->communicator_list = NULL;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < commcount; i++) {
|
|
Packit Service |
c5cf8c |
comm = comm_array[i];
|
|
Packit Service |
c5cf8c |
comm->next = p_info->communicator_list;
|
|
Packit Service |
c5cf8c |
p_info->communicator_list = comm;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
dbgr_free(comm_array);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mqs_ok;
|
|
Packit Service |
c5cf8c |
} /* rebuild_communicator_list */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Internal routine to free the communicator list */
|
|
Packit Service |
c5cf8c |
static void mqs_free_communicator_list(struct communicator_t *comm)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
while (comm) {
|
|
Packit Service |
c5cf8c |
communicator_t *next = comm->next;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Release the group data structures */
|
|
Packit Service |
c5cf8c |
/* group_decref (comm->group); */
|
|
Packit Service |
c5cf8c |
dbgr_free(comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
comm = next;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------ */
|
|
Packit Service |
c5cf8c |
/* Internal routine to fetch data from the process */
|
|
Packit Service |
c5cf8c |
static mqs_taddr_t fetch_pointer(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int asize = p_info->sizes.pointer_size;
|
|
Packit Service |
c5cf8c |
char data[8]; /* ASSUME a pointer fits in 8 bytes */
|
|
Packit Service |
c5cf8c |
mqs_taddr_t res = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mqs_ok == dbgr_fetch_data(proc, addr, asize, data))
|
|
Packit Service |
c5cf8c |
dbgr_target_to_host(proc, data,
|
|
Packit Service |
c5cf8c |
((char *) &res) + (host_is_big_endian ? sizeof(mqs_taddr_t) -
|
|
Packit Service |
c5cf8c |
asize : 0), asize);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return res;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static mqs_tword_t fetch_int(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int isize = p_info->sizes.int_size;
|
|
Packit Service |
c5cf8c |
char buffer[8]; /* ASSUME an integer fits in 8 bytes */
|
|
Packit Service |
c5cf8c |
mqs_tword_t res = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mqs_ok == dbgr_fetch_data(proc, addr, isize, buffer))
|
|
Packit Service |
c5cf8c |
dbgr_target_to_host(proc, buffer,
|
|
Packit Service |
c5cf8c |
((char *) &res) + (host_is_big_endian ? sizeof(mqs_tword_t) -
|
|
Packit Service |
c5cf8c |
isize : 0), isize);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return res;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static mqs_tword_t fetch_int16(mqs_process * proc, mqs_taddr_t addr, mpich_process_info * p_info)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buffer[8]; /* ASSUME an integer fits in 8 bytes */
|
|
Packit Service |
c5cf8c |
int16_t res = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mqs_ok == dbgr_fetch_data(proc, addr, 2, buffer))
|
|
Packit Service |
c5cf8c |
dbgr_target_to_host(proc, buffer,
|
|
Packit Service |
c5cf8c |
((char *) &res) + (host_is_big_endian ? sizeof(mqs_tword_t) - 2 : 0),
|
|
Packit Service |
c5cf8c |
2);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return res;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
/* With each communicator we need to translate ranks to/from their
|
|
Packit Service |
c5cf8c |
MPI_COMM_WORLD equivalents. This code is not yet implemented
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
/* idx is rank in group this; return rank in MPI_COMM_WORLD */
|
|
Packit Service |
c5cf8c |
static int translate(group_t * this, int idx)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#if 0
|
|
Packit Service |
c5cf8c |
/* idx is rank in MPI_COMM_WORLD, return rank in group this */
|
|
Packit Service |
c5cf8c |
static int reverse_translate(group_t * this, int idx)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
static group_t *find_or_create_group(mqs_process * proc, mqs_tword_t np, mqs_taddr_t table)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static void group_decref(group_t * group)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (--(group->ref_count) == 0) {
|
|
Packit Service |
c5cf8c |
dbgr_free(group->local_to_global);
|
|
Packit Service |
c5cf8c |
dbgr_free(group);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} /* group_decref */
|