45 template <
class IT,
class NT>
49 template <
class IT,
class NT>
54 template <
class IT,
class NT>
56 :m(nRow), n(nCol), nnz(size), splits(0)
64 template <
class IT,
class NT>
73 for(
int i=0; i<splits; ++i)
87 template <
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)
108 template <
class IT,
class NT>
110 : m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(0)
115 if(transpose) std::swap(m,n);
124 for(IT i=1; i< rhs.nnz; ++i)
135 for(IT i=0; i<rhs.nnz; ++i)
142 for(IT i=1; i<rhs.nnz; ++i)
147 dcsc->cp[jspos++] = i;
150 dcsc->cp[jspos] = rhs.nnz;
155 for(IT i=1; i<rhs.nnz; ++i)
166 for(IT i=0; i<rhs.nnz; ++i)
173 for(IT i=1; i<rhs.nnz; ++i)
178 dcsc->cp[jspos++] = i;
181 dcsc->cp[jspos] = rhs.nnz;
197 template <
class IT,
class NT>
199 : m(nRow), n(nCol), nnz(nTuples), splits(0)
212 totThreads = omp_get_num_threads();
216 std::vector <IT> tstart(totThreads);
217 std::vector <IT> tend(totThreads);
218 std::vector <IT> tdisp(totThreads+1);
221 IT* temp_jc =
new IT[nTuples];
222 IT* temp_cp =
new IT[nTuples];
230 threadID = omp_get_thread_num();
232 IT start = threadID * (nTuples / totThreads);
233 IT end = (threadID + 1) * (nTuples / totThreads);
234 if(threadID == (totThreads-1)) end = nTuples;
238 temp_jc[start] = std::get<1>(tuples[start]);
239 temp_cp[start] = start;
240 for (IT i = start+1; i < end; ++i)
242 if(std::get<1>(tuples[i]) != temp_jc[curpos] )
244 temp_jc[++curpos] = std::get<1>(tuples[i]);
250 tstart[threadID] = start;
251 if(end>start) tend[threadID] = curpos+1;
252 else tend[threadID] = end;
257 for(
int t=totThreads-1; t>0; --t)
259 if(tend[t] > tstart[t] && tend[t-1] > tstart[t-1])
261 if(temp_jc[tstart[t]] == temp_jc[tend[t-1]-1])
269 for(
int t=0; t<totThreads; ++t)
271 tdisp[t+1] = tdisp[t] + tend[t] - tstart[t];
274 IT localnzc = tdisp[totThreads];
283 threadID = omp_get_thread_num();
285 std::copy(temp_jc + tstart[threadID], temp_jc + tend[threadID],
dcsc->jc + tdisp[threadID]);
286 std::copy(temp_cp + tstart[threadID], temp_cp + tend[threadID],
dcsc->cp + tdisp[threadID]);
288 dcsc->cp[localnzc] = nTuples;
294 #pragma omp parallel for schedule (static) 296 for(IT i=0; i<nTuples; ++i)
298 dcsc->ir[i] = std::get<0>(tuples[i]);
299 dcsc->numx[i] = std::get<2>(tuples[i]);
364 template <
class IT,
class NT>
371 if(
dcsc != NULL && nnz > 0)
393 template <
class IT,
class NT>
400 if(m == rhs.m && n == rhs.n)
413 (*dcsc) += (*(rhs.
dcsc));
419 std::cout<<
"Not addable: " << m <<
"!=" << rhs.m <<
" or " << n <<
"!=" << rhs.n <<std::endl;
424 std::cout<<
"Missing feature (A+A): Use multiply with 2 instead !"<<std::endl;
429 template <
class IT,
class NT>
430 template <
typename _UnaryOperation,
typename GlobalIT>
435 Dcsc<IT,NT>* ret =
dcsc->PruneI (__unary_op, inPlace, rowOffset, colOffset);
452 retcols->nnz = retcols->
dcsc->nz;
467 retcols->
dcsc = NULL;
476 template <
class IT,
class NT>
477 template <
typename _UnaryOperation>
499 retcols->nnz = retcols->
dcsc->nz;
514 retcols->
dcsc = NULL;
525 template <
class IT,
class NT>
526 template <
typename _BinaryOperation>
548 retcols->nnz = retcols->
dcsc->nz;
563 retcols->
dcsc = NULL;
573 template <
class IT,
class NT>
574 template <
typename _BinaryOperation>
579 Dcsc<IT,NT>* ret =
dcsc->PruneColumn (pinds, pvals, __binary_op, inPlace);
596 retcols->nnz = retcols->
dcsc->nz;
611 retcols->
dcsc = NULL;
622 template <
class IT,
class NT>
627 if(m == rhs.m && n == rhs.n)
640 else if (rhs.nnz != 0 && nnz != 0)
642 dcsc->EWiseMult (*(rhs.
dcsc), exclude);
650 std::cout<<
"Matrices do not conform for A .* op(B) !"<<std::endl;
655 std::cout<<
"Missing feature (A .* A): Use Square_EWise() instead !"<<std::endl;
662 template <
class IT,
class NT>
665 if(m == m_scaler && n == n_scaler)
668 dcsc->EWiseScale (scaler);
672 std::cout<<
"Matrices do not conform for EWiseScale !"<<std::endl;
681 template <
class IT,
class NT>
694 template <
class IT,
class NT>
697 assert(essentials.size() ==
esscount);
708 template <
class IT,
class NT>
715 std::pair<IT,IT> rlim = tuples.
RowLimits();
716 std::pair<IT,IT> clim = tuples.
ColLimits();
719 std::stringstream ss;
722 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
725 std::string ofilename =
"Read";
727 oput.open(ofilename.c_str(), std::ios_base::app );
728 oput <<
"Creating of dimensions " << nRow <<
"-by-" << nCol <<
" of size: " << size <<
729 " with row range (" << rlim.first <<
"," << rlim.second <<
") and column range (" << clim.first <<
"," << clim.second <<
")" << std::endl;
732 IT minfr = joker::get<0>(tuples.
front());
733 IT minto = joker::get<1>(tuples.
front());
734 IT maxfr = joker::get<0>(tuples.
back());
735 IT maxto = joker::get<1>(tuples.
back());
737 oput <<
"Min: " << minfr <<
", " << minto <<
"; Max: " << maxfr <<
", " << maxto << std::endl;
747 template <
class IT,
class NT>
750 std::vector<IT> essentials(
esscount);
754 essentials[3] = (nnz > 0) ?
dcsc->nzc : 0;
758 template <
class IT,
class NT>
759 template <
typename NNT>
772 template <
class IT,
class NT>
773 template <
typename NIT,
typename NNT>
786 template <
class IT,
class NT>
814 template <
class IT,
class NT>
837 template <
class IT,
class NT>
851 template <
class IT,
class NT>
866 template <
class IT,
class NT>
872 std::cout<<
"Matrix is too small to be splitted" << std::endl;
881 dcsc->Split(Adcsc, Bdcsc, cut);
896 template <
class IT,
class NT>
901 matrices.emplace_back(*
this);
905 std::vector<IT> cuts(parts-1);
906 for(
int i=0; i< (parts-1); ++i)
908 cuts[i] = (i+1) * (n/parts);
912 std::cout<<
"Matrix is too small to be splitted" << std::endl;
915 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
919 dcsc->ColSplit(dcscs, cuts);
922 for(
int i=0; i< (parts-1); ++i)
925 matrices.emplace_back(matrix);
928 matrices.emplace_back(matrix);
938 template <
class IT,
class NT>
941 std::vector< SpDCCols<IT,NT> * > nonempties;
942 std::vector< Dcsc<IT,NT> * > dcscs;
943 std::vector< IT > offsets;
944 IT runningoffset = 0;
946 for(
size_t i=0; i< matrices.size(); ++i)
948 if(matrices[i].nnz != 0)
950 nonempties.push_back(&(matrices[i]));
951 dcscs.push_back(matrices[i].
dcsc);
952 offsets.push_back(runningoffset);
954 runningoffset += matrices[i].n;
957 if(nonempties.size() < 1)
960 std::cout <<
"Nothing to ColConcatenate" << std::endl;
964 else if(nonempties.size() < 2)
966 *
this = *(nonempties[0]);
977 for(
size_t i=0; i< matrices.size(); ++i)
989 template <
class IT,
class NT>
992 assert( partA.m == partB.m );
996 if(partA.nnz == 0 && partB.nnz == 0)
1000 else if(partA.nnz == 0)
1003 std::transform(Cdcsc->
jc, Cdcsc->
jc + Cdcsc->
nzc, Cdcsc->
jc, std::bind2nd(std::plus<IT>(), partA.n));
1005 else if(partB.nnz == 0)
1025 template <
class IT,
class NT>
1033 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1036 IT kisect =
static_cast<IT
>(itr1-isect1);
1044 IT cnz = SpHelper::SpCartesian< SR > (*(A.
dcsc), *(B.
dcsc), kisect, isect1, isect2, multstack);
1055 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1059 delete [] multstack;
1069 template <
class IT,
class NT>
1070 template <
typename SR>
1078 int cnz = SpHelper::SpColByCol< SR > (*(A.
dcsc), *(B.
dcsc), A.n, multstack);
1088 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1092 delete [] multstack;
1097 template <
class IT,
class NT>
1098 template <
typename SR>
1101 std::cout <<
"PlusEq_AtXBn function has not been implemented yet !" << std::endl;
1105 template <
class IT,
class NT>
1106 template <
typename SR>
1109 std::cout <<
"PlusEq_AtXBt function has not been implemented yet !" << std::endl;
1114 template <
class IT,
class NT>
1117 IT * itr = std::find(
dcsc->jc,
dcsc->jc +
dcsc->nzc, ci);
1120 IT irbeg =
dcsc->cp[itr -
dcsc->jc];
1121 IT irend =
dcsc->cp[itr -
dcsc->jc + 1];
1123 IT * ele = std::find(
dcsc->ir + irbeg,
dcsc->ir + irend, ri);
1124 if(ele !=
dcsc->ir + irend)
1128 *(SingEleMat.
dcsc->ir) = *ele;
1129 *(SingEleMat.
dcsc->jc) = *itr;
1130 (SingEleMat.
dcsc->cp)[0] = 0;
1131 (SingEleMat.
dcsc->cp)[1] = 1;
1149 template <
class IT,
class NT>
1154 IT rsize = ri.size();
1155 IT csize = ci.size();
1157 if(rsize == 0 && csize == 0)
1165 return ColIndex(ci);
1170 return LeftMatrix.OrdColByCol< PT >(*this);
1176 return LeftMatrix.OrdColByCol< PT >( OrdColByCol< PT >(RightMatrix) );
1180 template <
class IT,
class NT>
1185 outfile <<
"Matrix doesn't have any nonzeros" <<std::endl;
1189 outfile << tuples << std::endl;
1194 template <
class IT,
class NT>
1197 std::cout <<
"Getting... SpDCCols" << std::endl;
1199 infile >> m >> n >> nnz;
1210 template<
class IT,
class NT>
1214 out <<
", n: " << n ;
1215 out <<
", nnz: "<< nnz ;
1219 out <<
", local splits: " << splits << std::endl;
1225 out <<
", nzc: "<<
dcsc->nzc << std::endl;
1229 out <<
", nzc: "<< 0 << std::endl;
1234 template<
class IT,
class NT>
1237 std::cout <<
"m: " << m ;
1238 std::cout <<
", n: " << n ;
1239 std::cout <<
", nnz: "<< nnz ;
1243 std::cout <<
", local splits: " << splits << std::endl;
1249 std::cout <<
", nzc: "<<
dcsc->nzc << std::endl;
1253 std::cout <<
", nzc: "<< 0 << std::endl;
1258 NT **
A = SpHelper::allocate2D<NT>(m,n);
1259 for(IT i=0; i< m; ++i)
1260 for(IT j=0; j<n; ++j)
1264 for(IT i=0; i<
dcsc->nzc; ++i)
1266 for(IT j =
dcsc->cp[i]; j<dcsc->cp[i+1]; ++j)
1268 IT colid =
dcsc->jc[i];
1269 IT rowid =
dcsc->ir[j];
1270 A[rowid][colid] =
dcsc->numx[j];
1274 for(IT i=0; i< m; ++i)
1276 for(IT j=0; j<n; ++j)
1278 std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << A[i][j];
1281 std::cout << std::endl;
1294 template <
class IT,
class NT>
1296 :
dcsc(mydcsc), m(nRow), n(nCol), splits(0)
1305 template <
class IT,
class NT>
1307 :m(nRow), n(nCol), nnz(size), splits(0)
1320 template <
class IT,
class NT>
1336 template <
class IT,
class NT>
1339 IT csize = ci.size();
1352 for(IT i=0, j=0; i<
dcsc->nzc && j < csize;)
1354 if((
dcsc->jc)[i] < ci[j])
1358 else if ((
dcsc->jc)[i] > ci[j])
1364 estsize += (
dcsc->cp)[i+1] - (
dcsc->cp)[i];
1376 SubA.
dcsc->cp[0] = 0;
1379 for(IT i=0, j=0; i <
dcsc->nzc && j < csize;)
1381 if((
dcsc->jc)[i] < ci[j])
1385 else if ((
dcsc->jc)[i] > ci[j])
1391 IT columncount = (
dcsc->cp)[i+1] - (
dcsc->cp)[i];
1392 SubA.
dcsc->jc[cnzc++] = j;
1393 SubA.
dcsc->cp[cnzc] = SubA.
dcsc->cp[cnzc-1] + columncount;
1404 template <
class IT,
class NT>
1405 template <
typename SR,
typename NTR>
1416 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1419 IT kisect =
static_cast<IT
>(itr1-isect1);
1426 IT cnz = SpHelper::SpCartesian< SR > (*
dcsc, *(Btrans.
dcsc), kisect, isect1, isect2, multstack);
1433 delete [] multstack;
1439 template <
class IT,
class NT>
1440 template <
typename SR,
typename NTR>
1450 IT cnz = SpHelper::SpColByCol< SR > (*
dcsc, *(rhs.
dcsc), n, multstack);
1456 delete [] multstack;
Dcsc< IT, NT > ** dcscarr
int PlusEq_AtXBn(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
static void SpIntersect(const Dcsc< IT, NT1 > &Adcsc, const Dcsc< IT, NT2 > &Bdcsc, Isect< IT > *&cols, Isect< IT > *&rows, Isect< IT > *&isect1, Isect< IT > *&isect2, Isect< IT > *&itr1, Isect< IT > *&itr2)
SpDCCols< IT, NT > * PruneI(_UnaryOperation __unary_op, bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
void CreateImpl(const std::vector< IT > &essentials)
std::vector< LocArr< NT, IT > > numarrs
std::ofstream & put(std::ofstream &outfile) const
void EWiseScale(NT **scaler, IT m_scaler, IT n_scaler)
std::vector< LocArr< IT, IT > > indarrs
void ColConcatenate(std::vector< SpDCCols< IT, NT > > &matrices)
SpDCCols< IT, NT > * PruneColumn(NT *pvals, _BinaryOperation __binary_op, bool inPlace)
std::vector< IT > GetEssentials() const
int PlusEq_AnXBn(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
void ColSplit(int parts, std::vector< SpDCCols< IT, NT > > &matrices)
void Merge(const Dcsc< IT, NT > *Adcsc, const Dcsc< IT, NT > *B, IT cut)
int PlusEq_AnXBt(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
SpDCCols< IT, NT > TransposeConst() const
Const version, doesn't touch the existing object.
void ColConcatenate(std::vector< Dcsc< IT, NT > * > &parts, std::vector< IT > &offsets)
Arr< IT, NT > GetArrays() const
void Merge(SpDCCols< IT, NT > &partA, SpDCCols< IT, NT > &partB)
std::ifstream & get(std::ifstream &infile)
void EWiseMult(const SpDCCols< IT, NT > &rhs, bool exclude)
SpDCCols< IT, NT > operator()(IT ri, IT ci) const
SpDCCols< IT, NT > * Prune(_UnaryOperation __unary_op, bool inPlace)
std::tuple< IT, IT, NT > back()
std::pair< IT, IT > ColLimits()
IT nzc
number of columns with at least one non-zero in them
SpDCCols< IT, NT > * TransposeConstPtr() const
void Split(SpDCCols< IT, NT > &partA, SpDCCols< IT, NT > &partB)
SpDCCols< IT, NT > & operator+=(const SpDCCols< IT, NT > &rhs)
std::pair< IT, IT > RowLimits()
std::tuple< IT, IT, NT > front()
IT * jc
col indices, size nzc
SpDCCols< IT, NT > & operator=(const SpDCCols< IT, NT > &rhs)
static void deallocate2D(T **array, I m)
void Transpose()
Mutator version, replaces the calling object.
int PlusEq_AtXBt(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)