COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
TwitterEdge.h
Go to the documentation of this file.
1#ifndef _TWITTER_EDGE_
2#define _TWITTER_EDGE_
3
4#include <iostream>
5#include <ctime>
6#include "CombBLAS/CombBLAS.h"
7
8struct DetSymmetricize;
9
16{
17public:
18 TwitterEdge(): count(0), follower(0), latest(0) {};
19 template <typename X>
20 TwitterEdge(X x):count(0), follower(0), latest(0) {}; // any upcasting constructs the default object too
21
22 TwitterEdge(short mycount, bool myfollow, time_t mylatest):count(mycount), follower(myfollow), latest(mylatest) {};
23 bool isFollower() const { return follower; };
24 bool isRetwitter() const { return (count > 0); };
25 bool TweetWithinInterval (time_t begin, time_t end) const { return ((count > 0) && (begin <= latest && latest <= end)); };
26 bool TweetSince (time_t begin) const { return ((count > 0) && (begin <= latest)); };
27 bool LastTweetBy (time_t end) const { return ((count > 0) && (latest <= end)); };
28
29 operator bool () const { return true; } ; // Type conversion operator (ABAB: Shoots in the foot by implicitly converting many things)
30
32 {
33 std::cout << "Error: TwitterEdge::operator+=() shouldn't be executed" << std::endl;
34 count += rhs.count;
35 follower |= rhs.follower;
36 if(rhs.count > 0) // ensure that addition with additive identity doesn't change "latest"
37 latest = std::max(latest, rhs.latest);
38 return *this;
39 }
40 bool operator ==(const TwitterEdge & b) const
41 {
42 return ((follower == b.follower) && (latest == b.latest) && (count == b.count));
43 }
44
45 friend std::ostream& operator<<( std::ostream& os, const TwitterEdge & twe);
46 friend TwitterEdge operator*( const TwitterEdge & a, const TwitterEdge & b);
47
48private:
49 bool follower; // default constructor sets all to zero
50 time_t latest; // not assigned if no retweets happened
51 short count;
52
53 template <typename IT>
55
56 friend struct DetSymmetricize;
57};
58
59std::ostream& operator<<(std::ostream& os, const TwitterEdge & twe )
60{
61 if( twe.follower == 0 && twe.latest == 0 && twe.count == 0)
62 os << 0;
63 else
64 os << 1;
65 return os;
66};
67
69{
70 // One of the parameters is an upcast from bool (used in Indexing), so return the other one
71 if(a == TwitterEdge()) return b;
72 else return a;
73}
74
75
76template <class IT>
78{
79 public:
81 TwitterEdge getNoNum(IT row, IT col) { return TwitterEdge(); }
82
83 MPI_Datatype getMPIType()
84 {
85 return combblas::MPIType<TwitterEdge>(); // utilize the MPI type cache
86 }
87
88 void binaryfill(FILE * rFile, IT & row, IT & col, TwitterEdge & val)
89 {
90 TwitterInteraction twi;
91 size_t entryLength = fread (&twi,sizeof(TwitterInteraction),1,rFile);
92 row = twi.from - 1 ;
93 col = twi.to - 1;
94 val = TwitterEdge(twi.retweets, twi.follow, twi.twtime);
95 if(entryLength != 1)
96 std::cout << "Not enough bytes read in binaryfill " << std::endl;
97 }
98 size_t entrylength() { return sizeof(TwitterInteraction); }
99
100 template <typename c, typename t>
101 TwitterEdge read(std::basic_istream<c,t>& is, IT row, IT col)
102 {
103 TwitterEdge tw;
104 is >> tw.follower;
105 is >> tw.count;
106 if(tw.count > 0)
107 {
108 std::string date;
109 std::string time;
110 is >> date;
111 is >> time;
112
113 struct tm timeinfo;
114 int year, month, day, hour, min, sec;
115 sscanf (date.c_str(),"%d-%d-%d",&year, &month, &day);
116 sscanf (time.c_str(),"%d:%d:%d",&hour, &min, &sec);
117
118 memset(&timeinfo, 0, sizeof(struct tm));
119 timeinfo.tm_year = year - 1900; // year is "years since 1900"
120 timeinfo.tm_mon = month - 1 ; // month is in range 0...11
121 timeinfo.tm_mday = day; // range 1...31
122 timeinfo.tm_hour = hour; // range 0...23
123 timeinfo.tm_min = min; // range 0...59
124 timeinfo.tm_sec = sec; // range 0.
125 tw.latest = timegm(&timeinfo);
126 if(tw.latest == -1) { std::cout << "Can not parse time date" << std::endl; exit(-1);}
127 }
128 else
129 {
130 tw.latest = 0; // initialized to dummy
131 }
132 //cout << row << " follows " << col << "? : " << tw.follower << " and the retweet count is " << tw.count << endl;
133 return tw;
134 }
135
136
137 template <typename c, typename t>
138 void save(std::basic_ostream<c,t>& os, const TwitterEdge & tw, IT row, IT col) // save is NOT compatible with read
139 {
140 os << row << "\t" << col << "\t";
141 os << tw.follower << "\t";
142 os << tw.count << "\t";
143 os << tw.latest << std::endl;
144 }
145 private:
146 struct TwitterInteraction
147 {
148 int32_t from;
149 int32_t to;
150 bool follow;
151 int16_t retweets;
152 time_t twtime;
153 };
154};
155
156
157struct ParentType
158{
159 ParentType():id(-1) { };
160 ParentType(int64_t myid):id(myid) { };
162 bool operator ==(const ParentType & rhs) const
163 {
164 return (id == rhs.id);
165 }
166 bool operator !=(const ParentType & rhs) const
167 {
168 return (id != rhs.id);
169 }
171 {
172 std::cout << "Adding parent with id: " << rhs.id << " to this one with id " << id << std::endl;
173 return *this;
174 }
175 const ParentType operator++(int) // for iota
176 {
177 ParentType temp(*this); // post-fix requirement
178 ++id;
179 return temp;
180 }
181 friend std::ostream& operator<<(std::ostream& os, const ParentType & twe );
182
183 template <typename IT>
184 friend ParentType operator+( const IT & left, const ParentType & right);
185};
186
187std::ostream& operator<<(std::ostream& os, const ParentType & twe )
188{
189 os << "Parent=" << twe.id;
190 return os;
191};
192
194{
195 return ParentType(index);
196}
197
198template <typename IT>
199ParentType operator+( const IT & left, const ParentType & right)
200{
201 return ParentType(left+right.id);
202}
203
204// forward declaration
205template <typename SR, typename T>
206void select2nd(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype);
207
208
209template <typename SR, typename VECTYPE>
210static VECTYPE filtered_select2nd(const TwitterEdge & arg1, const VECTYPE & arg2, time_t & sincedate)
211{
212 if(sincedate == -1) // uninitialized
213 {
214 struct tm timeinfo;
215 memset(&timeinfo, 0, sizeof(struct tm));
216 int year, month, day, hour, min, sec;
217 year = 2009; month = 7; day = 1;
218 hour = 0; min = 0; sec = 0;
219
220 timeinfo.tm_year = year - 1900; // year is "years since 1900"
221 timeinfo.tm_mon = month - 1 ; // month is in range 0...11
222 timeinfo.tm_mday = day; // range 1...31
223 timeinfo.tm_hour = hour; // range 0...23
224 timeinfo.tm_min = min; // range 0...59
225 timeinfo.tm_sec = sec; // range 0.
226 sincedate = timegm(&timeinfo);
227
228 std::ostringstream outs;
229 outs << "Initializing since date (only once) to " << sincedate << std::endl;
231 }
232
233 if(arg1.isRetwitter() && arg1.LastTweetBy(sincedate)) // T1 is of type edges for BFS
234 {
235 return arg2;
236 }
237 else
238 {
239 SR::returnedSAID(true);
240 return VECTYPE();
241 // return null-type parent id (for BFS) or
242 // double() for MIS - POD objects are zero initilied
243 }
244}
245
246
247
254{
255 static MPI_Op MPI_BFSADD;
256 static ParentType id() { return ParentType(); } // additive identity
257
258 // the default argument means that this function can be used like this:
259 // if (returnedSAID()) {...}
260 // which is how it is called inside CombBLAS routines. That call conveniently clears the flag for us.
261 static bool returnedSAID(bool setFlagTo = false)
262 {
263 static bool flag = false;
264
265 bool temp = flag; // save the current flag value to be returned later. Saves an if statement.
266 flag = setFlagTo; // set/clear the flag.
267 return temp;
268 }
269
270 static ParentType add(const ParentType & arg1, const ParentType & arg2)
271 {
272 return ((arg2 == ParentType()) ? arg1: arg2);
273 }
274
275 static MPI_Op mpi_op()
276 {
277 MPI_Op_create(select2nd<LatestRetwitterBFS,ParentType>, false, &MPI_BFSADD); // \todo {do this once only, by greating a MPI_Op buffer}
278 return MPI_BFSADD;
279 }
280 static time_t sincedate;
281 static ParentType multiply(const TwitterEdge & arg1, const ParentType & arg2)
282 {
283 return filtered_select2nd<LatestRetwitterBFS>(arg1, arg2, sincedate);
284 }
285 static void axpy(TwitterEdge a, const ParentType & x, ParentType & y)
286 {
287 y = add(y, multiply(a, x));
288 }
289};
290
292
293// select2nd for doubles
294template <typename SR, typename T>
295void select2nd(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype)
296{
297 T * pinvec = static_cast<T*>(invec);
298 T * pinoutvec = static_cast<T*>(inoutvec);
299 for (int i = 0; i < *len; i++)
300 {
301 pinoutvec[i] = SR::add(pinvec[i], pinoutvec[i]);
302 }
303}
304
305
307
308struct getfringe: public std::binary_function<ParentType, ParentType, ParentType>
309{
311 {
312 return x;
313 }
314
315};
316
317// x: Parent type (always 1 if exits, sparse)
318// y: degree (dense)
319struct seldegree: public std::binary_function<ParentType, int64_t, int64_t>
320{
322 {
323 return y;
324 }
325
326};
327
328// This is like an "isparentset" with the extra parameter that we don't care
329struct passifthere: public std::binary_function<ParentType, int64_t, bool>
330{
331 bool operator()(ParentType x, const int64_t & y) const
332 {
333 return (x != ParentType());
334 }
335
336};
337
338// DoOp for MIS's EWiseApply
339struct is2ndSmaller: public std::binary_function<double, double, bool>
340{
341 bool operator()(double m, double c) const
342 {
343 return (c < m);
344 }
345};
346
347// BinOp for MIS's EWiseApply
348struct return1_uint8: public std::binary_function<double, double, uint8_t>
349{
350 uint8_t operator() (double t1, double t2)
351 {
352 return (uint8_t) 1;
353 }
354};
355
356
357// x: elements from fringe (sparse), y: elements from parents (dense)
358// return true for edges that are not filtered out, and not previously discovered
359// if the edge was filtered out, then x would be ParentType()
360// if y was already discovered its parent would NOT be ParentType()
361struct keepinfrontier_f: public std::binary_function<ParentType, ParentType, bool>
362{
363 bool operator()(ParentType x, const ParentType & y) const
364 {
365 return ( x != ParentType() && y == ParentType()) ;
366 }
367
368};
369
370struct isparentset: public std::unary_function<ParentType, bool>
371{
372 bool operator()(const ParentType & x) const
373 {
374 return ( x != ParentType() ) ;
375 }
376
377};
378
379// Matrix type: TwitterEdge
380// Vector type: double
382{
383 static double id() { return 0.0; } // additive identity
384
385 // the default argument means that this function can be used like this:
386 // if (returnedSAID()) {...}
387 // which is how it is called inside CombBLAS routines. That call conveniently clears the flag for us.
388 static bool returnedSAID(bool setFlagTo = false)
389 {
390 static bool flag = false;
391
392 bool temp = flag; // save the current flag value to be returned later. Saves an if statement.
393 flag = setFlagTo; // set/clear the flag.
394 return temp;
395 }
396
397 static double add(const double & arg1, const double & arg2)
398 {
399 return std::min(arg1, arg2);
400 }
401
402 static MPI_Op mpi_op()
403 {
404 return MPI_MIN;
405 }
406 static time_t sincedate;
407 static double multiply(const TwitterEdge & arg1, const double & arg2) // filtered select2nd
408 {
409 return filtered_select2nd<LatestRetwitterMIS>(arg1, arg2, sincedate);
410 }
411 static void axpy(TwitterEdge a, const double & x, double & y)
412 {
413 y = add(y, multiply(a, x));
414 }
415};
416
417// Matrix type: TwitterEdge
418// Vector type: double
419struct LatestRetwitterSelect2nd // also used for finding neighbors of the candidate set in MIS
420{
421 static MPI_Op MPI_SEL2NDADD;
422 static double id() { return 0.0; } // additive identity
423
424 // the default argument means that this function can be used like this:
425 // if (returnedSAID()) {...}
426 // which is how it is called inside CombBLAS routines. That call conveniently clears the flag for us.
427 static bool returnedSAID(bool setFlagTo = false)
428 {
429 static bool flag = false;
430
431 bool temp = flag; // save the current flag value to be returned later. Saves an if statement.
432 flag = setFlagTo; // set/clear the flag.
433 return temp;
434 }
435
436 static double add(const double & arg1, const double & arg2)
437 {
438 return arg2;
439 }
440
441 static MPI_Op mpi_op()
442 {
443 MPI_Op_create(select2nd<LatestRetwitterSelect2nd,double>, false, &MPI_SEL2NDADD); // \todo {do this once only, by greating a MPI_Op buffer}
444 return MPI_SEL2NDADD;
445 }
446 static time_t sincedate;
447 static double multiply(const TwitterEdge & arg1, const double & arg2) // filtered select2nd
448 {
449 return filtered_select2nd<LatestRetwitterSelect2nd>(arg1, arg2, sincedate);
450 }
451 static void axpy(TwitterEdge a, const double & x, double & y)
452 {
453 y = add(y, multiply(a, x));
454 }
455};
456
460
461
462
463#endif
int64_t IT
ParentType NumSetter(ParentType &num, int64_t index)
void select2nd(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)
TwitterEdge operator*(const TwitterEdge &a, const TwitterEdge &b)
Definition TwitterEdge.h:68
ParentType operator+(const IT &left, const ParentType &right)
std::ostream & operator<<(std::ostream &os, const TwitterEdge &twe)
Definition TwitterEdge.h:59
bool LastTweetBy(time_t end) const
Definition TwitterEdge.h:27
friend TwitterEdge operator*(const TwitterEdge &a, const TwitterEdge &b)
Definition TwitterEdge.h:68
friend std::ostream & operator<<(std::ostream &os, const TwitterEdge &twe)
Definition TwitterEdge.h:59
bool TweetSince(time_t begin) const
Definition TwitterEdge.h:26
bool TweetWithinInterval(time_t begin, time_t end) const
Definition TwitterEdge.h:25
bool isRetwitter() const
Definition TwitterEdge.h:24
TwitterEdge(X x)
Definition TwitterEdge.h:20
TwitterEdge(short mycount, bool myfollow, time_t mylatest)
Definition TwitterEdge.h:22
bool isFollower() const
Definition TwitterEdge.h:23
TwitterEdge & operator+=(const TwitterEdge &rhs)
Definition TwitterEdge.h:31
bool operator==(const TwitterEdge &b) const
Definition TwitterEdge.h:40
void save(std::basic_ostream< c, t > &os, const TwitterEdge &tw, IT row, IT col)
TwitterEdge read(std::basic_istream< c, t > &is, IT row, IT col)
void binaryfill(FILE *rFile, IT &row, IT &col, TwitterEdge &val)
Definition TwitterEdge.h:88
TwitterEdge getNoNum(IT row, IT col)
Definition TwitterEdge.h:81
MPI_Datatype getMPIType()
Definition TwitterEdge.h:83
static void Print(const std::string &s)
long int64_t
Definition compat.h:21
signed int int32_t
Definition stdint.h:77
static ParentType multiply(const TwitterEdge &arg1, const ParentType &arg2)
static MPI_Op mpi_op()
static MPI_Op MPI_BFSADD
static ParentType id()
static void axpy(TwitterEdge a, const ParentType &x, ParentType &y)
static ParentType add(const ParentType &arg1, const ParentType &arg2)
static time_t sincedate
static bool returnedSAID(bool setFlagTo=false)
static double multiply(const TwitterEdge &arg1, const double &arg2)
static time_t sincedate
static bool returnedSAID(bool setFlagTo=false)
static MPI_Op mpi_op()
static void axpy(TwitterEdge a, const double &x, double &y)
static double add(const double &arg1, const double &arg2)
static double id()
static MPI_Op mpi_op()
static MPI_Op MPI_SEL2NDADD
static void axpy(TwitterEdge a, const double &x, double &y)
static bool returnedSAID(bool setFlagTo=false)
static double add(const double &arg1, const double &arg2)
static double multiply(const TwitterEdge &arg1, const double &arg2)
const ParentType operator++(int)
ParentType(int64_t myid)
friend ParentType operator+(const IT &left, const ParentType &right)
bool operator!=(const ParentType &rhs) const
bool operator==(const ParentType &rhs) const
int64_t id
friend ostream & operator<<(ostream &os, const ParentType &vertex)
ParentType & operator+=(const ParentType &rhs)
ParentType operator()(ParentType x, const ParentType &y) const
bool operator()(double m, double c) const
bool operator()(const ParentType &x) const
bool operator()(ParentType x, const ParentType &y) const
bool operator()(ParentType x, const int64_t &y) const
uint8_t operator()(double t1, double t2)
int64_t operator()(ParentType x, const int64_t &y) const