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