9 #include <fei_macros.hpp>
11 #include <fei_Graph_Impl.hpp>
12 #include <fei_EqnComm.hpp>
13 #include <fei_CommUtils.hpp>
14 #include <fei_TemplateUtils.hpp>
15 #include <fei_VectorSpace.hpp>
18 #define fei_file "fei_Graph_Impl.cpp"
19 #include <fei_ErrMacros.hpp>
23 : localGraphData_(NULL),
26 firstLocalRow_(firstLocalRow),
27 lastLocalRow_(lastLocalRow),
36 remoteGraphData_.resize(numProcs_);
37 for(
int p=0; p<numProcs_; ++p) {
40 eqnComm_.
reset(
new fei::EqnComm(comm_, lastLocalRow-firstLocalRow+1));
41 localGraphData_ =
new table_type(firstLocalRow_, lastLocalRow_);
47 delete localGraphData_;
48 for(
unsigned i=0; i<remoteGraphData_.size(); ++i) {
49 delete remoteGraphData_[i];
60 if (row < firstLocalRow_ || row > lastLocalRow_) {
61 int p = eqnComm_->getOwnerProc(row);
62 remoteGraphData_[p]->addIndices(row, len, indices);
64 else localGraphData_->addIndices(row, len, indices);
74 addDiagonals(numIndices, indices);
78 bool all_local =
true;
80 for(
int i=0; i<numIndices; ++i) {
86 if (indices[i] < firstLocalRow_ || indices[i] > lastLocalRow_) {
92 int p = eqnComm_->getOwnerProc(indices[i]);
93 remoteGraphData_[p]->addIndices(indices[i], numIndices, indices);
99 localGraphData_->addIndices(numIndices, indices,
100 numIndices, indices);
103 for(
int i=0; i<numIndices; ++i) {
104 if (indices[i] >= firstLocalRow_ && indices[i] <= lastLocalRow_) {
105 localGraphData_->addIndices(indices[i], numIndices, indices);
114 void fei::Graph_Impl::addDiagonals(
int numIndices,
int* indices)
116 bool all_local =
true;
119 for(i=0; i<numIndices; ++i) {
120 int ind = indices[i];
122 throw std::runtime_error(
"fei::Graph_Impl::addDiagonals given negative index");
126 if (ind < firstLocalRow_ || ind > lastLocalRow_) {
132 int p=eqnComm_->getOwnerProc(ind);
133 remoteGraphData_[p]->addIndices(ind, 1, &ind);
139 localGraphData_->addDiagonals(numIndices, indices);
142 for(i=0; i<numIndices; ++i) {
143 int ind = indices[i];
144 if (ind >= firstLocalRow_ && ind <= lastLocalRow_) {
145 localGraphData_->addIndices(ind, 1, &ind);
153 bool prefixLinesWithPoundSign)
155 if (localGraphData_ == NULL) {
156 if (prefixLinesWithPoundSign) {
157 os <<
"# fei::Graph_Impl::writeLocalGraph numRows: 0"<<FEI_ENDL;
160 os <<
"0" << FEI_ENDL;
165 if (prefixLinesWithPoundSign) {
166 os <<
"# fei::Graph_Impl::writeLocalGraph numRows: ";
168 os << localGraphData_->getMap().size() <<FEI_ENDL;
170 if (prefixLinesWithPoundSign) {
183 for(
unsigned p=0; p<remoteGraphData_.size(); ++p) {
193 if (numProcs_ == 1)
return(0);
202 std::vector<int> sendProcs;
203 for(
unsigned i=0; i<remoteGraphData_.size(); ++i) {
204 if ((
int)i == localProc_)
continue;
205 if (remoteGraphData_[i] != NULL) {
206 if (remoteGraphData_[i]->getMap().size() == 0) {
210 sendProcs.push_back((
int)i);
215 std::vector<int> recvProcs;
219 std::vector<std::vector<int> > recv_ints(recvProcs.size());
222 std::vector<int> recv_sizes(recvProcs.size());
223 std::vector<MPI_Request> mpiReqs(recvProcs.size());
224 std::vector<MPI_Status> mpiStatuses(recvProcs.size());
229 for(
unsigned i=0; i<recvProcs.size(); ++i) {
230 MPI_Irecv(&recv_sizes[i], 1, MPI_INT, recvProcs[i],
231 tag1, comm_, &mpiReqs[i]);
236 std::vector<std::vector<int> > send_ints(sendProcs.size());
238 for(
unsigned i=0; i<sendProcs.size(); ++i) {
239 int proc = sendProcs[i];
241 fei::packRaggedTable(*(remoteGraphData_[proc]), send_ints[i]);
243 int isize = send_ints[i].size();
245 MPI_Send(&isize, 1, MPI_INT, proc, tag1, comm_);
248 if (mpiReqs.size() > 0) {
249 MPI_Waitall(mpiReqs.size(), &mpiReqs[0], &mpiStatuses[0]);
253 for(
size_t i=0; i<recvProcs.size(); ++i) {
254 int intsize = recv_sizes[i];
256 recv_ints[i].resize(intsize);
258 MPI_Irecv(&(recv_ints[i][0]), intsize, MPI_INT, recvProcs[i],
259 tag1, comm_, &mpiReqs[i]);
263 for(
size_t i=0; i<sendProcs.size(); ++i) {
264 int proc = sendProcs[i];
266 MPI_Send(&(send_ints[i][0]), send_ints[i].size(), MPI_INT,
270 if (mpiReqs.size() > 0) {
271 MPI_Waitall(mpiReqs.size(), &mpiReqs[0], &mpiStatuses[0]);
274 for(
unsigned i=0; i<recvProcs.size(); ++i) {
275 std::vector<int> recvdata = recv_ints[i];
276 int numRows = recvdata[0];
277 int* rowNumbers = &recvdata[1];
278 int* rowLengths = rowNumbers+numRows;
279 int* packedCols = rowLengths+numRows;
281 for(
int r=0; r<numRows; ++r) {
282 addIndices(rowNumbers[r], rowLengths[r], &packedCols[offset]);
283 offset += rowLengths[r];
295 if (colIndices == NULL) {
299 return(colIndices->
size());
305 int numLocalRows = localGraphData_->getMap().size();
307 return(numLocalRows);
int writeRemoteGraph(FEI_OSTREAM &os)
snl_fei::RaggedTable< snl_fei::MapContig< fei::ctg_set< int > * >, fei::ctg_set< int > > table_type
int countNonzeros(snl_fei::RaggedTable< MAP_TYPE, SET_TYPE > &table)
int addIndices(int row, int len, const int *indices)
Graph_Impl(MPI_Comm comm, int firstLocalRow, int lastLocalRow)
int writeLocalGraph(FEI_OSTREAM &os, bool debug=false, bool prefixLinesWithPoundSign=true)
void writeToStream(snl_fei::RaggedTable< MAP_TYPE, SET_TYPE > &table, FEI_OSTREAM &os, const char *lineprefix=NULL)
snl_fei::RaggedTable< std::map< int, fei::ctg_set< int > * >, fei::ctg_set< int > > remote_table_type
int getLocalRowLength(int row)
int mirrorProcs(MPI_Comm comm, std::vector< int > &toProcs, std::vector< int > &fromProcs)
int addSymmetricIndices(int numIndices, int *indices, bool diagonal=false)
int getNumLocalNonzeros() const
int localProc(MPI_Comm comm)
int numProcs(MPI_Comm comm)