Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_MatrixMarket_CoordDataReader.hpp
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
45#include "Teuchos_MatrixMarket_generic.hpp"
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>
550 class CoordDataReader<Callback, Ordinal, Scalar, false> :
551 public CoordDataReaderBase<Callback, Ordinal> {
552 public:
554 CoordDataReaderBase<Callback, Ordinal> (adder)
555 {}
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.
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.
Smart reference counting pointer class for automatic garbage collection.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Matrix Market file utilities.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
This structure defines some basic traits for a scalar field type.