Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
move smpi examples to teshsuite
[simgrid.git] / teshsuite / smpi / alltoallv.c
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *  (C) 2001 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 #include "mpi.h"
7 #include <string.h>
8
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 /*
13    This program tests MPI_Alltoallv by having processor i send different
14    amounts of data to each processor.
15
16    Because there are separate send and receive types to alltoallv,
17    there need to be tests to rearrange data on the fly.  Not done yet.
18
19    The first test sends i items to processor i from all processors.
20
21    Currently, the test uses only MPI_INT; this is adequate for testing systems
22    that use point-to-point operations
23  */
24
25
26 /* example values:
27  * For 3 processes:
28  * <0> sbuf: (#9):   [0][1][2][3][4][5][6][7][8]
29    <0> scount: (#3): [0][1][2]
30    <0> rcount: (#3): [0][0][0]
31    <0> sdisp: (#3):  [0][1][3]
32    <0> rdisp: (#3):  [0][0][0]
33
34    <1> sbuf: (#9):   [100][101][102][103][104][105][106][107][108]
35    <1> scount: (#3): [0][1][2]
36    <1> rcount: (#3): [1][1][1]
37    <1> sdisp: (#3):  [0][1][3]
38    <1> rdisp: (#3):  [0][1][2]
39
40    <2> sbuf: (#9):   [200][201][202][203][204][205][206][207][208]
41    <2> scount: (#3): [0][1][2]
42    <2> rcount: (#3): [2][2][2]
43    <2> sdisp: (#3):  [0][1][3]
44    <2> rdisp: (#3):  [0][2][4]
45
46    after MPI_Alltoallv :
47    <0> rbuf: (#9):   [0][-1][-2][-3][-4][-5][-6][-7][-8]
48    <1> rbuf: (#9):   [1][101][201][-3][-4][-5][-6][-7][-8]
49    <2> rbuf: (#9):   [3][4][103][104][203][204][-6][-7][-8]
50 */
51
52
53 static void print_buffer_int(void *buf, int len, char *msg, int rank)
54 {
55   int tmp, *v;
56   printf("**<%d> %s (#%d): ", rank, msg, len);
57   for (tmp = 0; tmp < len; tmp++) {
58     v = buf;
59     printf("[%d]", v[tmp]);
60   }
61   printf("\n");
62   free(msg);
63 }
64
65
66 int main(int argc, char **argv)
67 {
68
69   MPI_Comm comm;
70   int *sbuf, *rbuf, *erbuf;
71   int rank, size;
72   int *sendcounts, *recvcounts, *rdispls, *sdispls;
73   int i, j, *p, err;
74
75   MPI_Init(&argc, &argv);
76   err = 0;
77
78   comm = MPI_COMM_WORLD;
79
80   /* Create the buffer */
81   MPI_Comm_size(comm, &size);
82   MPI_Comm_rank(comm, &rank);
83   sbuf = (int *) malloc(size * size * sizeof(int));
84   rbuf = (int *) malloc(size * size * sizeof(int));
85   erbuf = (int *) malloc(size * size * sizeof(int));    // expected
86   if (!sbuf || !rbuf) {
87     fprintf(stderr, "Could not allocated buffers!\n");
88     MPI_Abort(comm, 1);
89   }
90
91   /* Load up the buffers */
92   for (i = 0; i < size * size; i++) {
93     sbuf[i] = i + 100 * rank;
94     rbuf[i] = -i;
95     erbuf[i] = -i;
96   }
97
98   /* Create and load the arguments to alltoallv */
99   sendcounts = (int *) malloc(size * sizeof(int));
100   recvcounts = (int *) malloc(size * sizeof(int));
101   rdispls = (int *) malloc(size * sizeof(int));
102   sdispls = (int *) malloc(size * sizeof(int));
103   if (!sendcounts || !recvcounts || !rdispls || !sdispls) {
104     fprintf(stderr, "Could not allocate arg items!\n");
105     MPI_Abort(comm, 1);
106   }
107   for (i = 0; i < size; i++) {
108     sendcounts[i] = i;
109     recvcounts[i] = rank;
110     rdispls[i] = i * rank;
111     sdispls[i] = (i * (i + 1)) / 2;
112   }
113
114   /* debug */
115   /* 
116      print_buffer_int( sbuf, size*size, strdup("sbuf:"),rank);
117      print_buffer_int( sendcounts, size, strdup("scount:"),rank);
118      print_buffer_int( recvcounts, size, strdup("rcount:"),rank);
119      print_buffer_int( sdispls, size, strdup("sdisp:"),rank);
120      print_buffer_int( rdispls, size, strdup("rdisp:"),rank);
121    */
122
123
124   /* debug : erbuf */
125   /* debug
126      for (i=0; i<size; i++) {
127      for (j=0; j<rank; j++) {
128      *(erbuf+j+ rdispls[i]) = i * 100 + (rank*(rank+1))/2 + j; 
129      }
130      }
131    */
132
133
134   //print_buffer_int( erbuf, size*size, strdup("erbuf:"),rank);
135
136   MPI_Alltoallv(sbuf, sendcounts, sdispls, MPI_INT,
137                 rbuf, recvcounts, rdispls, MPI_INT, comm);
138
139   // debug: print_buffer_int( rbuf, size*size, strdup("rbuf:"),rank);
140
141
142   /* Check rbuf */
143   for (i = 0; i < size; i++) {
144     p = rbuf + rdispls[i];
145     for (j = 0; j < rank; j++) {
146       if (p[j] != i * 100 + (rank * (rank + 1)) / 2 + j) {
147         fprintf(stderr, "** Error: <%d> got %d expected %d for %dth\n",
148                 rank, p[j], (i * (i + 1)) / 2 + j, j);
149         err++;
150       }
151     }
152   }
153
154   /* Summary */
155   if (err > 0) {
156     printf("<%d> Alltoallv test: failure (%d errors).\n", rank, err);
157   }
158   if (0 == rank) {
159     printf("* Alltoallv TEST COMPLETE.\n");
160   }
161   free(sdispls);
162   free(rdispls);
163   free(recvcounts);
164   free(sendcounts);
165   free(rbuf);
166   free(sbuf);
167
168   MPI_Barrier(MPI_COMM_WORLD);
169   MPI_Finalize();
170   return 0;
171 }