COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
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
43namespace combblas {
44
45template <class IU, class NU>
46class SpDCCols;
47
48template <class IU, class NU>
49class Dcsc;
50
51template <class IU, class NU>
52class SpCCols;
53
54template <class IU, class NU>
55class Csc;
56
64template <class IT, class NT>
65class SpTuples: public SpMat<IT, NT, SpTuples<IT,NT> >
66{
67public:
68 // Constructors
70 SpTuples (int64_t size, IT nRow, IT nCol, std::tuple<IT, IT, NT> * mytuples, bool sorted = false, bool isOpNew = false);
71 SpTuples (int64_t maxnnz, IT nRow, IT nCol, std::vector<IT> & edges, bool removeloops = true); // Graph500 contructor
72 SpTuples (int64_t size, IT nRow, IT nCol, StackEntry<NT, std::pair<IT,IT> > * & multstack);
73 SpTuples (const SpTuples<IT,NT> & rhs); // Actual Copy constructor
74 SpTuples (const SpDCCols<IT,NT> & rhs); // Copy constructor for conversion from SpDCCols
77
79
80 IT & rowindex (IT i) { return joker::get<0>(tuples[i]); }
81 IT & colindex (IT i) { return joker::get<1>(tuples[i]); }
82 NT & numvalue (IT i) { return joker::get<2>(tuples[i]); }
83
84 IT rowindex (IT i) const { return joker::get<0>(tuples[i]); }
85 IT colindex (IT i) const { return joker::get<1>(tuples[i]); }
86 NT numvalue (IT i) const { return joker::get<2>(tuples[i]); }
87
88
89 template <typename BINFUNC>
91
93 {
96 sort(tuples , tuples+nnz, rowlexicogcmp);
97
98 // Default "operator<" for tuples uses lexicographical ordering
99 // However, cray compiler complains about it, so we use rowlexicogcmp
100 }
101
108
114 {
115 std::vector<bool> existing(n,false); // none of the diagonals exist
116 IT loop = 0;
117 for(IT i=0; i< nnz; ++i)
118 {
119 if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i]))
120 {
121 ++loop;
122 existing[joker::get<0>(tuples[i])] = true;
124 joker::get<2>(tuples[i]) = loopval;
125 }
126 }
127 std::vector<IT> missingindices;
128 for(IT i = 0; i < n; ++i)
129 {
130 if(!existing[i]) missingindices.push_back(i);
131 }
132 IT toadd = n - loop; // number of new entries needed (equals missingindices.size())
133 std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz+toadd];
134
135 std::copy(tuples,tuples+nnz, ntuples);
136
137 // MCL: As for the loop weights that are chosen, experience shows that a neutral value works well. It is possible to choose larger weights,
138 // and this will increase cluster granularity. The effect is secondary however to that of varying the inflation parameter,
139 // and the algorithm is not very sensitive to changes in the loop weights.
140 for(IT i=0; i< toadd; ++i)
141 {
142 ntuples[nnz+i] = std::make_tuple(missingindices[i], missingindices[i], loopval);
143 }
144 if(isOperatorNew)
145 ::operator delete(tuples);
146 else
147 delete [] tuples;
148 tuples = ntuples;
149 isOperatorNew = false;
150 nnz = nnz+toadd;
151
152 return loop;
153 }
154
155
160 IT AddLoops(std::vector<NT> loopvals, bool replaceExisting=false)
161 {
162 // expectation n == loopvals.size())
163
164 std::vector<bool> existing(n,false); // none of the diagonals exist
165 IT loop = 0;
166 for(IT i=0; i< nnz; ++i)
167 {
168 if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i]))
169 {
170 ++loop;
171 existing[joker::get<0>(tuples[i])] = true;
173 joker::get<2>(tuples[i]) = loopvals[joker::get<0>(tuples[i])];
174 }
175 }
176 std::vector<IT> missingindices;
177 for(IT i = 0; i < n; ++i)
178 {
179 if(!existing[i]) missingindices.push_back(i);
180 }
181 IT toadd = n - loop; // number of new entries needed (equals missingindices.size())
182 std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz+toadd];
183
184 std::copy(tuples,tuples+nnz, ntuples);
185
186 for(IT i=0; i< toadd; ++i)
187 {
188 ntuples[nnz+i] = std::make_tuple(missingindices[i], missingindices[i], loopvals[missingindices[i]]);
189 }
190 if(isOperatorNew)
191 ::operator delete(tuples);
192 else
193 delete [] tuples;
194 tuples = ntuples;
195 isOperatorNew = false;
196 nnz = nnz+toadd;
197 return loop;
198 }
199
204 {
205 IT loop = 0;
206 for(IT i=0; i< nnz; ++i)
207 {
208 if(joker::get<0>(tuples[i]) == joker::get<1>(tuples[i])) ++loop;
209 }
210 std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz-loop];
211
212 IT ni = 0;
213 for(IT i=0; i< nnz; ++i)
214 {
215 if(joker::get<0>(tuples[i]) != joker::get<1>(tuples[i]))
216 {
217 ntuples[ni++] = tuples[i];
218 }
219 }
220 if(isOperatorNew)
221 ::operator delete(tuples);
222 else
223 delete [] tuples;
224 tuples = ntuples;
225 isOperatorNew = false;
226 nnz = nnz-loop;
227 return loop;
228 }
229
230 std::pair<IT,IT> RowLimits()
231 {
232 if(nnz > 0)
233 {
235 std::tuple<IT,IT,NT> * maxit = std::max_element(tuples, tuples+nnz, rowcmp);
236 std::tuple<IT,IT,NT> * minit = std::min_element(tuples, tuples+nnz, rowcmp);
237 return std::make_pair(joker::get<0>(*minit), joker::get<0>(*maxit));
238 }
239 else
240 return std::make_pair(0,0);
241 }
242 std::pair<IT,IT> ColLimits()
243 {
244 if(nnz > 0)
245 {
247 std::tuple<IT,IT,NT> * maxit = std::max_element(tuples, tuples+nnz, colcmp);
248 std::tuple<IT,IT,NT> * minit = std::min_element(tuples, tuples+nnz, colcmp);
249 return std::make_pair(joker::get<1>(*minit), joker::get<1>(*maxit));
250 }
251 else
252 return std::make_pair(0,0);
253 }
254 std::tuple<IT, IT, NT> front() { return tuples[0]; };
255 std::tuple<IT, IT, NT> back() { return tuples[nnz-1]; };
256
257 // Performs a balanced merge of the array of SpTuples
258 template<typename SR, typename IU, typename NU>
259 friend SpTuples<IU,NU> MergeAll(const std::vector<SpTuples<IU,NU> *> & ArrSpTups, IU mstar, IU nstar, bool delarrs);
260
261 template<typename SR, typename IU, typename NU>
263
264 std::ofstream& putstream (std::ofstream& outfile) const;
265 std::ofstream& put (std::ofstream& outfile) const
266 { return putstream(outfile); }
267
268 std::ifstream& getstream (std::ifstream& infile);
269 std::ifstream& get (std::ifstream& infile) { return getstream(infile); }
270
271
272 bool isZero() const { return (nnz == 0); }
273 IT getnrow() const { return m; }
274 IT getncol() const { return n; }
275 int64_t getnnz() const { return nnz; }
276
277 void PrintInfo();
278 std::tuple<IT, IT, NT> * tuples;
279 bool tuples_deleted = false; // This is a temporary patch to avoid memory leak in 3d-memory multiplication
280
281private:
282
283 IT m;
284 IT n;
285 int64_t nnz;
286 bool isOperatorNew; // if Operator New was used to allocate memory
287
288 SpTuples (){}; // Default constructor does nothing, hide it
289
290 void FillTuples (Dcsc<IT,NT> * mydcsc);
291
292 template <class IU, class NU>
293 friend class SpDCCols;
294
295 template <class IU, class NU>
296 friend class SpCCols;
297};
298
299
300// At this point, complete type of of SpTuples is known, safe to declare these specialization (but macros won't work as they are preprocessed)
301template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,int> >
302 {
304 };
305template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,float> >
306 {
308 };
309template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,double> >
310 {
312 };
313template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,int> >
314 {
316 };
317template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,bool> >
318 {
320 };
321template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,float> >
322 {
324 };
325template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,int> >
326 {
328 };
329template <> struct promote_trait< SpTuples<int,int> , SpTuples<int,double> >
330 {
332 };
333template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,int> >
334 {
336 };
337template <> struct promote_trait< SpTuples<int,unsigned> , SpTuples<int,bool> >
338 {
340 };
341template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,unsigned> >
342 {
344 };
345template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,double> >
346 {
348 };
349template <> struct promote_trait< SpTuples<int,bool> , SpTuples<int,float> >
350 {
352 };
353template <> struct promote_trait< SpTuples<int,double> , SpTuples<int,bool> >
354 {
356 };
357template <> struct promote_trait< SpTuples<int,float> , SpTuples<int,bool> >
358 {
360 };
361template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,int> >
362 {
364 };
365template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,float> >
366 {
368 };
369template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,double> >
370 {
372 };
374 {
376 };
377template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,int> >
378 {
380 };
381template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,bool> >
382 {
384 };
385template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,float> >
386 {
388 };
389template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,int> >
390 {
392 };
393template <> struct promote_trait< SpTuples<int64_t,int> , SpTuples<int64_t,double> >
394 {
396 };
397template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,int> >
398 {
400 };
401template <> struct promote_trait< SpTuples<int64_t,unsigned> , SpTuples<int64_t,bool> >
402 {
404 };
405template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,unsigned> >
406 {
408 };
409template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,double> >
410 {
412 };
413template <> struct promote_trait< SpTuples<int64_t,bool> , SpTuples<int64_t,float> >
414 {
416 };
417template <> struct promote_trait< SpTuples<int64_t,double> , SpTuples<int64_t,bool> >
418 {
420 };
421template <> struct promote_trait< SpTuples<int64_t,float> , SpTuples<int64_t,bool> >
422 {
424 };
425}
426
427#include "SpTuples.cpp"
428
429#endif
int64_t IT
double NT
static bool is_sorted(_ForwardIterator __first, _ForwardIterator __last)
Definition SpHelper.h:202
IT colindex(IT i) const
Definition SpTuples.h:85
IT getncol() const
Definition SpTuples.h:274
IT & colindex(IT i)
Definition SpTuples.h:81
bool isZero() const
Definition SpTuples.h:272
std::ifstream & get(std::ifstream &infile)
Definition SpTuples.h:269
NT numvalue(IT i) const
Definition SpTuples.h:86
NT & numvalue(IT i)
Definition SpTuples.h:82
std::ofstream & put(std::ofstream &outfile) const
Definition SpTuples.h:265
IT rowindex(IT i) const
Definition SpTuples.h:84
std::tuple< IT, IT, NT > * tuples
Definition SpTuples.h:278
SpTuples(const SpTuples< IT, NT > &rhs)
IT getnrow() const
Definition SpTuples.h:273
SpTuples(const SpDCCols< IT, NT > &rhs)
SpTuples< IT, NT > & operator=(const SpTuples< IT, NT > &rhs)
SpTuples(int64_t size, IT nRow, IT nCol)
IT AddLoops(NT loopval, bool replaceExisting=false)
Definition SpTuples.h:113
SpTuples(int64_t size, IT nRow, IT nCol, StackEntry< NT, std::pair< IT, IT > > *&multstack)
IT & rowindex(IT i)
Definition SpTuples.h:80
friend SpTuples< IU, NU > MergeAll(const std::vector< SpTuples< IU, NU > * > &ArrSpTups, IU mstar, IU nstar, bool delarrs)
Definition Friends.h:660
SpTuples(int64_t maxnnz, IT nRow, IT nCol, std::vector< IT > &edges, bool removeloops=true)
void SortRowBased()
Definition SpTuples.h:92
std::ofstream & putstream(std::ofstream &outfile) const
std::ifstream & getstream(std::ifstream &infile)
IT AddLoops(std::vector< NT > loopvals, bool replaceExisting=false)
Definition SpTuples.h:160
void RemoveDuplicates(BINFUNC BinOp)
SpTuples(int64_t size, IT nRow, IT nCol, std::tuple< IT, IT, NT > *mytuples, bool sorted=false, bool isOpNew=false)
int64_t getnnz() const
Definition SpTuples.h:275
SpTuples(const SpCCols< IT, NT > &rhs)
std::tuple< IT, IT, NT > back()
Definition SpTuples.h:255
std::pair< IT, IT > ColLimits()
Definition SpTuples.h:242
friend SpTuples< IU, NU > * MergeAllRec(const std::vector< SpTuples< IU, NU > * > &ArrSpTups, IU mstar, IU nstar)
std::tuple< IT, IT, NT > front()
Definition SpTuples.h:254
std::pair< IT, IT > RowLimits()
Definition SpTuples.h:230
int size
Definition common.h:20
long int64_t
Definition compat.h:21