Logo AND Algorithmique Numérique Distribuée

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