1 /*
2  * Copyright (c) 2008      The Trustees of Indiana University and Indiana
3  *                         University Research and Technology
4  *                         Corporation.  All rights reserved.
5  * Copyright (c) 2009      Cisco Systems, Inc.  All rights reserved.
6  * Copyright (c) 2011-2013 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2011-2013 Inria.  All rights reserved.
10  * Copyright (c) 2011-2013 Université Bordeaux 1
11  * Copyright (c) 2014-2015 Research Organization for Information Science
12  *                         and Technology (RIST). All rights reserved.
13  * Copyright (c) 2017      IBM Corp.  All rights reserved.
14  */
15 
16 #include "ompi_config.h"
17 
18 #include "ompi/communicator/communicator.h"
19 #include "ompi/info/info.h"
20 #include "ompi/mca/topo/base/base.h"
21 
22 
mca_topo_base_dist_graph_create_adjacent(mca_topo_base_module_t * module,ompi_communicator_t * comm_old,int indegree,const int sources[],const int sourceweights[],int outdegree,const int destinations[],const int destweights[],opal_info_t * info,int reorder,ompi_communicator_t ** newcomm)23 int mca_topo_base_dist_graph_create_adjacent(mca_topo_base_module_t* module,
24                                              ompi_communicator_t *comm_old,
25                                              int indegree, const int sources[],
26                                              const int sourceweights[],
27                                              int outdegree,
28                                              const int destinations[],
29                                              const int destweights[],
30                                              opal_info_t *info, int reorder,
31                                              ompi_communicator_t **newcomm)
32 {
33     mca_topo_base_comm_dist_graph_2_2_0_t *topo = NULL;
34     int err;
35 
36     if( OMPI_SUCCESS != (err = ompi_comm_create(comm_old,
37                                                 comm_old->c_local_group,
38                                                 newcomm)) ) {
39         return err;
40     }
41     // But if there is an info object, the above call didn't make use
42     // of it, so we'll do a dup-with-info to get the final comm and
43     // free the above intermediate newcomm:
44     if (info && info != &(MPI_INFO_NULL->super)) {
45         ompi_communicator_t *intermediate_comm = *newcomm;
46         ompi_comm_dup_with_info (intermediate_comm, info, newcomm);
47         ompi_comm_free(&intermediate_comm);
48     }
49 
50     err = OMPI_ERR_OUT_OF_RESOURCE;  /* suppose by default something bad will happens */
51 
52     assert( NULL == (*newcomm)->c_topo );
53 
54     topo = OBJ_NEW(mca_topo_base_comm_dist_graph_2_2_0_t);
55     if( NULL == topo ) {
56         goto bail_out;
57     }
58     topo->in = topo->inw = NULL;
59     topo->out = topo->outw = NULL;
60     topo->indegree = indegree;
61     topo->outdegree = outdegree;
62     topo->weighted = !((MPI_UNWEIGHTED == sourceweights) && (MPI_UNWEIGHTED == destweights));
63 
64     if (topo->indegree > 0) {
65         topo->in = (int*)malloc(sizeof(int) * topo->indegree);
66         if (NULL == topo->in) {
67             goto bail_out;
68         }
69         memcpy(topo->in, sources, sizeof(int) * topo->indegree);
70         if (MPI_UNWEIGHTED != sourceweights) {
71             topo->inw = (int*)malloc(sizeof(int) * topo->indegree);
72             if( NULL == topo->inw ) {
73                 goto bail_out;
74             }
75             memcpy( topo->inw, sourceweights, sizeof(int) * topo->indegree );
76         }
77     }
78 
79     if (topo->outdegree > 0) {
80         topo->out = (int*)malloc(sizeof(int) * topo->outdegree);
81         if (NULL == topo->out) {
82             goto bail_out;
83         }
84         memcpy(topo->out, destinations, sizeof(int) * topo->outdegree);
85         topo->outw = NULL;
86         if (MPI_UNWEIGHTED != destweights) {
87             if (topo->outdegree > 0) {
88                 topo->outw = (int*)malloc(sizeof(int) * topo->outdegree);
89                 if (NULL == topo->outw) {
90                     goto bail_out;
91                 }
92                 memcpy(topo->outw, destweights, sizeof(int) * topo->outdegree);
93             }
94         }
95     }
96 
97     (*newcomm)->c_topo                 = module;
98     (*newcomm)->c_topo->mtc.dist_graph = topo;
99     (*newcomm)->c_topo->reorder        = reorder;
100     (*newcomm)->c_flags               |= OMPI_COMM_DIST_GRAPH;
101 
102     return OMPI_SUCCESS;
103 
104  bail_out:
105     if (NULL != topo) {
106         if( NULL != topo->in ) free(topo->in);
107         if( MPI_UNWEIGHTED != sourceweights ) {
108             if( NULL != topo->inw ) free(topo->inw);
109         }
110         if( NULL != topo->out ) free(topo->out);
111         if( MPI_UNWEIGHTED != destweights ) {
112             if( NULL != topo->outw ) free(topo->outw);
113         }
114         OBJ_RELEASE(topo);
115     }
116     ompi_comm_free(newcomm);
117     return err;
118 }
119