Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'mc++'
[simgrid.git] / teshsuite / smpi / mpich3-test / topo / dgraph_unwgt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "mpi.h"
5 #include "mpitest.h"
6
7 #define RING_NUM_NEIGHBORS   2
8
9 static int validate_dgraph(MPI_Comm dgraph_comm)
10 {
11     int         comm_topo;
12     int         src_sz, dest_sz;
13     int         wgt_flag, ierr;
14     int         srcs[RING_NUM_NEIGHBORS], dests[RING_NUM_NEIGHBORS];
15     int        *src_wgts, *dest_wgts;
16
17     int         world_rank, world_size;
18     int         idx, nbr_sep;
19
20     comm_topo = MPI_UNDEFINED;
21     MPI_Topo_test(dgraph_comm, &comm_topo);
22     switch (comm_topo) {
23         case MPI_DIST_GRAPH :
24             break;
25         default:
26             fprintf(stderr, "dgraph_comm is NOT of type MPI_DIST_GRAPH\n");
27             return 0;
28     }
29
30     ierr = MPI_Dist_graph_neighbors_count(dgraph_comm,
31                                           &src_sz, &dest_sz, &wgt_flag);
32     if (ierr != MPI_SUCCESS) {
33         fprintf(stderr, "MPI_Dist_graph_neighbors_count() fails!\n");
34         return 0;
35     }
36 /*
37     else
38         fprintf(stderr, "MPI_Dist_graph_neighbors_count() succeeds!\n");
39 */
40
41     if (wgt_flag) {
42         fprintf(stderr, "dgraph_comm is NOT created with MPI_UNWEIGHTED\n");
43         return 0;
44     }
45 /*
46     else
47         fprintf(stderr, "dgraph_comm is created with MPI_UNWEIGHTED\n");
48 */
49     if (src_sz != RING_NUM_NEIGHBORS || dest_sz != RING_NUM_NEIGHBORS) {
50         fprintf(stderr, "source or destination edge array is not of size %d.\n",
51                          RING_NUM_NEIGHBORS);
52         fprintf(stderr, "src_sz = %d, dest_sz = %d\n", src_sz, dest_sz);
53         return 0;
54     }
55
56     /*
57        src_wgts and dest_wgts could be anything, e.g. NULL, since
58        MPI_Dist_graph_neighbors_count() returns MPI_UNWEIGHTED.
59        Since this program has a Fortran77 version, and standard Fortran77
60        has no pointer and NULL, so use MPI_UNWEIGHTED for the weighted arrays.
61     */
62     src_wgts  = MPI_UNWEIGHTED;
63     dest_wgts = MPI_UNWEIGHTED;
64     ierr = MPI_Dist_graph_neighbors(dgraph_comm,
65                                     src_sz, srcs, src_wgts,
66                                     dest_sz, dests, dest_wgts);
67     if (ierr != MPI_SUCCESS) {
68         fprintf(stderr, "MPI_Dist_graph_neighbors() fails!\n");
69         return 0;
70     }
71 /*
72     else
73         fprintf(stderr, "MPI_Dist_graph_neighbors() succeeds!\n");
74 */
75
76     /*
77        Check if the neighbors returned from MPI are really
78        the nearest neighbors within a ring.
79     */
80     MPI_Comm_size(MPI_COMM_WORLD, &world_size);
81     MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
82  
83     for (idx=0; idx < src_sz; idx++) {
84         nbr_sep = abs(srcs[idx] - world_rank);
85         if ( nbr_sep != 1 && nbr_sep != (world_size-1) ) {
86             fprintf(stderr, "srcs[%d]=%d is NOT a neighbor of my rank %d.\n",
87                             idx, srcs[idx], world_rank);
88             return 0;
89         }  
90     }
91     for (idx=0; idx < dest_sz; idx++) {
92         nbr_sep = abs(dests[idx] - world_rank);
93         if ( nbr_sep != 1 && nbr_sep != (world_size-1) ) {
94             fprintf(stderr, "dests[%d]=%d is NOT a neighbor of my rank %d.\n",
95                             idx, dests[idx], world_rank);
96             return 0;
97         }  
98     }
99
100     /*
101     fprintf(stderr, "dgraph_comm is of type MPI_DIST_GRAPH "
102                     "of a bidirectional ring.\n");
103     */
104     return 1;
105 }
106
107 /*
108    Specify a distributed graph of a bidirectional ring of the MPI_COMM_WORLD,
109    i.e. everyone only talks to left and right neighbors. 
110 */
111 int main(int argc, char *argv[])
112 {
113     MPI_Comm    dgraph_comm;
114     int         world_size, world_rank, ierr;
115     int         errs = 0;
116
117     int         src_sz, dest_sz;
118     int         degs[1];
119     int         srcs[RING_NUM_NEIGHBORS], dests[RING_NUM_NEIGHBORS];
120     
121     MTest_Init(&argc, &argv);
122     MPI_Comm_size(MPI_COMM_WORLD, &world_size);
123     MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
124
125     degs[0]  = 2;
126     srcs[0]  = world_rank;
127     dests[0] = world_rank-1 <  0          ? world_size-1 : world_rank-1 ;
128     dests[1] = world_rank+1 >= world_size ?            0 : world_rank+1 ;
129     ierr = MPI_Dist_graph_create(MPI_COMM_WORLD, 1, srcs, degs, dests,
130                                  MPI_UNWEIGHTED, MPI_INFO_NULL, 1,
131                                  &dgraph_comm);
132     if ( ierr != MPI_SUCCESS )  {
133         fprintf(stderr, "MPI_Dist_graph_create() fails!\n");
134         MPI_Abort(MPI_COMM_WORLD, 1);
135         return 1;
136     }
137     if (!validate_dgraph(dgraph_comm)) {
138         fprintf(stderr, "MPI_Dist_graph_create() does NOT create "
139                         "a bidirectional ring graph!\n");
140         MPI_Abort(MPI_COMM_WORLD, 1);
141         return 1;
142     }
143     MPI_Comm_free(&dgraph_comm);
144     
145     src_sz   = 2;
146     srcs[0]  = world_rank-1 <  0          ? world_size-1 : world_rank-1 ;
147     srcs[1]  = world_rank+1 >= world_size ?            0 : world_rank+1 ;
148     dest_sz  = 2;
149     dests[0] = world_rank-1 <  0          ? world_size-1 : world_rank-1 ;
150     dests[1] = world_rank+1 >= world_size ?            0 : world_rank+1 ;
151     ierr = MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD,
152                                           src_sz, srcs, MPI_UNWEIGHTED,
153                                           dest_sz, dests, MPI_UNWEIGHTED,
154                                           MPI_INFO_NULL, 1, &dgraph_comm);
155     if ( ierr != MPI_SUCCESS ) {
156         fprintf(stderr, "MPI_Dist_graph_create_adjacent() fails!\n");
157         MPI_Abort(MPI_COMM_WORLD, 1);
158         return 1;
159     }
160     if (!validate_dgraph(dgraph_comm)) {
161         fprintf(stderr, "MPI_Dist_graph_create_adjacent() does NOT create "
162                         "a bidirectional ring graph!\n");
163         MPI_Abort(MPI_COMM_WORLD, 1);
164         return 1;
165     }
166     MPI_Comm_free(&dgraph_comm);
167
168     MTest_Finalize(errs);
169     MPI_Finalize();
170     return 0;
171 }