COMBINATORIAL_BLAS  1.6
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 
8 struct DetSymmetricize;
9 
16 {
17 public:
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 
48 private:
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>
54  friend class TwitterReadSaveHandler;
55 
56  friend struct DetSymmetricize;
57 };
58 
59 std::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 
76 template <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 
157 struct ParentType
158 {
159  ParentType():id(-1) { };
160  ParentType(int64_t myid):id(myid) { };
161  int64_t id;
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 
187 std::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 
198 template <typename IT>
199 ParentType operator+( const IT & left, const ParentType & right)
200 {
201  return ParentType(left+right.id);
202 }
203 
204 // forward declaration
205 template <typename SR, typename T>
206 void select2nd(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype);
207 
208 
209 template <typename SR, typename VECTYPE>
210 static 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;
230  combblas::SpParHelper::Print(outs.str());
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
294 template <typename SR, typename T>
295 void 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 
308 struct 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)
319 struct seldegree: public std::binary_function<ParentType, int64_t, int64_t>
320 {
321  int64_t operator()(ParentType x, const int64_t & y) const
322  {
323  return y;
324  }
325 
326 };
327 
328 // This is like an "isparentset" with the extra parameter that we don't care
329 struct 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
339 struct 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
348 struct 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()
361 struct 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 
370 struct 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
419 struct 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
TwitterEdge & operator+=(const TwitterEdge &rhs)
Definition: TwitterEdge.h:31
bool TweetSince(time_t begin) const
Definition: TwitterEdge.h:26
static ParentType multiply(const TwitterEdge &arg1, const ParentType &arg2)
Definition: TwitterEdge.h:281
ParentType operator()(ParentType x, const ParentType &y) const
Definition: TwitterEdge.h:310
static time_t sincedate
Definition: TwitterEdge.h:446
ParentType NumSetter(ParentType &num, int64_t index)
Definition: TwitterEdge.h:193
static MPI_Op mpi_op()
Definition: TwitterEdge.h:402
bool isRetwitter() const
Definition: TwitterEdge.h:24
static MPI_Op mpi_op()
Definition: TwitterEdge.h:441
MPI_Datatype getMPIType()
Definition: TwitterEdge.h:83
void select2nd(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)
Definition: TwitterEdge.h:295
bool operator==(const TwitterEdge &b) const
Definition: TwitterEdge.h:40
bool operator()(ParentType x, const int64_t &y) const
Definition: TwitterEdge.h:331
bool operator()(ParentType x, const ParentType &y) const
Definition: TwitterEdge.h:363
static ParentType add(const ParentType &arg1, const ParentType &arg2)
Definition: TwitterEdge.h:270
ParentType operator+(const IT &left, const ParentType &right)
Definition: TwitterEdge.h:199
static double multiply(const TwitterEdge &arg1, const double &arg2)
Definition: TwitterEdge.h:447
static double add(const double &arg1, const double &arg2)
Definition: TwitterEdge.h:436
static MPI_Op mpi_op()
Definition: TwitterEdge.h:275
static bool returnedSAID(bool setFlagTo=false)
Definition: TwitterEdge.h:427
bool operator()(const ParentType &x) const
Definition: TwitterEdge.h:372
void binaryfill(FILE *rFile, IT &row, IT &col, TwitterEdge &val)
Definition: TwitterEdge.h:88
TwitterEdge(X x)
Definition: TwitterEdge.h:20
void save(std::basic_ostream< c, t > &os, const TwitterEdge &tw, IT row, IT col)
Definition: TwitterEdge.h:138
static bool returnedSAID(bool setFlagTo=false)
Definition: TwitterEdge.h:388
TwitterEdge(short mycount, bool myfollow, time_t mylatest)
Definition: TwitterEdge.h:22
static void Print(const std::string &s)
TwitterEdge getNoNum(IT row, IT col)
Definition: TwitterEdge.h:81
static void axpy(TwitterEdge a, const ParentType &x, ParentType &y)
Definition: TwitterEdge.h:285
const ParentType operator++(int)
Definition: TwitterEdge.h:175
long int64_t
Definition: compat.h:21
bool TweetWithinInterval(time_t begin, time_t end) const
Definition: TwitterEdge.h:25
bool operator()(double m, double c) const
Definition: TwitterEdge.h:341
static double multiply(const TwitterEdge &arg1, const double &arg2)
Definition: TwitterEdge.h:407
static void axpy(TwitterEdge a, const double &x, double &y)
Definition: TwitterEdge.h:411
friend std::ostream & operator<<(std::ostream &os, const TwitterEdge &twe)
Definition: TwitterEdge.h:59
static bool returnedSAID(bool setFlagTo=false)
Definition: TwitterEdge.h:261
static double add(const double &arg1, const double &arg2)
Definition: TwitterEdge.h:397
bool LastTweetBy(time_t end) const
Definition: TwitterEdge.h:27
static MPI_Op MPI_SEL2NDADD
Definition: TwitterEdge.h:421
int64_t id
Definition: TwitterEdge.h:160
static time_t sincedate
Definition: TwitterEdge.h:280
static double id()
Definition: TwitterEdge.h:383
ParentType(int64_t myid)
Definition: TwitterEdge.h:160
static double id()
Definition: TwitterEdge.h:422
int64_t operator()(ParentType x, const int64_t &y) const
Definition: TwitterEdge.h:321
static void axpy(TwitterEdge a, const double &x, double &y)
Definition: TwitterEdge.h:451
TwitterEdge read(std::basic_istream< c, t > &is, IT row, IT col)
Definition: TwitterEdge.h:101
SpDCCols< IT, NT > * multiply(SpDCCols< IT, NT > &splitA, SpDCCols< IT, NT > &splitB, CCGrid &CMG, bool isBT, bool threaded)
Definition: Multiplier.h:11
ParentType & operator+=(const ParentType &rhs)
Definition: TwitterEdge.h:170
friend TwitterEdge operator*(const TwitterEdge &a, const TwitterEdge &b)
Definition: TwitterEdge.h:68
static ParentType id()
Definition: TwitterEdge.h:256
static MPI_Op MPI_BFSADD
Definition: TwitterEdge.h:255
static time_t sincedate
Definition: TwitterEdge.h:406
bool isFollower() const
Definition: TwitterEdge.h:23