COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
SpTuples.cpp
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#include "SpTuples.h"
31#include "SpParHelper.h"
32#include <iomanip>
33
34namespace combblas {
35
36template <class IT,class NT>
37SpTuples<IT,NT>::SpTuples(int64_t size, IT nRow, IT nCol)
38:m(nRow), n(nCol), nnz(size)
39{
40 if(nnz > 0)
41 {
42 tuples = new std::tuple<IT, IT, NT>[nnz];
43 }
44 else
45 {
46 tuples = NULL;
47 }
48 isOperatorNew = false;
49}
50
51template <class IT,class NT>
52SpTuples<IT,NT>::SpTuples (int64_t size, IT nRow, IT nCol, std::tuple<IT, IT, NT> * mytuples, bool sorted, bool isOpNew)
53:tuples(mytuples), m(nRow), n(nCol), nnz(size), isOperatorNew(isOpNew)
54{
55 if(!sorted)
56 {
57 SortColBased();
58 }
59
60}
61
69template <class IT, class NT>
70SpTuples<IT,NT>::SpTuples (int64_t maxnnz, IT nRow, IT nCol, std::vector<IT> & edges, bool removeloops):m(nRow), n(nCol)
71{
72 if(maxnnz > 0)
73 {
74 tuples = new std::tuple<IT, IT, NT>[maxnnz];
75 }
76 for(int64_t i=0; i<maxnnz; ++i)
77 {
78 rowindex(i) = edges[2*i+0];
79 colindex(i) = edges[2*i+1];
80 numvalue(i) = (NT) 1;
81 }
82 std::vector<IT>().swap(edges); // free memory for edges
83
84 nnz = maxnnz; // for now (to sort)
85 SortColBased();
86
87 int64_t cnz = 0;
88 int64_t dup = 0; int64_t self = 0;
89 nnz = 0;
90 while(cnz < maxnnz)
91 {
92 int64_t j=cnz+1;
93 while(j < maxnnz && rowindex(cnz) == rowindex(j) && colindex(cnz) == colindex(j))
94 {
95 numvalue(cnz) += numvalue(j);
96 numvalue(j++) = 0; // mark for deletion
97 ++dup;
98 }
99 if(removeloops && rowindex(cnz) == colindex(cnz))
100 {
101 numvalue(cnz) = 0;
102 --nnz;
103 ++self;
104 }
105 ++nnz;
106 cnz = j;
107 }
108
109 std::tuple<IT, IT, NT> * ntuples = new std::tuple<IT,IT,NT>[nnz];
110 int64_t j = 0;
111 for(int64_t i=0; i<maxnnz; ++i)
112 {
113 if(numvalue(i) != 0)
114 {
115 ntuples[j++] = tuples[i];
116 }
117 }
118 assert(j == nnz);
119
120 delete [] tuples;
121 tuples = ntuples;
122 isOperatorNew = false;
123}
124
125
131template <class IT, class NT>
132SpTuples<IT,NT>::SpTuples (int64_t size, IT nRow, IT nCol, StackEntry<NT, std::pair<IT,IT> > * & multstack)
133:m(nRow), n(nCol), nnz(size)
134{
135 isOperatorNew = false;
136 if(nnz > 0)
137 {
138 tuples = new std::tuple<IT, IT, NT>[nnz];
139 }
140 for(int64_t i=0; i<nnz; ++i)
141 {
142 colindex(i) = multstack[i].key.first;
143 rowindex(i) = multstack[i].key.second;
144 numvalue(i) = multstack[i].value;
145 }
146 delete [] multstack;
147}
148
149
150template <class IT,class NT>
151SpTuples<IT,NT>::~SpTuples()
152{
153 if(nnz > 0)
154 {
155 if(isOperatorNew)
156 ::operator delete(tuples);
157 else
158 delete [] tuples;
159 }
160}
161
167template <class IT,class NT>
168SpTuples<IT,NT>::SpTuples(const SpTuples<IT,NT> & rhs): m(rhs.m), n(rhs.n), nnz(rhs.nnz)
169{
170 tuples = new std::tuple<IT, IT, NT>[nnz];
171 isOperatorNew = false;
172 for(IT i=0; i< nnz; ++i)
173 {
174 tuples[i] = rhs.tuples[i];
175 }
176}
177
179template <class IT,class NT>
180SpTuples<IT,NT>::SpTuples (const SpDCCols<IT,NT> & rhs): m(rhs.m), n(rhs.n), nnz(rhs.nnz)
181{
182 if(nnz > 0)
183 {
184 FillTuples(rhs.dcsc);
185 }
186 isOperatorNew = false;
187}
188
189template <class IT,class NT>
190inline void SpTuples<IT,NT>::FillTuples (Dcsc<IT,NT> * mydcsc)
191{
192 tuples = new std::tuple<IT, IT, NT>[nnz];
193 IT k = 0;
194 for(IT i = 0; i< mydcsc->nzc; ++i)
195 {
196 for(IT j = mydcsc->cp[i]; j< mydcsc->cp[i+1]; ++j)
197 {
198 colindex(k) = mydcsc->jc[i];
199 rowindex(k) = mydcsc->ir[j];
200 numvalue(k++) = mydcsc->numx[j];
201 }
202 }
203}
204
205
206// Hint1: The assignment operator (operates on an existing object)
207// Hint2: The assignment operator is the only operator that is not inherited.
208// Make sure that base class data are also updated during assignment
209template <class IT,class NT>
210SpTuples<IT,NT> & SpTuples<IT,NT>::operator=(const SpTuples<IT,NT> & rhs)
211{
212 if(this != &rhs) // "this" pointer stores the address of the class instance
213 {
214 if(nnz > 0)
215 {
216 // make empty
217 if(isOperatorNew)
218 ::operator delete(tuples);
219 else
220 delete [] tuples;
221 }
222 m = rhs.m;
223 n = rhs.n;
224 nnz = rhs.nnz;
225 isOperatorNew = false;
226
227 if(nnz> 0)
228 {
229 tuples = new std::tuple<IT, IT, NT>[nnz];
230 for(IT i=0; i< nnz; ++i)
231 {
232 tuples[i] = rhs.tuples[i];
233 }
234 }
235 }
236 return *this;
237}
238
242template <class IT,class NT>
243template <typename BINFUNC>
244void SpTuples<IT,NT>::RemoveDuplicates(BINFUNC BinOp)
245{
246 if(nnz > 0)
247 {
248 std::vector< std::tuple<IT, IT, NT> > summed;
249 summed.push_back(tuples[0]);
250
251 for(IT i=1; i< nnz; ++i)
252 {
253 if((joker::get<0>(summed.back()) == joker::get<0>(tuples[i])) && (joker::get<1>(summed.back()) == joker::get<1>(tuples[i])))
254 {
255 joker::get<2>(summed.back()) = BinOp(joker::get<2>(summed.back()), joker::get<2>(tuples[i]));
256 }
257 else
258 {
259 summed.push_back(tuples[i]);
260
261 }
262 }
263 if(isOperatorNew)
264 ::operator delete(tuples);
265 else
266 delete [] tuples;
267 tuples = new std::tuple<IT, IT, NT>[summed.size()];
268 isOperatorNew = false;
269 std::copy(summed.begin(), summed.end(), tuples);
270 nnz = summed.size();
271 }
272}
273
274
277template <class IT,class NT>
278std::ifstream& SpTuples<IT,NT>::getstream (std::ifstream& infile)
279{
280 std::cout << "Getting... SpTuples" << std::endl;
281 IT cnz = 0;
282 if (infile.is_open())
283 {
284 while ( (!infile.eof()) && cnz < nnz)
285 {
286 infile >> rowindex(cnz) >> colindex(cnz) >> numvalue(cnz); // row-col-value
287
288 rowindex(cnz) --;
289 colindex(cnz) --;
290
291 if((rowindex(cnz) > m) || (colindex(cnz) > n))
292 {
293 std::cerr << "supplied matrix indices are beyond specified boundaries, aborting..." << std::endl;
294 }
295 ++cnz;
296 }
297 assert(nnz == cnz);
298 }
299 else
300 {
301 std::cerr << "input file is not open!" << std::endl;
302 }
303 return infile;
304}
305
308template <class IT,class NT>
309std::ofstream& SpTuples<IT,NT>::putstream(std::ofstream& outfile) const
310{
311 outfile << m <<"\t"<< n <<"\t"<< nnz<<std::endl;
312 for (IT i = 0; i < nnz; ++i)
313 {
314 outfile << rowindex(i)+1 <<"\t"<< colindex(i)+1 <<"\t"
315 << numvalue(i) << std::endl;
316 }
317 return outfile;
318}
319
320template <class IT,class NT>
321void SpTuples<IT,NT>::PrintInfo()
322{
323 std::cout << "This is a SpTuples class" << std::endl;
324
325 std::cout << "m: " << m ;
326 std::cout << ", n: " << n ;
327 std::cout << ", nnz: "<< nnz << std::endl;
328
329 for(IT i=0; i< nnz; ++i)
330 {
331 if(rowindex(i) < 0 || colindex(i) < 0)
332 {
333 std::cout << "Negative index at " << i << std::endl;
334 return;
335 }
336 else if(rowindex(i) >= m || colindex(i) >= n)
337 {
338 std::cout << "Index " << i << " too big with values (" << rowindex(i) << ","<< colindex(i) << ")" << std::endl;
339 }
340 }
341
342 if(m < 8 && n < 8) // small enough to print
343 {
344 NT ** A = SpHelper::allocate2D<NT>(m,n);
345 for(IT i=0; i< m; ++i)
346 for(IT j=0; j<n; ++j)
347 A[i][j] = 0.0;
348
349 for(IT i=0; i< nnz; ++i)
350 {
351 A[rowindex(i)][colindex(i)] = numvalue(i);
352 }
353 for(IT i=0; i< m; ++i)
354 {
355 for(IT j=0; j<n; ++j)
356 {
357 std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << A[i][j];
358 std::cout << " ";
359 }
360 std::cout << std::endl;
361 }
362 SpHelper::deallocate2D(A,m);
363 }
364}
365
366}
int size
Definition common.h:20
long int64_t
Definition compat.h:21
double A