45template <
class IT,
class NT>
49template <
class IT,
class NT>
54template <
class IT,
class NT>
55SpCCols<IT,NT>::SpCCols(
IT size,
IT nRow,
IT nCol)
56:m(nRow), n(nCol), nnz(
size), splits(0)
59 csc =
new Csc<IT,NT>(nnz, n);
64template <
class IT,
class NT>
65SpCCols<IT,NT>::~SpCCols()
73 for(
int i=0; i<splits; ++i)
87template <
class IT,
class NT>
88SpCCols<IT,NT>::SpCCols(
const SpCCols<IT,NT> & rhs)
89: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(rhs.splits)
93 for(
int i=0; i<splits; ++i)
94 CopyCsc(rhs.cscarr[i]);
108template <
class IT,
class NT>
109SpCCols<IT,NT>::SpCCols(
const SpTuples<IT, NT> & rhs,
bool transpose)
110: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(0)
115 if(transpose) std::swap(m,n);
123 csc =
new Csc<IT,NT>(nnz,n);
124 std::vector< std::pair<IT,NT> > tosort (nnz);
125 std::vector<IT> work(n+1, (
IT) 0 );
126 for (
IT k = 0 ; k < nnz ; ++k)
128 IT tmp = rhs.rowindex(k);
133 std::partial_sum(work.begin(), work.end(), work.begin());
134 std::copy(work.begin(), work.end(), csc->jc);
136 for (
IT k = 0 ; k < nnz ; ++k)
138 tosort[ work[ rhs.rowindex(k) ]++] = std::make_pair( rhs.colindex(k), rhs.numvalue(k));
141 #pragma omp parallel for
143 for(
int i=0; i< n; ++i)
145 sort(tosort.begin() + csc->jc[i], tosort.begin() + csc->jc[i+1]);
148 typename std::vector<std::pair<IT,NT> >::iterator itr;
149 for(itr = tosort.begin() + csc->jc[i], ind = csc->jc[i]; itr != tosort.begin() + csc->jc[i+1]; ++itr, ++ind)
151 csc->ir[ind] = itr->first;
152 csc->num[ind] = itr->second;
159 csc =
new Csc<IT,NT>(nnz,n);
160 std::vector< std::pair<IT,NT> > tosort (nnz);
161 std::vector<IT> work(n+1, (
IT) 0 );
162 for (
IT k = 0 ; k < nnz ; ++k)
164 IT tmp = rhs.colindex(k);
169 std::partial_sum(work.begin(), work.end(), work.begin());
170 std::copy(work.begin(), work.end(), csc->jc);
172 for (
IT k = 0 ; k < nnz ; ++k)
174 tosort[ work[ rhs.colindex(k) ]++] = std::make_pair( rhs.rowindex(k), rhs.numvalue(k));
177 #pragma omp parallel for
179 for(
int i=0; i< n; ++i)
181 sort(tosort.begin() + csc->jc[i], tosort.begin() + csc->jc[i+1]);
184 typename std::vector<std::pair<IT,NT> >::iterator itr;
185 for(itr = tosort.begin() + csc->jc[i], ind = csc->jc[i]; itr != tosort.begin() + csc->jc[i+1]; ++itr, ++ind)
187 csc->ir[ind] = itr->first;
188 csc->num[ind] = itr->second;
205template <
class IT,
class NT>
206SpCCols<IT,NT> & SpCCols<IT,NT>::operator=(
const SpCCols<IT,NT> & rhs)
212 if(csc != NULL && nnz > 0)
218 csc =
new Csc<IT,NT>(*(rhs.csc));
235template <
class IT,
class NT>
236void SpCCols<IT,NT>::RowSplit(
int numsplits)
239 IT perpiece = m / splits;
240 std::vector<IT> nnzs(splits, 0);
241 std::vector < std::vector < std::tuple<IT,IT,NT> > > colrowpairs(splits);
242 std::vector< std::vector<IT> > colcnts(splits);
243 for(
int i=0; i< splits; ++i)
244 colcnts[i].resize(n, 0);
246 if(nnz > 0 && csc != NULL)
248 for(
IT i=0; i< csc->n; ++i)
250 for(
IT j = csc->jc[i]; j< csc->jc[i+1]; ++j)
252 IT rowid = csc->ir[j];
253 IT owner = std::min(rowid / perpiece,
static_cast<IT>(splits-1));
254 colrowpairs[owner].push_back(std::make_tuple(i, rowid - owner*perpiece, csc->num[i]));
256 ++(colcnts[owner][i]);
262 cscarr =
new Csc<IT,NT>*[splits];
265 #pragma omp parallel for
267 for(
int i=0; i< splits; ++i)
269 cscarr[i] =
new Csc<IT,NT>(nnzs[i],n);
270 sort(colrowpairs[i].begin(), colrowpairs[i].end());
271 cscarr[i]->jc[0] = 0;
272 std::partial_sum(colcnts[i].begin(), colcnts[i].end(), cscarr[i]->jc+1);
273 std::copy(cscarr[i]->jc, cscarr[i]->jc+n, colcnts[i].begin());
276 for(
IT k=0; k<nnzs[i]; ++k)
278 IT cindex = std::get<0>(colrowpairs[i][k]);
279 IT rindex = std::get<1>(colrowpairs[i][k]);
280 NT value = std::get<2>(colrowpairs[i][k]);
282 IT curcptr = (colcnts[i][cindex])++;
283 cscarr[i]->ir[curcptr] = rindex;
284 cscarr[i]->num[curcptr] = value;
290template<
class IT,
class NT>
291void SpCCols<IT,NT>::PrintInfo()
const
293 std::cout <<
"m: " << m ;
294 std::cout <<
", n: " << n ;
295 std::cout <<
", nnz: "<< nnz ;
299 std::cout <<
", local splits: " << splits << std::endl;
301 if(omp_get_thread_num() == 0)
303 SubPrintInfo(cscarr[0]);
309 std::cout << std::endl;
315template <
class IT,
class NT>
316template <
typename UnaryOperation,
typename GlobalIT>
318SpCCols<IT, NT>::PruneI (UnaryOperation unary_op,
324 SpCCols<IT, NT> *retcols = NULL;
328 Csc<IT, NT> *ret = csc->PruneI(unary_op, inPlace, rowOffset, colOffset);
342 retcols =
new SpCCols<IT, NT>();
344 retcols->nnz = retcols->csc->nz;
355 retcols =
new SpCCols<IT, NT>();
368template <
class IT,
class NT>
370SpCCols<IT, NT>::GetEssentials (
void)
const
372 std::vector<IT> essentials(esscount);
381template <
class IT,
class NT>
383SpCCols<IT, NT>::CreateImpl (
const std::vector<IT> &essentials)
385 assert(essentials.size() == esscount);
392 csc =
new Csc<IT, NT>(nnz, n);
399template <
class IT,
class NT>
401SpCCols<IT, NT>::CreateImpl (
IT size,
404 std::tuple<IT, IT, NT> *mytuples)
406 SpTuples<IT,NT> tuples(
size, nRow, nCol, mytuples);
407 tuples.SortColBased();
408 SpCCols<IT, NT> tmp(tuples,
false);
414template <
class IT,
class NT>
416SpCCols<IT, NT>::GetArrays (
void)
const
418 Arr<IT, NT> arr(2, 1);
422 arr.indarrs[0] = LocArr<IT, IT>(csc->jc, csc->n + 1);
423 arr.indarrs[1] = LocArr<IT, IT>(csc->ir, csc->nz);
424 arr.numarrs[0] = LocArr<NT, IT>(csc->num, csc->nz);
428 arr.indarrs[0] = LocArr<IT, IT>(NULL, 0);
429 arr.indarrs[1] = LocArr<IT, IT>(NULL, 0);
430 arr.numarrs[0] = LocArr<NT, IT>(NULL, 0);
438template <
class IT,
class NT>
440SpCCols<IT, NT>::Transpose (
void)
444 SpTuples<IT, NT> tuples(*
this);
445 tuples.SortRowBased();
446 *
this = SpCCols<IT, NT>(tuples,
true);
449 *
this = SpCCols<IT, NT>(0, n, m);
454template <
class IT,
class NT>
456SpCCols<IT, NT>::TransposeConst (
void)
const
458 SpTuples<IT, NT> tuples(*
this);
459 tuples.SortRowBased();
461 return SpCCols<IT, NT>(tuples,
true);
466template <
class IT,
class NT>
468SpCCols<IT, NT>::TransposeConstPtr (
void)
const
470 SpTuples<IT, NT> tuples(*
this);
471 tuples.SortRowBased();
473 return new SpCCols<IT, NT>(tuples,
true);
478template <
class IT,
class NT>
480SpCCols<IT, NT>::Split (SpCCols<IT, NT> &partA,
481 SpCCols<IT, NT> &partB
487 std::cout<<
"Matrix is too small to be splitted" << std::endl;
491 Csc<IT, NT> *Acsc = NULL;
492 Csc<IT, NT> *Bcsc = NULL;
495 csc->Split(Acsc, Bcsc, cut);
497 partA = SpCCols<IT, NT>(m, cut, Acsc);
498 partB = SpCCols<IT, NT>(m, n - cut, Bcsc);
500 *
this = SpCCols<IT, NT>();
505template <
class IT,
class NT>
507SpCCols<IT, NT>::Merge (SpCCols<IT, NT> &partA,
508 SpCCols<IT, NT> &partB
511 assert (partA.m == partB.m);
513 Csc<IT, NT> *Ccsc =
new Csc<IT, NT>();
514 if (partA.nnz == 0 && partB.nnz == 0)
516 else if (partA.nnz == 0)
518 Ccsc =
new Csc<IT, NT>(partB.nnz, partA.n + partB.n);
519 std::fill(Ccsc->jc, Ccsc->jc + partA.n, 0);
520 std::copy(partB.csc->jc, partB.csc->jc + partB.n + 1,
522 std::copy(partB.csc->ir, partB.csc->ir + partB.nnz, Ccsc->ir);
523 std::copy(partB.csc->num, partB.csc->num + partB.nnz, Ccsc->num);
526 else if (partB.nnz == 0)
528 Ccsc =
new Csc<IT, NT>(partA.nnz, partA.n + partB.n);
529 std::copy(partA.csc->jc, partA.csc->jc + partA.n + 1, Ccsc->jc);
530 std::fill(Ccsc->jc + partA.n + 1, Ccsc->jc + partA.n + partB.n + 1,
531 partA.csc->jc[partA.n]);
532 std::copy(partA.csc->ir, partA.csc->ir + partA.nnz, Ccsc->ir);
533 std::copy(partA.csc->num, partA.csc->num + partA.nnz, Ccsc->num);
537 Ccsc->Merge(partA.csc, partB.csc, partA.n);
539 *
this = SpCCols<IT, NT>(partA.m, partA.n + partB.n, Ccsc);
541 partA = SpCCols<IT, NT>();
542 partB = SpCCols<IT, NT>();
547template <
class IT,
class NT>
549SpCCols<IT, NT>::put (std::ofstream &outfile)
const
553 outfile <<
"Matrix doesn't have any nonzeros" << std::endl;
557 SpTuples<IT, NT> tuples(*
this);
558 outfile << tuples << std::endl;
570template <
class IT,
class NT>
571SpCCols<IT, NT>::SpCCols (
IT nRow,
575 csc(mycsc), m(nRow), n(nCol), splits(0)
585template <
class IT,
class NT>
586void SpCCols<IT,NT>::SubPrintInfo(Csc<IT,NT> * mycsc)
const
589 std::cout <<
"Printing for thread " << omp_get_thread_num() << std::endl;
593 NT **
A = SpHelper::allocate2D<NT>(m,n);
594 for(
IT i=0; i< m; ++i)
595 for(
IT j=0; j<n; ++j)
599 for(
IT i=0; i< n; ++i)
601 for(
IT j = mycsc->jc[i]; j< mycsc->jc[i+1]; ++j)
603 IT rowid = mycsc->ir[j];
604 A[rowid][i] = mycsc->num[j];
608 for(
IT i=0; i< m; ++i)
610 for(
IT j=0; j<n; ++j)
612 std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) <<
A[i][j];
615 std::cout << std::endl;
617 SpHelper::deallocate2D(
A,m);
622template <
class IT,
class NT>
623inline void SpCCols<IT,NT>::CopyCsc(Csc<IT,NT> * source)
627 csc =
new Csc<IT,NT>(*source);