10 #ifndef __READMATRIXFROMBINARYFILE_HPP
11 #define __READMATRIXFROMBINARYFILE_HPP
20 #include "Tpetra_Details_makeColMap.hpp"
22 template <
typename global_ordinal_type,
typename local_ordinal_type,
typename scalar_type,
typename map_type>
24 distribute (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
25 Teuchos::ArrayRCP<size_t>& myRowPtr,
26 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
27 Teuchos::ArrayRCP<scalar_type>& myValues,
28 const Teuchos::RCP<const map_type>& pRowMap,
29 global_ordinal_type *rowPtr,
30 global_ordinal_type *colInd,
31 const bool debug=
false)
34 int maxNumEnt = INT_MAX/
sizeof(global_ordinal_type);
36 Teuchos::RCP<const Teuchos::Comm<int>> pComm = pRowMap->getComm ();
37 const int numProcs = pComm->getSize ();
38 const int myRank = pComm->getRank ();
39 const int rootRank = 0;
41 Teuchos::ArrayView<const global_ordinal_type> myRows = pRowMap->getLocalElementList();
42 const size_t myNumRows = myRows.size();
44 myNumEntriesPerRow = Teuchos::ArrayRCP<size_t> (myNumRows);
46 if (myRank != rootRank) {
48 Teuchos::send (*pComm, myNumRows, rootRank);
52 Teuchos::send (*pComm, static_cast<int> (myNumRows), myRows.getRawPtr(), rootRank);
53 Teuchos::receive (*pComm, rootRank, static_cast<int> (myNumRows), myNumEntriesPerRow.getRawPtr());
55 const global_ordinal_type myNumEntries =
56 std::accumulate (myNumEntriesPerRow.begin(),
57 myNumEntriesPerRow.end(), 0);
59 myColInd = Teuchos::ArrayRCP<global_ordinal_type> (myNumEntries);
60 myValues = Teuchos::ArrayRCP<scalar_type> (myNumEntries, 1.0);
61 if (myNumEntries > 0) {
63 if(myNumEntries < maxNumEnt)
64 Teuchos::receive (*pComm, rootRank, static_cast<int> (myNumEntries), &myColInd[0]);
66 int nchunks = myNumEntries/maxNumEnt;
67 if(myNumEntries % maxNumEnt != 0)
69 for(
int i = 0; i < nchunks-1; i++) {
70 Teuchos::receive (*pComm, rootRank, maxNumEnt, &myColInd[maxNumEnt*i]);
71 std::cout <<
"Chunk " << i <<
" received by myRank "<< myRank <<
", size: " << maxNumEnt <<
"\n";
73 int lastsize = (int)(myNumEntries - (nchunks-1)*maxNumEnt);
74 Teuchos::receive (*pComm, rootRank, lastsize, &myColInd[maxNumEnt*(nchunks-1)]);
75 std::cout <<
"Chunk " << nchunks-1 <<
" received by myRank " << myRank <<
", size: " << lastsize <<
"\n";
85 std::cout <<
"-- Proc 0: Copying my data from global arrays" << std::endl;
88 for (
size_t k = 0; k < myNumRows; ++k) {
89 const global_ordinal_type myCurRow = myRows[k];
90 const global_ordinal_type numEntriesInThisRow = rowPtr[myCurRow+1] - rowPtr[myCurRow];
91 myNumEntriesPerRow[k] = numEntriesInThisRow;
95 size_t myNumEntries = std::accumulate (myNumEntriesPerRow.begin(),
96 myNumEntriesPerRow.end(), 0);
98 std::cout <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
99 << myNumEntries <<
" entries" << std::endl;
101 myColInd = Teuchos::ArrayRCP<global_ordinal_type> (myNumEntries);
102 myValues = Teuchos::ArrayRCP<scalar_type> (myNumEntries, 1.0);
104 global_ordinal_type myCurPos = 0;
105 for (
size_t k = 0; k < myNumRows; ++k) {
106 const global_ordinal_type curNumEntries = myNumEntriesPerRow[k];
107 const global_ordinal_type myRow = myRows[k];
108 global_ordinal_type curPos = rowPtr[myRow];
110 if (curNumEntries > 0) {
111 for(global_ordinal_type ii = 0; ii < curNumEntries; ++ii) {
112 myColInd[myCurPos++] = colInd[curPos++];
117 for (
int p = 1; p < numProcs; ++p) {
119 std::cout <<
"-- Proc 0: Processing proc " << p << std::endl;
122 size_t theirNumRows = 0;
123 Teuchos::receive (*pComm, p, &theirNumRows);
125 std::cout <<
"-- Proc 0: Proc " << p <<
" owns "
126 << theirNumRows <<
" rows" << std::endl;
129 if (theirNumRows != 0) {
130 Teuchos::ArrayRCP<global_ordinal_type> theirRows(theirNumRows);
131 Teuchos::receive (*pComm, p, Teuchos::as<int> (theirNumRows), theirRows.getRawPtr ());
133 Teuchos::ArrayRCP<size_t> theirNumEntriesPerRow = Teuchos::ArrayRCP<size_t> (theirNumRows);
134 for (
size_t k = 0; k < theirNumRows; ++k) {
135 theirNumEntriesPerRow[k] = rowPtr[theirRows[k]+1] - rowPtr[theirRows[k]];
138 Teuchos::send (*pComm, static_cast<int> (theirNumRows), theirNumEntriesPerRow.getRawPtr(), p);
140 const global_ordinal_type theirNumEntries =
141 std::accumulate (theirNumEntriesPerRow.begin(),
142 theirNumEntriesPerRow.end(), 0);
145 std::cout <<
"-- Proc 0: Proc " << p <<
" owns "
146 << theirNumEntries <<
" entries" << std::endl;
149 if (theirNumEntries == 0) {
153 Teuchos::ArrayRCP<global_ordinal_type> theirColInd (theirNumEntries);
155 global_ordinal_type theirCurPos = 0;
156 for (
size_t k = 0; k < theirNumRows; k++) {
157 const global_ordinal_type curNumEntries = theirNumEntriesPerRow[k];
158 const global_ordinal_type theirRow = theirRows[k];
159 global_ordinal_type curPos = rowPtr[theirRow];
161 if (curNumEntries > 0) {
163 for(global_ordinal_type ii = 0; ii < curNumEntries; ++ii) {
164 theirColInd[theirCurPos++] = colInd[curPos++];
170 if(theirNumEntries < maxNumEnt)
171 Teuchos::send (*pComm, static_cast<int> (theirNumEntries), &theirColInd[0], p);
173 int nchunks = theirNumEntries/maxNumEnt;
174 if(theirNumEntries % maxNumEnt != 0)
176 for(
int i = 0; i < nchunks-1; i++) {
177 Teuchos::send (*pComm, maxNumEnt, &theirColInd[maxNumEnt*i], p);
178 std::cout <<
"Chunk " << i <<
" sent to Rank "<< p <<
", size: " << maxNumEnt <<
"\n";
180 int lastsize = (int)(theirNumEntries - (nchunks-1)*maxNumEnt);
181 Teuchos::send (*pComm, lastsize, &theirColInd[maxNumEnt*(nchunks-1)], p);
182 std::cout <<
"Chunk " << nchunks-1 <<
" sent to Rank "<< p <<
", size: " << lastsize <<
"\n";
186 std::cout <<
"-- Proc 0: Finished with proc " << p << std::endl;
193 if (debug && myRank == 0) {
194 std::cout <<
"-- Proc 0: About to fill in myRowPtr" << std::endl;
197 myRowPtr = Teuchos::ArrayRCP<size_t> (myNumRows+1);
199 for (
size_t k = 1; k < myNumRows+1; ++k) {
200 myRowPtr[k] = myRowPtr[k-1] + myNumEntriesPerRow[k-1];
202 if (debug && myRank == 0) {
203 std::cout <<
"-- Proc 0: Done with distribute" << std::endl;
207 template <
typename crs_matrix_type>
208 Teuchos::RCP<crs_matrix_type>
209 readBinaryFile(std::string filename,
const Teuchos::RCP<
const Teuchos::Comm<int>> pComm,
bool callFillComplete=
true,
bool debug=
false)
211 typedef typename crs_matrix_type::global_ordinal_type global_ordinal_type;
212 typedef typename crs_matrix_type::local_ordinal_type local_ordinal_type;
213 typedef typename crs_matrix_type::scalar_type scalar_type;
214 typedef typename crs_matrix_type::node_type node_type;
216 typedef typename Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
218 const int myRank = pComm->getRank();
219 const int rootRank = 0;
221 if (debug && myRank == rootRank) {
222 std::cout <<
"Binary CRS reader: readSparse:" << std::endl
223 <<
"-- Reading started" << std::endl;
226 Teuchos::RCP<std::ifstream> in;
227 global_ordinal_type globalNumRows;
228 global_ordinal_type globalNumNonzeros;
230 if (myRank == rootRank) {
233 in = Teuchos::RCP<std::ifstream>(
new std::ifstream(filename, std::ios::in | std::ios::binary));
236 in->read((
char *)&globalNumRows,
sizeof(global_ordinal_type));
237 in->read((
char *)&globalNumNonzeros,
sizeof(global_ordinal_type));
239 TEUCHOS_TEST_FOR_EXCEPTION(globalNumRows <= 0 || globalNumNonzeros <= 0, std::invalid_argument,
240 "Global number of rows or nonzeros have nonpositive value." << globalNumRows <<
" " << globalNumNonzeros <<
" " <<
sizeof(global_ordinal_type) );
243 broadcast (*pComm, rootRank, 1, &globalNumRows);
244 broadcast (*pComm, rootRank, 1, &globalNumNonzeros);
246 global_ordinal_type *rowPtr = 0;
247 global_ordinal_type *colInd = 0;
249 if (myRank == rootRank) {
251 rowPtr =
new global_ordinal_type[globalNumRows+1];
252 colInd =
new global_ordinal_type[globalNumNonzeros];
254 in->read((
char*)rowPtr,
sizeof(global_ordinal_type)*(globalNumRows+1));
255 in->read((
char*)colInd,
sizeof(global_ordinal_type)*(globalNumNonzeros));
258 Teuchos::RCP<const map_type> pRowMap = Teuchos::rcp (
new map_type (static_cast<Tpetra::global_size_t> (globalNumRows),
259 static_cast<global_ordinal_type> (0),
260 pComm, Tpetra::GloballyDistributed));
262 Teuchos::RCP<const map_type> pRangeMap = Teuchos::rcp (
new map_type (static_cast<Tpetra::global_size_t> (globalNumRows),
263 static_cast<global_ordinal_type> (0),
264 pComm, Tpetra::GloballyDistributed));
266 Teuchos::RCP<const map_type> pDomainMap = pRangeMap;
268 Teuchos::ArrayView<const global_ordinal_type> myRows = pRowMap->getLocalElementList ();
269 const size_t myNumRows = myRows.size ();
271 Teuchos::ArrayRCP<size_t> myNumEntriesPerRow(myNumRows);
272 Teuchos::ArrayRCP<size_t> myRowPtr;
273 Teuchos::ArrayRCP<global_ordinal_type> myColInd;
274 Teuchos::ArrayRCP<scalar_type> myValues;
276 distribute<global_ordinal_type, local_ordinal_type, scalar_type, map_type>(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap, rowPtr, colInd, debug);
279 if (debug && myRank == rootRank) {
280 std::cout <<
"-- Inserting matrix entries on each processor";
281 if (callFillComplete) {
282 std::cout <<
" and calling fillComplete()";
284 std::cout << std::endl;
287 Teuchos::RCP<crs_matrix_type> pMatrix = Teuchos::rcp (
new crs_matrix_type (pRowMap, myNumEntriesPerRow()));
289 const global_ordinal_type indexBase = pRowMap->getIndexBase ();
290 for (
size_t i = 0; i < myNumRows; ++i) {
291 const size_t myCurPos = myRowPtr[i];
292 const local_ordinal_type curNumEntries = myNumEntriesPerRow[i];
293 Teuchos::ArrayView<global_ordinal_type> curColInd = myColInd.view (myCurPos, curNumEntries);
294 Teuchos::ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
296 for (
size_t k = 0; k < curNumEntries; ++k) {
297 curColInd[k] += indexBase;
300 if (curNumEntries > 0) {
301 pMatrix->insertGlobalValues (myRows[i], curColInd, curValues);
305 if (debug && myRank == rootRank) {
306 std::cout <<
"-- Done with inserting." << std::endl;
309 myNumEntriesPerRow = Teuchos::null;
310 myRowPtr = Teuchos::null;
311 myColInd = Teuchos::null;
312 myValues = Teuchos::null;
314 if (callFillComplete) {
315 pMatrix->fillComplete (pDomainMap, pRangeMap);
318 if (debug && myRank == rootRank) {
319 std::cout <<
"-- Done with fill complete." << std::endl;
323 if(myRank == rootRank) {
331 template <
typename crs_matrix_type>
332 Teuchos::RCP<crs_matrix_type>
333 readBinaryFileFast(std::string filename,
const Teuchos::RCP<
const Teuchos::Comm<int>> pComm,
bool callFillComplete=
true,
bool debug=
false)
335 typedef typename crs_matrix_type::global_ordinal_type global_ordinal_type;
336 typedef typename crs_matrix_type::local_ordinal_type local_ordinal_type;
337 typedef typename crs_matrix_type::scalar_type scalar_type;
338 typedef typename crs_matrix_type::node_type node_type;
339 typedef typename crs_matrix_type::crs_graph_type crs_graph_type;
341 typedef typename Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
343 const int myRank = pComm->getRank();
344 const int rootRank = 0;
346 if (debug && myRank == rootRank) {
347 std::cout <<
"Binary CRS reader: readSparse:" << std::endl
348 <<
"-- Reading started" << std::endl;
351 Teuchos::RCP<std::ifstream> in;
352 global_ordinal_type globalNumRows;
353 global_ordinal_type globalNumNonzeros;
355 if (myRank == rootRank) {
358 in = Teuchos::RCP<std::ifstream>(
new std::ifstream(filename, std::ios::in | std::ios::binary));
361 in->read((
char *)&globalNumRows,
sizeof(global_ordinal_type));
362 in->read((
char *)&globalNumNonzeros,
sizeof(global_ordinal_type));
364 TEUCHOS_TEST_FOR_EXCEPTION(globalNumRows <= 0 || globalNumNonzeros <= 0, std::invalid_argument,
365 "Global number of rows or nonzeros have nonpositive value." << globalNumRows <<
" " << globalNumNonzeros <<
" " <<
sizeof(global_ordinal_type) );
368 broadcast (*pComm, rootRank, 1, &globalNumRows);
369 broadcast (*pComm, rootRank, 1, &globalNumNonzeros);
371 global_ordinal_type *rowPtr = 0;
372 global_ordinal_type *colInd = 0;
374 if (myRank == rootRank) {
376 rowPtr =
new global_ordinal_type[globalNumRows+1];
377 colInd =
new global_ordinal_type[globalNumNonzeros];
379 in->read((
char*)rowPtr,
sizeof(global_ordinal_type)*(globalNumRows+1));
380 in->read((
char*)colInd,
sizeof(global_ordinal_type)*(globalNumNonzeros));
385 Teuchos::RCP<const map_type> pRowMap = Teuchos::rcp (
new map_type (static_cast<Tpetra::global_size_t> (globalNumRows),
386 static_cast<global_ordinal_type> (0),
387 pComm, Tpetra::GloballyDistributed));
389 Teuchos::RCP<const map_type> pRangeMap = Teuchos::rcp (
new map_type (static_cast<Tpetra::global_size_t> (globalNumRows),
390 static_cast<global_ordinal_type> (0),
391 pComm, Tpetra::GloballyDistributed));
393 Teuchos::RCP<const map_type> pDomainMap = pRangeMap;
395 Teuchos::ArrayView<const global_ordinal_type> myRows = pRowMap->getLocalElementList ();
396 const size_t myNumRows = myRows.size ();
398 Teuchos::ArrayRCP<size_t> myNumEntriesPerRow(myNumRows);
399 Teuchos::ArrayRCP<size_t> myRowPtr;
400 Teuchos::ArrayRCP<global_ordinal_type> myColInd;
401 Teuchos::ArrayRCP<scalar_type> myValues;
404 distribute<global_ordinal_type, local_ordinal_type, scalar_type, map_type>(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap, rowPtr, colInd, debug);
407 if (debug && myRank == rootRank) {
408 std::cout <<
"-- Inserting matrix entries on each processor";
409 if (callFillComplete) {
410 std::cout <<
" and calling fillComplete()";
412 std::cout << std::endl;
416 std::vector<bool> mark(globalNumRows,
false);
417 size_t myNumEntries = myRowPtr[myNumRows];
418 for(
size_t i = 0; i < myNumEntries; i++)
419 mark[myColInd[i]] =
true;
421 local_ordinal_type myNumCols = 0;
422 for(global_ordinal_type i = 0; i < globalNumRows; i++)
426 Kokkos::View<global_ordinal_type*, typename node_type::memory_space> myColGIDs(
"myColGIDs", myNumCols);
427 auto myColGIDs_host = Kokkos::create_mirror_view(Kokkos::HostSpace(), myColGIDs);
430 for(global_ordinal_type i = 0; i < globalNumRows; i++)
431 if(mark[i] ==
true) {
432 myColGIDs_host(myNumCols)= i;
436 Kokkos::deep_copy(myColGIDs, myColGIDs_host);
438 Teuchos::RCP<const map_type> pColumnMap;
439 Tpetra::Details::makeColMap(pColumnMap, pDomainMap, myColGIDs);
441 std::vector<local_ordinal_type> map(globalNumRows);
442 for(global_ordinal_type i = 0; i < globalNumRows; i++) {
444 map[i] = pColumnMap->getLocalElement(i);
447 Teuchos::ArrayRCP<local_ordinal_type> myLclColInd(myNumEntries);
448 for(
size_t i = 0; i < myNumEntries; i++)
449 myLclColInd[i] = map[myColInd[i]];
451 local_ordinal_type *cur = myLclColInd.getRawPtr();
453 for(
size_t i = 0; i < myNumRows; i++) {
454 size_t start = myRowPtr[i];
455 size_t end = myRowPtr[i+1];
457 std::sort(&cur[start], &cur[end]);
460 Teuchos::RCP<crs_graph_type> graph(
new crs_graph_type(pRowMap, pColumnMap, myRowPtr, myLclColInd));
461 graph->fillComplete(pDomainMap, pRangeMap);
463 Kokkos::View<scalar_type*, typename node_type::memory_space> values(
"values", myNumEntries);
464 Kokkos::deep_copy(values, 1.0);
466 Teuchos::RCP<crs_matrix_type> pMatrix (
new crs_matrix_type(graph, values));
467 pMatrix->fillComplete(pDomainMap, pRangeMap);
470 if (debug && myRank == rootRank) {
471 std::cout <<
"-- Done with fill complete." << std::endl;
474 if(myRank == rootRank) {
482 template <
typename crs_matrix_type>
483 Teuchos::RCP<crs_matrix_type>
484 readMatrixFromBinaryFile(std::string filename,
const Teuchos::RCP<
const Teuchos::Comm<int>> pComm,
bool binary=
true,
bool debug=
false)
486 return readBinaryFileFast<crs_matrix_type>(filename, pComm,
true, debug);
void distribute(Teuchos::ArrayRCP< size_t > &myNumEntriesPerRow, Teuchos::ArrayRCP< size_t > &myRowPtr, Teuchos::ArrayRCP< global_ordinal_type > &myColInd, Teuchos::ArrayRCP< scalar_type > &myValues, const Teuchos::RCP< const map_type > &pRowMap, global_ordinal_type *rowPtr, global_ordinal_type *colInd, const bool debug=false)
Teuchos::RCP< crs_matrix_type > readBinaryFileFast(std::string filename, const Teuchos::RCP< const Teuchos::Comm< int >> pComm, bool callFillComplete=true, bool debug=false)
Teuchos::RCP< crs_matrix_type > readMatrixFromBinaryFile(std::string filename, const Teuchos::RCP< const Teuchos::Comm< int >> pComm, bool binary=true, bool debug=false)
Teuchos::RCP< crs_matrix_type > readBinaryFile(std::string filename, const Teuchos::RCP< const Teuchos::Comm< int >> pComm, bool callFillComplete=true, bool debug=false)