1
1
openmpi/ompi/peruse/peruse.c
George Bosilca 686cc9ef54 First cut of PERUSE. Right now we support all the Peruse definitions from the
version 1.12. As in the 2.0 everything related to windows and files has been removed
I prefer to add the complete files, so I have a trace in the SN for later.

This commit was SVN r9373.
2006-03-23 05:00:55 +00:00

467 строки
14 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include "mpi.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include "ompi/peruse/peruse.h"
#include "ompi/peruse/peruse-internal.h"
#include "opal/class/opal_hash_table.h"
#include "ompi/communicator/communicator.h"
#include "ompi/file/file.h"
OMPI_DECLSPEC extern bool ompi_mpi_param_check;
/*
* Data
*/
/*
* This array has to match the array in peruse.h
* and the PERUSE_events -array below.
*/
const char * PERUSE_event_names[] = {
/* Point-to-point request events */
"PERUSE_COMM_REQ_ACTIVATE",
"PERUSE_COMM_REQ_MATCH_UNEX",
"PERUSE_COMM_REQ_INSERT_IN_POSTED_Q",
"PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q",
"PERUSE_COMM_REQ_XFER_BEGIN",
"PERUSE_COMM_REQ_XFER_END",
"PERUSE_COMM_REQ_COMPLETE",
"PERUSE_COMM_REQ_NOTIFY",
"PERUSE_COMM_MSG_ARRIVED",
"PERUSE_COMM_MSG_INSERT_IN_UNEX_Q",
"PERUSE_COMM_MSG_REMOVE_FROM_UNEX_Q",
"PERUSE_COMM_MSG_MATCH_POSTED_REQ",
/* Queue events*/
"PERUSE_COMM_SEARCH_POSTED_Q_BEGIN",
"PERUSE_COMM_SEARCH_POSTED_Q_END",
"PERUSE_COMM_SEARCH_UNEX_Q_BEGIN", /* XXX Devation from 1.11 */
"PERUSE_COMM_SEARCH_UNEX_Q_END"
};
const int PERUSE_events[] = {
/* Point-to-point request events */
PERUSE_COMM_REQ_ACTIVATE,
PERUSE_COMM_REQ_MATCH_UNEX,
PERUSE_COMM_REQ_INSERT_IN_POSTED_Q,
PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q,
PERUSE_COMM_REQ_XFER_BEGIN,
PERUSE_COMM_REQ_XFER_END,
PERUSE_COMM_REQ_COMPLETE,
PERUSE_COMM_REQ_NOTIFY,
PERUSE_COMM_MSG_ARRIVED,
PERUSE_COMM_MSG_INSERT_IN_UNEX_Q,
PERUSE_COMM_MSG_REMOVE_FROM_UNEX_Q,
PERUSE_COMM_MSG_MATCH_POSTED_REQ,
/* Queue events*/
PERUSE_COMM_SEARCH_POSTED_Q_BEGIN,
PERUSE_COMM_SEARCH_POSTED_Q_END,
PERUSE_COMM_SEARCH_UNEX_Q_BEGIN,
PERUSE_COMM_SEARCH_UNEX_Q_END
};
const int PERUSE_num_events = (sizeof (PERUSE_events) / sizeof (PERUSE_events[0]));
/*
* PERUSE user-callable function
*/
int PERUSE_Init (void)
{
ompi_peruse_init ();
return PERUSE_SUCCESS;
}
/* Query all implemented events */
int PERUSE_Query_supported_events (
int * num_supported,
char *** event_names,
int ** events)
{
int i;
*num_supported = PERUSE_num_events;
/*
* Play save and copy all values.
*/
*event_names = (char**) malloc (PERUSE_num_events * sizeof (char *));
*events = (int*) malloc (PERUSE_num_events * sizeof (int));
for (i = 0; i < PERUSE_num_events; i++) {
(*event_names)[i] = strdup (PERUSE_event_names[i]);
(*events)[i] = PERUSE_events[i];
}
return PERUSE_SUCCESS;
}
/* Query supported events */
int PERUSE_Query_event (const char * event_name, int *event)
{
int i;
for (i = 0; i < PERUSE_num_events; i++) {
if (!strcmp (event_name, PERUSE_event_names[i]))
break;
}
if (i == PERUSE_num_events)
return PERUSE_ERR_EVENT;
*event = PERUSE_events[i];
return PERUSE_SUCCESS;
}
/* Query event name */
int PERUSE_Query_event_name (int event, char ** event_name)
{
if (event < 0 || event > PERUSE_num_events ||
NULL == PERUSE_event_names[event])
return PERUSE_EVENT_INVALID;
*event_name = strdup (PERUSE_event_names[event]);
return PERUSE_SUCCESS;
}
/* Get environment variables that affect MPI library behavior */
int PERUSE_Query_environment (int * env_size, char *** env)
{
/* XXX tbd */
return PERUSE_SUCCESS;
}
/* Query the scope of queue metrics - global or per communicator */
int PERUSE_Query_queue_event_scope (int * scope)
{
*scope = PERUSE_PER_COMM; /* XXX; not yet realized */
return PERUSE_SUCCESS;
}
/*
* II. Events, objects initialization and manipulation
*/
/* Initialize event associated with an MPI communicator */
int PERUSE_Event_comm_register (
int event,
MPI_Comm comm,
peruse_comm_callback_f * callback_fn,
void * param,
peruse_event_h * event_h)
{
ompi_peruse_handle_t * handle;
if (MPI_PARAM_CHECK) {
if (event < 0 || event > PERUSE_num_events ||
NULL == PERUSE_event_names[event])
return PERUSE_ERR_EVENT;
if (MPI_COMM_NULL == comm || ompi_comm_invalid (comm))
return PERUSE_ERR_COMM;
if (NULL == callback_fn)
return PERUSE_ERR_GENERIC;
if (NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
}
handle = OBJ_NEW (ompi_peruse_handle_t);
/*
* Initialize the newly created handle to the default inactive state.
*/
handle->active = 0;
handle->event = event;
handle->type = PERUSE_TYPE_COMM;
handle->comm = comm;
handle->fn = (ompi_peruse_callback_f*) callback_fn;
handle->param = param;
/*
* Update the information on the handle on the communicator
*/
OPAL_THREAD_LOCK (&comm->c_lock);
if( NULL == comm->c_peruse_handles ) {
comm->c_peruse_handles = malloc( PERUSE_num_events * sizeof(ompi_peruse_handle_t*) );
}
OPAL_THREAD_UNLOCK (&comm->c_lock);
comm->c_peruse_handles[event] = handle;
*event_h = handle;
return PERUSE_SUCCESS;
}
/* Start collecting data (activate event) */
int PERUSE_Event_activate (peruse_event_h event_h)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
if (MPI_PARAM_CHECK) {
if (PERUSE_EVENT_HANDLE_NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
}
OPAL_THREAD_LOCK (&handle->lock);
handle->active = 1;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Stop collecting data (deactivate event) */
int PERUSE_Event_deactivate (peruse_event_h event_h)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
if (MPI_PARAM_CHECK) {
if (PERUSE_EVENT_HANDLE_NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
}
OPAL_THREAD_LOCK (&handle->lock);
handle->active = 0;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Free event handle */
int PERUSE_Event_release (peruse_event_h * event_h)
{
if (MPI_PARAM_CHECK) {
if (PERUSE_EVENT_HANDLE_NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
}
/*
* XXX
*/
*event_h = PERUSE_EVENT_HANDLE_NULL;
return PERUSE_SUCCESS;
}
#undef PERUSE_MPI_PARAM_CHECK
#define PERUSE_MPI_PARAM_CHECK(obj_upper,obj_lower ) \
if (MPI_PARAM_CHECK) { \
if (PERUSE_EVENT_HANDLE_NULL == event_h || \
((ompi_peruse_handle_t*)event_h)->active || \
((ompi_peruse_handle_t*)event_h)->type != \
PERUSE_TYPE_ ## obj_upper) \
return PERUSE_ERR_EVENT_HANDLE; \
\
if (NULL == callback_fn) \
return PERUSE_ERR_PARAMETER; \
/* \
* XXX whethter the underlying MPI-object has been freed!?? \
if (ompi_ ## obj_lower ## _invalid ( \
((ompi_peruse_handle_t*)event_h)->obj_lower)) \
return PERUSE_ERR_MPI_OBJECT; \
*/ \
} \
/* Set a new comm callback */
int PERUSE_Event_comm_callback_set (
peruse_event_h event_h,
peruse_comm_callback_f * callback_fn,
void * param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (COMM, comm);
OPAL_THREAD_LOCK (&handle->lock);
handle->fn = (ompi_peruse_callback_f*) callback_fn;
handle->param = param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Set a new file callback */
int PERUSE_Event_file_callback_set (
peruse_event_h event_h,
peruse_file_callback_f * callback_fn,
void * param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (FILE, file);
OPAL_THREAD_LOCK (&handle->lock);
handle->fn = (ompi_peruse_callback_f*) callback_fn;
handle->param = param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Set a new win callback */
int PERUSE_Event_win_callback_set (
peruse_event_h event_h,
peruse_win_callback_f * callback_fn,
void * param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (WIN, win);
OPAL_THREAD_LOCK (&handle->lock);
handle->fn = (ompi_peruse_callback_f*) callback_fn;
handle->param = param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
#undef PERUSE_MPI_PARAM_CHECK
#define PERUSE_MPI_PARAM_CHECK(obj_upper,obj_lower ) \
if (MPI_PARAM_CHECK) { \
if (PERUSE_EVENT_HANDLE_NULL == event_h || \
((ompi_peruse_handle_t*)event_h)->active || \
((ompi_peruse_handle_t*)event_h)->type != \
PERUSE_TYPE_ ## obj_upper) \
return PERUSE_ERR_EVENT_HANDLE; \
\
if (NULL == callback_fn || NULL == param) \
return PERUSE_ERR_PARAMETER; \
/* \
* XXX whethter the underlying MPI-object has been freed!?? \
if (ompi_ ## obj_lower ## _invalid ( \
((ompi_peruse_handle_t*)event_h)->obj_lower)) \
return PERUSE_ERR_MPI_OBJECT; \
*/ \
} \
/* Get the current comm callback */
int PERUSE_Event_comm_callback_get (
peruse_event_h event_h,
peruse_comm_callback_f ** callback_fn,
void ** param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (COMM, comm);
OPAL_THREAD_LOCK (&handle->lock);
*callback_fn = (peruse_comm_callback_f*) handle->fn;
*param = handle->param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Get the current ile callback */
int PERUSE_Event_file_callback_get (
peruse_event_h event_h,
peruse_file_callback_f ** callback_fn,
void ** param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (FILE, file);
OPAL_THREAD_LOCK (&handle->lock);
*callback_fn = (peruse_file_callback_f*) handle->fn;
*param = handle->param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Get the current win callback */
int PERUSE_Event_win_callback_get (
peruse_event_h event_h,
peruse_win_callback_f ** callback_fn,
void ** param)
{
ompi_peruse_handle_t* handle = (ompi_peruse_handle_t*)event_h;
PERUSE_MPI_PARAM_CHECK (WIN, win);
OPAL_THREAD_LOCK (&handle->lock);
*callback_fn = (peruse_win_callback_f*) handle->fn;
*param = handle->param;
OPAL_THREAD_UNLOCK (&handle->lock);
return PERUSE_SUCCESS;
}
/* Obtain event descriptor from an event handle (reverse lookup) */
int PERUSE_Event_get (peruse_event_h event_h, int * event)
{
if (MPI_PARAM_CHECK) {
if (NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
if (NULL == event)
return PERUSE_ERR_PARAMETER;
}
*event = ((ompi_peruse_handle_t*)event_h)->event;
return PERUSE_SUCCESS;
}
/* Obtain MPI object associated with event handle */
/* XXX Shouldn't we have 3 different functions to obtain a specific object Comm/File/Win */
int PERUSE_Event_object_get (peruse_event_h event_h, void ** mpi_object)
{
ompi_peruse_handle_t * p = event_h;
if (MPI_PARAM_CHECK) {
if (NULL == event_h)
return PERUSE_ERR_EVENT_HANDLE;
if (NULL == mpi_object)
return PERUSE_ERR_PARAMETER;
}
switch (p->type) {
case PERUSE_TYPE_INVALID:
return PERUSE_ERR_GENERIC;
case PERUSE_TYPE_COMM:
*mpi_object = p->comm;
break;
case PERUSE_TYPE_FILE:
*mpi_object = p->file;
break;
case PERUSE_TYPE_WIN:
*mpi_object = p->win;
break;
}
return PERUSE_SUCCESS;
}
/* Propagaiont mode */
int PERUSE_Event_propagate (peruse_event_h event_h, int mode)
{
return PERUSE_SUCCESS;
}