Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Reindent + minor stylistic issues.
[simgrid.git] / teshsuite / smpi / topo-cart-sub / topo-cart-sub.c
1 /* Copyright (c) 2009-2019. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /* Copyright (c) 2019. Jonathan Borne.                                      */
8
9 #include <mpi.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #define DIM 2
14 #define Q 2
15 /* Where DIM is the dimension of the Grid (2D) */
16 /* and Q is the number of processes per dimension */
17 #define N 3
18 /* Local matrices size N*N */
19
20 int main(int argc, char** argv)
21 {
22   /* Nb of nodes in the grid:
23      initialized by MPI_Comm_size according to commandline -np value */
24   int nbNodes;
25
26   /* Communicators */
27   MPI_Comm gridComm;
28   MPI_Comm lineComm;
29   /* Current process ranks */
30   int rank;
31   int gridSize;
32   int myGridRank;
33   int myLineRank;
34   int myColRank;
35   /* coords: used to get myLineRank and myColRank
36      initialized by MPI_Cart_coords
37    */
38   int coords[DIM];
39   /* dims: Integer array of size ndims specifying the number
40      of processes in each dimension.
41      if init value is 0 it is reset by MPI_Dims_create.
42   */
43   int dims[DIM];
44   for (int i = 0; i < DIM; i++) {
45     dims[i] = Q;
46   }
47   /* periods:
48      Logical array of size ndims specifying whether the grid is
49      periodic (true) or not (false) in each dimension. */
50   int periods[DIM];
51   for (int i = 0; i < DIM; i++) {
52     periods[i] = 1;
53   }
54   /* reorder: do not allows rank reordering when creating the grid comm */
55   int reorder = 0;
56   /* remainDims[]: used to set which dimension is kept in subcommunicators */
57   int remainDim[DIM];
58
59   /* Local Matrix */
60   int* A = malloc(N * N * sizeof(int));
61
62   /* Init */
63   MPI_Init(&argc, &argv);
64   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
65   MPI_Comm_size(MPI_COMM_WORLD, &nbNodes);
66
67   printf("rank %d: Alive \n", rank);
68
69   MPI_Barrier(MPI_COMM_WORLD);
70
71   /* Set dims[] values to descibe a grid of nbNodes and DIM dimensions*/
72   MPI_Cart_create(MPI_COMM_WORLD, DIM, dims, periods, reorder, &gridComm);
73
74   if (gridComm == MPI_COMM_NULL)
75     printf("error grid NULLCOMM \n");
76
77   MPI_Comm_rank(gridComm, &myGridRank);
78   MPI_Comm_size(gridComm, &gridSize);
79   MPI_Cart_coords(gridComm, myGridRank, DIM, coords);
80   myLineRank = coords[0];
81   myColRank  = coords[1];
82
83   MPI_Barrier(MPI_COMM_WORLD);
84
85   /* Create a line communicator for current process */
86   remainDim[0] = 0;
87   remainDim[1] = 1;
88   MPI_Cart_sub(gridComm, remainDim, &lineComm);
89
90   /* Check if lineComm was initialized */
91   if (lineComm == MPI_COMM_NULL)
92     printf("(%d,%d): ERR (lineComm == NULLCOMM)\n", myLineRank, myColRank);
93
94   /* A Initialization */
95   for (int i = 0; i < N; i++) {
96     for (int j = 0; j < N; j++) {
97       *(A + (i * N) + j) = i == j ? rank : 0;
98     }
99   }
100
101   MPI_Barrier(MPI_COMM_WORLD);
102
103   /* Broadcast */
104   int root = 0;
105   MPI_Bcast(A, N * N, MPI_INT, root, lineComm);
106
107   /* Print A */
108   printf("process:(%d,%d) \n", myLineRank, myColRank);
109
110   printf("-------------------\n");
111   for (int i = 0; i < N; i++) {
112     for (int j = 0; j < N; j++) {
113       printf("%d ", *(A + (i * N) + j));
114     }
115     printf("\n");
116   }
117   printf("-------------------\n");
118   free(A);
119   MPI_Barrier(MPI_COMM_WORLD);
120   MPI_Finalize();
121   return 0;
122 }