00001 #ifndef _CSR_HPP_
00002 #define _CSR_HPP_
00003
00004
00005 #include <vector>
00006 #include <iterator>
00007 #include <fstream>
00008 #include <utility>
00009 #include <iostream>
00010
00011 #include "mmh_intf.h"
00012 #include "uth_log.h"
00013
00014 using namespace std::rel_ops;
00015
00016 template<typename T>
00017 class CSR
00018 {
00019 public:
00020 typedef T Tind;
00021 typedef Tind* pTind;
00022 typedef const Tind* cpTind;
00023
00024 static const int n_max_neig=MMC_MAXELFAC;
00025
00026 friend class CsrNode;
00027 friend class CsrNodeInternal;
00028
00029
00031 typename std::vector<Tind>::iterator write(std::vector<Tind> & v) const {
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 v.reserve(size());
00044 v.push_back(xadj_.size());
00045 v.insert(v.end(),xadj_.begin(),xadj_.end());
00046 v.push_back(adjncy_.size());
00047 v.insert(v.end(),adjncy_.begin(),adjncy_.end());
00048 v.push_back(vwgt_.size());
00049 v.insert(v.end(),vwgt_.begin(),vwgt_.end());
00050 v.push_back(adjwgt_.size());
00051 v.insert(v.end(),adjwgt_.begin(),adjwgt_.end());
00052 v.push_back(el_loc_id_.size());
00053 v.insert(v.end(),el_loc_id_.begin(),el_loc_id_.end());
00054 v.push_back(part_.size());
00055 v.insert(v.end(),part_.begin(),part_.end());
00056 v.push_back(adj_neig_no_.size());
00057 v.insert(v.end(),adj_neig_no_.begin(),adj_neig_no_.end());
00058
00059
00060
00061
00062
00063
00064
00065
00066 return v.end();
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00083
00084
00085
00086 typename std::vector<T>::const_iterator read(const std::vector<T> & v) {
00087
00088
00089
00090
00091
00092
00093
00094 typename std::vector<T>::const_iterator it(v.begin());
00095 xadj_.resize(*it); ++it;
00096 std::copy(it,it+xadj_.size(),xadj_.begin());
00097 it+=+xadj_.size();
00098
00099 adjncy_.resize(*it); ++it;
00100 std::copy(it,it+adjncy_.size(),adjncy_.begin());
00101 it+=+adjncy_.size();
00102
00103 vwgt_.resize(*it); ++it;
00104 std::copy(it,it+vwgt_.size(),vwgt_.begin());
00105 it+=+vwgt_.size();
00106
00107 adjwgt_.resize(*it); ++it;
00108 std::copy(it,it+adjwgt_.size(),adjwgt_.begin());
00109 it+=+adjwgt_.size();
00110
00111 el_loc_id_.resize(*it); ++it;
00112 std::copy(it,it+el_loc_id_.size(),el_loc_id_.begin());
00113 it+=+el_loc_id_.size();
00114
00115 part_.resize(*it); ++it;
00116 std::copy(it,it+part_.size(),part_.begin());
00117 it+=+part_.size();
00118
00119 adj_neig_no_.resize(*it); ++it;
00120 std::copy(it,it+adj_neig_no_.size(),adj_neig_no_.begin());
00121 it+=+adj_neig_no_.size();
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 return it;
00136 }
00137
00138 std::istream& read(std::istream & is) {
00139 T size=0;
00140 is >> size;
00141 resize(size);
00142 std::istream_iterator<T> iit(is);
00143
00144 std::copy(iit,iit+xadj_.size(),xadj());
00145 std::copy(iit,iit+adjncy_.size(),adjncy());
00146 std::copy(iit,iit+vwgt_.size(),vwgt());
00147 std::copy(iit,iit+adjwgt_.size(), adjwgt());
00148 std::copy(iit,iit+el_loc_id_.size(),el_id());
00149 std::copy(iit,iit+part_.size(), part());
00150 std::copy(iit,iit+adj_neig_no_.size(),adj_neig_no());
00151
00152
00153
00154
00155
00156
00157 return is;
00158 }
00159
00160 friend std::ostream& operator<<(std::ostream & os, CSR<T> const& csr) {
00161 return csr.write(os);
00162 }
00163
00164 friend std::istream& operator>>(std::istream & is, CSR<T> & csr) {
00165 return csr.read(is);
00166 }
00168 class CsrNode
00169 {
00170 public:
00171
00172 friend class iterator;
00173 friend class const_iterator;
00174
00175 CsrNode() : el_id(0), vwgt(0), n_neighs(0) {
00176 std::fill(neighs,neighs+n_max_neig,0);
00177 std::fill(neig_no,neighs+n_max_neig,0);
00178 }
00179
00180 pTind end_neighs() const {return neighs+n_neighs;}
00181
00182 bool operator==(const CsrNode & other) const { return el_id == other.el_id; }
00183
00184 Tind el_id,vwgt,n_neighs;
00185 Tind neighs[n_max_neig], neig_no[n_max_neig];
00186 };
00188 class CsrNodeInternal
00189 {
00190 friend class iterator;
00191 public:
00192 CsrNodeInternal(CSR *container = NULL)
00193 : pxadj(NULL),padjncy(NULL),pvwgt(NULL),
00194 padjwgt(NULL),pel_id(NULL),pos_(0),padj_neig_no(NULL) {
00195 if(container != NULL) {
00196 pxadj = container->xadj();
00197 padjncy = container->adjncy();
00198 pvwgt = container->vwgt();
00199 padjwgt = container->adjwgt();
00200 pel_id = container->el_id();
00201 ppart = container->part();
00202 padj_neig_no = container->adj_neig_no();
00203 }
00204 }
00205
00206 CsrNodeInternal(const CsrNodeInternal &x) {
00207 pxadj = x.pxadj;
00208 pvwgt = x.pvwgt;
00209 pel_id = x.pel_id;
00210 ppart = x.ppart;
00211 pos_ = x.pos_;
00212 padjncy = x.padjncy;
00213 padjwgt = x.padjwgt;
00214 padj_neig_no = x.padj_neig_no;
00215 }
00216
00217 CsrNodeInternal( CsrNodeInternal &x) {
00218 pxadj = x.pxadj;
00219 pvwgt = x.pvwgt;
00220 pel_id = x.pel_id;
00221 ppart = x.ppart;
00222 pos_ = x.pos_;
00223 padjncy = x.padjncy;
00224 padjwgt = x.padjwgt;
00225 padj_neig_no = x.padj_neig_no;
00226
00227
00228
00229
00230
00231
00232
00233 }
00234
00235 CsrNodeInternal& operator=(const CsrNodeInternal &x){
00236
00237 *pvwgt = *x.pvwgt;
00238 *pel_id = *x.pel_id;
00239 *ppart = *x.ppart;
00240 pos_ = x.pos_;
00241 const int nx= *(x.pxadj+1) - *x.pxadj;
00242 assert(nx == (*(pxadj+1) - *pxadj) );
00243
00244 std::copy(x.padjncy,x.padjncy + nx, padjncy);
00245 std::copy(x.padjwgt,x.padjwgt + nx, padjwgt);
00246 std::copy(x.padj_neig_no,x.padj_neig_no + nx, padj_neig_no);
00247 return *this;
00248 }
00249
00250 CsrNodeInternal& operator++() {
00251 ++pxadj;
00252 ++pvwgt;
00253 ++pel_id;
00254 padjwgt += *pxadj - *(pxadj-1);
00255 padjncy += *pxadj - *(pxadj-1);
00256 ++ppart;
00257 ++pos_;
00258 padj_neig_no += *pxadj - *(pxadj-1);
00259 return *this;
00260 }
00261
00262 CsrNodeInternal& operator+(int n) {
00263 return move_forward(n);
00264 }
00265
00266 CsrNodeInternal& operator--() {
00267 --pxadj;
00268 --pvwgt;
00269 --pel_id;
00270 padjwgt -= *(pxadj+1) - *pxadj;
00271 padjncy -= *(pxadj+1) - *pxadj;
00272 --ppart;
00273 --pos_;
00274 padj_neig_no -= *(pxadj+1) - *pxadj;
00275 return *this;
00276 }
00277
00278 CsrNodeInternal& operator-(int n) {
00279 return move_back(n);
00280 }
00281
00282 std::ptrdiff_t operator-(const CsrNodeInternal & x) const {
00283 return pel_id - x.pel_id;
00284 }
00285
00286 bool operator == (const CsrNodeInternal & x) const {
00287 return pel_id == x.pel_id;
00288 }
00289
00290 bool operator != (const CsrNodeInternal & x) const {
00291 return pel_id != x.pel_id;
00292 }
00293
00294 bool operator < (const CsrNodeInternal & x) const {
00295 return pel_id < x.pel_id;
00296 }
00297
00298 CsrNodeInternal& move_forward(const int n) {
00299 pxadj+=n;
00300 pvwgt+=n;
00301 pel_id+=n;
00302 padjwgt += *pxadj - *(pxadj-n);
00303 padjncy += *pxadj - *(pxadj-n);
00304 ppart+=n;
00305 pos_+=n;
00306 padj_neig_no += *pxadj - *(pxadj-n);
00307 return *this;
00308 }
00309
00310 CsrNodeInternal& move_back(const int n) {
00311 pxadj-=n;
00312 pvwgt-=n;
00313 pel_id-=n;
00314 padjwgt -= *(pxadj+n) -*pxadj;
00315 padjncy -= *(pxadj+n) -*pxadj;
00316 ppart-=n;
00317 pos_-=n;
00318 padj_neig_no -= *(pxadj+n) -*pxadj;
00319 return *this;
00320 }
00321
00322 Tind pos() const {return pos_;}
00323 Tind part() const {return *ppart; }
00324
00325 pTind pxadj,padjncy,pvwgt,padjwgt,pel_id,ppart, padj_neig_no;
00326 Tind pos_;
00327 };
00328
00329
00331 class iterator
00332 : public std::iterator< std::random_access_iterator_tag, CsrNodeInternal >
00333 {
00334 public:
00335 iterator(CSR *container = NULL)
00336 : node(container){}
00337
00338 iterator(const iterator &x) {
00339 *this = x;
00340 }
00341
00342 iterator( iterator &x) {
00343 node.pxadj = x.node.pxadj;
00344 node.pvwgt = x.node.pvwgt;
00345 node.pel_id = x.node.pel_id;
00346 node.ppart = x.node.ppart;
00347 node.pos_ = x.node.pos_;
00348 node.padjncy = x.node.padjncy;
00349 node.padjwgt = x.node.padjwgt;
00350 node.padj_neig_no = x .node.padj_neig_no;
00351 x.node.pxadj = NULL;
00352 x.node.pvwgt = NULL;
00353 x.node.pel_id = NULL;
00354 x.node.ppart = NULL;
00355 x.node.pos_ = 0;
00356 x.node.padjncy = NULL;
00357 x.node.padjwgt = NULL;
00358 x.node.padj_neig_no = NULL;
00359 }
00360
00361 iterator& operator=(const iterator &it) {
00362 node.pxadj = it.node.pxadj;
00363 node.pvwgt = it.node.pvwgt;
00364 node.pel_id = it.node.pel_id;
00365 node.padjwgt = it.node.padjwgt;
00366 node.padjncy = it.node.padjncy;
00367 node.ppart = it.node.ppart;
00368 node.pos_ = it.node.pos_;
00369 node.padj_neig_no = it.node.padj_neig_no;
00370
00371 return *this;
00372 }
00373
00374 iterator& operator++() {
00375 ++node;
00376 return *this;
00377 }
00378
00379 iterator& operator+(const int n) {
00380 node.move_forward(n);
00381 return *this;
00382 }
00383
00384 iterator& operator--() {
00385 --node;
00386 return *this;
00387 }
00388
00389 iterator& operator-(const int n) {
00390 node.move_back(n);
00391 return *this;
00392 }
00393
00394 std::ptrdiff_t operator-(const iterator & x) const {
00395 return node - x.node;
00396 }
00397
00398 bool operator == (const iterator & x) const {
00399 return node == x.node;
00400 }
00401
00402 bool operator != (const iterator & x) const {
00403 return node != x.node;
00404 }
00405
00406 bool operator < (const iterator & x) const {
00407 return node < x.node;
00408 }
00409
00410 CsrNodeInternal& operator*() {
00411 return node;
00412 }
00413
00414 protected:
00415 CsrNodeInternal node;
00416 };
00418 CSR(const Tind size=0) {
00419 resize(size);
00420 }
00421
00422 void resize (Tind size) {
00423 if(size > 0) {
00424 xadj_.resize(size+1,0);
00425 adjncy_.resize(2*(size+1)*n_max_neig,0);
00426 vwgt_.resize(size,0);
00427 adjwgt_.resize((size+1)*n_max_neig,0);
00428 el_loc_id_.resize(size,0);
00429 part_.resize(size,0);
00430 adj_neig_no_.resize(adjncy_.size(),0);
00431 }
00432 else {
00433 clear();
00434 }
00435 }
00436
00437 void reserve (Tind size) {
00438 if(size > 0) {
00439 xadj_.reserve(size+1);
00440 adjncy_.reserve(2*(size+1)*n_max_neig);
00441 vwgt_.reserve(size);
00442 adjwgt_.reserve(2*(size+1)*n_max_neig);
00443 el_loc_id_.reserve(size);
00444 part_.reserve(size);
00445 adj_neig_no_.reserve(adjncy_.capacity());
00446 }
00447 }
00448
00449 Tind capacity() const {
00450 return el_loc_id_.capacity();
00451 }
00452
00453 CsrNodeInternal& at(const int pos) {
00454 assert(pos >= 0);
00455 assert(pos < size());
00456 return CsrNodeInternal(this,pos);
00457 }
00458
00459 void clear() {
00460 xadj_.clear();
00461 adjncy_.clear();
00462 vwgt_.clear();
00463 adjwgt_.clear();
00464 el_loc_id_.clear();
00465 part_.clear();
00466 adj_neig_no_.clear();
00467 }
00468
00469 iterator begin() { return iterator(this); }
00470 iterator end() {return iterator(this)+el_loc_id_.size(); }
00471
00472
00473
00474
00475 Tind size() const { return el_loc_id_.size() ;}
00476 bool empty() const { return el_loc_id_.empty(); }
00477
00478 pTind xadj() {return xadj_.data(); }
00479 pTind adjncy() {return adjncy_.data(); }
00480 pTind vwgt() {return vwgt_.data(); }
00481 pTind adjwgt() {return adjwgt_.data(); }
00482 pTind el_id() {return el_loc_id_.data(); }
00483 pTind part() {return part_.data(); }
00484 pTind adj_neig_no() { return adj_neig_no_.data(); }
00485
00486 cpTind xadj() const {return xadj_.data(); }
00487 cpTind adjncy() const {return adjncy_.data(); }
00488 cpTind vwgt() const {return vwgt_.data(); }
00489 cpTind adjwgt() const {return adjwgt_.data(); }
00490 cpTind el_id() const {return el_loc_id_.data(); }
00491 cpTind part() const {return part_.data(); }
00492 cpTind adj_neig_no() const {return adj_neig_no_.data(); }
00493
00494 void push_back(CsrNode & val) {
00495 push_back(val.el_id, val.neighs, val.n_neighs, val.vwgt, 0, val.neig_no);
00496 }
00497
00498 void push_back(CsrNodeInternal & val) {
00499 push_back(*val.pel_id, val.padjncy, *(val.pxadj+1) - *val.pxadj, *val.pvwgt, *val.ppart, val.padj_neig_no);
00500 }
00501
00502 void push_back(Tind el_id, pTind neigs,Tind n_neigs,Tind vtxwgt,Tind part, pTind neig_no) {
00503 assert(el_id > 0);
00504 assert(neigs != NULL);
00505 assert(n_neigs > 0);
00506 assert(n_neigs <= n_max_neig);
00507 assert(vtxwgt>0);
00508
00509 if(xadj_.empty()) {
00510 xadj_.push_back(0);
00511 }
00512
00513 el_loc_id_.push_back(el_id);
00514 vwgt_.push_back(vtxwgt);
00515 adjncy_.insert(adjncy_.end(),neigs,neigs+n_neigs);
00516 adjwgt_.insert(adjwgt_.end(),n_neigs,vtxwgt);
00517 xadj_.push_back( adjncy_.size() );
00518 part_.push_back(0);
00519 adj_neig_no_.insert(adj_neig_no_.end(), neig_no, neig_no+n_neigs);
00520 }
00521
00522 template<class Archive>
00523 void serialize(Archive & archive)
00524 {
00525
00526 archive( xadj_);
00527 archive( adjncy_);
00528 archive( vwgt_ );
00529 archive( adjwgt_ );
00530 archive( el_loc_id_ );
00531 archive( part_ );
00532 archive( adj_neig_no_ );
00533 }
00534
00535 std::vector<T>& getOverlapElems(std::vector<T> & overlap, const int part_no)
00536 {
00537 overlap.clear();
00538
00539 assert(part_no >= 0);
00540
00541 for(iterator it = begin(); it != end(); ++it) {
00542 if(* (*it).ppart == part_no) {
00543 const int n_neigs = *((*it).pxadj+1) - *((*it).pxadj);
00544 for(int n=0 ; n < n_neigs; ++n) {
00545 const int neig_el = (*it).padjncy[n];
00546 if(part_ [ neig_el ] != part_no) {
00547 overlap.push_back( el_loc_id_[neig_el] );
00548 }
00549 }
00550 }
00551 }
00552
00553 std::sort(overlap.begin(), overlap.end() );
00554 overlap.erase( std::unique( overlap.begin(), overlap.end() ), overlap.end() );
00555
00556 return overlap;
00557 }
00558
00559
00560 std::vector<Tind> xadj_,adjncy_,vwgt_,adjwgt_,el_loc_id_,part_,adj_neig_no_;
00561
00562 };
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 template<class Tind>
00578 bool operator!= (const typename CSR<Tind>::CsrNodeInternal & x, const typename CSR<Tind>::CsrNodeInternal& y) {
00579 return x.pel_id != y.pel_id;
00580 }
00581
00582 template<class Tind>
00583 bool operator<(const typename CSR<Tind>::CsrNodeInternal & x, const typename CSR<Tind>::CsrNodeInternal & y) {
00584 return x.pel_id < y.pel_id;
00585 }
00586
00587
00588 #endif //_CSR_HPP_