Right now I'm trying to write some Halide code that subsamples an image. Basically I want every 2 by 2 square of the image to be reduced to one pixel that contains the maximum. A simple example would be transforming
1 2 3 4
5 6 7 8
9 0 1 2
4 3 5 6
into
6 8
9 6
Right now I'm trying something along the lines of (I'm aware that this would give the sum instead of the maximum, but it's a toy example of the same process):
Halide::Image<uint8_t> input = load<uint8_t>("test.png");
Halide::Image<uint8_t> output(input.width() / 2, input.height() / 2, input.channels());
Halide::Func subsample;
Halide::Var c;
for (int i = 0; i < input.height(); i += 2) {
for (int j = 0; j < input.width(); j += 2) {
Halide::RDom r = Halide::RDom(i, 2, j, 2);
subsample(i, j, c) += input(r.x, r.y, c);
}
}
subsample.realize(output);
save(output, "test.png");
However, this code runs infinitely. (I'm not sure why). I know I can use Halide::RDom to represent a reduce operation over some range. However, in no example I find can you pass a variable into a random domain object.
EDIT:
After playing around with Halide some more, I was able to construct this:
subsample(x, y, c) = Halide::max(input(2*x,2*y,c),input(2*x+1,2*y,c));
subsample(x, y, c) = Halide::max(subsample(x,y,c),input(2*x,2*y+1,c));
subsample(x, y, c) = Halide::max(subsample(x,y,c),input(2*x+1,2*y+1,c));
To get a 2x2 max reduction. However, when I put this in a loop, it won't call because it cannot be defined. Is there anyway to put this in terms of a domain reduction?
After looking more into Halide, I realized I could get what I wanted with this:
Halide::Func subsample;
Halide::Var x, y, c;
Halide::RDom r(0, size, 0, size);
subsample(x, y, c) = input(size * x, size * y, c);
subsample(x, y, c) = Halide::max(input(size*x + r.x, size*y + r.y, c),
subsample(x,y,c));