#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 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;
}