改变维度遍历起点
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
int main(int argc, char **argv) {
Func gradient("gradient");
Var x("x"), y("y");
gradient(x, y) = x + y;
gradient.trace_stores();
printf("Evaluating gradient from (0, 0) to (7, 7)\n");
// 普通的起点为0的正方形
Buffer<int> result(8, 8);
gradient.realize(result);
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
if (result(x, y) != x + y) {
printf("Something went wrong!\n");
return -1;
}
}
}
// 现在定义一个起点不为0的长方形
Buffer<int> shifted(5, 7); //形状尺寸
shifted.set_min(100, 50); //左上角的起点位置
printf("Evaluating gradient from (100, 50) to (104, 56)\n");
gradient.realize(shifted);
// 等效C代码如下所示
for (int y = 50; y < 57; y++) {
for (int x = 100; x < 105; x++) {
if (shifted(x, y) != x + y) {//此刻就无法读取边界外的序号点了
printf("Something went wrong!\n");
return -1;
}
}
}
// Halide只适合矩形的边界数据
return 0;
}
# 结果如下所示
Begin pipeline gradient.0()
Tag gradient.0() tag = "func_type_and_dim: 1 0 32 1 2 100 5 50 7"
Store gradient.0(100, 50) = 150
Store gradient.0(101, 50) = 151
Store gradient.0(102, 50) = 152
Store gradient.0(103, 50) = 153
Store gradient.0(104, 50) = 154
Store gradient.0(100, 51) = 151
Store gradient.0(101, 51) = 152
Store gradient.0(102, 51) = 153
Store gradient.0(103, 51) = 154
Store gradient.0(104, 51) = 155
Store gradient.0(100, 52) = 152
Store gradient.0(101, 52) = 153
Store gradient.0(102, 52) = 154
Store gradient.0(103, 52) = 155
Store gradient.0(104, 52) = 156
Store gradient.0(100, 53) = 153
Store gradient.0(101, 53) = 154
Store gradient.0(102, 53) = 155
Store gradient.0(103, 53) = 156
Store gradient.0(104, 53) = 157
Store gradient.0(100, 54) = 154
Store gradient.0(101, 54) = 155
Store gradient.0(102, 54) = 156
Store gradient.0(103, 54) = 157
Store gradient.0(104, 54) = 158
Store gradient.0(100, 55) = 155
Store gradient.0(101, 55) = 156
Store gradient.0(102, 55) = 157
Store gradient.0(103, 55) = 158
Store gradient.0(104, 55) = 159
Store gradient.0(100, 56) = 156
Store gradient.0(101, 56) = 157
Store gradient.0(102, 56) = 158
Store gradient.0(103, 56) = 159
Store gradient.0(104, 56) = 160
End pipeline gradient.0()
多计算图组合示例
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
#include "halide_image_io.h"
using namespace Halide::Tools;
int main(int argc, char **argv) {
Var x("x"), y("y"), c("c");
// 这里使用多计算图,先垂直后水平
{
// 得到一个全彩图片
Buffer<uint8_t> input = load_image("../../images/vscode.jpg");
// 提升精度到16bit
Func input_16("input_16");
input_16(x, y, c) = cast<uint16_t>(input(x, y, c));
// 水平模糊:水平方向取邻近像素均值
Func blur_x("blur_x");
blur_x(x, y, c) = (input_16(x - 1, y, c) +
2 * input_16(x, y, c) +
input_16(x + 1, y, c)) / 4;
// 垂直模糊:垂直方向取邻近像素均值
Func blur_y("blur_y");
blur_y(x, y, c) = (blur_x(x, y - 1, c) +
2 * blur_x(x, y, c) +
blur_x(x, y + 1, c)) / 4;
// 降低精度为8bit
Func output("output");
output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));
// Halide中,计算图都是前向计算图
// 下述的实例化代码是需要考虑到边界溢出的问题,所以这里的尺寸需要减2,同时起点需要偏移到(1,1)
Buffer<uint8_t> result(input.width() - 2, input.height() - 2, 3);
result.set_min(1, 1);
output.realize(result);
save_image(result, "../../images/blurry_parrot_1.png");
}
// 一样的操作,但是采用了截断操作来防止边界溢出的报错
{
Buffer<uint8_t> input = load_image("../../images/vscode.jpg");
Func clamped("clamped");
// 使用Halide::clamp函数,可以把索引限制在边界内
Expr clamped_x = clamp(x, 0, input.width() - 1);
Expr clamped_y = clamp(y, 0, input.height() - 1);
clamped(x, y, c) = input(clamped_x, clamped_y, c);
Func input_16("input_16");
input_16(x, y, c) = cast<uint16_t>(clamped(x, y, c));
Func blur_x("blur_x");
blur_x(x, y, c) = (input_16(x - 1, y, c) +
2 * input_16(x, y, c) +
input_16(x + 1, y, c)) / 4;
Func blur_y("blur_y");
blur_y(x, y, c) = (blur_x(x, y - 1, c) +
2 * blur_x(x, y, c) +
blur_x(x, y + 1, c)) / 4;
Func output("output");
output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));
// 此时就不需要继续在实例化的时候再进行边界检查
Buffer<uint8_t> result = output.realize({input.width(), input.height(), 3});
save_image(result, "../../images/blurry_parrot_2.png");
}
printf("Success!\n");
return 0;
}
示例图结果如下所示:
- 原图(112x61)
- 不使用截断(110x59)
- 使用截断(112x61)