快速入门Halide

本文介绍了Halide语言的代码流程,包括声明函数、调度策略、并行化及数据处理方法。通过设置调试环境变量,可以查看编译过程和优化后的伪代码。Halide支持向量化、并行化和平铺等优化手段,通过Func的调度方法减少计算冗余。此外,还提到了生成器和BoundaryConditions类的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Halide代码流程:

  • 声明函数,变量,表达式
  • 用变量、表达式等实现算法
  • 使用调度策略对算法进行调度调优
  • 调用函数的realize成员函数,对函数进行实现
  • 写出数据
example 1:
Halide::Func gradient;
// Func对象表示了一个pipeline阶段。它是一个纯函数,定义了每个像素点对应的值。
Halide::Var x, y;
// Var对象是Func的定义域,或者说是Func的参数。它们本身没有任何意义。Var用来索引
Halide::Expr e = x + y;
// 义了一个 x + y的表达式。变量重载了算数运算符,因此变量进行运算的结果是一个Expr对象
gradient(x, y) = e;
// 在像素点x,y处,图像的像素值为表达式e的结果  gradient(x, y) = x + y;

// 告诉Halide在在指定的区域进行计算。这里的domain可以理解为像素点的范围。
Halide::Buffer<int32_t> output = gradient.realize(800, 600);
output(i, j) !=  i + j
example 2:
Halide::Buffer<uint8_t> input = load_image("s.png");
//定义Func对象,Func对象表示我们将要进行的图像亮度提升pipeline
Halide::Func brighter;
//定义操作图像像素的索引,即Var(变量)x(column),y(row),c(channel)
// x,y为坐标索引,c为颜色通道索引。
Halide::Var x, y, c;
//value表达式表示c通道(x,y)坐标处的像素值
Halide::Expr value = input(x, y, c);
// 为了进行浮点计算,先将数据类型转换成单精度浮点类型
value = Halide::cast<float>(value);
// 将c通道(x,y)坐标处的像素值放大1.5倍
value = value * 1.5f;
// 为了防止数据溢出,将放大后的像素值clip到[0,255]区间,并转换成8位无符号整型
value = Halide::min(value, 255.0f);
value = Halide::cast<uint8_t>(value);
//定义函数,将亮度提升后的像素值,赋值给函数对象的(x,y,c)点
brighter(x, y, c) = value;
// brighter(x, y, c) = Halide::cast<uint8_t>(min(input(x, y, c) * 1.5f, 255));
// 上述所有操作知识在内存中建立Halide程序,告诉Halide怎么去进行算法操作,即对算法进行了定义。
// 实际上还没有开始进行任何像素的处理。甚至Halide程序还没有进行编译

// 现在将要实现函数。输出图像的尺寸必须和输入图像的尺寸相匹配。
//如果我们只想提高输入图像部分区域像素点的亮度,可以指定一个小一点的尺寸。
//如果需要一个更大尺寸的输出,Halide在运行时会抛出一个错误告诉我们,边界超出输入图像。
Halide::Buffer<uint8_t> output =
    brighter.realize(input.width(), input.height(), input.channels());
// 写下被处理过的图像
save_image(output, "brighter.png");

调试

  • 设置环境变量HL_DEBUG_CODEGEN=1,此时运行程序会打印出编译的不同阶段和最终pipeline的伪代码
  • 设置HL_DEBUG_CODEGEN=2,此时会输出Halide编译的各个不同阶段,而且会输出llvm最终生成的字节码
  • 也提供HTML形式的伪代码输出,支持语法高亮,代码折叠,翻遍大规模复杂pipeline的阅读
Func gradient("gradient");
Var x("x"), y("y");
gradient(x, y) = x + y;
// 给Func和Var的构造函数传入一个string类型的名字
Buffer<int> output = gradient.realize(8, 8);
gradient.compile_to_lowered_stmt("gradient.html", {}, HTML);
  • 用tracing,print,print_when调试
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值