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