COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
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
27namespace combblas {
28
29template <typename NT, typename IT>
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;
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;
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;
75
76 return A->seqptr();
77 }
78 else
79 return new SpDCCols<IT,NT>();
80}
81
82template<typename IT, typename NT>
83SpDCCols<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;
97
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;
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;
124 }
125
126
127
128 float balance = A->LoadImbalance();
129 std::ostringstream outs;
130 outs << "Load balance: " << balance << std::endl;
132
133 return A->seqptr();
134 }
135 else
136 return new SpDCCols<IT,NT>();
137}
138
143template <typename IT, typename NT>
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 }
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 }
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;
212
213}
214
215}
216
217#endif
#define EDGEFACTOR
Definition DirOptBFS.cpp:81
double comp_split
double comm_split
void GenGraph500Data(double initiator[4], int log_numverts, int edgefactor, bool scramble=false, bool packed=false)
std::shared_ptr< CommGrid > commGrid
static void Print(const std::string &s)
int nprocs
Definition comms.cpp:55
SpDCCols< IT, NT > * ReadMat(std::string filename, CCGrid &CMG, bool permute, FullyDistVec< IT, IT > &p)
void SplitMat(CCGrid &CMG, SpDCCols< IT, NT > *localmat, SpDCCols< IT, NT > &splitmat, bool rowsplit=false)
SpDCCols< IT, NT > * GenMat(CCGrid &CMG, unsigned scale, unsigned EDGEFACTOR, double initiator[4], bool permute)
double A