• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/ViennaCL-1.1.2/viennacl/io/matrix_market.hpp

Go to the documentation of this file.
00001 /* =======================================================================
00002    Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
00003    http://www.iue.tuwien.ac.at
00004                              -----------------
00005                      ViennaCL - The Vienna Computing Library
00006                              -----------------
00007                             
00008    authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
00009                Florian Rudolf                     flo.rudy+viennacl@gmail.com
00010                Josef Weinbub                      weinbub@iue.tuwien.ac.at
00011 
00012    license:    MIT (X11), see file LICENSE in the ViennaCL base directory
00013 ======================================================================= */
00014 
00015 
00016 #ifndef _VIENNACL_MATRIX_MARKET_HPP_
00017 #define _VIENNACL_MATRIX_MARKET_HPP_
00018 
00023 #include <algorithm>
00024 #include <string>
00025 #include <iostream>
00026 #include <fstream>
00027 #include <sstream>
00028 #include <vector>
00029 #include <map>
00030 #include <cctype>
00031 #include "viennacl/tools/adapter.hpp"
00032 
00033 namespace viennacl
00034 {
00035   namespace io
00036   {
00037     //helper
00038     namespace
00039     {
00040       void trim(char * buffer, long max_size)
00041       {
00042         //trim at beginning of string
00043         long start = 0;
00044         for (long i=0; i<max_size; ++i)
00045         {
00046           if (buffer[i] == ' ')
00047             ++start;
00048           else
00049             break;
00050         }
00051 
00052         //trim at end of string
00053         long stop = start;
00054         for (long i=stop; i<max_size; ++i)
00055         {
00056           if (buffer[i] == 0)   //end of string
00057             break;
00058           
00059           if (buffer[i] != ' ')
00060             stop = i;
00061         }
00062 
00063         for (long i=0; i<=stop - start; ++i)
00064         {
00065           buffer[i] = buffer[start + i];
00066         }
00067         
00068         if (buffer[0] != ' ')
00069           buffer[stop - start + 1] = 0; //terminate string
00070         else
00071           buffer[0] = 0;
00072       }      
00073       
00074       std::string tolower(std::string & s)
00075       {
00076         std::transform(s.begin(), s.end(), s.begin(), static_cast < int(*)(int) > (std::tolower));
00077         return s;
00078       }
00079       
00080       
00081       
00082     } //namespace 
00083     
00085     
00094     template <typename MatrixType>
00095     long read_matrix_market_file_impl(MatrixType & mat,
00096                                       const char * file,
00097                                       long index_base)
00098     {
00099       std::cout << "Reading matrix market file" << std::endl;
00100       char buffer[1025];
00101       std::ifstream reader(file);
00102       std::string token;
00103       long linenum = 0;
00104       bool symmetric = false;
00105       bool dense_format = false;
00106       bool is_header = true;
00107       long cur_row = 0;
00108       long cur_col = 0;
00109       long valid_entries = 0;
00110       long nnz = 0;
00111 
00112       
00113       if (!reader){
00114         std::cerr << "ViennaCL: Matrix Market Reader: Cannot open file " << file << std::endl;
00115         return 0;
00116       }
00117       
00118       while (reader.good())
00119       {
00120         // get a non-empty line
00121         do
00122         {
00123           reader.getline(buffer, 1024);
00124           ++linenum;
00125           trim(buffer, 1024);
00126         }
00127         while (reader.good() && buffer[0] == 0);
00128         
00129         if (buffer[0] == '%')
00130         {
00131           if (buffer[1] == '%')
00132           {
00133             //parse header:
00134             std::stringstream line(std::string(buffer + 2));
00135             line >> token;
00136             if (tolower(token) != "matrixmarket")
00137             {
00138               std::cerr << "Error in file " << file << " at line " << linenum << " in file " << file << ": Expected 'MatrixMarket', got '" << token << "'" << std::endl;
00139               return 0;
00140             }
00141 
00142             line >> token;
00143             if (tolower(token) != "matrix")
00144             {
00145               std::cerr << "Error in file " << file << " at line " << linenum << " in file " << file << ": Expected 'matrix', got '" << token << "'" << std::endl;
00146               return 0;
00147             }
00148 
00149             line >> token;
00150             if (tolower(token) != "coordinate")
00151             {
00152               if (tolower(token) == "array")
00153               {
00154                 dense_format = true;
00155                 std::cerr << "Error in file " << file << " at line " << linenum << " in file " << file << ": 'array' type is not supported yet!" << std::endl;
00156                 return 0;
00157               }
00158               else
00159               {
00160                 std::cerr << "Error in file " << file << " at line " << linenum << " in file " << file << ": Expected 'array' or 'coordinate', got '" << token << "'" << std::endl;
00161                 return 0;
00162               }
00163             }
00164 
00165             line >> token;
00166             if (tolower(token) != "real")
00167             {
00168               std::cerr << "Error in file " << file << ": The MatrixMarket reader provided with ViennaCL supports only real valued floating point arithmetic." << std::endl;
00169               return 0;
00170             }
00171 
00172             line >> token;
00173             if (tolower(token) == "general"){ }
00174             else if (tolower(token) == "symmetric"){ symmetric = true; }
00175             else
00176             {
00177               std::cerr << "Error in file " << file << ": The MatrixMarket reader provided with ViennaCL supports only general or symmetric matrices." << std::endl;
00178               return 0;
00179             }
00180             
00181           }
00182         }
00183         else
00184         {
00185           std::stringstream line(std::stringstream::in | std::stringstream::out);
00186           line << std::string(buffer);
00187 
00188           if (is_header)
00189           {
00190             //read header line
00191             long rows;
00192             long cols;
00193             
00194             if (line.good())
00195               line >> rows;
00196             else
00197             {
00198               std::cerr << "Error in file " << file << ": Could not get matrix dimensions (rows) in line " << linenum << std::endl;
00199               return 0;
00200             }
00201             
00202             if (line.good())
00203               line >> cols;
00204             else
00205             {
00206               std::cerr << "Error in file " << file << ": Could not get matrix dimensions (columns) in line " << linenum << std::endl;
00207               return 0;
00208             }
00209             if (!dense_format)
00210             {
00211               if (line.good())
00212                 line >> nnz;
00213               else
00214               {
00215                 std::cerr << "Error in file " << file << ": Could not get matrix dimensions (columns) in line " << linenum << std::endl;
00216                 return 0;
00217               }
00218             }
00219             
00220             if (rows > 0 && cols > 0)
00221               mat.resize(rows, cols, false);
00222             
00223             is_header = false;
00224           }
00225           else
00226           {
00227             //read data
00228             if (dense_format)
00229             {
00230               double value;
00231               line >> value;
00232               mat(cur_row, cur_col) = value;
00233               
00234               if (++cur_row == static_cast<long>(mat.size1()))
00235               {
00236                 //next column
00237                 ++cur_col;
00238                 cur_row = 0;
00239               }
00240             }
00241             else //sparse format
00242             {
00243               long row;
00244               long col;
00245               double value;
00246               
00247               //parse data:
00248               if (line.good())
00249                 line >> row;
00250               else
00251               {
00252                 std::cerr << "Error in file " << file << ": Parse error for matrix entry in line " << linenum << std::endl;
00253                 return 0;
00254               }
00255               
00256               if (line.good())
00257                 line >> col;
00258               else
00259               {
00260                 std::cerr << "Error in file " << file << ": Parse error for matrix entry in line " << linenum << std::endl;
00261                 return 0;
00262               }
00263               
00264               //take index_base base into account:
00265               row -= index_base;
00266               col -= index_base;
00267               
00268               if (line.good())
00269                 line >> value;
00270               else
00271               {
00272                 std::cerr << "Error in file " << file << ": Parse error for matrix entry in line " << linenum << std::endl;
00273                 return 0;
00274               }
00275               
00276               if (row >= static_cast<long>(mat.size1()) || row < 0)
00277               {
00278                 std::cerr << "Error in file " << file << " at line " << linenum << ": Row index out of bounds: " << row << " (matrix dim: " << mat.size1() << " x " << mat.size2() << ")" << std::endl;
00279                 return 0;
00280               }
00281                   
00282               if (col >= static_cast<long>(mat.size2()) || col < 0)
00283               {
00284                 std::cerr << "Error in file " << file << " at line " << linenum << ": Column index out of bounds: " << col << " (matrix dim: " << mat.size1() << " x " << mat.size2() << ")" << std::endl;
00285                 return 0;
00286               }
00287               
00288               mat(row, col) = value;
00289               if (symmetric)
00290                 mat(col, row) = value;
00291               
00292               if (++valid_entries == nnz)
00293                 break;
00294               
00295             } //else dense_format
00296           }
00297         }
00298       }
00299       
00300       std::cout << linenum << " lines read." << std::endl;
00301       reader.close();
00302       return linenum;
00303     }
00304     
00305 
00314     template <typename MatrixType>
00315     long read_matrix_market_file(MatrixType & mat,
00316                                  const char * file,
00317                                  long index_base = 1)
00318     {
00319       return read_matrix_market_file_impl(mat, file, index_base);  
00320     }
00321 
00322     template <typename MatrixType>
00323     long read_matrix_market_file(MatrixType & mat,
00324                                  const std::string & file,
00325                                  long index_base = 1)
00326     {
00327       return read_matrix_market_file_impl(mat, file.c_str(), index_base);
00328     }
00329     
00330     template <typename ScalarType>
00331     long read_matrix_market_file(std::vector< std::map<unsigned int, ScalarType> > & mat,
00332                                  const char * file,
00333                                  long index_base = 1)
00334     {
00335       viennacl::tools::sparse_matrix_adapter<ScalarType> adapted_matrix(mat);
00336       return read_matrix_market_file_impl(adapted_matrix, file, index_base);
00337     }
00338     
00339     template <typename ScalarType>
00340     long read_matrix_market_file(std::vector< std::map<unsigned int, ScalarType> > & mat,
00341                                  const std::string & file,
00342                                  long index_base = 1)
00343     {
00344       viennacl::tools::sparse_matrix_adapter<ScalarType> adapted_matrix(mat);
00345       return read_matrix_market_file_impl(adapted_matrix, file.c_str(), index_base);
00346     }
00347 
00348 
00350     template <typename MatrixType>
00351     void write_matrix_market_file_impl(MatrixType const & mat, const char * file, long index_base)
00352     {
00353       std::ofstream writer(file);
00354       
00355       long num_entries = 0;
00356       for (typename MatrixType::const_iterator1 row_it = mat.begin1();
00357             row_it != mat.end1();
00358             ++row_it)
00359         for (typename MatrixType::const_iterator2 col_it = row_it.begin();
00360               col_it != row_it.end();
00361               ++col_it)
00362           ++num_entries;
00363 
00364       writer << "%%MatrixMarket matrix coordinate real general" << std::endl;
00365       writer << mat.size1() << " " << mat.size2() << " " << num_entries << std::endl;
00366       
00367       for (typename MatrixType::const_iterator1 row_it = mat.begin1();
00368             row_it != mat.end1();
00369             ++row_it)
00370         for (typename MatrixType::const_iterator2 col_it = row_it.begin();
00371               col_it != row_it.end();
00372               ++col_it)
00373           writer << col_it.index1() + index_base << " " << col_it.index2() + index_base << " " << *col_it << std::endl;
00374       
00375       writer.close();
00376     }
00377 
00378     template <typename ScalarType>
00379     void write_matrix_market_file(std::vector< std::map<unsigned int, ScalarType> > const & mat,
00380                                   const char * file,
00381                                   long index_base = 1)
00382     {
00383       viennacl::tools::const_sparse_matrix_adapter<ScalarType> adapted_matrix(mat);
00384       return write_matrix_market_file_impl(adapted_matrix, file, index_base);
00385     }
00386 
00387     template <typename ScalarType>
00388     void write_matrix_market_file(std::vector< std::map<unsigned int, ScalarType> > const & mat,
00389                                   const std::string & file,
00390                                   long index_base = 1)
00391     {
00392       viennacl::tools::const_sparse_matrix_adapter<ScalarType> adapted_matrix(mat);
00393       return write_matrix_market_file_impl(adapted_matrix, file.c_str(), index_base);
00394     }
00395 
00404     template <typename MatrixType>
00405     void write_matrix_market_file(MatrixType const & mat,
00406                                   const std::string & file,
00407                                   long index_base = 1)
00408     {
00409       write_matrix_market_file_impl(mat, file.c_str(), index_base);
00410     }
00411 
00412     
00413   } //namespace io
00414 } //namespace viennacl
00415 
00416 #endif

Generated on Sat May 21 2011 20:36:50 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1