root/ompi/mpi/c/comm_spawn_multiple.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. MPI_Comm_spawn_multiple

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2015 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2009      Sun Microsystems, Inc.  All rights reserved.
  15  * Copyright (c) 2012-2013 Los Alamos National Security, LLC.  All rights
  16  *                         reserved.
  17  * Copyright (c) 2015      Intel, Inc. All rights reserved.
  18  * Copyright (c) 2015      Research Organization for Information Science
  19  *                         and Technology (RIST). All rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 #include "ompi_config.h"
  27 #include <stdio.h>
  28 
  29 #include "opal/util/show_help.h"
  30 
  31 #include "ompi/mpi/c/bindings.h"
  32 #include "ompi/runtime/params.h"
  33 #include "ompi/runtime/mpiruntime.h"
  34 #include "ompi/communicator/communicator.h"
  35 #include "ompi/errhandler/errhandler.h"
  36 #include "ompi/info/info.h"
  37 #include "ompi/dpm/dpm.h"
  38 #include "ompi/memchecker.h"
  39 
  40 #if OMPI_BUILD_MPI_PROFILING
  41 #if OPAL_HAVE_WEAK_SYMBOLS
  42 #pragma weak MPI_Comm_spawn_multiple = PMPI_Comm_spawn_multiple
  43 #endif
  44 #define MPI_Comm_spawn_multiple PMPI_Comm_spawn_multiple
  45 #endif
  46 
  47 static const char FUNC_NAME[] = "MPI_Comm_spawn_multiple";
  48 
  49 
  50 int MPI_Comm_spawn_multiple(int count, char *array_of_commands[], char **array_of_argv[],
  51                             const int array_of_maxprocs[], const MPI_Info array_of_info[],
  52                             int root, MPI_Comm comm, MPI_Comm *intercomm,
  53                             int array_of_errcodes[])
  54 {
  55     int i=0, rc=0, rank=0, size=0, flag;
  56     ompi_communicator_t *newcomp=NULL;
  57     bool send_first=false; /* they are contacting us first */
  58     char port_name[MPI_MAX_PORT_NAME];
  59     bool non_mpi = false, cumulative = false;
  60 
  61     MEMCHECKER(
  62         memchecker_comm(comm);
  63     );
  64 
  65     if ( MPI_PARAM_CHECK ) {
  66         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
  67 
  68         if ( ompi_comm_invalid (comm)) {
  69             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
  70                                           FUNC_NAME);
  71         }
  72         if ( OMPI_COMM_IS_INTER(comm)) {
  73             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COMM, FUNC_NAME);
  74         }
  75         if ( (0 > root) || (ompi_comm_size(comm) <= root) ) {
  76             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  77         }
  78         if ( NULL == intercomm ) {
  79             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  80         }
  81     }
  82 
  83     rank = ompi_comm_rank ( comm );
  84     if ( MPI_PARAM_CHECK ) {
  85         if ( rank == root ) {
  86             if ( 0 > count ) {
  87                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  88             }
  89             if ( NULL == array_of_commands ) {
  90                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  91             }
  92             if ( NULL ==  array_of_maxprocs ) {
  93                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  94             }
  95             if ( NULL == array_of_info ) {
  96                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_INFO, FUNC_NAME);
  97             }
  98             for (i = 0; i < count; ++i) {
  99                 if (NULL == array_of_info[i] ||
 100                     ompi_info_is_freed(array_of_info[i])) {
 101                     return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INFO,
 102                                                   FUNC_NAME);
 103                 }
 104                 /* If ompi_non_mpi is set to true on any info, it must
 105                    be set to true on all of them.  Note that not
 106                    setting ompi_non_mpi is the same as setting it to
 107                    false. */
 108                 ompi_info_get_bool(array_of_info[i], "ompi_non_mpi", &non_mpi,
 109                                    &flag);
 110                 if (flag && 0 == i) {
 111                     /* If this is the first info, save its
 112                        ompi_non_mpi value */
 113                     cumulative = non_mpi;
 114                 } else if (!flag) {
 115                     non_mpi = false;
 116                 }
 117                 /* If this info's effective value doesn't agree with
 118                    the rest of them, error */
 119                 if (cumulative != non_mpi) {
 120                     return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD,
 121                                                   MPI_ERR_INFO,
 122                                                   FUNC_NAME);
 123                 }
 124             }
 125             for ( i=0; i<count; i++ ) {
 126                 if ( NULL == array_of_commands[i] ) {
 127                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 128                 }
 129                 if ( 0 > array_of_maxprocs[i] ) {
 130                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 131                 }
 132             }
 133         }
 134     }
 135 
 136     if (!ompi_mpi_dynamics_is_enabled(FUNC_NAME)) {
 137         return OMPI_ERRHANDLER_INVOKE(comm, OMPI_ERR_NOT_SUPPORTED, FUNC_NAME);
 138     }
 139 
 140     if (rank == root) {
 141         if (MPI_INFO_NULL == array_of_info[0]) {
 142             non_mpi = false;
 143         } else {
 144             ompi_info_get_bool(array_of_info[0], "ompi_non_mpi", &non_mpi,
 145                                &flag);
 146             if (!flag) {
 147                 non_mpi = false;
 148             }
 149         }
 150     }
 151 
 152     /* initialize the port name to avoid problems */
 153     memset(port_name, 0, MPI_MAX_PORT_NAME);
 154 
 155     OPAL_CR_ENTER_LIBRARY();
 156 
 157     if ( rank == root ) {
 158         if (!non_mpi) {
 159             /* Open a port. The port_name is passed as an environment
 160                variable to the children. */
 161             if (OMPI_SUCCESS != (rc = ompi_dpm_open_port (port_name))) {
 162                 goto error;
 163             }
 164         } else if (1 < ompi_comm_size(comm)) {
 165             /* we do not support non_mpi spawns on comms this size */
 166             rc = OMPI_ERR_NOT_SUPPORTED;
 167             goto error;
 168         }
 169         if (OMPI_SUCCESS != (rc = ompi_dpm_spawn(count, (const char **) array_of_commands,
 170                                                  array_of_argv, array_of_maxprocs,
 171                                                  array_of_info, port_name))) {
 172             goto error;
 173         }
 174     }
 175 
 176     if (non_mpi) {
 177         newcomp = MPI_COMM_NULL;
 178     } else {
 179         rc = ompi_dpm_connect_accept (comm, root, port_name, send_first, &newcomp);
 180     }
 181 
 182 error:
 183     if (OPAL_ERR_NOT_SUPPORTED == rc) {
 184         opal_show_help("help-mpi-api.txt",
 185                        "MPI function not supported",
 186                        true,
 187                        FUNC_NAME,
 188                        "Underlying runtime environment does not support spawn functionality");
 189     }
 190 
 191     /* close the port */
 192     if (rank == root && !non_mpi) {
 193         ompi_dpm_close_port(port_name);
 194     }
 195 
 196     OPAL_CR_EXIT_LIBRARY();
 197 
 198     /* set array of errorcodes */
 199     if (MPI_ERRCODES_IGNORE != array_of_errcodes) {
 200         if (NULL != newcomp) {
 201             size = newcomp->c_remote_group->grp_proc_count;
 202         } else {
 203             for ( i=0; i < count; i++) {
 204                 size = size + array_of_maxprocs[i];
 205             }
 206         }
 207         for ( i=0; i < size; i++ ) {
 208             array_of_errcodes[i]=rc;
 209         }
 210     }
 211 
 212     *intercomm = newcomp;
 213     OMPI_ERRHANDLER_RETURN (rc, comm, rc, FUNC_NAME);
 214 }
 215 

/* [<][>][^][v][top][bottom][index][help] */