45template <
class IT,
class NT>
49template <
class IT,
class NT>
54template <
class IT,
class NT>
56:m(nRow), n(nCol), nnz(
size), splits(0)
64template <
class IT,
class NT>
73 for(
int i=0; i<splits; ++i)
87template <
class IT,
class NT>
89: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(rhs.splits)
93 for(
int i=0; i<splits; ++i)
108template <
class IT,
class NT>
110: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(0)
115 if(transpose) std::swap(m,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)
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)
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;
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)
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)
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>
212 if(csc != NULL && nnz > 0)
235template <
class IT,
class NT>
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]);
265 #pragma omp parallel for
267 for(
int i=0; i< splits; ++i)
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>
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>
344 retcols->nnz = retcols->
csc->nz;
368template <
class IT,
class NT>
372 std::vector<IT> essentials(esscount);
381template <
class IT,
class NT>
385 assert(essentials.size() == esscount);
399template <
class IT,
class NT>
404 std::tuple<IT, IT, NT> *mytuples)
414template <
class IT,
class NT>
438template <
class IT,
class NT>
454template <
class IT,
class NT>
466template <
class IT,
class NT>
478template <
class IT,
class NT>
487 std::cout<<
"Matrix is too small to be splitted" << std::endl;
495 csc->
Split(Acsc, Bcsc, cut);
505template <
class IT,
class NT>
511 assert (partA.m == partB.m);
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);
547template <
class IT,
class NT>
553 outfile <<
"Matrix doesn't have any nonzeros" << std::endl;
558 outfile << tuples << std::endl;
570template <
class IT,
class NT>
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;
622template <
class IT,
class NT>
623inline void SpCCols<IT,NT>::CopyCsc(Csc<IT,NT> * source)
627 csc =
new Csc<IT,NT>(*source);
void Merge(const Csc< IT, NT > *A, const Csc< IT, NT > *B, IT cut)
Csc< IT, NT > * PruneI(UnaryOperation unary_op, bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
void Split(Csc< IT, NT > *&A, Csc< IT, NT > *&B, IT cut)
void CreateImpl(const std::vector< IT > &essentials)
void RowSplit(int numsplits)
void Split(SpCCols< IT, NT > &partA, SpCCols< IT, NT > &partB)
SpCCols< IT, NT > TransposeConst() const
SpCCols< IT, NT > * TransposeConstPtr() const
SpCCols< IT, NT > * PruneI(UnaryOperation unary_op, bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
Arr< IT, NT > GetArrays() const
std::ofstream & put(std::ofstream &outfile) const
SpCCols< IT, NT > & operator=(const SpCCols< IT, NT > &rhs)
void Merge(SpCCols< IT, NT > &partA, SpCCols< IT, NT > &partB)
std::vector< IT > GetEssentials() const
static void deallocate2D(T **array, I m)
std::vector< LocArr< NT, IT > > numarrs
std::vector< LocArr< IT, IT > > indarrs