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 66 67 68 69 70 71 72 73 74
|
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
int main(int argc, char **argv) {
Func f;
Var x;
// Don't bother with a pure definition. Because this will be the
// output stage, that means leave whatever's already in the output
// buffer untouched.
f(x) = undef<float>();
// But do a sum-scan of it from 0 to 100
RDom r(1, 99);
f(r) += f(r - 1);
// Make some test data.
Buffer<float> data = lambda(x, sin(x)).realize({100});
f.realize(data);
// Do the same thing not in-place
Buffer<float> reference_in = lambda(x, sin(x)).realize({100});
Func g;
g(x) = reference_in(x);
g(r) += g(r - 1);
Buffer<float> reference_out = g.realize({100});
float err = evaluate_may_gpu<float>(sum(abs(data(r) - reference_out(r))));
if (err > 0.0001f) {
printf("Failed\n");
return 1;
}
// Undef on one side of a select doesn't destroy the entire
// select. Instead, it makes the containing store conditionally
// not occur using an if statement. You probably shouldn't use
// this feature. For one thing it vectorizes poorly (it reverts to
// scalar code). This test does not exist in order to encourage
// you to use this behavior. This just makes sure the expected
// thing happens if someone is mad enough to write this.
//
// In general, it's better to use a completely undef pure case,
// and then have an update step that loads the existing value and
// stores it again unchanged at those pixels you don't want to
// modify. However, this exists if you really need it. E.g. if one
// page in the middle of your halide_buffer_t is memprotected as read
// only and you can't store to it safely, or if you have some
// weird memory mapping or race condition for which loading then
// storing the same value has undesireable side-effects.
// This sets the even numbered entires to 1.
data = lambda(x, sin(x)).realize({100});
Func h;
h(x) = select(x % 2 == 0, 1.0f, undef<float>());
h.vectorize(x, 4);
h.realize(data);
for (int x = 0; x < 100; x++) {
double correct = sin((double)x);
if (x % 2 == 0) {
correct = 1.0;
}
if (fabs(data(x) - correct) > 0.001) {
printf("data(%d) = %f instead of %f\n", x, data(x), correct);
return 1;
}
}
printf("Success!\n");
return 0;
}
|