/****************************************************************************
**  SCALASCA    http://www.scalasca.org/                                   **
*****************************************************************************
**  Copyright (c) 1998-2012                                                **
**  Forschungszentrum Juelich GmbH, Juelich Supercomputing Centre          **
**                                                                         **
**  Copyright (c) 2010-2012                                                **
**  German Research School for Simulation Sciences GmbH,                   **
**  Laboratory for Parallel Programming                                    **
**                                                                         **
**  Copyright (c) 2003-2008                                                **
**  University of Tennessee, Innovative Computing Laboratory               **
**                                                                         **
**  See the file COPYRIGHT in the package base directory for details       **
****************************************************************************/

/**
 * @file  epk_mpiwrap_ext.c
 *
 * @brief C interface wrappers for external interface functions
 */

#include <mpi.h>

#include "esd_event.h"

#include "elg_error.h"

#include "epk_defs_mpi.h"
#include "epk_mpiwrap.h"

/**
 * @name C wrappers
 * @{
 */

#if defined(HAS_MPI_ABORT)
/**
 * Measurement wrapper for MPI_Abort
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 1.0
 * @ingroup ext
 */
int MPI_Abort(MPI_Comm comm,
              int      errorcode)
{
  int return_val;

  elg_warning("Explicit MPI_Abort call abandoning Scalasca measurement.");

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_ABORT]);

    return_val = PMPI_Abort(comm, errorcode);

    esd_exit(epk_mpi_regid[EPK__MPI_ABORT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Abort(comm, errorcode);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_GET_COUNT) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Get_count
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 1.0
 * @ingroup ext
 */
int MPI_Get_count(MPI_Status*  status,
                  MPI_Datatype datatype,
                  int*         count)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_GET_COUNT]);

    return_val = PMPI_Get_count(status, datatype, count);

    esd_exit(epk_mpi_regid[EPK__MPI_GET_COUNT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Get_count(status, datatype, count);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_GET_ELEMENTS) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Get_elements
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 1.0
 * @ingroup ext
 */
int MPI_Get_elements(MPI_Status*  status,
                     MPI_Datatype datatype,
                     int*         count)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_GET_ELEMENTS]);

    return_val = PMPI_Get_elements(status, datatype, count);

    esd_exit(epk_mpi_regid[EPK__MPI_GET_ELEMENTS]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Get_elements(status, datatype, count);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_GET_PROCESSOR_NAME) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Get_processor_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 1.0
 * @ingroup ext
 */
int MPI_Get_processor_name(char* name,
                           int*  resultlen)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_GET_PROCESSOR_NAME]);

    return_val = PMPI_Get_processor_name(name, resultlen);

    esd_exit(epk_mpi_regid[EPK__MPI_GET_PROCESSOR_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Get_processor_name(name, resultlen);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_GREQUEST_COMPLETE) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Grequest_complete
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup ext
 */
int MPI_Grequest_complete(MPI_Request request)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_GREQUEST_COMPLETE]);

    return_val = PMPI_Grequest_complete(request);

    esd_exit(epk_mpi_regid[EPK__MPI_GREQUEST_COMPLETE]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Grequest_complete(request);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_GREQUEST_START) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Grequest_start
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup ext
 */
int MPI_Grequest_start(MPI_Grequest_query_function*  query_fn,
                       MPI_Grequest_free_function*   free_fn,
                       MPI_Grequest_cancel_function* cancel_fn,
                       void*                         extra_state,
                       MPI_Request*                  request)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_GREQUEST_START]);

    return_val = PMPI_Grequest_start(query_fn,
                                     free_fn,
                                     cancel_fn,
                                     extra_state,
                                     request);

    esd_exit(epk_mpi_regid[EPK__MPI_GREQUEST_START]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Grequest_start(query_fn,
                                     free_fn,
                                     cancel_fn,
                                     extra_state,
                                     request);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_STATUS_SET_CANCELLED) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_MISC)
/**
 * Measurement wrapper for MPI_Status_set_cancelled
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup ext
 */
int MPI_Status_set_cancelled(MPI_Status* status,
                             int         flag)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_STATUS_SET_CANCELLED]);

    return_val = PMPI_Status_set_cancelled(status, flag);

    esd_exit(epk_mpi_regid[EPK__MPI_STATUS_SET_CANCELLED]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Status_set_cancelled(status, flag);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_STATUS_SET_ELEMENTS) && !defined(NO_MPI_EXTRA) \
  && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Status_set_elements
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup ext
 */
int MPI_Status_set_elements(MPI_Status*  status,
                            MPI_Datatype datatype,
                            int          count)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_STATUS_SET_ELEMENTS]);

    return_val = PMPI_Status_set_elements(status, datatype, count);

    esd_exit(epk_mpi_regid[EPK__MPI_STATUS_SET_ELEMENTS]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Status_set_elements(status, datatype, count);
  }

  return return_val;
}

#endif

/**
 * @}
 */
