3 Test for the MPI Graph routines :
10 MPI_Graph_neighbors_count
16 /* stdlib.h Needed for malloc declaration */
20 void NumberEdges ( int **, int **, int, int, int );
21 void PrintGraph ( int, int *, int * );
23 int main( int argc, char **argv )
25 MPI_Comm comm, new_comm;
27 int nbrarray[3], baseindex;
28 int size, i, j, nnodes, nedges, q_nnodes, q_nedges, q_nnbrs, newrank;
29 int *index, *edges, *q_index, *q_edges, *rankbuf;
30 int worldrank, err = 0, toterr;
32 MPI_Init( &argc, &argv );
34 MPI_Comm_rank( MPI_COMM_WORLD, &worldrank );
36 /* Generate the graph for a binary tree.
38 Note that EVERY process must have the SAME data
40 comm = MPI_COMM_WORLD;
41 MPI_Comm_size( comm, &size );
43 index = (int *)malloc( (size + 1) * sizeof(int) );
44 edges = (int *)malloc( (size + 1) * 3 * sizeof(int) );
46 for (i=0; i < size; i++) {
49 NumberEdges( &index, &edges, -1, 0, size - 1 );
51 for (i=1; i<size; i++) {
53 index[i] = index[i] + index[i-1];
57 PrintGraph( nnodes, index, edges );
59 MPI_Graph_create( comm, nnodes, index, edges, reorder, &new_comm );
61 /* Now, try to get the information about this graph */
62 MPI_Graphdims_get( new_comm, &q_nnodes, &q_nedges );
63 if (q_nnodes != nnodes) {
64 printf( "Wrong number of nodes, expected %d got %d\n", nnodes, q_nnodes );
67 if (q_nedges != nedges) {
68 printf( "Wrong number of edges; expected %d got %d\n", nedges, q_nedges );
71 q_index = (int *)malloc( q_nnodes * sizeof(int) );
72 q_edges = (int *)malloc( q_nedges * sizeof(int) );
74 MPI_Graph_get( new_comm, q_nnodes, q_nedges, q_index, q_edges );
76 /* Check with original */
78 printf( "Checking graph_get\n" );
80 /* Because reorder was set to zero, we should have the same data */
81 for (i=0; i<size; i++) {
82 if (index[i] != q_index[i]) {
84 printf( "index[%d] is %d, should be %d\n", i, q_index[i], index[i] );
87 for (i=0; i<nedges; i++) {
88 if (edges[i] != q_edges[i]) {
90 printf( "edges[%d] is %d, should be %d\n", i, q_edges[i], edges[i] );
94 /* Now, get each neighbor set individually */
95 for (i=0; i<size; i++) {
96 MPI_Graph_neighbors_count( new_comm, i, &q_nnbrs );
97 MPI_Graph_neighbors( new_comm, i, 3, nbrarray );
100 baseindex = (i > 0) ? index[i-1] : 0;
101 for (j=0; j<q_nnbrs; j++) {
102 if (nbrarray[j] != edges[baseindex+j]) {
104 printf( "nbrarray[%d] for rank %d should be %d, is %d\n",
105 j, i, edges[baseindex+j], nbrarray[j] );
110 /* Test MPI_Graph_map by seeing what ranks are generated for this graph */
111 MPI_Graph_map( comm, nnodes, index, edges, &newrank );
113 if (worldrank == 0) {
114 printf( "Checking graph_map\n" );
116 /* Check that the ranks are at least disjoint among all processors. */
117 rankbuf = (int *)malloc( size * sizeof(int) );
118 MPI_Allgather( &newrank, 1, MPI_INT, rankbuf, 1, MPI_INT, comm );
119 for (i=0; i<size; i++) {
120 for (j=0; j<size; j++) {
121 if (rankbuf[j] == i) break;
125 printf( "Rank %d missing in graph_map\n", i );
129 MPI_Allreduce( &err, &toterr, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
130 if (worldrank == 0) {
132 printf( "No errors in MPI Graph routines\n" );
134 printf( "Found %d errors in MPI Graph routines\n", toterr );
137 MPI_Comm_free( &new_comm );
148 * Routine to print out a graph for debugging
150 void PrintGraph( nnodes, index, edges )
151 int nnodes, *index, *edges;
155 printf( "rank\tindex\tedges\n" );
156 for (i=0; i<nnodes; i++) {
157 printf( "%d\t%d\t", i, index[i] );
158 for (j=0; j<index[i] - lastidx; j++) {
159 printf( "%d ", *edges++ );
167 Number index[0] as first, add its children, and then number them.
168 Note that because of the way the index/edge list is defined, we
169 need to do a depth-first evaluation
171 Each process is connected to the processes rank+1
172 and rank + 1 + floor((size)/2), where size is the size of the subtree
174 Make index[i] the DEGREE of node i. We'll make the relative to 0
177 void NumberEdges( Index, Edges, parent, first, last )
178 int **Index, **Edges, parent, first, last;
187 printf( "Adding parent %d to %d\n", parent, first );
202 /* Internal node. Always at least a left child */
204 printf( "Adding left child %d to %d\n", first + 1, first );
207 *edges++ = first + 1;
209 /* Try to add a right child */
210 right = (last - first)/2;
211 right = first + right + 1;
212 if (right == first + 1)
217 printf( "Adding rightchild %d to %d\n", right, first );
223 if (first + 1 <= last && right - 1 > first) {
224 NumberEdges( &index, &edges, first, first + 1,
225 (right <= last) ? right - 1: last );
228 NumberEdges( &index, &edges, first, right, last );