/****************************************************************************
**  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_spawn.c
 *
 * @brief C interface wrappers for process creation and management
 *        functions (spawning interface)
 */

#include <mpi.h>

#include "esd_event.h"

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

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

#if defined(HAS_MPI_COMM_ACCEPT) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_accept
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_accept(char*     port_name,
                    MPI_Info  info,
                    int       root,
                    MPI_Comm  comm,
                    MPI_Comm* newcomm)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  return_val = PMPI_Comm_accept(port_name, info, root, comm, newcomm);
  if (*newcomm != MPI_COMM_NULL)
  {
    epk_comm_create(*newcomm);
  }

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_CONNECT) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_connect
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_connect(char*     port_name,
                     MPI_Info  info,
                     int       root,
                     MPI_Comm  comm,
                     MPI_Comm* newcomm)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  return_val = PMPI_Comm_connect(port_name, info, root, comm, newcomm);
  if (*newcomm != MPI_COMM_NULL)
  {
    epk_comm_create(*newcomm);
  }

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_JOIN) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_join
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_join(int       fd,
                  MPI_Comm* newcomm)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  return_val = PMPI_Comm_join(fd, newcomm);
  if (*newcomm != MPI_COMM_NULL)
  {
    epk_comm_create(*newcomm);
  }

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_SPAWN) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_spawn
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_spawn(char*     command,
                   char*     argv[],
                   int       maxprocs,
                   MPI_Info  info,
                   int       root,
                   MPI_Comm  comm,
                   MPI_Comm* newcomm,
                   int       array_of_errcodes[])
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  return_val = PMPI_Comm_spawn(command,
                               argv,
                               maxprocs,
                               info,
                               root,
                               comm,
                               newcomm,
                               array_of_errcodes);
  if (*newcomm != MPI_COMM_NULL)
  {
    epk_comm_create(*newcomm);
  }

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_SPAWN_MULTIPLE) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_spawn_multiple
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_spawn_multiple(int       count,
                            char*     array_of_commands[],
                            char**    array_of_argv[],
                            int       array_of_maxprocs[],
                            MPI_Info  array_of_info[],
                            int       root,
                            MPI_Comm  comm,
                            MPI_Comm* newcomm,
                            int       array_of_errcodes[])
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  return_val = PMPI_Comm_spawn_multiple(count,
                                        array_of_commands,
                                        array_of_argv,
                                        array_of_maxprocs,
                                        array_of_info,
                                        root,
                                        comm,
                                        newcomm,
                                        array_of_errcodes);
  if (*newcomm != MPI_COMM_NULL)
  {
    epk_comm_create(*newcomm);
  }

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_DISCONNECT) && !defined(NO_MPI_SPAWN)
/**
 * Measurement wrapper for MPI_Comm_disconnect
 * @note Auto-generated by wrapgen from template: comm_mgnt.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_disconnect(MPI_Comm* comm)
{
  const int event_gen_active = IS_EVENT_GEN_ON_FOR(SPAWN);
  int       return_val;

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

  epk_comm_free(*comm);
  return_val = PMPI_Comm_disconnect(comm);

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

  return return_val;
}

#endif

#if defined(HAS_MPI_COMM_GET_PARENT) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Comm_get_parent
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Comm_get_parent(MPI_Comm* parent)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_COMM_GET_PARENT]);

    return_val = PMPI_Comm_get_parent(parent);

    esd_exit(epk_mpi_regid[EPK__MPI_COMM_GET_PARENT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Comm_get_parent(parent);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_LOOKUP_NAME) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Lookup_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Lookup_name(char*    service_name,
                    MPI_Info info,
                    char*    port_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_LOOKUP_NAME]);

    return_val = PMPI_Lookup_name(service_name, info, port_name);

    esd_exit(epk_mpi_regid[EPK__MPI_LOOKUP_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Lookup_name(service_name, info, port_name);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_PUBLISH_NAME) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Publish_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Publish_name(char*    service_name,
                     MPI_Info info,
                     char*    port_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_PUBLISH_NAME]);

    return_val = PMPI_Publish_name(service_name, info, port_name);

    esd_exit(epk_mpi_regid[EPK__MPI_PUBLISH_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Publish_name(service_name, info, port_name);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_UNPUBLISH_NAME) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Unpublish_name
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Unpublish_name(char*    service_name,
                       MPI_Info info,
                       char*    port_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_UNPUBLISH_NAME]);

    return_val = PMPI_Unpublish_name(service_name, info, port_name);

    esd_exit(epk_mpi_regid[EPK__MPI_UNPUBLISH_NAME]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Unpublish_name(service_name, info, port_name);
  }

  return return_val;
}

#endif

#if defined(HAS_MPI_CLOSE_PORT) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Close_port
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Close_port(char* port_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_CLOSE_PORT]);

    return_val = PMPI_Close_port(port_name);

    esd_exit(epk_mpi_regid[EPK__MPI_CLOSE_PORT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Close_port(port_name);
  }

  return return_val;
}

#endif
#if defined(HAS_MPI_OPEN_PORT) && !defined(NO_MPI_SPAWN) \
  && !defined(NO_MPI_EXTRA)
/**
 * Measurement wrapper for MPI_Open_port
 * @note Auto-generated by wrapgen from template: std.w
 * @note C interface
 * @note Introduced with MPI 2.0
 * @ingroup spawn
 */
int MPI_Open_port(MPI_Info info,
                  char*    port_name)
{
  int return_val;

  if (IS_EVENT_GEN_ON_FOR(SPAWN))
  {
    EVENT_GEN_OFF();
    esd_enter(epk_mpi_regid[EPK__MPI_OPEN_PORT]);

    return_val = PMPI_Open_port(info, port_name);

    esd_exit(epk_mpi_regid[EPK__MPI_OPEN_PORT]);
    EVENT_GEN_ON();
  }
  else
  {
    return_val = PMPI_Open_port(info, port_name);
  }

  return return_val;
}

#endif

/**
 * @}
 */
