/****************************************************************************
**  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_rma.c
 *
 * @brief C interface wrappers for one-sided communication
 */

#if defined(_SX)
/* Workaround to fix missing include with NEC MPI */
#include <stddef.h>
#endif

#include <mpi.h>

#include "esd_event.h"

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

/** internal id counter for rma operations */
static int epk_rma_id = 0;

/** current rma id to use in event generation */
#define EPK_CURR_RMA_ID   epk_rma_id
/** increment and get rma id to use in event generation */
#define EPK_NEXT_RMA_ID ++epk_rma_id

/**
 * @name C wrappers for access functions
 * @{
 */
#if defined(HAS_MPI_ACCUMULATE) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Accumulate
 * @note Auto-generated by wrapgen from template: rma_put.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Accumulate(void*        origin_addr,
                   int          origin_count,
                   MPI_Datatype origin_datatype,
                   int          target_rank,
                   MPI_Aint     target_disp,
                   int          target_count,
                   MPI_Datatype target_datatype,
                   MPI_Op       op,
                   MPI_Win      win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    int     sendsz;
    elg_ui4 dpid;
    elg_ui4 wid;

    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_ACCUMULATE]);

    dpid = EPK_RANK(target_rank);
    wid  = epk_win_id(win);

    PMPI_Type_size(origin_datatype, &sendsz);
    esd_mpi_put_1ts(dpid, wid, EPK_NEXT_RMA_ID, origin_count * sendsz);

    return_val = PMPI_Accumulate(origin_addr,
                                 origin_count,
                                 origin_datatype,
                                 target_rank,
                                 target_disp,
                                 target_count,
                                 target_datatype,
                                 op,
                                 win);

    esd_mpi_put_1te_remote(dpid, wid, EPK_CURR_RMA_ID);

    esd_exit(epk_mpi_regid[EPK__MPI_ACCUMULATE]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Accumulate(origin_addr,
                                 origin_count,
                                 origin_datatype,
                                 target_rank,
                                 target_disp,
                                 target_count,
                                 target_datatype,
                                 op,
                                 win);
  }

  return return_val;
} /* MPI_Accumulate */

#endif

#if defined(HAS_MPI_GET) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Get
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Get(void*        origin_addr,
            int          origin_count,
            MPI_Datatype origin_datatype,
            int          target_rank,
            MPI_Aint     target_disp,
            int          target_count,
            MPI_Datatype target_datatype,
            MPI_Win      win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    int     sendsz;
    elg_ui4 dpid;
    elg_ui4 wid;

    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_GET]);

    dpid = EPK_RANK(target_rank);
    wid  = epk_win_id(win);

    /* in MPI_GET the target buffer is remote */
    PMPI_Type_size(target_datatype, &sendsz);
    esd_mpi_get_1ts_remote(dpid,
                           wid,
                           EPK_NEXT_RMA_ID,
                           target_count * sendsz);

    return_val = PMPI_Get(origin_addr, origin_count,
                          origin_datatype, target_rank, target_disp,
                          target_count, target_datatype, win);

    /* in MPI_GET the origin buffer is local */
    esd_mpi_get_1te(dpid, wid, EPK_CURR_RMA_ID);

    esd_exit(epk_mpi_regid[EPK__MPI_GET]);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Get(origin_addr, origin_count,
                          origin_datatype, target_rank, target_disp,
                          target_count, target_datatype, win);
  }

  return return_val;
} /* MPI_Get */

#endif

#if defined(HAS_MPI_PUT) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Put
 * @note Auto-generated by wrapgen from template: rma_put.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Put(void*        origin_addr,
            int          origin_count,
            MPI_Datatype origin_datatype,
            int          target_rank,
            MPI_Aint     target_disp,
            int          target_count,
            MPI_Datatype target_datatype,
            MPI_Win      win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    int     sendsz;
    elg_ui4 dpid;
    elg_ui4 wid;

    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_PUT]);

    dpid = EPK_RANK(target_rank);
    wid  = epk_win_id(win);

    PMPI_Type_size(origin_datatype, &sendsz);
    esd_mpi_put_1ts(dpid, wid, EPK_NEXT_RMA_ID, origin_count * sendsz);

    return_val = PMPI_Put(origin_addr,
                          origin_count,
                          origin_datatype,
                          target_rank,
                          target_disp,
                          target_count,
                          target_datatype,
                          win);

    esd_mpi_put_1te_remote(dpid, wid, EPK_CURR_RMA_ID);

    esd_exit(epk_mpi_regid[EPK__MPI_PUT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Put(origin_addr,
                          origin_count,
                          origin_datatype,
                          target_rank,
                          target_disp,
                          target_count,
                          target_datatype,
                          win);
  }

  return return_val;
} /* MPI_Put */

#endif

/**
 * @}
 * @name C wrappers for window management functions
 * @{
 */

#if defined(HAS_MPI_WIN_CREATE) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_create
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_create(void*    base,
                   MPI_Aint size,
                   int      disp_unit,
                   MPI_Info info,
                   MPI_Comm comm,
                   MPI_Win* win)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(RMA);
  int       return_val;

  if (event_gen_active)
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_CREATE]);
  }

  return_val = PMPI_Win_create(base, size, disp_unit,
                               info, comm, win);

  if (*win != MPI_WIN_NULL)
  {
    epk_win_create(*win, comm);
  }

  if (event_gen_active)
  {
    esd_mpi_wincollexit(epk_mpi_regid[EPK__MPI_WIN_CREATE],
                        epk_win_id(*win));

    EVENT_GEN_ON();
  }

  return return_val;
} /* MPI_Win_create */

#endif

#if defined(HAS_MPI_WIN_FREE) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_free
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_free(MPI_Win* win)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(RMA);
  int       return_val;
  elg_ui4   wid;

  if (event_gen_active)
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_FREE]);

    wid = epk_win_id(*win);
  }

  epk_win_free(*win);
  return_val = PMPI_Win_free(win);

  if (event_gen_active)
  {
    esd_mpi_wincollexit(epk_mpi_regid[EPK__MPI_WIN_FREE], wid);

    EVENT_GEN_ON();
  }

  return return_val;
} /* MPI_Win_free */

#endif

/**
 * @}
 * @name C wrappers for synchonization functions
 * @{
 */

#if defined(HAS_MPI_WIN_COMPLETE) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_complete
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_complete(MPI_Win win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_COMPLETE]);

    return_val = PMPI_Win_complete(win);

    esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_COMPLETE],
                    epk_win_id(win), epk_winacc_get_gid(win, 1), 1);
    epk_winacc_end(win, 1);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_complete(win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_FENCE) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_fence
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_fence(int     assert,
                  MPI_Win win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_FENCE]);

    return_val = PMPI_Win_fence(assert, win);

    esd_mpi_wincollexit(epk_mpi_regid[EPK__MPI_WIN_FENCE], epk_win_id(win));

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_fence(assert, win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_LOCK) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_lock
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_lock(int     lock_type,
                 int     rank,
                 int     assert,
                 MPI_Win win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_LOCK]);

    esd_mpi_win_lock(EPK_RANK(rank),
                     epk_win_id(win),
                     lock_type == MPI_LOCK_EXCLUSIVE);

    return_val = PMPI_Win_lock(lock_type, rank,
                               assert, win);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_LOCK]);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_lock(lock_type, rank,
                               assert, win);
  }
  return return_val;
} /* MPI_Win_lock */

#endif

#if defined(HAS_MPI_WIN_POST) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_post
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_post(MPI_Group group,
                 int       assert,
                 MPI_Win   win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_POST]);

    epk_winacc_start(win, group, 0);
    return_val = PMPI_Win_post(group, assert, win);

    esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_POST],
                    epk_win_id(win), epk_winacc_get_gid(win, 0), 0);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_post(group, assert, win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_START) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_start
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_start(MPI_Group group,
                  int       assert,
                  MPI_Win   win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_START]);

    epk_winacc_start(win, group, 1);
    return_val = PMPI_Win_start(group, assert, win);

    esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_START],
                    epk_win_id(win), epk_winacc_get_gid(win, 1), 0);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_start(group, assert, win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_TEST) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_test
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_test(MPI_Win win,
                 int*    flag)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_TEST]);

    return_val = PMPI_Win_test(win, flag);

    if (*flag != 0)
    {
      esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_TEST],
                      epk_win_id(win), epk_winacc_get_gid(win, 0), 1);
      epk_winacc_end(win, 0);
    }
    else
    {
      esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_TEST],
                      epk_win_id(win), epk_winacc_get_gid(win, 0), 0);
    }

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_test(win, flag);
  }

  return return_val;
} /* MPI_Win_test */

#endif

#if defined(HAS_MPI_WIN_UNLOCK) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_unlock
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_unlock(int     rank,
                   MPI_Win win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_UNLOCK]);

    return_val = PMPI_Win_unlock(rank, win);

    esd_mpi_win_unlock(EPK_RANK(rank),
                       epk_win_id(win));

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_UNLOCK]);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_unlock(rank, win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_WAIT) && !defined(NO_MPI_RMA)
/**
 * Measurement wrapper for MPI_Win_wait
 * @note Manually adapted wrapper
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_wait(MPI_Win win)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA))
  {
    EVENT_GEN_OFF();

    esd_enter(epk_mpi_regid[EPK__MPI_WIN_WAIT]);

    return_val = PMPI_Win_wait(win);

    esd_mpi_winexit(epk_mpi_regid[EPK__MPI_WIN_WAIT],
                    epk_win_id(win), epk_winacc_get_gid(win, 0), 1);
    epk_winacc_end(win, 0);

    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_wait(win);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_WIN_GET_GROUP) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Win_get_group
 * @note Auto-generated by wrapgen from template: group.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma
 */
int MPI_Win_get_group(MPI_Win    win,
                      MPI_Group* group)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(RMA);
  int       return_val;

  if (event_gen_active)
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_GET_GROUP]);
  }

  return_val = PMPI_Win_get_group(win, group);
  if (*group != MPI_GROUP_NULL)
  {
    epk_group_create(*group);
  }

  if (event_gen_active)
  {
    esd_exit(epk_mpi_regid[EPK__MPI_WIN_GET_GROUP]);
    EVENT_GEN_ON();
  }

  return return_val;
}

#endif

/**
 * @}
 * @name C wrappers for error handling functions
 * @{
 */
#if defined(HAS_MPI_WIN_CALL_ERRHANDLER) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_ERR)
/**
 * Measurement wrapper for MPI_Win_call_errhandler
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_err
 */
int MPI_Win_call_errhandler(MPI_Win win,
                            int     errorcode)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_ERR))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_CALL_ERRHANDLER]);

    return_val = PMPI_Win_call_errhandler(win, errorcode);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_CALL_ERRHANDLER]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_call_errhandler(win, errorcode);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_CREATE_ERRHANDLER) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_ERR)
/**
 * Measurement wrapper for MPI_Win_create_errhandler
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_err
 */
int MPI_Win_create_errhandler(MPI_Win_errhandler_fn* function,
                              MPI_Errhandler*        errhandler)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_ERR))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_CREATE_ERRHANDLER]);

    return_val = PMPI_Win_create_errhandler(function, errhandler);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_CREATE_ERRHANDLER]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_create_errhandler(function, errhandler);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_GET_ERRHANDLER) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_ERR)
/**
 * Measurement wrapper for MPI_Win_get_errhandler
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_err
 */
int MPI_Win_get_errhandler(MPI_Win         win,
                           MPI_Errhandler* errhandler)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_ERR))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_GET_ERRHANDLER]);

    return_val = PMPI_Win_get_errhandler(win, errhandler);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_GET_ERRHANDLER]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_get_errhandler(win, errhandler);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_SET_ERRHANDLER) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_ERR)
/**
 * Measurement wrapper for MPI_Win_set_errhandler
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_err
 */
int MPI_Win_set_errhandler(MPI_Win        win,
                           MPI_Errhandler errhandler)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_ERR))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_SET_ERRHANDLER]);

    return_val = PMPI_Win_set_errhandler(win, errhandler);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_SET_ERRHANDLER]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_set_errhandler(win, errhandler);
  }

  return return_val;
}

#endif

/**
 * @}
 * @name C wrappers for external interface functions
 * @{
 */
#if defined(HAS_MPI_WIN_CREATE_KEYVAL) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_create_keyval
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_create_keyval(MPI_Win_copy_attr_function*   win_copy_attr_fn,
                          MPI_Win_delete_attr_function* win_delete_attr_fn,
                          int*                          win_keyval,
                          void*                         extra_state)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_CREATE_KEYVAL]);

    return_val = PMPI_Win_create_keyval(win_copy_attr_fn,
                                        win_delete_attr_fn,
                                        win_keyval,
                                        extra_state);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_CREATE_KEYVAL]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_create_keyval(win_copy_attr_fn,
                                        win_delete_attr_fn,
                                        win_keyval,
                                        extra_state);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_DELETE_ATTR) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_delete_attr
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_delete_attr(MPI_Win win,
                        int     win_keyval)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_DELETE_ATTR]);

    return_val = PMPI_Win_delete_attr(win, win_keyval);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_DELETE_ATTR]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_delete_attr(win, win_keyval);
  }

  return return_val;
}

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

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_FREE_KEYVAL]);

    return_val = PMPI_Win_free_keyval(win_keyval);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_FREE_KEYVAL]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_free_keyval(win_keyval);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_GET_ATTR) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_get_attr
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_get_attr(MPI_Win win,
                     int     win_keyval,
                     void*   attribute_val,
                     int*    flag)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_GET_ATTR]);

    return_val = PMPI_Win_get_attr(win, win_keyval, attribute_val, flag);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_GET_ATTR]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_get_attr(win, win_keyval, attribute_val, flag);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_GET_NAME) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_get_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_get_name(MPI_Win win,
                     char*   win_name,
                     int*    resultlen)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_GET_NAME]);

    return_val = PMPI_Win_get_name(win, win_name, resultlen);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_GET_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_get_name(win, win_name, resultlen);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_SET_ATTR) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_set_attr
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_set_attr(MPI_Win win,
                     int     win_keyval,
                     void*   attribute_val)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_SET_ATTR]);

    return_val = PMPI_Win_set_attr(win, win_keyval, attribute_val);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_SET_ATTR]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_set_attr(win, win_keyval, attribute_val);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_SET_NAME) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_EXT)
/**
 * Measurement wrapper for MPI_Win_set_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_ext
 */
int MPI_Win_set_name(MPI_Win win,
                     char*   win_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_EXT))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_SET_NAME]);

    return_val = PMPI_Win_set_name(win, win_name);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_SET_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_set_name(win, win_name);
  }

  return return_val;
}

#endif

/**
 * @}
 * @name C wrappers for handle conversion functions
 * @{
 */
#if defined(HAS_MPI_WIN_C2F) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_MISC)
/**
 * Measurement wrapper for MPI_Win_c2f
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_misc
 */
MPI_Fint MPI_Win_c2f(MPI_Win win)
{
  MPI_Fint return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_MISC))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_C2F]);

    return_val = PMPI_Win_c2f(win);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_C2F]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_c2f(win);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_WIN_F2C) && !defined(NO_MPI_RMA) \
  && !defined(NO_MPI_EXTRA) && !defined(NO_MPI_MISC)
/**
 * Measurement wrapper for MPI_Win_f2c
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup rma_misc
 */
MPI_Win MPI_Win_f2c(MPI_Fint win)
{
  MPI_Win return_val;

  if (IS_EVENT_GEN_ON_FOR(RMA_MISC))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_WIN_F2C]);

    return_val = PMPI_Win_f2c(win);

    esd_exit(epk_mpi_regid[EPK__MPI_WIN_F2C]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Win_f2c(win);
  }

  return return_val;
}

#endif

/**
 * @}
 */
