COMBINATORIAL_BLAS  1.6
SplitMatDist.h
Go to the documentation of this file.
1 #ifndef _SPLIT_MAT_DIST_H_
2 #define _SPLIT_MAT_DIST_H_
3 
4 #include <mpi.h>
5 #include <sys/time.h>
6 #include <iostream>
7 #include <iomanip>
8 #include <functional>
9 #include <algorithm>
10 #include <vector>
11 #include <string>
12 #include <sstream>
13 
14 // These macros should be defined before stdint.h is included
15 #ifndef __STDC_CONSTANT_MACROS
16 #define __STDC_CONSTANT_MACROS
17 #endif
18 #ifndef __STDC_LIMIT_MACROS
19 #define __STDC_LIMIT_MACROS
20 #endif
21 #include <stdint.h>
22 
23 #include "CombBLAS/CombBLAS.h"
24 #include "Glue.h"
25 #include "CCGrid.h"
26 
27 namespace combblas {
28 
29 template <typename NT, typename IT>
30 SpDCCols<IT,NT> * ReadMat(std::string filename, CCGrid & CMG, bool permute, FullyDistVec<IT, IT>& p)
31 {
32  double t01 = MPI_Wtime();
33  double t02;
34  if(CMG.layer_grid == 0)
35  {
36  std::shared_ptr<CommGrid> layerGrid;
37  layerGrid.reset( new CommGrid(CMG.layerWorld, 0, 0) );
39 
40  SpParHelper::Print("Reading input file....\n");
41  A->ParallelReadMM(filename, true, maximum<double>());
42  A->PrintInfo();
43  std::ostringstream tinfo;
44  t02 = MPI_Wtime();
45  tinfo << "Reader took " << t02-t01 << " seconds" << std::endl;
46  SpParHelper::Print(tinfo.str());
47 
48  // random permutations for load balance
49  if(permute)
50  {
51  if(A->getnrow() == A->getncol())
52  {
53  if(p.TotalLength()!=A->getnrow())
54  {
55  SpParHelper::Print("Generating random permutation vector.\n");
56  p.iota(A->getnrow(), 0);
57  p.RandPerm();
58  }
59  SpParHelper::Print("Perfoming random permuation of matrix.\n");
60  (*A)(p,p,true);// in-place permute to save memory
61  std::ostringstream tinfo1;
62  tinfo1 << "Permutation took " << MPI_Wtime()-t02 << " seconds" << std::endl;
63  SpParHelper::Print(tinfo1.str());
64  }
65  else
66  {
67  SpParHelper::Print("nrow != ncol. Can not apply symmetric permutation.\n");
68  }
69  }
70 
71  float balance = A->LoadImbalance();
72  std::ostringstream outs;
73  outs << "Input load balance: " << balance << std::endl;
74  SpParHelper::Print(outs.str());
75 
76  return A->seqptr();
77  }
78  else
79  return new SpDCCols<IT,NT>();
80 }
81 
82 template<typename IT, typename NT>
83 SpDCCols<IT,NT> * GenMat(CCGrid & CMG, unsigned scale, unsigned EDGEFACTOR, double initiator[4], bool permute)
84 {
85  double t01 = MPI_Wtime();
86  double t02;
87 
88  if(CMG.layer_grid == 0)
89  {
91 
92  std::ostringstream minfo;
93  int nprocs = DEL->commGrid->GetSize();
94  minfo << "Started Generation of scale "<< scale << std::endl;
95  minfo << "Using " << nprocs << " MPI processes" << std::endl;
96  SpParHelper::Print(minfo.str());
97 
98  DEL->GenGraph500Data(initiator, scale, EDGEFACTOR, true, false );
99 
100  SpParHelper::Print("Generated renamed edge lists\n");
101  std::ostringstream tinfo;
102  t02 = MPI_Wtime();
103  tinfo << "Generation took " << t02-t01 << " seconds" << std::endl;
104  SpParHelper::Print(tinfo.str());
105 
107  delete DEL;
108  SpParHelper::Print("Created Sparse Matrix\n");
109  A->PrintInfo();
110 
111 
112  if(permute)
113  {
114  SpParHelper::Print("Perfoming random permuation of matrix.\n");
115  std::shared_ptr<CommGrid> layerGrid;
116  layerGrid.reset( new CommGrid(CMG.layerWorld, 0, 0) );
117  FullyDistVec<IT, IT> p(layerGrid); // permutation vector defined on layers
118  p.iota(A->getnrow(), 0);
119  p.RandPerm();
120  (*A)(p,p,true);// in-place permute to save memory
121  std::ostringstream tinfo1;
122  tinfo1 << "Permutation took " << MPI_Wtime()-t02 << " seconds" << std::endl;
123  SpParHelper::Print(tinfo1.str());
124  }
125 
126 
127 
128  float balance = A->LoadImbalance();
129  std::ostringstream outs;
130  outs << "Load balance: " << balance << std::endl;
131  SpParHelper::Print(outs.str());
132 
133  return A->seqptr();
134  }
135  else
136  return new SpDCCols<IT,NT>();
137 }
138 
143 template <typename IT, typename NT>
144 void SplitMat(CCGrid & CMG, SpDCCols<IT, NT> * localmat, SpDCCols<IT,NT> & splitmat, bool rowsplit=false)
145 {
146  double t01 = MPI_Wtime();
147  std::vector<IT> vecEss; // at layer_grid=0, this will have [CMG.GridLayers * SpDCCols<IT,NT>::esscount] entries
148  std::vector< SpDCCols<IT, NT> > partsmat; // only valid at layer_grid=0
149  int nparts = CMG.GridLayers;
150  if(CMG.layer_grid == 0)
151  {
152  double split_beg = MPI_Wtime();
153  if(rowsplit && nparts>1) localmat->Transpose(); // local rowsplit is performaned local transpose and ColSplit
154  localmat->ColSplit(nparts, partsmat); // split matrices are emplaced-back into partsmat vector, localmat destroyed
155 
156  for(int i=0; i< nparts; ++i)
157  {
158  std::vector<IT> ess = partsmat[i].GetEssentials();
159  for(auto itr = ess.begin(); itr != ess.end(); ++itr)
160  {
161  vecEss.push_back(*itr);
162  }
163  }
164  comp_split += (MPI_Wtime() - split_beg);
165  }
166 
167  double scatter_beg = MPI_Wtime(); // timer on
168  int esscnt = SpDCCols<IT,NT>::esscount; // necessary cast for MPI
169 
170  std::vector<IT> myess(esscnt);
171  MPI_Scatter(vecEss.data(), esscnt, MPIType<IT>(), myess.data(), esscnt, MPIType<IT>(), 0, CMG.fiberWorld);
172 
173  if(CMG.layer_grid == 0) // senders
174  {
175  splitmat = partsmat[0]; // just copy the local split
176  for(int recipient=1; recipient< nparts; ++recipient) // scatter the others
177  {
178  int tag = 0;
179  Arr<IT,NT> arrinfo = partsmat[recipient].GetArrays();
180  for(unsigned int i=0; i< arrinfo.indarrs.size(); ++i) // get index arrays
181  {
182  // MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
183  MPI_Send(arrinfo.indarrs[i].addr, arrinfo.indarrs[i].count, MPIType<IT>(), recipient, tag++, CMG.fiberWorld);
184  }
185  for(unsigned int i=0; i< arrinfo.numarrs.size(); ++i) // get numerical arrays
186  {
187  MPI_Send(arrinfo.numarrs[i].addr, arrinfo.numarrs[i].count, MPIType<NT>(), recipient, tag++, CMG.fiberWorld);
188  }
189  }
190  }
191  else // receivers
192  {
193  splitmat.Create(myess); // allocate memory for arrays
194  Arr<IT,NT> arrinfo = splitmat.GetArrays();
195 
196  int tag = 0;
197  for(unsigned int i=0; i< arrinfo.indarrs.size(); ++i) // get index arrays
198  {
199  MPI_Recv(arrinfo.indarrs[i].addr, arrinfo.indarrs[i].count, MPIType<IT>(), 0, tag++, CMG.fiberWorld, MPI_STATUS_IGNORE);
200  }
201  for(unsigned int i=0; i< arrinfo.numarrs.size(); ++i) // get numerical arrays
202  {
203  MPI_Recv(arrinfo.numarrs[i].addr, arrinfo.numarrs[i].count, MPIType<NT>(), 0, tag++, CMG.fiberWorld, MPI_STATUS_IGNORE);
204  }
205  }
206  comm_split += (MPI_Wtime() - scatter_beg);
207 
208  if(rowsplit && nparts>1) splitmat.Transpose(); //transpose back after row-splitting
209  std::ostringstream tinfo;
210  tinfo << "Matrix split and distributed along layers: time " << MPI_Wtime()-t01 << " seconds" << std::endl;
211  SpParHelper::Print(tinfo.str());
212 
213 }
214 
215 }
216 
217 #endif
Compute the maximum of two values.
Definition: Operations.h:154
SpDCCols< IT, NT > * ReadMat(std::string filename, CCGrid &CMG, bool permute, FullyDistVec< IT, IT > &p)
Definition: SplitMatDist.h:30
int layer_grid
Definition: CCGrid.h:40
void GenGraph500Data(double initiator[4], int log_numverts, int edgefactor, bool scramble=false, bool packed=false)
std::vector< LocArr< NT, IT > > numarrs
Definition: LocArr.h:55
SpDCCols< IT, NT > * GenMat(CCGrid &CMG, unsigned scale, unsigned EDGEFACTOR, double initiator[4], bool permute)
Definition: SplitMatDist.h:83
std::vector< LocArr< IT, IT > > indarrs
Definition: LocArr.h:54
double comp_split
Definition: mpipspgemm.cpp:28
#define EDGEFACTOR
Definition: DirOptBFS.cpp:81
MPI_Comm layerWorld
Definition: CCGrid.h:41
float LoadImbalance() const
Definition: SpParMat.cpp:665
void ColSplit(int parts, std::vector< SpDCCols< IT, NT > > &matrices)
Definition: SpDCCols.cpp:897
void Create(const std::vector< IT > &essentials)
Definition: SpMat.h:61
void SplitMat(CCGrid &CMG, SpDCCols< IT, NT > *localmat, SpDCCols< IT, NT > &splitmat, bool rowsplit=false)
Definition: SplitMatDist.h:144
double A
static void Print(const std::string &s)
void iota(IT globalsize, NT first)
Arr< IT, NT > GetArrays() const
Definition: SpDCCols.cpp:787
double comm_split
Definition: mpipspgemm.cpp:30
IT getncol() const
Definition: SpParMat.cpp:694
void PrintInfo() const
Definition: SpParMat.cpp:2387
Definition: CCGrid.h:4
MPI_Comm fiberWorld
Definition: CCGrid.h:42
std::shared_ptr< CommGrid > commGrid
Definition: DistEdgeList.h:99
void Transpose()
Mutator version, replaces the calling object.
Definition: SpDCCols.cpp:815
int GridLayers
Definition: CCGrid.h:36
void ParallelReadMM(const std::string &filename, bool onebased, _BinaryOperation BinOp)
Definition: SpParMat.cpp:3417
IT getnrow() const
Definition: SpParMat.cpp:685