Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Teuchos_MatrixMarket_CoordDataReader.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Tpetra: Templated Linear Algebra Services Package
5// Copyright (2008) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ************************************************************************
40// @HEADER
41
42#ifndef __Teuchos_MatrixMarket_CoordDataReader_hpp
43#define __Teuchos_MatrixMarket_CoordDataReader_hpp
44
46#include "Teuchos_RCP.hpp"
48#include "Teuchos_Tuple.hpp"
49
50
51namespace Teuchos {
52 namespace MatrixMarket {
99 template<class Callback, class Ordinal>
101 protected:
104
105 public:
118
127
130
138 adder_ = adder;
139 }
140
141 protected:
168 virtual bool
169 readLine (const std::string& theLine,
170 const size_t lineNumber,
171 const bool tolerant) = 0;
172
173 public:
174
202 virtual std::pair<bool, std::vector<size_t> >
203 read (std::istream& in,
204 const size_t startingLineNumber,
205 const bool tolerant,
206 const bool debug = false)
207 {
208 (void) debug; // silence unused input argument warning
209 TEUCHOS_TEST_FOR_EXCEPTION(! in, std::invalid_argument,
210 "Input stream is invalid.");
211
212 std::string line;
214 bool allSucceeded = true;
215 std::vector<size_t> badLineNumbers;
216 size_t validDataLines = 0;
217 while (getline (in, line)) {
218 size_t start, size;
219 if (checkCommentLine (line, start, size, lineNumber, tolerant)) {
220 ++lineNumber;
221 continue; // it's a comment line
222 }
223 const std::string theLine = line.substr (start, size);
224
226 ++lineNumber;
228 if (! localSuccess) {
229 badLineNumbers.push_back (lineNumber);
230 }
231 else {
233 }
234 }
235 return std::make_pair (allSucceeded, badLineNumbers);
236 }
237
261 std::pair<Teuchos::Tuple<Ordinal, 3>, bool>
262 readDimensions (std::istream& in,
263 size_t& lineNumber,
264 const bool tolerant = false)
265 {
267 // Fill in (numRows, numCols, numNonzeros) with reasonable
268 // defaults. If we don't succeed in reading all the data
269 // from the current line of the input stream, the remaining
270 // values not read will be these default values.
271 dims[0] = 0;
272 dims[1] = 0;
273 dims[2] = 0;
274
275 // Keep reading lines from the input stream until we find a
276 // non-comment line, or until we run out of lines. The latter
277 // is an error, since every "coordinate" format Matrix Market
278 // file must have a dimensions line after the banner (even if
279 // the matrix has zero rows or columns, or zero entries).
280 std::string line;
281 bool commentLine = true;
282 while (commentLine) {
283 // Is it even valid to read from the input stream?
284 if (in.eof() || in.fail()) {
285 if (tolerant) {
286 return std::make_pair (dims, false);
287 }
288 else {
289 std::ostringstream os;
290 os << "Unable to get coordinate dimensions line (at all) "
291 "from (line " << lineNumber << ") of input stream; the "
292 "input stream claims that it is at \"end-of-file\" or has "
293 "an otherwise \"fail\"ed state.";
294 throw std::invalid_argument(os.str());
295 }
296 }
297 // Try to get the next line from the input stream.
298 if (getline(in, line)) {
299 lineNumber++; // We did actually read a line
300 }
301 else {
302 if (tolerant) {
303 return std::make_pair (dims, false);
304 }
305 else {
306 std::ostringstream os;
307 os << "Failed to read coordinate dimensions line (at all) "
308 "from (line " << lineNumber << " from input stream. The "
309 "line should contain the coordinate matrix dimensions in "
310 << " the form \"<numRows> <numCols> <numNonzeros>\".";
311 throw std::invalid_argument (os.str());
312 }
313 }
314 // Is the current line a comment line? Ignore start and
315 // size; they are only useful for reading the actual matrix
316 // entries. (We could use them here as an optimization, but
317 // we've chosen not to.)
318 size_t start = 0, size = 0;
319 commentLine = checkCommentLine (line, start, size,
321 }
322 //
323 // Read in <numRows> <numCols> <numNonzeros> from input line
324 //
325 std::istringstream istr (line);
326 // Does line contain anything at all? Can we safely read from
327 // the input stream wrapping the line?
328 if (istr.eof() || istr.fail()) {
329 if (tolerant) {
330 return std::make_pair (dims, false);
331 }
332 std::ostringstream os;
333 os << "Unable to read any data from line " << lineNumber
334 << " of input; the line should contain the coordinate matrix "
335 << "dimensions \"<numRows> <numCols> <numNonzeros>\".";
336 throw std::invalid_argument(os.str());
337 }
338 // Read in <numRows>
339 {
340 Ordinal theNumRows = 0;
341 istr >> theNumRows;
342 if (istr.fail()) {
343 if (tolerant) {
344 return std::make_pair (dims, false);
345 }
346 std::ostringstream os;
347 os << "Failed to get number of rows from line " << lineNumber
348 << " of input; the line should contain the coordinate matrix "
349 << " dimensions \"<numRows> <numCols> <numNonzeros>\".";
350 throw std::invalid_argument(os.str());
351 }
352 else { // Capture the validly read result before checking for eof.
353 dims[0] = theNumRows;
354 }
355 }
356 // There should be two more things to read.
357 if (istr.eof()) {
358 if (tolerant) {
359 return std::make_pair (dims, false);
360 }
361 std::ostringstream os;
362 os << "No more data after number of rows on line " << lineNumber
363 << " of input; the line should contain the coordinate matrix "
364 << " dimensions \"<numRows> <numCols> <numNonzeros>\".";
365 throw std::invalid_argument(os.str());
366 }
367 // Read in <numCols>
368 {
369 Ordinal theNumCols = 0;
370 istr >> theNumCols;
371 if (istr.fail()) {
372 if (tolerant) {
373 return std::make_pair (dims, false);
374 }
375 std::ostringstream os;
376 os << "Failed to get number of columns from line " << lineNumber
377 << " of input; the line should contain the coordinate matrix "
378 << " dimensions \"<numRows> <numCols> <numNonzeros>\".";
379 throw std::invalid_argument(os.str());
380 }
381 else { // Capture the validly read result before checking for eof.
382 dims[1] = theNumCols;
383 }
384 }
385 // There should be one more thing to read.
386 if (istr.eof()) {
387 if (tolerant) {
388 return std::make_pair (dims, false);
389 }
390 std::ostringstream os;
391 os << "No more data after number of columns on line " << lineNumber
392 << " of input; the line should contain the coordinate matrix "
393 << " dimensions \"<numRows> <numCols> <numNonzeros>\".";
394 throw std::invalid_argument(os.str());
395 }
396 // Read in <numNonzeros>
397 {
398 Ordinal theNumNonzeros = 0;
400 if (istr.fail()) {
401 if (tolerant) {
402 return std::make_pair (dims, false);
403 }
404 std::ostringstream os;
405 os << "Failed to get number of (structural) nonzeros from line "
406 << lineNumber
407 << " of input; the line should contain the coordinate matrix "
408 << " dimensions \"<numRows> <numCols> <numNonzeros>\".";
409 throw std::invalid_argument(os.str());
410 }
411 else { // Capture the validly read result
412 dims[2] = theNumNonzeros;
413 }
414 }
415 // It would be nice to validate the read-in data further. The
416 // only thing we can do now is test if it's negative. However,
417 // we don't know syntactically whether Ordinal is a signed or
418 // unsigned type, so we shouldn't even test for negativity.
419 return std::make_pair (dims, true);
420 }
421 };
422
457 template<class Callback,
458 class Ordinal,
459 class Scalar,
461 class CoordDataReader : public CoordDataReaderBase<Callback, Ordinal> {
462 public:
476
485
488
489 protected:
490 bool
491 readLine (const std::string& theLine,
492 const size_t lineNumber,
493 const bool tolerant);
494 };
495
496#ifdef HAVE_TEUCHOS_COMPLEX
497 // Partial specialization for complex Scalar types.
498 template<class Callback, class Ordinal, class Scalar>
499 class CoordDataReader<Callback, Ordinal, Scalar, true> :
500 public CoordDataReaderBase<Callback, Ordinal> {
501 public:
504 {}
505
507 CoordDataReaderBase<Callback, Ordinal> (null)
508 {}
509
510 virtual ~CoordDataReader() {};
511
512 protected:
513 bool
514 readLine (const std::string& theLine,
515 const size_t lineNumber,
516 const bool tolerant)
517 {
519 typedef typename STS::magnitudeType Real;
520
521 Ordinal rowIndex;
522 Ordinal colIndex;
523 Scalar value;
524
525 Real realPart, imagPart;
526 const bool localSuccess =
527 readComplexLine (theLine, rowIndex, colIndex, realPart, imagPart,
528 lineNumber, tolerant);
529 if (localSuccess) {
530 // Assume that assignment from std::complex<Real> to Scalar
531 // (which itself is complex-valued) is valid. We have to do
532 // this, since the C++ compiler may not be smart enough to
533 // assume here (when it instantiates the templates) that
534 // Scalar is an std::complex<Real> -- even though it has to
535 // be, if STS::isComplex is true (which as of 31 Jan 2011,
536 // only holds for std::complex<T>).
537 value = std::complex<Real> (realPart, imagPart);
538
539 // Now that we've read in the (i, j, A_ij) triple
540 // successfully, we can add the entry to the sparse matrix.
541 (*(this->adder_)) (rowIndex, colIndex, value);
542 }
543 return localSuccess;
544 }
545 };
546#endif // HAVE_TEUCHOS_COMPLEX
547
548 // Partial specialization for real Scalar types.
549 template<class Callback, class Ordinal, class Scalar>
551 public CoordDataReaderBase<Callback, Ordinal> {
552 public:
556
558 CoordDataReaderBase<Callback, Ordinal> (null)
559 {}
560
561 virtual ~CoordDataReader() {};
562
563 protected:
564 bool
565 readLine (const std::string& theLine,
566 const size_t lineNumber,
567 const bool tolerant)
568 {
569 Ordinal rowIndex;
570 Ordinal colIndex;
571 Scalar value;
572 const bool localSuccess = readRealLine (theLine, rowIndex, colIndex,
573 value, lineNumber, tolerant);
574 if (localSuccess) {
575 // Now that we've read in the (i, j, A_ij) triple
576 // successfully, we can add the entry to the sparse matrix.
577 (*(this->adder_)) (rowIndex, colIndex, value);
578 }
579 return localSuccess;
580 }
581 };
582
583
606 template<class Callback, class Ordinal>
607 class CoordPatternReader : public CoordDataReaderBase<Callback, Ordinal> {
608 public:
624
633 CoordDataReaderBase<Callback, Ordinal> (null)
634 {}
635
638
639 protected:
640 bool
641 readLine (const std::string& theLine,
642 const size_t lineNumber,
643 const bool tolerant)
644 {
645 Ordinal rowIndex;
646 Ordinal colIndex;
647 const bool localSuccess =
648 readPatternLine (theLine, rowIndex, colIndex, lineNumber, tolerant);
649 if (localSuccess) {
650 // Now that we've read in the (i, j) pair successfully, we
651 // can add the entry to the sparse graph.
652 (*(this->adder_)) (rowIndex, colIndex);
653 }
654 return localSuccess;
655 }
656 };
657
658 } // namespace MatrixMarket
659} // namespace Teuchos
660
661#endif // __Teuchos_MatrixMarket_CoordDataReader_hpp
Reference-counted pointer class and non-member templated function implementations.
Defines basic traits for the scalar field type.
Common functionality of a coordinate-format sparse matrix or graph data reader.
virtual ~CoordDataReaderBase()
Virtual destructor for safety and happy compilers.
virtual std::pair< bool, std::vector< size_t > > read(std::istream &in, const size_t startingLineNumber, const bool tolerant, const bool debug=false)
Read in all the data from the given input stream.
std::pair< Teuchos::Tuple< Ordinal, 3 >, bool > readDimensions(std::istream &in, size_t &lineNumber, const bool tolerant=false)
Read (numRows, numCols, numNonzeros).
Teuchos::RCP< Callback > adder_
Closure that knows how to add entries to the sparse graph or matrix.
CoordDataReaderBase(const Teuchos::RCP< Callback > &adder)
Constructor with "adder" argument.
virtual bool readLine(const std::string &theLine, const size_t lineNumber, const bool tolerant)=0
Read in the data from a single line of the input stream.
void setAdder(const Teuchos::RCP< Callback > &adder)
Set the Adder object.
bool readLine(const std::string &theLine, const size_t lineNumber, const bool tolerant)
Read in the data from a single line of the input stream.
Coordinate-format sparse matrix data reader.
CoordDataReader()
No-argument constructor.
virtual ~CoordDataReader()
Virtual destructor for safety and happy compilers.
CoordDataReader(const Teuchos::RCP< Callback > &adder)
Constructor with "adder" argument.
bool readLine(const std::string &theLine, const size_t lineNumber, const bool tolerant)
Read in the data from a single line of the input stream.
CoordPatternReader(const Teuchos::RCP< Callback > &adder)
Constructor with "adder" argument.
virtual ~CoordPatternReader()
Virtual destructor for safety and happy compilers.
bool readLine(const std::string &theLine, const size_t lineNumber, const bool tolerant)
Read in the data from a single line of the input stream.
Concrete serial communicator subclass.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Matrix Market file utilities.
bool checkCommentLine(const std::string &line, size_t &start, size_t &size, const size_t lineNumber, const bool tolerant, const bool maybeBannerLine)
True if the line is a comment line, false otherwise.
bool readRealLine(const std::string &line, Ordinal &rowIndex, Ordinal &colIndex, Real &realValue, const size_t lineNumber, const bool tolerant)
bool readPatternLine(const std::string &line, Ordinal &rowIndex, Ordinal &colIndex, const size_t lineNumber, const bool tolerant)
This structure defines some basic traits for a scalar field type.