卤化物可变域减少
Variable Domain Reduction in Halide
现在我正在尝试编写一些对图像进行子采样的 Halide 代码。基本上我希望图像的每 2 x 2 平方减少到一个包含最大值的像素。一个简单的例子是转换
1 2 3 4
5 6 7 8
9 0 1 2
4 3 5 6
进入
6 8
9 6
现在我正在尝试一些类似的方法(我知道这会给出总和而不是最大值,但它是同一过程的玩具示例):
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");
但是,这段代码会无限运行。 (我不确定为什么)。我知道我可以使用 Halide::RDom 来表示某个范围内的减少操作。但是,在我发现的任何示例中,您都不能将变量传递给随机域对象。
编辑:
在进一步使用 Halide 之后,我构建了这个:
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));
最大减少 2x2。但是,当我把它放在一个循环中时,它不会调用,因为它无法定义。有没有办法把它放在域缩减方面?
我认为您只是想要一个更简单的纯函数定义(没有 C++ 循环,它不会执行我认为您期望它们执行的操作……;没有 RDoms):
// using Halide::max
subsample(x,y,c) = max( max( input(2*x,2*y ), input(2*x+1,2*y ) ),
max( input(2*x,2*y+1), input(2*x+1,2*y+1) ) );
在深入研究 Halide 之后,我意识到我可以用这个得到我想要的东西:
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));
我认为 argmax(嵌入式 Halide 函数)可以用于您想要的:)
#include "Halide.h"
#include <stdio.h>
uint8_t data[16] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 2,
3, 4, 5, 6
};
using namespace Halide;
int main(int argc, char** argv) {
Halide::Image<uint8_t> input(4, 4);
for(int j = 0; j < 4; j++) {
for(int i = 0; i < 4; i++) {
input(j, i) = data[j*4 + i];
}
}
Halide::Func f, max2x2;
Halide::Var x, y, dx, dy;
Halide::Expr x_ = x * 2;
Halide::Expr y_ = y * 2;
f(x, y, dx, dy) = input(x_ + dx, y_ + dy);
RDom r(0, 2, 0, 2);
max2x2(x, y) = argmax(f(x, y, r.x, r.y))[2];
Halide::Image<uint8_t> output(2, 2);
max2x2.realize(output);
for(int j = 0; j < 2; j++) {
for(int i = 0; i < 2; i++) {
printf("%d ", output(j, i));
}
printf("\n");
}
return 0;
}
现在我正在尝试编写一些对图像进行子采样的 Halide 代码。基本上我希望图像的每 2 x 2 平方减少到一个包含最大值的像素。一个简单的例子是转换
1 2 3 4
5 6 7 8
9 0 1 2
4 3 5 6
进入
6 8
9 6
现在我正在尝试一些类似的方法(我知道这会给出总和而不是最大值,但它是同一过程的玩具示例):
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");
但是,这段代码会无限运行。 (我不确定为什么)。我知道我可以使用 Halide::RDom 来表示某个范围内的减少操作。但是,在我发现的任何示例中,您都不能将变量传递给随机域对象。
编辑:
在进一步使用 Halide 之后,我构建了这个:
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));
最大减少 2x2。但是,当我把它放在一个循环中时,它不会调用,因为它无法定义。有没有办法把它放在域缩减方面?
我认为您只是想要一个更简单的纯函数定义(没有 C++ 循环,它不会执行我认为您期望它们执行的操作……;没有 RDoms):
// using Halide::max
subsample(x,y,c) = max( max( input(2*x,2*y ), input(2*x+1,2*y ) ),
max( input(2*x,2*y+1), input(2*x+1,2*y+1) ) );
在深入研究 Halide 之后,我意识到我可以用这个得到我想要的东西:
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));
我认为 argmax(嵌入式 Halide 函数)可以用于您想要的:)
#include "Halide.h"
#include <stdio.h>
uint8_t data[16] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 2,
3, 4, 5, 6
};
using namespace Halide;
int main(int argc, char** argv) {
Halide::Image<uint8_t> input(4, 4);
for(int j = 0; j < 4; j++) {
for(int i = 0; i < 4; i++) {
input(j, i) = data[j*4 + i];
}
}
Halide::Func f, max2x2;
Halide::Var x, y, dx, dy;
Halide::Expr x_ = x * 2;
Halide::Expr y_ = y * 2;
f(x, y, dx, dy) = input(x_ + dx, y_ + dy);
RDom r(0, 2, 0, 2);
max2x2(x, y) = argmax(f(x, y, r.x, r.y))[2];
Halide::Image<uint8_t> output(2, 2);
max2x2.realize(output);
for(int j = 0; j < 2; j++) {
for(int i = 0; i < 2; i++) {
printf("%d ", output(j, i));
}
printf("\n");
}
return 0;
}