COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
CommGrid3D.h
Go to the documentation of this file.
1#ifndef _COMM_GRID_3D_H_
2#define _COMM_GRID_3D_H_
3
4
5using namespace std;
6
7namespace combblas {
8
10{
11public:
12 // Create a special 3D CommGrid with all the processors involved in the given world
13 // Parameters:
14 // - A communication world with all the processors with which 3D grid would be made
15 // - Number of layers in the 3D grid
16 // - Number of processors along the row of each layer in the 3D grid
17 // - Number of processors along the column of each layer in the 3D grid
18 // - A flag which will denote if matrix distribution in the comm grid will be in column split manner or row split manner
19 // - A flag which will denote that this CommGrid3D object will be formed in special fashion for communication optimization
20 // Information about number of layers, rows and colunmns is being saved to member variables before the execution of this constructor with the help of copy constructors
21 CommGrid3D(MPI_Comm world, int nlayers, int nrowproc, int ncolproc, bool special = false): gridLayers(nlayers), gridRows(nrowproc), gridCols(ncolproc), special(special)
22 {
23 int nproc;
24 MPI_Comm_dup(world, & world3D);
25 MPI_Comm_rank(world3D, & myrank);
26 MPI_Comm_size(world3D, & nproc);
27
28 if(nlayers<1){
29 cerr << "A 3D grid can not be created with less than one layer" << endl;
31 }
32 if(nproc % nlayers != 0){
33 cerr << "Number of processes is not divisible by number of layers" << endl;
35 }
36 if(special){
37 if(((int)std::sqrt((float)nlayers) * (int)std::sqrt((float)nlayers)) != nlayers){
38 // Number of layers need to be a square number for this special distribution.
39 cerr << "Number of layers is not a square number" << endl;
41 }
42 }
43
44 int procPerLayer = nproc / nlayers;
45 // If given number of rows and columns in a layer has not been provided by the caller then we need to calculate that as well
46 if(gridRows == 0 && gridCols == 0)
47 {
48 // Calculate number of rows and columns in a layer by taking square root of previously calculated number of processors in each layer
49 gridRows = (int)std::sqrt((float)procPerLayer);
50 gridCols = gridRows;
51
52 // Do an additional error handling depending on given processors and number of layers whether the layers can be square 2D grid or not
53 if(gridRows * gridCols != procPerLayer)
54 {
55 cerr << "This version of the Combinatorial BLAS only works on a square logical processor grid in a layer of the 3D grid" << endl;
57 }
58 }
59 // Another extra layer of assertion if number of layers, rows and columns it covers all the given processors or not
60 assert((nproc == (gridRows * gridCols * gridLayers)));
61
62 if(special){
63 int nCol2D = (int)std::sqrt((float)nproc);
64 int rankInRow2D = myrank / nCol2D;
65 int rankInCol2D = myrank % nCol2D;
66 int sqrtLayer = (int)std::sqrt((float)nlayers);
67 rankInFiber = (rankInCol2D % sqrtLayer) * sqrtLayer + (rankInRow2D % sqrtLayer);
68 rankInLayer = (rankInRow2D / sqrtLayer) * gridCols + (rankInCol2D / sqrtLayer);
69 MPI_Comm_split(world3D, rankInFiber, rankInLayer, &layerWorld);
70 MPI_Comm_split(world3D, rankInLayer, rankInFiber, &fiberWorld);
71 }
72 else{
73 rankInFiber = myrank / procPerLayer;
74 rankInLayer = myrank % procPerLayer;
75 MPI_Comm_split(world3D, rankInFiber, rankInLayer, &layerWorld);
76 MPI_Comm_split(world3D, rankInLayer, rankInFiber, &fiberWorld);
77 }
78
79 commGridLayer.reset(new CommGrid(layerWorld, gridRows, gridCols));
80 }
81
83 MPI_Comm_free(&world3D);
84 MPI_Comm_free(&fiberWorld);
85 MPI_Comm_free(&layerWorld);
86 }
87
88 // Processor grid is (gridLayers x gridRows X gridCols)
89 // Function to return rank of a processor in global 2D CommGrid from it's layer, row and column information in 3D CommGrid
90 int GetRank(int layerrank, int rowrank, int colrank) {
91 if(!special) return layerrank * gridRows * gridCols + rowrank * gridCols + colrank;
92 //else {
94 //}
95 }
96 int GetGridLayers() {return gridLayers;}
97 int GetGridRows() {return gridRows;}
98 int GetGridCols() {return gridCols;}
99 int GetSize() { return gridLayers * gridRows * gridCols; }
100 bool isSpecial() { return special; }
101 MPI_Comm & GetWorld(){return world3D;}
102 MPI_Comm & GetFiberWorld(){return fiberWorld;}
103 MPI_Comm & GetLayerWorld(){return layerWorld;}
104 std::shared_ptr<CommGrid> GetCommGridLayer(){return commGridLayer;}
105 int GetRankInWorld(){return myrank;}
106 int GetRankInFiber(){return rankInFiber;}
107 int GetRankInLayer(){return rankInLayer;}
108private:
109 bool special;
110 int gridRows; // Number of processors along row of each layer in this 3D CommGrid
111 int gridCols; // Number of processors along column of each layer in this 3D CommGrid
112 int gridLayers; // Number of layers in this 3D CommGrid
113 int myrank; // ID of the running processor in the communication world
114 int rankInFiber;
115 int rankInLayer;
116 MPI_Comm world3D;
117 MPI_Comm layerWorld;
118 MPI_Comm fiberWorld;
119 std::shared_ptr<CommGrid> commGridLayer; // 2D CommGrid corresponding to the layer to which running processor belongs
120};
121
122}
123
124#endif
MPI_Comm & GetFiberWorld()
Definition CommGrid3D.h:102
MPI_Comm & GetLayerWorld()
Definition CommGrid3D.h:103
CommGrid3D(MPI_Comm world, int nlayers, int nrowproc, int ncolproc, bool special=false)
Definition CommGrid3D.h:21
int GetRank(int layerrank, int rowrank, int colrank)
Definition CommGrid3D.h:90
std::shared_ptr< CommGrid > GetCommGridLayer()
Definition CommGrid3D.h:104
MPI_Comm & GetWorld()
Definition CommGrid3D.h:101
#define NOTSQUARE
Definition SpDefs.h:74