root/ompi/mca/topo/base/topo_base_graph_create.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_topo_base_graph_create
  2. mca_topo_base_comm_graph_2_2_0_construct
  3. mca_topo_base_comm_graph_2_2_0_destruct

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2013 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2012-2013 Inria.  All rights reserved.
  13  * Copyright (c) 2014      Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2014-2015 Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "ompi_config.h"
  24 #include "ompi/mca/topo/base/base.h"
  25 #include "ompi/mca/topo/topo.h"
  26 
  27 /*
  28  *
  29  * function - makes a new communicator to which topology information
  30  *            has been attached
  31  *
  32  * @param comm_old input communicator without topology (handle)
  33  * @param nnodes number of nodes in graph (integer)
  34  * @param index array of integers describing node degrees (see below)
  35  * @param edges array of integers describing graph edges (see below)
  36  * @param reorder ranking may be reordered (true) or not (false) (logical)
  37  * @param comm_graph communicator with graph topology added (handle)
  38  *
  39  * @retval MPI_SUCCESS
  40  * @retval MPI_ERR_OUT_OF_RESOURCE
  41  */
  42 
  43 int mca_topo_base_graph_create(mca_topo_base_module_t *topo,
  44                                ompi_communicator_t* old_comm,
  45                                int nnodes,
  46                                const int *index,
  47                                const int *edges,
  48                                bool reorder,
  49                                ompi_communicator_t** comm_topo)
  50 {
  51     ompi_communicator_t *new_comm;
  52     int new_rank, num_procs, ret, i;
  53     ompi_proc_t **topo_procs = NULL;
  54     mca_topo_base_comm_graph_2_2_0_t* graph;
  55 
  56     num_procs = old_comm->c_local_group->grp_proc_count;
  57     new_rank = old_comm->c_local_group->grp_my_rank;
  58     assert(topo->type == OMPI_COMM_GRAPH);
  59 
  60     if( num_procs < nnodes ) {
  61         return MPI_ERR_DIMS;
  62     }
  63     if( num_procs > nnodes ) {
  64         num_procs = nnodes;
  65     }
  66     if( new_rank > (nnodes - 1) ) {
  67         new_rank = MPI_UNDEFINED;
  68         num_procs = 0;
  69         nnodes = 0;
  70     }
  71 
  72     graph = OBJ_NEW(mca_topo_base_comm_graph_2_2_0_t);
  73     if( NULL == graph ) {
  74         return OMPI_ERR_OUT_OF_RESOURCE;
  75     }
  76     graph->nnodes = nnodes;
  77 
  78     /* Don't do any of the other initialization if we're not supposed
  79        to be part of the new communicator (because nnodes has been
  80        reset to 0, making things like index[nnodes-1] be junk).
  81 
  82        JMS: This should really be refactored to use
  83        comm_create_group(), because ompi_comm_allocate() still
  84        complains about 0-byte mallocs in debug builds for 0-member
  85        groups. */
  86     if (MPI_UNDEFINED != new_rank) {
  87         graph->index = (int*)malloc(sizeof(int) * nnodes);
  88         if (NULL == graph->index) {
  89             OBJ_RELEASE(graph);
  90             return OMPI_ERR_OUT_OF_RESOURCE;
  91         }
  92         memcpy(graph->index, index, nnodes * sizeof(int));
  93 
  94         /* Graph communicator; copy the right data to the common information */
  95         graph->edges = (int*)malloc(sizeof(int) * index[nnodes-1]);
  96         if (NULL == graph->edges) {
  97             OBJ_RELEASE(graph);
  98             return OMPI_ERR_OUT_OF_RESOURCE;
  99         }
 100         memcpy(graph->edges, edges, index[nnodes-1] * sizeof(int));
 101 
 102         topo_procs = (ompi_proc_t**)malloc(num_procs * sizeof(ompi_proc_t *));
 103         if (NULL == topo_procs) {
 104            OBJ_RELEASE(graph);
 105            return OMPI_ERR_OUT_OF_RESOURCE;
 106         }
 107         if(OMPI_GROUP_IS_DENSE(old_comm->c_local_group)) {
 108             memcpy(topo_procs,
 109                    old_comm->c_local_group->grp_proc_pointers,
 110                    num_procs * sizeof(ompi_proc_t *));
 111         } else {
 112             for(i = 0 ; i < num_procs; i++) {
 113                 topo_procs[i] = ompi_group_peer_lookup(old_comm->c_local_group,i);
 114             }
 115         }
 116     }
 117 
 118     /* allocate a new communicator */
 119     new_comm = ompi_comm_allocate(nnodes, 0);
 120     if (NULL == new_comm) {
 121         free(topo_procs);
 122         OBJ_RELEASE(graph);
 123         return OMPI_ERR_OUT_OF_RESOURCE;
 124     }
 125 
 126     ret = ompi_comm_enable(old_comm, new_comm,
 127                            new_rank, num_procs, topo_procs);
 128     if (OMPI_SUCCESS != ret) {
 129         free(topo_procs);
 130         OBJ_RELEASE(graph);
 131         if (MPI_COMM_NULL != new_comm) {
 132             new_comm->c_topo            = NULL;
 133             new_comm->c_flags          &= ~OMPI_COMM_GRAPH;
 134             ompi_comm_free (&new_comm);
 135         }
 136         return ret;
 137     }
 138     
 139     new_comm->c_topo            = topo;
 140     new_comm->c_topo->mtc.graph = graph;
 141     new_comm->c_flags          |= OMPI_COMM_GRAPH;
 142     new_comm->c_topo->reorder   = reorder;
 143     *comm_topo = new_comm;
 144 
 145     if( MPI_UNDEFINED == new_rank ) {
 146         ompi_comm_free(&new_comm);
 147         *comm_topo = MPI_COMM_NULL;
 148     }
 149 
 150     return OMPI_SUCCESS;
 151 }
 152 
 153 static void mca_topo_base_comm_graph_2_2_0_construct(mca_topo_base_comm_graph_2_2_0_t * graph) {
 154     graph->nnodes = 0;
 155     graph->index = NULL;
 156     graph->edges = NULL;
 157 }
 158 
 159 static void mca_topo_base_comm_graph_2_2_0_destruct(mca_topo_base_comm_graph_2_2_0_t * graph) {
 160     if (NULL != graph->index) {
 161         free(graph->index);
 162     }
 163     if (NULL != graph->edges) {
 164         free(graph->edges);
 165     }
 166 }
 167 
 168 OBJ_CLASS_INSTANCE(mca_topo_base_comm_graph_2_2_0_t, opal_object_t,
 169                    mca_topo_base_comm_graph_2_2_0_construct,
 170                    mca_topo_base_comm_graph_2_2_0_destruct);

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