示例学习
基本变量和概念
// 使用Halide,我们只需要包含Halide.h这个头文件就可以了
#include "Halide.h"
#include <stdio.h>
int main(int argc, char **argv) {
// Halide::Func代表了一个计算图,代表了每一个像素值需要进行的计算操作
Halide::Func gradient;
// Halide::Var代表了一个变量名,需要跟Func配合使用才有意义
Halide::Var x, y;
// Halide::Expr代表一个表达式,可由变量的数学表达式组合成
Halide::Expr e = x + y;
// 现在使用左值等式接口,再计算图上添加表达式
gradient(x, y) = e;
// 上述写法等同如下
//
// gradient(x, y) = x + y;
//
// 上述只是在定义计算图,没有进行实际的运算
// 以下的语句在实际运行计算图,同事得到结果保存在output中
Halide::Buffer<int32_t> output = gradient.realize({800, 600});
// 以下是检查代码
for (int j = 0; j < output.height(); j++) {
for (int i = 0; i < output.width(); i++) {
if (output(i, j) != i + j) {
printf("Something went wrong!\n"
"Pixel %d, %d was supposed to be %d, but instead it's %d\n",
i, j, i + j, output(i, j));
return -1;
}
}
}
printf("Success!\n");
return 0;
}
Success!
操控图片操作
#include "Halide.h"
// 为了能够加载png图片而引入的库
#include "halide_image_io.h"
using namespace Halide::Tools;
int main(int argc, char **argv) {
// 该程序主要是进行图像的过曝操作,提高亮度
// 加载图像
Halide::Buffer<uint8_t> input = load_image("../../images/rgb.png");
Halide::Func brighter;
Halide::Var x, y, c; // 多维度的图像
// 第一个表达式
Halide::Expr value = input(x, y, c);
// char--->fp32
value = Halide::cast<float>(value);
// 乘以1.5进行提高亮度
value = value * 1.5f;
// 然后截断在255以内
value = Halide::min(value, 255.0f);
// 最后fp32--->char
value = Halide::cast<uint8_t>(value);
// 最后组成计算图
brighter(x, y, c) = value;
// 以上操作也跟下面的语句同样的效果
//
// brighter(x, y, c) = Halide::cast<uint8_t>(min(input(x, y, c) * 1.5f, 255));
//
// 下述命令进行计算图的计算
Halide::Buffer<uint8_t> output =
brighter.realize({input.width(), input.height(), input.channels()});
// 最后进行output的操作
save_image(output, "../../result/lesson_02_brighter.png");
printf("Success!\n");
return 0;
}
输入图片如下所示:
输出图片如下所示:
debug操作1
#include "Halide.h"
#include <stdio.h>
using namespace Halide;
int main(int argc, char **argv) {
// 为了能够进行更清晰的说明,这里使用string赋值给函数和变量
Func gradient("gradient");
Var x("x"), y("y");
gradient(x, y) = x + y;
Buffer<int> output = gradient.realize({8, 8});
// 把计算图的编译过程使用了html来进行展示
gradient.compile_to_lowered_stmt("../../result/gradient.html", {}, HTML);
printf("Success!\n");
return 0;
}
module name=gradient, target=x86-64-linux-avx-avx2-avx512-avx512_skylake-f16c-fma-sse41 {
func gradient(gradient) {
assert((reinterpret(gradient.buffer) != (uint64)0), halide_error_buffer_argument_is_null("gradient"))
let gradient = _halide_buffer_get_host(gradient.buffer)
let gradient.type = _halide_buffer_get_type(gradient.buffer)
let gradient.device_dirty = _halide_buffer_get_device_dirty(gradient.buffer)
let gradient.dimensions = _halide_buffer_get_dimensions(gradient.buffer)
let gradient.min.0 = _halide_buffer_get_min(gradient.buffer, 0)
let gradient.extent.0 = _halide_buffer_get_extent(gradient.buffer, 0)
let gradient.stride.0 = _halide_buffer_get_stride(gradient.buffer, 0)
let gradient.min.1 = _halide_buffer_get_min(gradient.buffer, 1)
let gradient.extent.1 = _halide_buffer_get_extent(gradient.buffer, 1)
let gradient.stride.1 = _halide_buffer_get_stride(gradient.buffer, 1)
if (_halide_buffer_is_bounds_query(gradient.buffer)) {
_halide_buffer_init(gradient.buffer, _halide_buffer_get_shape(gradient.buffer), reinterpret((uint64)0), (uint64)0, reinterpret((uint64)0), 0, 32, 2, make_struct(gradient.min.0, gradient.extent.0, 1, 0, gradient.min.1, gradient.extent.1, gradient.extent.0, 0), (uint64)0)
}
if (!_halide_buffer_is_bounds_query(gradient.buffer)) {
assert((gradient.type == (uint32)73728), halide_error_bad_type("Output buffer gradient", gradient.type, (uint32)73728))
assert((gradient.dimensions == 2), halide_error_bad_dimensions("Output buffer gradient", gradient.dimensions, 2))
assert((0 <= gradient.extent.0), halide_error_buffer_extents_negative("Output buffer gradient", 0, gradient.extent.0))
assert((0 <= gradient.extent.1), halide_error_buffer_extents_negative("Output buffer gradient", 1, gradient.extent.1))
assert((gradient.stride.0 == 1), halide_error_constraint_violated("gradient.stride.0", gradient.stride.0, "1", 1))
let gradient.total_extent.1 = (int64(gradient.extent.1) * int64(gradient.extent.0))
assert((uint64(gradient.extent.0) <= (uint64)2147483647), halide_error_buffer_allocation_too_large("gradient", uint64(gradient.extent.0), (uint64)2147483647))
assert((abs((int64(gradient.extent.1) * int64(gradient.stride.1))) <= (uint64)2147483647), halide_error_buffer_allocation_too_large("gradient", abs((int64(gradient.extent.1) * int64(gradient.stride.1))), (uint64)2147483647))
assert((gradient.total_extent.1 <= (int64)2147483647), halide_error_buffer_extents_too_large("gradient", gradient.total_extent.1, (int64)2147483647))
assert(!gradient.device_dirty, halide_error_device_dirty_with_no_device_support("Output buffer gradient"))
assert((gradient != reinterpret((uint64)0)), halide_error_host_is_null("Output buffer gradient"))
produce gradient {
let t7 = (0 - (gradient.min.1 * gradient.stride.1))
let t6 = (gradient.min.0 + gradient.min.1)
for (gradient.s0.y.rebased, 0, gradient.extent.1) {
let t9 = (((gradient.min.1 + gradient.s0.y.rebased) * gradient.stride.1) + t7)
let t8 = (gradient.s0.y.rebased + t6)
for (gradient.s0.x.rebased, 0, gradient.extent.0) {
gradient[(gradient.s0.x.rebased + t9)] = (gradient.s0.x.rebased + t8)
}
}
}
}
}
}
|