COMBINATORIAL_BLAS  1.6
SpTuples.h
Go to the documentation of this file.
1 /****************************************************************/
2 /* Parallel Combinatorial BLAS Library (for Graph Computations) */
3 /* version 1.6 -------------------------------------------------*/
4 /* date: 6/15/2017 ---------------------------------------------*/
5 /* authors: Ariful Azad, Aydin Buluc --------------------------*/
6 /****************************************************************/
7 /*
8  Copyright (c) 2010-2017, The Regents of the University of California
9 
10  Permission is hereby granted, free of charge, to any person obtaining a copy
11  of this software and associated documentation files (the "Software"), to deal
12  in the Software without restriction, including without limitation the rights
13  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  copies of the Software, and to permit persons to whom the Software is
15  furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included in
18  all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  THE SOFTWARE.
27  */
28 
29 
30 #ifndef _SP_TUPLES_H
31 #define _SP_TUPLES_H
32 
33 #include <iostream>
34 #include <fstream>
35 #include <cmath>
36 #include <cassert>
37 #include "CombBLAS.h"
38 #include "SpMat.h"
39 #include "SpDefs.h"
40 #include "StackEntry.h"
41 #include "Compare.h"
42 
43 namespace combblas {
44 
45 template <class IU, class NU>
46 class SpDCCols;
47 
48 template <class IU, class NU>
49 class Dcsc;
50 
51 
59 template <class IT, class NT>
60 class SpTuples: public SpMat<IT, NT, SpTuples<IT,NT> >
61 {
62 public:
63  // Constructors
64  SpTuples (int64_t size, IT nRow, IT nCol);
65  SpTuples (int64_t size, IT nRow, IT nCol, std::tuple<IT, IT, NT> * mytuples, bool sorted = false, bool isOpNew = false);
66  SpTuples (int64_t maxnnz, IT nRow, IT nCol, std::vector<IT> & edges, bool removeloops = true); // Graph500 contructor
67  SpTuples (int64_t size, IT nRow, IT nCol, StackEntry<NT, std::pair<IT,IT> > * & multstack);
68  SpTuples (const SpTuples<IT,NT> & rhs); // Actual Copy constructor
69  SpTuples (const SpDCCols<IT,NT> & rhs); // Copy constructor for conversion from SpDCCols
70  ~SpTuples();
71 
72  SpTuples<IT,NT> & operator=(const SpTuples<IT,NT> & rhs);
73 
74  IT & rowindex (IT i) { return joker::get<0>(tuples[i]); }
75  IT & colindex (IT i) { return joker::get<1>(tuples[i]); }
76  NT & numvalue (IT i) { return joker::get<2>(tuples[i]); }
77 
78  IT rowindex (IT i) const { return joker::get<0>(tuples[i]); }
79  IT colindex (IT i) const { return joker::get<1>(tuples[i]); }
80  NT numvalue (IT i) const { return joker::get<2>(tuples[i]); }
81 
82 
83  template <typename BINFUNC>
84  void RemoveDuplicates(BINFUNC BinOp);
85 
86  void SortRowBased()
87  {
88  RowLexiCompare<IT,NT> rowlexicogcmp;
89  if(!SpHelper::is_sorted(tuples, tuples+nnz, rowlexicogcmp))
90  sort(tuples , tuples+nnz, rowlexicogcmp);
91 
92  // Default "operator<" for tuples uses lexicographical ordering
93  // However, cray compiler complains about it, so we use rowlexicogcmp
94  }
95 
96  void SortColBased()
97  {
98  ColLexiCompare<IT,NT> collexicogcmp;
99  if(!SpHelper::is_sorted(tuples, tuples+nnz, collexicogcmp))
100  sort(tuples , tuples+nnz, collexicogcmp );
101  }
102 
107  IT AddLoops(NT loopval, bool replaceExisting=false)
108  {
109  std::vector<bool> existing(n,false); // none of the diagonals exist
110  IT loop = 0;
111  for(IT i=0; i< nnz; ++i)
112  {
113  if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i]))
114  {
115  ++loop;
116  existing[joker::get<0>(tuples[i])] = true;
117  if(replaceExisting)
118  joker::get<2>(tuples[i]) = loopval;
119  }
120  }
121  std::vector<IT> missingindices;
122  for(IT i = 0; i < n; ++i)
123  {
124  if(!existing[i]) missingindices.push_back(i);
125  }
126  IT toadd = n - loop; // number of new entries needed (equals missingindices.size())
127  std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz+toadd];
128 
129  std::copy(tuples,tuples+nnz, ntuples);
130 
131  // MCL: As for the loop weights that are chosen, experience shows that a neutral value works well. It is possible to choose larger weights,
132  // and this will increase cluster granularity. The effect is secondary however to that of varying the inflation parameter,
133  // and the algorithm is not very sensitive to changes in the loop weights.
134  for(IT i=0; i< toadd; ++i)
135  {
136  ntuples[nnz+i] = std::make_tuple(missingindices[i], missingindices[i], loopval);
137  }
138  if(isOperatorNew)
139  ::operator delete(tuples);
140  else
141  delete [] tuples;
142  tuples = ntuples;
143  isOperatorNew = false;
144  nnz = nnz+toadd;
145 
146  return loop;
147  }
148 
149 
154  IT AddLoops(std::vector<NT> loopvals, bool replaceExisting=false)
155  {
156  // expectation n == loopvals.size())
157 
158  std::vector<bool> existing(n,false); // none of the diagonals exist
159  IT loop = 0;
160  for(IT i=0; i< nnz; ++i)
161  {
162  if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i]))
163  {
164  ++loop;
165  existing[joker::get<0>(tuples[i])] = true;
166  if(replaceExisting)
167  joker::get<2>(tuples[i]) = loopvals[joker::get<0>(tuples[i])];
168  }
169  }
170  std::vector<IT> missingindices;
171  for(IT i = 0; i < n; ++i)
172  {
173  if(!existing[i]) missingindices.push_back(i);
174  }
175  IT toadd = n - loop; // number of new entries needed (equals missingindices.size())
176  std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz+toadd];
177 
178  std::copy(tuples,tuples+nnz, ntuples);
179 
180  for(IT i=0; i< toadd; ++i)
181  {
182  ntuples[nnz+i] = std::make_tuple(missingindices[i], missingindices[i], loopvals[missingindices[i]]);
183  }
184  if(isOperatorNew)
185  ::operator delete(tuples);
186  else
187  delete [] tuples;
188  tuples = ntuples;
189  isOperatorNew = false;
190  nnz = nnz+toadd;
191  return loop;
192  }
193 
198  {
199  IT loop = 0;
200  for(IT i=0; i< nnz; ++i)
201  {
202  if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i])) ++loop;
203  }
204  std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz-loop];
205 
206  IT ni = 0;
207  for(IT i=0; i< nnz; ++i)
208  {
209  if(joker::get<0>(tuples[i]) != joker::get<1>(tuples[i]))
210  {
211  ntuples[ni++] = tuples[i];
212  }
213  }
214  if(isOperatorNew)
215  ::operator delete(tuples);
216  else
217  delete [] tuples;
218  tuples = ntuples;
219  isOperatorNew = false;
220  nnz = nnz-loop;
221  return loop;
222  }
223 
224  std::pair<IT,IT> RowLimits()
225  {
226  if(nnz > 0)
227  {
228  RowCompare<IT,NT> rowcmp;
229  std::tuple<IT,IT,NT> * maxit = std::max_element(tuples, tuples+nnz, rowcmp);
230  std::tuple<IT,IT,NT> * minit = std::min_element(tuples, tuples+nnz, rowcmp);
231  return std::make_pair(joker::get<0>(*minit), joker::get<0>(*maxit));
232  }
233  else
234  return std::make_pair(0,0);
235  }
236  std::pair<IT,IT> ColLimits()
237  {
238  if(nnz > 0)
239  {
240  ColCompare<IT,NT> colcmp;
241  std::tuple<IT,IT,NT> * maxit = std::max_element(tuples, tuples+nnz, colcmp);
242  std::tuple<IT,IT,NT> * minit = std::min_element(tuples, tuples+nnz, colcmp);
243  return std::make_pair(joker::get<1>(*minit), joker::get<1>(*maxit));
244  }
245  else
246  return std::make_pair(0,0);
247  }
248  std::tuple<IT, IT, NT> front() { return tuples[0]; };
249  std::tuple<IT, IT, NT> back() { return tuples[nnz-1]; };
250 
251  // Performs a balanced merge of the array of SpTuples
252  template<typename SR, typename IU, typename NU>
253  friend SpTuples<IU,NU> MergeAll(const std::vector<SpTuples<IU,NU> *> & ArrSpTups, IU mstar, IU nstar, bool delarrs);
254 
255  template<typename SR, typename IU, typename NU>
256  friend SpTuples<IU,NU> * MergeAllRec(const std::vector<SpTuples<IU,NU> *> & ArrSpTups, IU mstar, IU nstar);
257 
258  std::ofstream& putstream (std::ofstream& outfile) const;
259  std::ofstream& put (std::ofstream& outfile) const
260  { return putstream(outfile); }
261 
262  std::ifstream& getstream (std::ifstream& infile);
263  std::ifstream& get (std::ifstream& infile) { return getstream(infile); }
264 
265 
266  bool isZero() const { return (nnz == 0); }
267  IT getnrow() const { return m; }
268  IT getncol() const { return n; }
269  int64_t getnnz() const { return nnz; }
270 
271  void PrintInfo();
272  std::tuple<IT, IT, NT> * tuples;
273 
274 private:
275 
276  IT m;
277  IT n;
278  int64_t nnz;
279  bool isOperatorNew; // if Operator New was used to allocate memory
280 
281  SpTuples (){}; // Default constructor does nothing, hide it
282 
283  void FillTuples (Dcsc<IT,NT> * mydcsc);
284 
285  template <class IU, class NU>
286  friend class SpDCCols;
287 
288  template <class IU, class NU>
289  friend class SpCCols;
290 };
291 
292 
293 // At this point, complete type of of SpTuples is known, safe to declare these specialization (but macros won't work as they are preprocessed)
294 template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,int> >
295  {
297  };
298 template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,float> >
299  {
301  };
302 template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,double> >
303  {
305  };
306 template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,int> >
307  {
309  };
310 template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,bool> >
311  {
313  };
314 template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,float> >
315  {
317  };
318 template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,int> >
319  {
321  };
322 template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,double> >
323  {
325  };
326 template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,int> >
327  {
329  };
330 template <> struct promote_trait< SpTuples<int,unsigned> , SpTuples<int,bool> >
331  {
333  };
334 template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,unsigned> >
335  {
337  };
338 template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,double> >
339  {
341  };
342 template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,float> >
343  {
345  };
346 template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,bool> >
347  {
349  };
350 template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,bool> >
351  {
353  };
354 template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,int> >
355  {
357  };
358 template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,float> >
359  {
361  };
362 template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,double> >
363  {
365  };
367  {
369  };
370 template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,int> >
371  {
373  };
374 template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,bool> >
375  {
377  };
378 template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,float> >
379  {
381  };
382 template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,int> >
383  {
385  };
386 template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,double> >
387  {
389  };
390 template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,int> >
391  {
393  };
394 template <> struct promote_trait< SpTuples<int64_t,unsigned> , SpTuples<int64_t,bool> >
395  {
397  };
398 template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,unsigned> >
399  {
401  };
402 template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,double> >
403  {
405  };
406 template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,float> >
407  {
409  };
410 template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,bool> >
411  {
413  };
414 template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,bool> >
415  {
417  };
418 }
419 
420 #include "SpTuples.cpp"
421 
422 #endif
NT numvalue(IT i) const
Definition: SpTuples.h:80
std::tuple< IT, IT, NT > * tuples
Definition: SpTuples.h:272
bool isZero() const
Definition: SpTuples.h:266
static bool is_sorted(_ForwardIterator __first, _ForwardIterator __last)
Definition: SpHelper.h:202
friend SpTuples< IU, NU > MergeAll(const std::vector< SpTuples< IU, NU > *> &ArrSpTups, IU mstar, IU nstar, bool delarrs)
Definition: Friends.h:605
int size
IT AddLoops(NT loopval, bool replaceExisting=false)
Definition: SpTuples.h:107
void SortRowBased()
Definition: SpTuples.h:86
IT rowindex(IT i) const
Definition: SpTuples.h:78
IT & colindex(IT i)
Definition: SpTuples.h:75
void RemoveDuplicates(BINFUNC BinOp)
Definition: SpTuples.cpp:244
NT & numvalue(IT i)
Definition: SpTuples.h:76
IT AddLoops(std::vector< NT > loopvals, bool replaceExisting=false)
Definition: SpTuples.h:154
int64_t getnnz() const
Definition: SpTuples.h:269
long int64_t
Definition: compat.h:21
IT getnrow() const
Definition: SpTuples.h:267
std::tuple< IT, IT, NT > back()
Definition: SpTuples.h:249
friend SpTuples< IU, NU > * MergeAllRec(const std::vector< SpTuples< IU, NU > *> &ArrSpTups, IU mstar, IU nstar)
IT colindex(IT i) const
Definition: SpTuples.h:79
std::pair< IT, IT > ColLimits()
Definition: SpTuples.h:236
IT & rowindex(IT i)
Definition: SpTuples.h:74
IT getncol() const
Definition: SpTuples.h:268
SpTuples(int64_t size, IT nRow, IT nCol)
Definition: SpTuples.cpp:37
Definition: CCGrid.h:4
void SortColBased()
Definition: SpTuples.h:96
std::pair< IT, IT > RowLimits()
Definition: SpTuples.h:224
std::ofstream & putstream(std::ofstream &outfile) const
Definition: SpTuples.cpp:309
std::tuple< IT, IT, NT > front()
Definition: SpTuples.h:248
std::ifstream & getstream(std::ifstream &infile)
Definition: SpTuples.cpp:278
std::ofstream & put(std::ofstream &outfile) const
Definition: SpTuples.h:259
SpTuples< IT, NT > & operator=(const SpTuples< IT, NT > &rhs)
Definition: SpTuples.cpp:210