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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#include "Halide.h"
using namespace Halide;
template<typename T>
void test() {
{
// Test div_round_to_zero
Func f;
Var x, y;
Expr d = cast<T>(y - 128);
Expr n = cast<T>(x - 128);
d = select(d == 0 || (d == -1 && n == d.type().min()),
cast<T>(1),
d);
f(x, y) = div_round_to_zero(n, d);
f.vectorize(x, 8);
Buffer<T> result = f.realize({256, 256});
for (int d = -128; d < 128; d++) {
if (d == 0) {
continue;
}
for (int n = -128; n < 128; n++) {
if (d == -1 && n == std::numeric_limits<T>::min()) {
continue;
}
int correct = d == 0 ? n : (T)(n / d);
int r = result(n + 128, d + 128);
if (r != correct) {
printf("result(%d, %d) = %d instead of %d\n", n, d, r, correct);
exit(1);
}
}
}
}
{
// Test the fast version
Func f;
Var x, y;
f(x, y) = fast_integer_divide_round_to_zero(cast<T>(x - 128), cast<uint8_t>(y + 1));
f.vectorize(x, 8);
Buffer<T> result_fast = f.realize({256, 255});
for (int d = 1; d < 256; d++) {
for (int n = -128; n < 128; n++) {
int correct = (T)(n / d);
int r = result_fast(n + 128, d - 1);
if (r != correct) {
printf("result_fast(%d, %d) = %d instead of %d\n", n, d, r, correct);
exit(1);
}
}
}
}
{
// Try some constant denominators
for (int d : {-128, -54, -3, -1, 1, 2, 25, 32, 127}) {
if (d == 0) {
continue;
}
Func f;
Var x;
f(x) = div_round_to_zero(cast<T>(x - 128), cast<T>(d));
f.vectorize(x, 8);
Buffer<T> result_const = f.realize({256});
for (int n = -128; n < 128; n++) {
int correct = (T)(n / d);
int r = result_const(n + 128);
if (r != correct) {
printf("result_const(%d, %d) = %d instead of %d\n", n, d, r, correct);
exit(1);
}
}
}
}
}
int main(int argc, char **argv) {
test<int8_t>();
test<int16_t>();
test<int32_t>();
printf("Success!\n");
return 0;
}
|