Changeset 3836


Ignore:
Timestamp:
05/25/12 11:18:20 (2 years ago)
Author:
gemacke
Message:

Importing of all matrix market types are now parallelized in Qthreads (#4080).

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/mtgl/read_matrix_market.hpp

    r3734 r3836  
    4444#endif 
    4545 
     46#ifdef USING_QTHREADS 
     47#include <qthread/qloop.hpp> 
     48#endif 
     49 
    4650namespace mtgl { 
    4751 
     
    111115  size_type& num_lines; 
    112116  long* start_positions; 
     117}; 
     118 
     119template <typename size_type, typename T, typename WT, int weight_cat> 
     120class count_diags { 
     121public: 
     122  count_diags(char* b, long* sp, size_type& nd, size_type* lnd, 
     123              size_type ne, size_type nt) : 
     124    buf(b), start_positions(sp), num_diags(nd), local_num_diags(lnd), 
     125    num_entries(ne), num_threads(nt) {} 
     126 
     127  void operator()(const size_t start, const size_t stop) 
     128  { 
     129    size_type thread_id = start; 
     130 
     131    size_type beg = begin_block_range(num_entries, thread_id, num_threads); 
     132    size_type end = end_block_range(num_entries, thread_id, num_threads); 
     133 
     134    size_type my_num_diags = 0; 
     135 
     136    for (size_type i = beg; i != end; ++i) 
     137    { 
     138      char* a = &buf[start_positions[i]]; 
     139      char* b = NULL; 
     140 
     141      long from = strtol(a, &b, 10); 
     142      long to = strtol(b, &a, 10); 
     143 
     144      // No need to check for errors in reading from and to because strtol() 
     145      // always returns a valid integer.  Errors will be caught later. 
     146      my_num_diags += from == to; 
     147    } 
     148 
     149    mt_incr(num_diags, my_num_diags); 
     150    local_num_diags[thread_id] = my_num_diags; 
     151  } 
     152 
     153private: 
     154  char* buf; 
     155  long* start_positions; 
     156  size_type& num_diags; 
     157  size_type* local_num_diags; 
     158  size_type num_entries; 
     159  size_type num_threads; 
    113160}; 
    114161 
     
    119166//   3 - complex 
    120167template <typename size_type, typename T, typename WT, int weight_cat> 
    121 class parse_edges { 
     168class parse_general_edges { 
    122169public: 
    123   parse_edges(char* b, size_type nil, long* sp, size_type* eh, size_type *et, 
    124               dynamic_array<T>& v, size_type nv, size_type ne) : 
     170  parse_general_edges(char* b, long nil, long* sp, size_type* eh, 
     171                      size_type *et, dynamic_array<T>& v, size_type nv, 
     172                      size_type ne, size_type nent, size_type nt) : 
    125173    buf(b), num_intro_lines(nil), start_positions(sp), edge_heads(eh), 
    126     edge_tails(et), values(v), num_vertices(nv), num_edges(ne) {} 
     174    edge_tails(et), values(v), num_vertices(nv), num_edges(ne), 
     175    num_entries(nent), num_threads(nt) {} 
    127176 
    128177  void operator()(const size_t start, const size_t stop) 
    129178  { 
    130     for (size_t i = start; i != stop; ++i) 
    131     { 
    132       long from; 
    133       long to; 
     179    size_type thread_id = start; 
     180 
     181    size_type beg = begin_block_range(num_entries, thread_id, num_threads); 
     182    size_type end = end_block_range(num_entries, thread_id, num_threads); 
     183 
     184    for (size_type i = beg; i != end; ++i) 
     185    { 
     186      char* a = &buf[start_positions[i]]; 
     187      char* b = NULL; 
     188 
     189      // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     190      long from = strtol(a, &b, 10) - 1; 
     191      long to = strtol(b, &a, 10) - 1; 
     192 
    134193      WT value; 
    135194      WT imag; 
    136  
    137       char* a = &buf[start_positions[i]]; 
    138       char* b = NULL; 
    139  
    140       from = strtol(a, &b, 10); 
    141       to = strtol(b, &a, 10); 
    142195 
    143196      if (weight_cat == 1) 
     
    163216      } 
    164217 
    165       // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    166       --from; 
    167       --to; 
    168  
    169218      if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    170219      { 
     
    190239private: 
    191240  char* buf; 
    192   size_type num_intro_lines; 
     241  long num_intro_lines; 
    193242  long* start_positions; 
    194243  size_type* edge_heads; 
     
    197246  size_type num_vertices; 
    198247  size_type num_edges; 
     248  size_type num_entries; 
     249  size_type num_threads; 
     250}; 
     251 
     252// weight_cat: 
     253//   0 - pattern 
     254//   1 - integer 
     255//   2 - real 
     256//   3 - complex 
     257template <typename size_type, typename T, typename WT, int weight_cat> 
     258class parse_symmetric_edges { 
     259public: 
     260  parse_symmetric_edges(char* b, long nil, long* sp, size_type* eh, 
     261                        size_type *et, dynamic_array<T>& v, size_type nv, 
     262                        size_type ne, size_type nd, size_type* lnd, long& dc, 
     263                        long& oc, size_type nent, size_type nt) : 
     264    buf(b), num_intro_lines(nil), start_positions(sp), edge_heads(eh), 
     265    edge_tails(et), values(v), num_vertices(nv), num_edges(ne), num_diags(nd), 
     266    local_num_diags(lnd), diag_count(dc), offdiag_count(oc), 
     267    num_entries(nent), num_threads(nt) {} 
     268 
     269  void operator()(const size_t start, const size_t stop) 
     270  { 
     271    size_type thread_id = start; 
     272 
     273    size_type beg = begin_block_range(num_entries, thread_id, num_threads); 
     274    size_type end = end_block_range(num_entries, thread_id, num_threads); 
     275 
     276    long my_num_edges = end - beg; 
     277    long my_num_diags = local_num_diags[thread_id]; 
     278    long my_num_offdiags = my_num_edges - my_num_diags; 
     279 
     280    long diag_pos = mt_incr(diag_count, my_num_diags); 
     281    long offdiag_pos = mt_incr(offdiag_count, my_num_offdiags); 
     282 
     283    for (size_type i = beg; i != end; ++i) 
     284    { 
     285      char* a = &buf[start_positions[i]]; 
     286      char* b = NULL; 
     287 
     288      // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     289      long from = strtol(a, &b, 10) - 1; 
     290      long to = strtol(b, &a, 10) - 1; 
     291 
     292      WT value; 
     293      WT imag; 
     294 
     295      if (weight_cat == 1) 
     296      { 
     297        value = strtol(a, &b, 10); 
     298      } 
     299      else if (weight_cat == 2) 
     300      { 
     301        value = strtod(a, &b); 
     302      } 
     303      else if (weight_cat == 3) 
     304      { 
     305        value = strtod(a, &b); 
     306        imag = strtod(b, &a); 
     307      } 
     308 
     309      if (a == b) 
     310      { 
     311        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     312                  << ": Too few parameters when describing edge." 
     313                  << std::endl; 
     314        exit(1); 
     315      } 
     316 
     317      if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     318      { 
     319        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     320                  << ": First vertex id is invalid." << std::endl; 
     321        exit(1); 
     322      } 
     323      else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     324      { 
     325        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     326                  << ": Second vertex id is invalid." << std::endl; 
     327        exit(1); 
     328      } 
     329 
     330      if (to == from) 
     331      { 
     332        // Diagonal edges only get one entry in the matrix. 
     333        edge_heads[diag_pos] = static_cast<size_type>(from); 
     334        edge_tails[diag_pos] = static_cast<size_type>(to); 
     335 
     336        if (weight_cat != 0) values[diag_pos] = static_cast<T>(value); 
     337        if (weight_cat == 3) 
     338        { 
     339          values[diag_pos + num_edges] = static_cast<T>(imag); 
     340        } 
     341 
     342        ++diag_pos; 
     343      } 
     344      else 
     345      { 
     346        // Off diagonal edges get two entries in the matrix. 
     347        edge_heads[num_diags + 2 * offdiag_pos] = static_cast<size_type>(from); 
     348        edge_tails[num_diags + 2 * offdiag_pos] = static_cast<size_type>(to); 
     349        edge_heads[num_diags + 2 * offdiag_pos + 1] = 
     350          static_cast<size_type>(to); 
     351        edge_tails[num_diags + 2 * offdiag_pos + 1] = 
     352          static_cast<size_type>(from); 
     353 
     354        if (weight_cat != 0) 
     355        { 
     356          values[num_diags + 2 * offdiag_pos] = static_cast<T>(value); 
     357          values[num_diags + 2 * offdiag_pos + 1] = static_cast<T>(value); 
     358        } 
     359 
     360        if (weight_cat == 3) 
     361        { 
     362          values[num_diags + 2 * offdiag_pos + num_edges] = 
     363            static_cast<T>(imag); 
     364          values[num_diags + 2 * offdiag_pos + 1 + num_edges] = 
     365            static_cast<T>(imag); 
     366        } 
     367 
     368        ++offdiag_pos; 
     369      } 
     370    } 
     371  } 
     372 
     373private: 
     374  char* buf; 
     375  long num_intro_lines; 
     376  long* start_positions; 
     377  size_type* edge_heads; 
     378  size_type* edge_tails; 
     379  dynamic_array<T>& values; 
     380  size_type num_vertices; 
     381  size_type num_edges; 
     382  size_type num_diags; 
     383  size_type* local_num_diags; 
     384  long& diag_count; 
     385  long& offdiag_count; 
     386  size_type num_entries; 
     387  size_type num_threads; 
     388}; 
     389 
     390// weight_cat: 
     391//   0 - pattern 
     392//   1 - integer 
     393//   2 - real 
     394//   3 - complex 
     395template <typename size_type, typename T, typename WT, int weight_cat> 
     396class parse_skew_symmetric_edges { 
     397public: 
     398  parse_skew_symmetric_edges(char* b, long nil, long* sp, size_type* eh, 
     399                             size_type *et, dynamic_array<T>& v, size_type nv, 
     400                             size_type ne, size_type nent, size_type nt) : 
     401    buf(b), num_intro_lines(nil), start_positions(sp), edge_heads(eh), 
     402    edge_tails(et), values(v), num_vertices(nv), num_edges(ne), 
     403    num_entries(nent), num_threads(nt) {} 
     404 
     405  void operator()(const size_t start, const size_t stop) 
     406  { 
     407    size_type thread_id = start; 
     408 
     409    size_type beg = begin_block_range(num_entries, thread_id, num_threads); 
     410    size_type end = end_block_range(num_entries, thread_id, num_threads); 
     411 
     412    for (size_type i = beg; i != end; ++i) 
     413    { 
     414      char* a = &buf[start_positions[i]]; 
     415      char* b = NULL; 
     416 
     417      // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     418      long from = strtol(a, &b, 10) - 1; 
     419      long to = strtol(b, &a, 10) - 1; 
     420 
     421      WT value; 
     422      WT imag; 
     423 
     424      if (weight_cat == 1) 
     425      { 
     426        value = strtol(a, &b, 10); 
     427      } 
     428      else if (weight_cat == 2) 
     429      { 
     430        value = strtod(a, &b); 
     431      } 
     432      else if (weight_cat == 3) 
     433      { 
     434        value = strtod(a, &b); 
     435        imag = strtod(b, &a); 
     436      } 
     437 
     438      if (a == b) 
     439      { 
     440        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     441                  << ": Too few parameters when describing edge." 
     442                  << std::endl; 
     443        exit(1); 
     444      } 
     445 
     446      if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     447      { 
     448        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     449                  << ": First vertex id is invalid." << std::endl; 
     450        exit(1); 
     451      } 
     452      else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     453      { 
     454        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     455                  << ": Second vertex id is invalid." << std::endl; 
     456        exit(1); 
     457      } 
     458 
     459      edge_heads[2 * i] = static_cast<size_type>(from); 
     460      edge_tails[2 * i] = static_cast<size_type>(to); 
     461      values[2 * i] = static_cast<T>(value); 
     462 
     463      edge_heads[2 * i + 1] = static_cast<size_type>(to); 
     464      edge_tails[2 * i + 1] = static_cast<size_type>(from); 
     465      values[2 * i + 1] = static_cast<T>(-value); 
     466 
     467      if (weight_cat == 3) 
     468      { 
     469        values[2 * i + num_edges] = static_cast<T>(imag); 
     470        values[2 * i + 1 + num_edges] = static_cast<T>(-imag); 
     471      } 
     472    } 
     473  } 
     474 
     475private: 
     476  char* buf; 
     477  long num_intro_lines; 
     478  long* start_positions; 
     479  size_type* edge_heads; 
     480  size_type* edge_tails; 
     481  dynamic_array<T>& values; 
     482  size_type num_vertices; 
     483  size_type num_edges; 
     484  size_type num_entries; 
     485  size_type num_threads; 
     486}; 
     487 
     488template <typename size_type, typename T> 
     489class parse_hermitian_edges { 
     490public: 
     491  parse_hermitian_edges(char* b, long nil, long* sp, size_type* eh, 
     492                        size_type *et, dynamic_array<T>& v, size_type nv, 
     493                        size_type ne, size_type nd, size_type* lnd, long& dc, 
     494                        long& oc, size_type nent, size_type nt) : 
     495    buf(b), num_intro_lines(nil), start_positions(sp), edge_heads(eh), 
     496    edge_tails(et), values(v), num_vertices(nv), num_edges(ne), num_diags(nd), 
     497    local_num_diags(lnd), diag_count(dc), offdiag_count(oc), 
     498    num_entries(nent), num_threads(nt) {} 
     499 
     500  void operator()(const size_t start, const size_t stop) 
     501  { 
     502    size_type thread_id = start; 
     503 
     504    size_type beg = begin_block_range(num_entries, thread_id, num_threads); 
     505    size_type end = end_block_range(num_entries, thread_id, num_threads); 
     506 
     507    long my_num_edges = end - beg; 
     508    long my_num_diags = local_num_diags[thread_id]; 
     509    long my_num_offdiags = my_num_edges - my_num_diags; 
     510 
     511    long diag_pos = mt_incr(diag_count, my_num_diags); 
     512    long offdiag_pos = mt_incr(offdiag_count, my_num_offdiags); 
     513 
     514    for (size_type i = beg; i != end; ++i) 
     515    { 
     516      char* a = &buf[start_positions[i]]; 
     517      char* b = NULL; 
     518 
     519      // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     520      long from = strtol(a, &b, 10) - 1; 
     521      long to = strtol(b, &a, 10) - 1; 
     522 
     523      double value = strtod(a, &b); 
     524      double imag = strtod(b, &a); 
     525 
     526      if (a == b) 
     527      { 
     528        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     529                  << ": Too few parameters when describing edge." 
     530                  << std::endl; 
     531        exit(1); 
     532      } 
     533 
     534      if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     535      { 
     536        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     537                  << ": First vertex id is invalid." << std::endl; 
     538        exit(1); 
     539      } 
     540      else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     541      { 
     542        std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     543                  << ": Second vertex id is invalid." << std::endl; 
     544        exit(1); 
     545      } 
     546 
     547      if (to == from) 
     548      { 
     549        // Diagonal edges only get one entry in the matrix. 
     550        edge_heads[diag_pos] = static_cast<size_type>(from); 
     551        edge_tails[diag_pos] = static_cast<size_type>(to); 
     552 
     553        values[diag_pos] = static_cast<T>(value); 
     554        values[diag_pos + num_edges] = static_cast<T>(imag); 
     555 
     556        ++diag_pos; 
     557      } 
     558      else 
     559      { 
     560        // Off diagonal edges get two entries in the matrix. 
     561        edge_heads[num_diags + 2 * offdiag_pos] = static_cast<size_type>(from); 
     562        edge_tails[num_diags + 2 * offdiag_pos] = static_cast<size_type>(to); 
     563        edge_heads[num_diags + 2 * offdiag_pos + 1] = 
     564          static_cast<size_type>(to); 
     565        edge_tails[num_diags + 2 * offdiag_pos + 1] = 
     566          static_cast<size_type>(from); 
     567 
     568        values[num_diags + 2 * offdiag_pos] = static_cast<T>(value); 
     569        values[num_diags + 2 * offdiag_pos + 1] = static_cast<T>(value); 
     570        values[num_diags + 2 * offdiag_pos + num_edges] = static_cast<T>(imag); 
     571        values[num_diags + 2 * offdiag_pos + 1 + num_edges] = 
     572          static_cast<T>(-imag); 
     573 
     574        ++offdiag_pos; 
     575      } 
     576    } 
     577  } 
     578 
     579private: 
     580  char* buf; 
     581  long num_intro_lines; 
     582  long* start_positions; 
     583  size_type* edge_heads; 
     584  size_type* edge_tails; 
     585  dynamic_array<T>& values; 
     586  size_type num_vertices; 
     587  size_type num_edges; 
     588  size_type num_diags; 
     589  size_type* local_num_diags; 
     590  long& diag_count; 
     591  long& offdiag_count; 
     592  size_type num_entries; 
     593  size_type num_threads; 
    199594}; 
    200595 
     
    218613  #pragma mta fence 
    219614  timer.start(); 
     615#endif 
     616 
     617#ifdef USING_QTHREADS 
     618  size_type num_threads = qthread_num_shepherds(); 
    220619#endif 
    221620 
     
    441840  size_type num_edges = 0; 
    442841  size_type num_diags = 0; 
     842 
     843#ifdef USING_QTHREADS 
     844  size_type* local_num_diags = 
     845    (size_type*) malloc(num_threads * sizeof(size_type)); 
     846#endif 
     847 
    443848  if (strcmp(symmetry_format, "general") == 0) 
    444849  { 
     
    456861    // num_diags + 2 * num_offdiags edges, so we need to count the number of 
    457862    // entries on the diagonal to calculate the number of edges. 
     863#ifdef USING_QTHREADS 
     864  detail::count_diags<size_type, T, long, 0> 
     865    cd(buf, start_positions, num_diags, local_num_diags, num_entries, 
     866       num_threads); 
     867  qt_loop_balance(0, num_threads, cd); 
     868#else 
    458869    for (size_type i = 0; i < num_entries; ++i) 
    459870    { 
    460       long from; 
    461       long to; 
    462  
    463871      char* a = &buf[start_positions[i]]; 
    464872      char* b = NULL; 
    465873 
    466       from = strtol(a, &b, 10); 
    467       to = strtol(b, &a, 10); 
     874      long from = strtol(a, &b, 10); 
     875      long to = strtol(b, &a, 10); 
    468876 
    469877      // No need to check for errors in reading from and to because strtol() 
     
    471879      num_diags += from == to; 
    472880    } 
     881#endif 
    473882 
    474883    num_edges = num_diags + 2 * (num_entries - num_diags); 
     
    498907    if (strcmp(entry_type, "pattern") == 0) 
    499908    { 
    500       detail::parse_edges<size_type, T, long, 0> 
    501         pe(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
    502            values, num_vertices, num_edges); 
    503       qt_loop_balance(0, num_entries, pe); 
     909      detail::parse_general_edges<size_type, T, long, 0> 
     910        pge(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     911            values, num_vertices, num_edges, num_entries, num_threads); 
     912      qt_loop_balance(0, num_threads, pge); 
    504913    } 
    505914    else if (strcmp(entry_type, "integer") == 0) 
    506915    { 
    507       detail::parse_edges<size_type, T, long, 1> 
    508         pe(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
    509            values, num_vertices, num_edges); 
    510       qt_loop_balance(0, num_entries, pe); 
     916      detail::parse_general_edges<size_type, T, long, 1> 
     917        pge(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     918            values, num_vertices, num_edges, num_entries, num_threads); 
     919      qt_loop_balance(0, num_threads, pge); 
    511920    } 
    512921    else if (strcmp(entry_type, "real") == 0) 
    513922    { 
    514       detail::parse_edges<size_type, T, double, 2> 
    515         pe(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
    516            values, num_vertices, num_edges); 
    517       qt_loop_balance(0, num_entries, pe); 
     923      detail::parse_general_edges<size_type, T, double, 2> 
     924        pge(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     925            values, num_vertices, num_edges, num_entries, num_threads); 
     926      qt_loop_balance(0, num_threads, pge); 
    518927    } 
    519928    else if (strcmp(entry_type, "complex") == 0) 
    520929    { 
    521       detail::parse_edges<size_type, T, double, 3> 
    522         pe(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
    523            values, num_vertices, num_edges); 
    524       qt_loop_balance(0, num_entries, pe); 
     930      detail::parse_general_edges<size_type, T, double, 3> 
     931        pge(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     932            values, num_vertices, num_edges, num_entries, num_threads); 
     933      qt_loop_balance(0, num_threads, pge); 
    525934    } 
    526935#else 
    527     if (strcmp(entry_type, "real") == 0) 
     936    if (strcmp(entry_type, "pattern") == 0) 
    528937    { 
    529938      #pragma mta assert parallel 
    530939      for (size_type i = 0; i < num_entries; ++i) 
    531940      { 
    532         long from; 
    533         long to; 
    534         double value; 
    535  
    536941        char* a = &buf[start_positions[i]]; 
    537942        char* b = NULL; 
    538943 
    539         from = strtol(a, &b, 10); 
    540         to = strtol(b, &a, 10); 
    541         value = strtod(a, &b); 
     944        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     945        long from = strtol(a, &b, 10) - 1; 
     946        long to = strtol(b, &a, 10) - 1; 
    542947 
    543948        if (a == b) 
     
    549954        } 
    550955 
     956        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     957        { 
     958          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     959                    << ": First vertex id is invalid." << std::endl; 
     960          exit(1); 
     961        } 
     962        else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     963        { 
     964          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     965                    << ": Second vertex id is invalid." << std::endl; 
     966          exit(1); 
     967        } 
     968 
     969        edge_heads[i] = static_cast<size_type>(from); 
     970        edge_tails[i] = static_cast<size_type>(to); 
     971      } 
     972    } 
     973    else if (strcmp(entry_type, "integer") == 0) 
     974    { 
     975      #pragma mta assert parallel 
     976      for (size_type i = 0; i < num_entries; ++i) 
     977      { 
     978        char* a = &buf[start_positions[i]]; 
     979        char* b = NULL; 
     980 
    551981        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    552         --from; 
    553         --to; 
     982        long from = strtol(a, &b, 10) - 1; 
     983        long to = strtol(b, &a, 10) - 1; 
     984        long value = strtol(a, &b, 10); 
     985 
     986        if (a == b) 
     987        { 
     988          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     989                    << ": Too few parameters when describing edge." 
     990                    << std::endl; 
     991          exit(1); 
     992        } 
    554993 
    555994        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     
    5711010      } 
    5721011    } 
    573     else if (strcmp(entry_type, "complex") == 0) 
     1012    else if (strcmp(entry_type, "real") == 0) 
    5741013    { 
    5751014      #pragma mta assert parallel 
    5761015      for (size_type i = 0; i < num_entries; ++i) 
    5771016      { 
    578         long from; 
    579         long to; 
    580         double real; 
    581         double imag; 
    582  
    5831017        char* a = &buf[start_positions[i]]; 
    5841018        char* b = NULL; 
    5851019 
    586         from = strtol(a, &b, 10); 
    587         to = strtol(b, &a, 10); 
    588         real = strtod(a, &b); 
    589         imag = strtod(b, &a); 
     1020        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1021        long from = strtol(a, &b, 10) - 1; 
     1022        long to = strtol(b, &a, 10) - 1; 
     1023        double value = strtod(a, &b); 
    5901024 
    5911025        if (a == b) 
     
    5971031        } 
    5981032 
     1033        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     1034        { 
     1035          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1036                    << ": First vertex id is invalid." << std::endl; 
     1037          exit(1); 
     1038        } 
     1039        else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     1040        { 
     1041          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1042                    << ": Second vertex id is invalid." << std::endl; 
     1043          exit(1); 
     1044        } 
     1045 
     1046        edge_heads[i] = static_cast<size_type>(from); 
     1047        edge_tails[i] = static_cast<size_type>(to); 
     1048        values[i] = static_cast<T>(value); 
     1049      } 
     1050    } 
     1051    else if (strcmp(entry_type, "complex") == 0) 
     1052    { 
     1053      #pragma mta assert parallel 
     1054      for (size_type i = 0; i < num_entries; ++i) 
     1055      { 
     1056        char* a = &buf[start_positions[i]]; 
     1057        char* b = NULL; 
     1058 
    5991059        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    600         --from; 
    601         --to; 
     1060        long from = strtol(a, &b, 10) - 1; 
     1061        long to = strtol(b, &a, 10) - 1; 
     1062        double real = strtod(a, &b); 
     1063        double imag = strtod(b, &a); 
     1064 
     1065        if (a == b) 
     1066        { 
     1067          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1068                    << ": Too few parameters when describing edge." 
     1069                    << std::endl; 
     1070          exit(1); 
     1071        } 
    6021072 
    6031073        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     
    6201090      } 
    6211091    } 
     1092#endif 
     1093  } 
     1094  else if (strcmp(symmetry_format, "symmetric") == 0) 
     1095  { 
     1096    long diag_count = 0; 
     1097    long offdiag_count = 0; 
     1098 
     1099#ifdef USING_QTHREADS 
     1100    if (strcmp(entry_type, "pattern") == 0) 
     1101    { 
     1102      detail::parse_symmetric_edges<size_type, T, long, 0> 
     1103        pse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1104            values, num_vertices, num_edges, num_diags, local_num_diags, 
     1105            diag_count, offdiag_count, num_entries, num_threads); 
     1106      qt_loop_balance(0, num_threads, pse); 
     1107    } 
    6221108    else if (strcmp(entry_type, "integer") == 0) 
     1109    { 
     1110      detail::parse_symmetric_edges<size_type, T, long, 1> 
     1111        pse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1112            values, num_vertices, num_edges, num_diags, local_num_diags, 
     1113            diag_count, offdiag_count, num_entries, num_threads); 
     1114      qt_loop_balance(0, num_threads, pse); 
     1115    } 
     1116    else if (strcmp(entry_type, "real") == 0) 
     1117    { 
     1118      detail::parse_symmetric_edges<size_type, T, double, 2> 
     1119        pse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1120            values, num_vertices, num_edges, num_diags, local_num_diags, 
     1121            diag_count, offdiag_count, num_entries, num_threads); 
     1122      qt_loop_balance(0, num_threads, pse); 
     1123    } 
     1124    else if (strcmp(entry_type, "complex") == 0) 
     1125    { 
     1126      detail::parse_symmetric_edges<size_type, T, double, 3> 
     1127        pse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1128            values, num_vertices, num_edges, num_diags, local_num_diags, 
     1129            diag_count, offdiag_count, num_entries, num_threads); 
     1130      qt_loop_balance(0, num_threads, pse); 
     1131    } 
     1132#else 
     1133    if (strcmp(entry_type, "pattern") == 0) 
    6231134    { 
    6241135      #pragma mta assert parallel 
    6251136      for (size_type i = 0; i < num_entries; ++i) 
    6261137      { 
    627         long from; 
    628         long to; 
    629         long value; 
    630  
    6311138        char* a = &buf[start_positions[i]]; 
    6321139        char* b = NULL; 
    6331140 
    634         from = strtol(a, &b, 10); 
    635         to = strtol(b, &a, 10); 
    636         value = strtol(a, &b, 10); 
     1141        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1142        long from = strtol(a, &b, 10) - 1; 
     1143        long to = strtol(b, &a, 10) - 1; 
    6371144 
    6381145        if (a == b) 
     
    6441151        } 
    6451152 
    646         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    647         --from; 
    648         --to; 
    649  
    6501153        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    6511154        { 
     
    6611164        } 
    6621165 
    663         edge_heads[i] = static_cast<size_type>(from); 
    664         edge_tails[i] = static_cast<size_type>(to); 
    665         values[i] = static_cast<T>(value); 
    666       } 
    667     } 
    668     else if (strcmp(entry_type, "pattern") == 0) 
     1166        if (to == from) 
     1167        { 
     1168          // Diagonal edges only get one entry in the matrix. 
     1169          long pos = mt_incr(diag_count, 1); 
     1170          edge_heads[pos] = static_cast<size_type>(from); 
     1171          edge_tails[pos] = static_cast<size_type>(to); 
     1172        } 
     1173        else 
     1174        { 
     1175          // Off diagonal edges get two entries in the matrix. 
     1176          long pos = mt_incr(offdiag_count, 1); 
     1177          edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
     1178          edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
     1179          edge_heads[num_diags + 2 * pos + 1] = static_cast<size_type>(to); 
     1180          edge_tails[num_diags + 2 * pos + 1] = static_cast<size_type>(from); 
     1181        } 
     1182      } 
     1183    } 
     1184    else if (strcmp(entry_type, "integer") == 0) 
    6691185    { 
    6701186      #pragma mta assert parallel 
    6711187      for (size_type i = 0; i < num_entries; ++i) 
    6721188      { 
    673         long from; 
    674         long to; 
    675  
    6761189        char* a = &buf[start_positions[i]]; 
    6771190        char* b = NULL; 
    6781191 
    679         from = strtol(a, &b, 10); 
    680         to = strtol(b, &a, 10); 
     1192        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1193        long from = strtol(a, &b, 10) - 1; 
     1194        long to = strtol(b, &a, 10) - 1; 
     1195        long value = strtol(a, &b, 10); 
    6811196 
    6821197        if (a == b) 
     
    6881203        } 
    6891204 
    690         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    691         --from; 
    692         --to; 
    693  
    6941205        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    6951206        { 
     
    7051216        } 
    7061217 
    707         edge_heads[i] = static_cast<size_type>(from); 
    708         edge_tails[i] = static_cast<size_type>(to); 
    709       } 
    710     } 
    711 #endif 
    712   } 
    713   else if (strcmp(symmetry_format, "symmetric") == 0) 
    714   { 
    715     if (strcmp(entry_type, "real") == 0) 
    716     { 
    717       long my_num_diags = 0; 
    718       long my_num_offdiags = 0; 
    719  
    720       #pragma mta assert parallel 
    721       for (size_type i = 0; i < num_entries; ++i) 
    722       { 
    723         long from; 
    724         long to; 
    725         double value; 
    726  
    727         char* a = &buf[start_positions[i]]; 
    728         char* b = NULL; 
    729  
    730         from = strtol(a, &b, 10); 
    731         to = strtol(b, &a, 10); 
    732         value = strtod(a, &b); 
    733  
    734         if (a == b) 
    735         { 
    736           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    737                     << ": Too few parameters when describing edge." 
    738                     << std::endl; 
    739           exit(1); 
    740         } 
    741  
    742         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    743         --from; 
    744         --to; 
    745  
    746         if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    747         { 
    748           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    749                     << ": First vertex id is invalid." << std::endl; 
    750           exit(1); 
    751         } 
    752         else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
    753         { 
    754           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    755                     << ": Second vertex id is invalid." << std::endl; 
    756           exit(1); 
    757         } 
    758  
    7591218        if (to == from) 
    7601219        { 
    7611220          // Diagonal edges only get one entry in the matrix. 
    762           long pos = mt_incr(my_num_diags, 1); 
     1221          long pos = mt_incr(diag_count, 1); 
    7631222          edge_heads[pos] = static_cast<size_type>(from); 
    7641223          edge_tails[pos] = static_cast<size_type>(to); 
     
    7681227        { 
    7691228          // Off diagonal edges get two entries in the matrix. 
    770           long pos = mt_incr(my_num_offdiags, 1); 
     1229          long pos = mt_incr(offdiag_count, 1); 
    7711230          edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
    7721231          edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
     
    7781237      } 
    7791238    } 
    780     else if (strcmp(entry_type, "complex") == 0) 
    781     { 
    782       long my_num_diags = 0; 
    783       long my_num_offdiags = 0; 
    784  
     1239    else if (strcmp(entry_type, "real") == 0) 
     1240    { 
    7851241      #pragma mta assert parallel 
    7861242      for (size_type i = 0; i < num_entries; ++i) 
    7871243      { 
    788         long from; 
    789         long to; 
    790         double real; 
    791         double imag; 
    792  
    7931244        char* a = &buf[start_positions[i]]; 
    7941245        char* b = NULL; 
    7951246 
    796         from = strtol(a, &b, 10); 
    797         to = strtol(b, &a, 10); 
    798         real = strtod(a, &b); 
    799         imag = strtod(b, &a); 
     1247        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1248        long from = strtol(a, &b, 10) - 1; 
     1249        long to = strtol(b, &a, 10) - 1; 
     1250        double value = strtod(a, &b); 
    8001251 
    8011252        if (a == b) 
     
    8071258        } 
    8081259 
     1260        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     1261        { 
     1262          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1263                    << ": First vertex id is invalid." << std::endl; 
     1264          exit(1); 
     1265        } 
     1266        else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     1267        { 
     1268          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1269                    << ": Second vertex id is invalid." << std::endl; 
     1270          exit(1); 
     1271        } 
     1272 
     1273        if (to == from) 
     1274        { 
     1275          // Diagonal edges only get one entry in the matrix. 
     1276          long pos = mt_incr(diag_count, 1); 
     1277          edge_heads[pos] = static_cast<size_type>(from); 
     1278          edge_tails[pos] = static_cast<size_type>(to); 
     1279          values[pos] = static_cast<T>(value); 
     1280        } 
     1281        else 
     1282        { 
     1283          // Off diagonal edges get two entries in the matrix. 
     1284          long pos = mt_incr(offdiag_count, 1); 
     1285          edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
     1286          edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
     1287          values[num_diags + 2 * pos] = static_cast<T>(value); 
     1288          edge_heads[num_diags + 2 * pos + 1] = static_cast<size_type>(to); 
     1289          edge_tails[num_diags + 2 * pos + 1] = static_cast<size_type>(from); 
     1290          values[num_diags + 2 * pos + 1] = static_cast<T>(value); 
     1291        } 
     1292      } 
     1293    } 
     1294    else if (strcmp(entry_type, "complex") == 0) 
     1295    { 
     1296      #pragma mta assert parallel 
     1297      for (size_type i = 0; i < num_entries; ++i) 
     1298      { 
     1299        char* a = &buf[start_positions[i]]; 
     1300        char* b = NULL; 
     1301 
    8091302        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    810         --from; 
    811         --to; 
     1303        long from = strtol(a, &b, 10) - 1; 
     1304        long to = strtol(b, &a, 10) - 1; 
     1305        double real = strtod(a, &b); 
     1306        double imag = strtod(b, &a); 
     1307 
     1308        if (a == b) 
     1309        { 
     1310          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1311                    << ": Too few parameters when describing edge." 
     1312                    << std::endl; 
     1313          exit(1); 
     1314        } 
    8121315 
    8131316        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     
    8271330        { 
    8281331          // Diagonal edges only get one entry in the matrix. 
    829           long pos = mt_incr(my_num_diags, 1); 
     1332          long pos = mt_incr(diag_count, 1); 
    8301333          edge_heads[pos] = static_cast<size_type>(from); 
    8311334          edge_tails[pos] = static_cast<size_type>(to); 
     
    8361339        { 
    8371340          // Off diagonal edges get two entries in the matrix. 
    838           long pos = mt_incr(my_num_offdiags, 1); 
     1341          long pos = mt_incr(offdiag_count, 1); 
    8391342          edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
    8401343          edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
     
    8481351      } 
    8491352    } 
    850     else if (strcmp(entry_type, "integer") == 0) 
    851     { 
    852       long my_num_diags = 0; 
    853       long my_num_offdiags = 0; 
    854  
     1353#endif 
     1354  } 
     1355  else if (strcmp(symmetry_format, "skew-symmetric") == 0) 
     1356  { 
     1357#ifdef USING_QTHREADS 
     1358    if (strcmp(entry_type, "integer") == 0) 
     1359    { 
     1360      detail::parse_skew_symmetric_edges<size_type, T, long, 1> 
     1361        psse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1362             values, num_vertices, num_edges, num_entries, num_threads); 
     1363      qt_loop_balance(0, num_threads, psse); 
     1364    } 
     1365    else if (strcmp(entry_type, "real") == 0) 
     1366    { 
     1367      detail::parse_skew_symmetric_edges<size_type, T, double, 2> 
     1368        psse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1369             values, num_vertices, num_edges, num_entries, num_threads); 
     1370      qt_loop_balance(0, num_threads, psse); 
     1371    } 
     1372    else if (strcmp(entry_type, "complex") == 0) 
     1373    { 
     1374      detail::parse_skew_symmetric_edges<size_type, T, double, 3> 
     1375        psse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1376             values, num_vertices, num_edges, num_entries, num_threads); 
     1377      qt_loop_balance(0, num_threads, psse); 
     1378    } 
     1379#else 
     1380    if (strcmp(entry_type, "integer") == 0) 
     1381    { 
    8551382      #pragma mta assert parallel 
    8561383      for (size_type i = 0; i < num_entries; ++i) 
    8571384      { 
    858         long from; 
    859         long to; 
    860         long value; 
    861  
    8621385        char* a = &buf[start_positions[i]]; 
    8631386        char* b = NULL; 
    8641387 
    865         from = strtol(a, &b, 10); 
    866         to = strtol(b, &a, 10); 
    867         value = strtol(a, &b, 10); 
     1388        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1389        long from = strtol(a, &b, 10) - 1; 
     1390        long to = strtol(b, &a, 10) - 1; 
     1391        long value = strtol(a, &b, 10); 
    8681392 
    8691393        if (a == b) 
     
    8741398          exit(1); 
    8751399        } 
    876  
    877         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    878         --from; 
    879         --to; 
    880  
    881         if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    882         { 
    883           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    884                     << ": First vertex id is invalid." << std::endl; 
    885           exit(1); 
    886         } 
    887         else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
    888         { 
    889           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    890                     << ": Second vertex id is invalid." << std::endl; 
    891           exit(1); 
    892         } 
    893  
    894         if (to == from) 
    895         { 
    896           // Diagonal edges only get one entry in the matrix. 
    897           long pos = mt_incr(my_num_diags, 1); 
    898           edge_heads[pos] = static_cast<size_type>(from); 
    899           edge_tails[pos] = static_cast<size_type>(to); 
    900           values[pos] = static_cast<T>(value); 
    901         } 
    902         else 
    903         { 
    904           // Off diagonal edges get two entries in the matrix. 
    905           long pos = mt_incr(my_num_offdiags, 1); 
    906           edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
    907           edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
    908           values[num_diags + 2 * pos] = static_cast<T>(value); 
    909           edge_heads[num_diags + 2 * pos + 1] = static_cast<size_type>(to); 
    910           edge_tails[num_diags + 2 * pos + 1] = static_cast<size_type>(from); 
    911           values[num_diags + 2 * pos + 1] = static_cast<T>(value); 
    912         } 
    913       } 
    914     } 
    915     else if (strcmp(entry_type, "pattern") == 0) 
    916     { 
    917       long my_num_diags = 0; 
    918       long my_num_offdiags = 0; 
    919  
    920       #pragma mta assert parallel 
    921       for (size_type i = 0; i < num_entries; ++i) 
    922       { 
    923         long from; 
    924         long to; 
    925  
    926         char* a = &buf[start_positions[i]]; 
    927         char* b = NULL; 
    928  
    929         from = strtol(a, &b, 10); 
    930         to = strtol(b, &a, 10); 
    931  
    932         if (a == b) 
    933         { 
    934           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    935                     << ": Too few parameters when describing edge." 
    936                     << std::endl; 
    937           exit(1); 
    938         } 
    939  
    940         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    941         --from; 
    942         --to; 
    943  
    944         if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    945         { 
    946           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    947                     << ": First vertex id is invalid." << std::endl; 
    948           exit(1); 
    949         } 
    950         else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
    951         { 
    952           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    953                     << ": Second vertex id is invalid." << std::endl; 
    954           exit(1); 
    955         } 
    956  
    957         if (to == from) 
    958         { 
    959           // Diagonal edges only get one entry in the matrix. 
    960           long pos = mt_incr(my_num_diags, 1); 
    961           edge_heads[pos] = static_cast<size_type>(from); 
    962           edge_tails[pos] = static_cast<size_type>(to); 
    963         } 
    964         else 
    965         { 
    966           // Off diagonal edges get two entries in the matrix. 
    967           long pos = mt_incr(my_num_offdiags, 1); 
    968           edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
    969           edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
    970           edge_heads[num_diags + 2 * pos + 1] = static_cast<size_type>(to); 
    971           edge_tails[num_diags + 2 * pos + 1] = static_cast<size_type>(from); 
    972         } 
    973       } 
    974     } 
    975   } 
    976   else if (strcmp(symmetry_format, "skew-symmetric") == 0) 
    977   { 
    978     if (strcmp(entry_type, "real") == 0) 
    979     { 
    980       #pragma mta assert parallel 
    981       for (size_type i = 0; i < num_entries; ++i) 
    982       { 
    983         long from; 
    984         long to; 
    985         double value; 
    986  
    987         char* a = &buf[start_positions[i]]; 
    988         char* b = NULL; 
    989  
    990         from = strtol(a, &b, 10); 
    991         to = strtol(b, &a, 10); 
    992         value = strtod(a, &b); 
    993  
    994         if (a == b) 
    995         { 
    996           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    997                     << ": Too few parameters when describing edge." 
    998                     << std::endl; 
    999           exit(1); 
    1000         } 
    1001  
    1002         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    1003         --from; 
    1004         --to; 
    10051400 
    10061401        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     
    10331428      } 
    10341429    } 
    1035     else if (strcmp(entry_type, "complex") == 0) 
     1430    else if (strcmp(entry_type, "real") == 0) 
    10361431    { 
    10371432      #pragma mta assert parallel 
    10381433      for (size_type i = 0; i < num_entries; ++i) 
    10391434      { 
    1040         long from; 
    1041         long to; 
    1042         double real; 
    1043         double imag; 
    1044  
    10451435        char* a = &buf[start_positions[i]]; 
    10461436        char* b = NULL; 
    10471437 
    1048         from = strtol(a, &b, 10); 
    1049         to = strtol(b, &a, 10); 
    1050         real = strtod(a, &b); 
    1051         imag = strtod(b, &a); 
     1438        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1439        long from = strtol(a, &b, 10) - 1; 
     1440        long to = strtol(b, &a, 10) - 1; 
     1441        double value = strtod(a, &b); 
    10521442 
    10531443        if (a == b) 
     
    10591449        } 
    10601450 
     1451        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     1452        { 
     1453          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1454                    << ": First vertex id is invalid." << std::endl; 
     1455          exit(1); 
     1456        } 
     1457        else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
     1458        { 
     1459          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1460                    << ": Second vertex id is invalid." << std::endl; 
     1461          exit(1); 
     1462        } 
     1463        else if (from == to) 
     1464        { 
     1465          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1466                    << ": Can't have diagonal entry in skew-symmetric matrix." 
     1467                    << std::endl; 
     1468          exit(1); 
     1469        } 
     1470 
     1471        edge_heads[2 * i] = static_cast<size_type>(from); 
     1472        edge_tails[2 * i] = static_cast<size_type>(to); 
     1473        values[2 * i] = static_cast<T>(value); 
     1474 
     1475        edge_heads[2 * i + 1] = static_cast<size_type>(to); 
     1476        edge_tails[2 * i + 1] = static_cast<size_type>(from); 
     1477        values[2 * i + 1] = static_cast<T>(-value); 
     1478      } 
     1479    } 
     1480    else if (strcmp(entry_type, "complex") == 0) 
     1481    { 
     1482      #pragma mta assert parallel 
     1483      for (size_type i = 0; i < num_entries; ++i) 
     1484      { 
     1485        char* a = &buf[start_positions[i]]; 
     1486        char* b = NULL; 
     1487 
    10611488        // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    1062         --from; 
    1063         --to; 
     1489        long from = strtol(a, &b, 10) - 1; 
     1490        long to = strtol(b, &a, 10) - 1; 
     1491        double real = strtod(a, &b); 
     1492        double imag = strtod(b, &a); 
     1493 
     1494        if (a == b) 
     1495        { 
     1496          std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
     1497                    << ": Too few parameters when describing edge." 
     1498                    << std::endl; 
     1499          exit(1); 
     1500        } 
    10641501 
    10651502        if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
     
    10941531      } 
    10951532    } 
    1096     else if (strcmp(entry_type, "integer") == 0) 
    1097     { 
    1098       #pragma mta assert parallel 
    1099       for (size_type i = 0; i < num_entries; ++i) 
    1100       { 
    1101         long from; 
    1102         long to; 
    1103         long value; 
    1104  
    1105         char* a = &buf[start_positions[i]]; 
    1106         char* b = NULL; 
    1107  
    1108         from = strtol(a, &b, 10); 
    1109         to = strtol(b, &a, 10); 
    1110         value = strtol(a, &b, 10); 
    1111  
    1112         if (a == b) 
    1113         { 
    1114           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    1115                     << ": Too few parameters when describing edge." 
    1116                     << std::endl; 
    1117           exit(1); 
    1118         } 
    1119  
    1120         // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    1121         --from; 
    1122         --to; 
    1123  
    1124         if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    1125         { 
    1126           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    1127                     << ": First vertex id is invalid." << std::endl; 
    1128           exit(1); 
    1129         } 
    1130         else if (to < 0 || static_cast<size_type>(to) >= num_vertices) 
    1131         { 
    1132           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    1133                     << ": Second vertex id is invalid." << std::endl; 
    1134           exit(1); 
    1135         } 
    1136         else if (from == to) 
    1137         { 
    1138           std::cerr << std::endl << "Error on line " << i + num_intro_lines + 1 
    1139                     << ": Can't have diagonal entry in skew-symmetric matrix." 
    1140                     << std::endl; 
    1141           exit(1); 
    1142         } 
    1143  
    1144         edge_heads[2 * i] = static_cast<size_type>(from); 
    1145         edge_tails[2 * i] = static_cast<size_type>(to); 
    1146         values[2 * i] = static_cast<T>(value); 
    1147  
    1148         edge_heads[2 * i + 1] = static_cast<size_type>(to); 
    1149         edge_tails[2 * i + 1] = static_cast<size_type>(from); 
    1150         values[2 * i + 1] = static_cast<T>(-value); 
    1151       } 
    1152     } 
     1533#endif 
    11531534  } 
    11541535  else if (strcmp(symmetry_format, "hermitian") == 0) 
     
    11571538    // complex entry_type. 
    11581539 
    1159     long my_num_diags = 0; 
    1160     long my_num_offdiags = 0; 
    1161  
     1540    long diag_count = 0; 
     1541    long offdiag_count = 0; 
     1542 
     1543#ifdef USING_QTHREADS 
     1544    detail::parse_hermitian_edges<size_type, T> 
     1545      pse(buf, num_intro_lines, start_positions, edge_heads, edge_tails, 
     1546          values, num_vertices, num_edges, num_diags, local_num_diags, 
     1547          diag_count, offdiag_count, num_entries, num_threads); 
     1548    qt_loop_balance(0, num_threads, pse); 
     1549#else 
    11621550    #pragma mta assert parallel 
    11631551    for (size_type i = 0; i < num_entries; ++i) 
    11641552    { 
    1165       long from; 
    1166       long to; 
    1167       double real; 
    1168       double imag; 
    1169  
    11701553      char* a = &buf[start_positions[i]]; 
    11711554      char* b = NULL; 
    11721555 
    1173       from = strtol(a, &b, 10); 
    1174       to = strtol(b, &a, 10); 
    1175       real = strtod(a, &b); 
    1176       imag = strtod(b, &a); 
     1556      // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
     1557      long from = strtol(a, &b, 10) - 1; 
     1558      long to = strtol(b, &a, 10) - 1; 
     1559      double real = strtod(a, &b); 
     1560      double imag = strtod(b, &a); 
    11771561 
    11781562      if (a == b) 
     
    11831567      } 
    11841568 
    1185       // Matrix Market vertex ids are 1-based.  We need them to be 0-based. 
    1186       --from; 
    1187       --to; 
    1188  
    11891569      if (from < 0 || static_cast<size_type>(from) >= num_vertices) 
    11901570      { 
     
    12031583      { 
    12041584        // Diagonal edges only get one entry in the matrix. 
    1205         long pos = mt_incr(my_num_diags, 1); 
     1585        long pos = mt_incr(diag_count, 1); 
    12061586        edge_heads[pos] = static_cast<size_type>(from); 
    12071587        edge_tails[pos] = static_cast<size_type>(to); 
     
    12121592      { 
    12131593        // Off diagonal edges get two entries in the matrix. 
    1214         long pos = mt_incr(my_num_offdiags, 1); 
     1594        long pos = mt_incr(offdiag_count, 1); 
    12151595        edge_heads[num_diags + 2 * pos] = static_cast<size_type>(from); 
    12161596        edge_tails[num_diags + 2 * pos] = static_cast<size_type>(to); 
     
    12231603      } 
    12241604    } 
     1605#endif 
    12251606  } 
    12261607 
     
    12281609  #pragma mta fence 
    12291610  timer2.stop(); 
     1611  timer.stop(); 
     1612 
    12301613  std::cout << "                 Edge read time: " << std::setw(10) 
    12311614            << std::fixed << std::setprecision(6) << timer2.getElapsedSeconds() 
    1232             << std::endl; 
    1233  
    1234   #pragma mta fence 
    1235   timer.stop(); 
    1236   std::cout << "                File parse time: " << std::setw(10) 
     1615            << std::endl 
     1616            << "                File parse time: " << std::setw(10) 
    12371617            << std::fixed << std::setprecision(6) << timer.getElapsedSeconds() 
    12381618            << std::endl; 
     
    12561636  free(edge_tails); 
    12571637  free(buf); 
     1638#ifdef USING_QTHREADS 
     1639  free(local_num_diags); 
     1640#endif 
    12581641 
    12591642  return true; 
  • trunk/test/test_read_graph.cpp

    r3455 r3836  
    2121/****************************************************************************/ 
    2222 
    23 #define DEBUG 
    2423//#define MM_REAL 
    2524#define MM_INT 
     
    2827 
    2928#include <mtgl/compressed_sparse_row_graph.hpp> 
     29 
     30#define DEBUG 
     31 
    3032#include <mtgl/mtgl_io.hpp> 
     33#include <mtgl/mtgl_test.hpp> 
    3134#include <mtgl/dynamic_array.hpp> 
    3235 
     
    4144  typedef graph_traits<Graph>::edge_iterator edge_iterator; 
    4245 
    43   if (argc < 2) 
    44   { 
    45     std::cerr << "Usage: " << argv[0] << " <filename>\n" 
    46               << "       where filename is in dimacs, matrix market, or " 
    47               << "srcs-dests format.\n\n" 
    48               << "DIMACS files must end with suffix '.dimacs.'\n" 
    49               << "MatrixMarket files must end with suffix '.mtx.'\n" 
    50               << "Srcs-dests files must end with suffixes '.srcs' and '.dests'." 
    51               << std::endl; 
    52     exit(1); 
    53   } 
     46  init_test(argc, argv); 
    5447 
    5548  Graph g; 
    56  
    57   int llen = strlen(argv[1]); 
    5849 
    5950#ifdef MM_REAL 
     
    6354#endif 
    6455 
    65   if (strcmp(&argv[1][llen - 6], "dimacs") == 0) 
    66   { 
    67     // DIMACS input. 
    68 #ifdef MM_INT 
    69     read_dimacs(g, argv[1], values); 
    70 #else 
    71     read_dimacs(g, argv[1]); 
    72 #endif 
    73   } 
    74   else if (strcmp(&argv[1][llen - 3], "mtx") == 0) 
    75   { 
    76     // Matrix-market input. 
    77 #if defined MM_REAL || defined MM_INT 
    78     read_matrix_market(g, argv[1], values); 
    79 #else 
    80     read_matrix_market(g, argv[1]); 
    81 #endif 
    82   } 
    83   else if (strcmp(&argv[1][llen - 4], "srcs") == 0) 
    84   { 
    85     // Snapshot input: <file>.srcs, <file>.dests 
    86     char* srcs_fname = argv[1]; 
    87     char dests_fname[256]; 
    88  
    89     strcpy(dests_fname, srcs_fname); 
    90     strcpy(&dests_fname[llen - 4], "dests"); 
    91  
    92     read_binary(g, srcs_fname, dests_fname); 
    93   } 
    94   else 
    95   { 
    96     std::cerr << "Invalid graph file type.\nAvailable types:\n" 
    97               << "    dimacs (.dimacs)\n" 
    98               << "    matrix market (.mtx)\n" 
    99               << "    srcs-dests (.srcs, .dests)" << std::endl; 
    100     exit(1); 
    101   } 
     56  create_test_graph(g, values, argc, argv); 
    10257 
    10358  size_type order = num_vertices(g); 
Note: See TracChangeset for help on using the changeset viewer.