Skip to content

Commit ff324b5

Browse files
committed
🦨 update src
1 parent 909dfa8 commit ff324b5

17 files changed

+1351
-325
lines changed

main.cu

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <string>
2+
#include <vector>
13
#include <cstdio>
24
#include <iostream>
35
#include <algorithm>
@@ -8,21 +10,22 @@ using namespace std;
810

911

1012

11-
#define REPEAT 5
13+
#define TYPE float
14+
1215

1316
template <class G, class H>
14-
void runPagerank(const G& x, const H& xt, bool show) {
15-
vector<float> *init = nullptr;
17+
void runPagerank(const G& x, const H& xt, int repeat) {
18+
vector<TYPE> *init = nullptr;
1619

1720
// Find pagerank using a single thread.
18-
auto a1 = pagerankNvgraph(xt, init, {REPEAT});
21+
auto a1 = pagerankNvgraph(xt, init, {repeat});
1922
auto e1 = l1Norm(a1.ranks, a1.ranks);
2023
printf("[%09.3f ms; %03d iters.] [%.4e err.] pagerankNvgraph\n", a1.time, a1.iterations, e1);
2124

22-
// Find pagerank using CUDA thread-per-vertex.
25+
// Find pagerank using CUDA switched-per-vertex.
2326
for (int degree=2; degree<=BLOCK_LIMIT; degree*=2) {
2427
for (int limit=1; limit<=BLOCK_LIMIT; limit*=2) {
25-
auto a2 = pagerankCuda(xt, init, {REPEAT, degree, limit});
28+
auto a2 = pagerankCuda(xt, init, {repeat, degree, limit});
2629
auto e2 = l1Norm(a2.ranks, a1.ranks);
2730
printf("[%09.3f ms; %03d iters.] [%.4e err.] pagerankCuda [degree=%d; limit=%d]\n", a2.time, a2.iterations, e2, degree, limit);
2831
}
@@ -32,11 +35,11 @@ void runPagerank(const G& x, const H& xt, bool show) {
3235

3336
int main(int argc, char **argv) {
3437
char *file = argv[1];
35-
bool show = argc > 2;
38+
int repeat = argc>2? stoi(argv[2]) : 5;
3639
printf("Loading graph %s ...\n", file);
3740
auto x = readMtx(file); println(x);
3841
auto xt = transposeWithDegree(x); print(xt); printf(" (transposeWithDegree)\n");
39-
runPagerank(x, xt, show);
42+
runPagerank(x, xt, repeat);
4043
printf("\n");
4144
return 0;
4245
}

src/DiGraph.hxx

+15-16
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ class DiGraph {
2121
using TEdge = E;
2222

2323
private:
24-
vector<int> none;
25-
vector<bool> vex;
26-
vector<vector<int>> vto;
27-
vector<vector<E>> edata;
28-
vector<V> vdata;
24+
vector<int> none;
25+
vector<bool> vex;
26+
vector2d<int> vto;
27+
vector2d<E> edata;
28+
vector<V> vdata;
2929
int N = 0, M = 0;
3030

3131
// Cute helpers
3232
private:
3333
int s() const { return vto.size(); }
34-
int ei(int u, int v) const { return findIndex(vto[u], v); }
34+
int ei(int u, int v) const { return findEqIndex(vto[u], v); }
3535

3636
// Read operations
3737
public:
@@ -41,12 +41,12 @@ class DiGraph {
4141

4242
bool hasVertex(int u) const { return u < s() && vex[u]; }
4343
bool hasEdge(int u, int v) const { return u < s() && ei(u, v) >= 0; }
44-
auto edges(int u) const { return u < s()? iterable(vto[u]) : iterable(none); }
44+
auto edges(int u) const { return u < s()? makeIter(vto[u]) : makeIter(none); }
4545
int degree(int u) const { return u < s()? vto[u].size() : 0; }
46-
auto vertices() const { return filter(range(s()), [&](int u) { return vex[u]; }); }
47-
auto nonVertices() const { return filter(range(s()), [&](int u) { return !vex[u]; }); }
48-
auto inEdges(int v) const { return filter(range(s()), [&](int u) { return ei(u, v) >= 0; }); }
49-
int inDegree(int v) const { return countIf(range(s()), [&](int u) { return ei(u, v) >= 0; }); }
46+
auto vertices() const { return filterIter(rangeIter(s()), [&](int u) { return vex[u]; }); }
47+
auto nonVertices() const { return filterIter(rangeIter(s()), [&](int u) { return !vex[u]; }); }
48+
auto inEdges(int v) const { return filterIter(rangeIter(s()), [&](int u) { return ei(u, v) >= 0; }); }
49+
int inDegree(int v) const { return countIf(rangeIter(s()), [&](int u) { return ei(u, v) >= 0; }); }
5050

5151
V vertexData(int u) const { return hasVertex(u)? vdata[u] : V(); }
5252
void setVertexData(int u, V d) { if (hasVertex(u)) vdata[u] = d; }
@@ -113,7 +113,6 @@ class DiGraph {
113113
// DI-GRAPH PRINT
114114
// --------------
115115

116-
117116
template <class V, class E>
118117
void write(ostream& a, const DiGraph<V, E>& x, bool all=false) {
119118
a << "order: " << x.order() << " size: " << x.size();
@@ -129,7 +128,7 @@ void write(ostream& a, const DiGraph<V, E>& x, bool all=false) {
129128
}
130129

131130
template <class V, class E>
132-
void print(const DiGraph<V, E>& x, bool all=false) { write(cout, x, all); }
133-
134-
template <class V, class E>
135-
void println(const DiGraph<V, E>& x, bool all=false) { print(x, all); cout << "\n"; }
131+
ostream& operator<<(ostream& a, const DiGraph<V, E>& x) {
132+
write(a, x);
133+
return a;
134+
}

src/_algorithm.hxx

+231-7
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,55 @@
33
#include <unordered_map>
44
#include <iterator>
55
#include <algorithm>
6+
#include <functional>
67

78
using std::vector;
89
using std::unordered_map;
910
using std::iterator_traits;
10-
using std::back_inserter;
11-
using std::set_difference;
11+
using std::hash;
12+
using std::for_each;
13+
using std::any_of;
14+
using std::all_of;
15+
using std::find;
16+
using std::find_if;
17+
using std::lower_bound;
1218
using std::count;
1319
using std::count_if;
14-
using std::find;
20+
using std::transform;
21+
using std::set_difference;
22+
using std::back_inserter;
23+
24+
25+
26+
27+
// ANY-OF
28+
// ------
29+
30+
template <class I, class F>
31+
auto anyOf(I ib, I ie, F fn) {
32+
return any_of(ib, ie, fn);
33+
}
34+
35+
template <class J, class F>
36+
auto anyOf(const J& x, F fn) {
37+
return any_of(x.begin(), x.end(), fn);
38+
}
39+
40+
41+
42+
43+
// ALL-OF
44+
// ------
45+
46+
template <class I, class F>
47+
auto allOf(I ib, I ie, F fn) {
48+
return all_of(ib, ie, fn);
49+
}
50+
51+
template <class J, class F>
52+
auto allOf(const J& x, F fn) {
53+
return all_of(x.begin(), x.end(), fn);
54+
}
1555

1656

1757

@@ -26,15 +66,86 @@ auto find(const J& x, const T& v) {
2666

2767
template <class J, class T>
2868
int findIndex(const J& x, const T& v) {
29-
auto i = find(x.begin(), x.end(), v);
30-
return i==x.end()? -1 : i-x.begin();
69+
return find(x.begin(), x.end(), v) - x.begin();
3170
}
3271

72+
template <class J, class T>
73+
int findEqIndex(const J& x, const T& v) {
74+
auto it = find(x.begin(), x.end(), v);
75+
return it==x.end()? -1 : it-x.begin();
76+
}
3377

3478

79+
template <class I, class F>
80+
auto findIf(I ib, I ie, F fn) {
81+
return find_if(ib, ie, fn);
82+
}
3583

36-
// COUNT-*
37-
// -------
84+
template <class J, class F>
85+
auto findIf(const J& x, F fn) {
86+
return find_if(x.begin(), x.end(), fn);
87+
}
88+
89+
template <class J, class F>
90+
int findIfIndex(const J& x, F fn) {
91+
return find_if(x.begin(), x.end(), fn) - x.begin();
92+
}
93+
94+
template <class J, class F>
95+
int findIfEqIndex(const J& x, F fn) {
96+
auto it = find_if(x.begin(), x.end(), fn);
97+
return it==x.end()? -1 : it-x.begin();
98+
}
99+
100+
101+
102+
103+
// LOWER-BOUND
104+
// -----------
105+
106+
template <class J, class T>
107+
auto lowerBound(const J& x, const T& v) {
108+
return lower_bound(x.begin(), x.end(), v);
109+
}
110+
111+
template <class J, class T, class F>
112+
auto lowerBound(const J& x, const T& v, F fl) {
113+
return lower_bound(x.begin(), x.end(), v, fl);
114+
}
115+
116+
template <class J, class T>
117+
int lowerBoundIndex(const J& x, const T& v) {
118+
return lower_bound(x.begin(), x.end(), v) - x.begin();
119+
}
120+
121+
template <class J, class T, class F>
122+
int lowerBoundIndex(const J& x, const T& v, F fl) {
123+
return lower_bound(x.begin(), x.end(), v, fl) - x.begin();
124+
}
125+
126+
template <class J, class T>
127+
int lowerBoundEqIndex(const J& x, const T& v) {
128+
auto it = lower_bound(x.begin(), x.end(), v);
129+
return it==x.end() || *it!=v? -1 : it-x.begin();
130+
}
131+
132+
template <class J, class T, class F>
133+
int lowerBoundEqIndex(const J& x, const T& v, F fl) {
134+
auto it = lower_bound(x.begin(), x.end(), v, fl);
135+
return it==x.end() || *it!=v? -1 : it-x.begin();
136+
}
137+
138+
template <class J, class T, class F, class G>
139+
int lowerBoundEqIndex(const J& x, const T& v, F fl, G fe) {
140+
auto it = lower_bound(x.begin(), x.end(), v, fl);
141+
return it==x.end() || !fe(*it, v)? -1 : it-x.begin();
142+
}
143+
144+
145+
146+
147+
// COUNT
148+
// -----
38149

39150
template <class J, class T>
40151
int count(const J& x, const T& v) {
@@ -55,6 +166,25 @@ int countIf(const J& x, F fn) {
55166

56167

57168

169+
// COUNT-ALL
170+
// ---------
171+
172+
template <class I>
173+
auto countAll(I ib, I ie) {
174+
using T = typename I::value_type;
175+
unordered_map<T, int> a;
176+
for_each(ib, ie, [&](const auto& v) { a[v]++; });
177+
return a;
178+
}
179+
180+
template <class J>
181+
auto countAll(const J& x) {
182+
return countAll(x.begin(), x.end());
183+
}
184+
185+
186+
187+
58188
// INDICES
59189
// -------
60190

@@ -75,6 +205,37 @@ auto indices(J&& x) {
75205

76206

77207

208+
// IDENTIFIERS
209+
// -----------
210+
211+
template <class I>
212+
auto identifiers(I ib, I ie) {
213+
using K = typename iterator_traits<I>::value_type;
214+
unordered_map<K, int> a; int i = 0;
215+
for (I it=ib; it!=ie; ++it)
216+
if (a.count(*it)==0) a[*it] = i++;
217+
return a;
218+
}
219+
220+
template <class J>
221+
auto identifiers(const J& x) {
222+
return identifiers(x.begin(), x.end());
223+
}
224+
225+
226+
227+
228+
// TRANSFORM
229+
// ---------
230+
231+
template <class J, class F>
232+
void transform(J& x, F fn) {
233+
transform(x.begin(), x.end(), x.begin(), fn);
234+
}
235+
236+
237+
238+
78239
// SET-DIFFERENCE
79240
// --------------
80241

@@ -95,3 +256,66 @@ auto setDifference(J&& x, K&& y) {
95256
vector<T> a; setDifference(a, x, y);
96257
return a;
97258
}
259+
260+
261+
262+
263+
// TO-*
264+
// ----
265+
266+
template <class T, class I>
267+
void toVector(vector<T>& a, I ib, I ie) {
268+
a.clear();
269+
for (I it=ib; it!=ie; ++it)
270+
a.push_back(*it);;
271+
}
272+
273+
template <class I>
274+
auto toVector(I ib, I ie) {
275+
using T = typename I::value_type;
276+
vector<T> a; toVector(a, ib, ie);
277+
return a;
278+
}
279+
280+
template <class T, class J>
281+
void toVector(vector<T>& a, const J& x) {
282+
toVector(a, x.begin(), x.end());
283+
}
284+
285+
template <class J>
286+
void toVector(const J& x) {
287+
return toVector(x.begin(), x.end());
288+
}
289+
290+
291+
292+
293+
// HASH-VALUE
294+
// ----------
295+
296+
template <class T, class I>
297+
size_t hashValue(vector<T>& vs, I ib, I ie) {
298+
size_t a = 0;
299+
toVector(vs, ib, ie);
300+
sort(vs.begin(), vs.end());
301+
for (const T& v : vs)
302+
a ^= hash<T>{}(v) + 0x9e3779b9 + (a<<6) + (a>>2); // from boost::hash_combine
303+
return a;
304+
}
305+
306+
template <class I>
307+
size_t hashValue(I ib, I ie) {
308+
using T = typename I::value_type;
309+
vector<T> vs;
310+
return hashValue(vs, ib, ie);
311+
}
312+
313+
template <class T, class J>
314+
size_t hashValue(vector<T>& vs, const J& x) {
315+
return hashValue(vs, x.begin(), x.end());
316+
}
317+
318+
template <class J>
319+
size_t hashValue(const J& x) {
320+
return hashValue(x.begin(), x.end());
321+
}

0 commit comments

Comments
 (0)