forked from halide/Halide
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgpu_sum_scan.cpp
More file actions
65 lines (49 loc) · 1.58 KB
/
gpu_sum_scan.cpp
File metadata and controls
65 lines (49 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
int main(int argc, char **argv) {
if (!get_jit_target_from_environment().has_gpu_feature()) {
printf("No gpu target enabled. Skipping test.\n");
return 0;
}
Func f;
Var x, y;
ImageParam im(Int(32), 1);
const int B = 16;
const int N = 1024*16;
Expr blocks = im.width() / B;
f(x, y) = 0;
f.compute_root().gpu_blocks(y).gpu_threads(x);
// Sum-scan within each block of size B.
RDom r1(0, B);
f(r1, y) = im(y*B + r1) + f(r1-1, y);
f.update(0).gpu_blocks(y);
// Sum-scan along the last element of each block into a scratch space just before the start of each block.
RDom r2(1, blocks-1);
f(-1, r2) = f(B-1, r2-1) + f(-1, r2-1);
f.update(1).gpu_single_thread();
// Add the last element of the previous block to everything in each row
RDom r3(0, B);
f(r3, y) += f(-1, y);
f.update(2).gpu_blocks(y).gpu_threads(r3);
// Read out the output
Func out;
out(x) = f(x % B, x / B);
out.gpu_tile(x, B);
// Only deal with inputs that are a multiple of B
out.bound(x, 0, im.width()/B * B);
Image<int> input = lambda(x, cast<int>(floor((sin(x))*100))).realize(N);
im.set(input);
Image<int> output = out.realize(N);
int correct = 0;
for (int i = 0; i < N; i++) {
correct += input(i);
if (output(i) != correct) {
printf("output(%d) = %d instead of %d\n",
i, output(i), correct);
return -1;
}
}
printf("Success!\n");
return 0;
}