Halide::Generator生成器使用说明

Halide::Generator 使用指南:优化AI核函数与OpenCL后端
本文档详细介绍了如何利用Halide::Generator生成器来创建和优化AI模型的核函数,以及如何指定GPU约束和自动调度。通过示例代码展示了从输入输出定义到核函数实现、调度设置的完整流程,并提供了OpenCL后端的生成代码片段。此外,还讨论了后续如何使用生成的核函数。

我们之前已经能够使用Halide去调用OpenCL后端了,但是我们的代码总是在建立计算图和调度后使用realize实例化进行运行。
这很明显对于我们AI模型优化核函数、推理运行时这些操作造成不小的影响。而且也无法剥离出Halide这个庞大的依赖库,导致
最终的推理时依赖过多引起的接口过于复杂。

1、前言

本次的主要工作就是尝试了Halide::Generator生成器去进行核函数生成以及如何使用不同后端的试验。
关键信息如下所示:

  • 多计算图
  • 调度gpu约束
  • 输入输出定义信息
  • 自动调度操作
  • 生成器调用示例

2、核心代码总览

#include <stdio.h>
#include "Halide.h"
#include "HalideBuffer.h"
#include "clock.h"
using namespace Halide;
using namespace Halide::Tools;
//尝试进行核函数生成操作。
class image_f4:public Halide::Generator<image_f4>{
public:
    // 定义输入buffer,图片数据,三维数据
    Input<Buffer<uint8_t>> input{"input", 3};
    // 定义输出buffer,图片数据,三维数据,两者shape完全一致。
    Output<Buffer<uint8_t>> output{"output", 3};
    void generate()
    {
        
        Var x, y, c, i, ii, xo, yo, xi, yi;
        Func lut;
        Func curved;
        Func padded;

        lut(i) = cast<uint8_t>(clamp(pow(i / 255.0f, 1.2f) * 255.0f, 0, 255));

        // Augment the input with a boundary condition.
        padded(x, y, c) = input(clamp(x, 0, input.width() - 1),
                                clamp(y, 0, input.height() - 1), c);

        // Cast it to 16-bit to do the math.
        Func padded16;
        padded16(x, y, c) = cast<uint16_t>(padded(x, y, c));

        // Next we sharpen it with a five-tap filter.
        Func sharpen;
        sharpen(x, y, c) = (padded16(x, y, c) * 2 -
                            (padded16(x - 1, y, c) +
                                padded16(x, y - 1, c) +
                                padded16(x + 1, y, c) +
                                padded16(x, y + 1, c)) /
                                4);
        curved(x, y, c) = lut(sharpen(x, y, c));
        lut.compute_root();

        Var block, thread;
        lut.split(i, block, thread, 16);
        lut.gpu_blocks(block)
            .gpu_threads(thread);
        output(x, y, c) = curved(x, y, c);
    }

    void schedule()
    {
	/* THE SCHEDULE */
        // input.set_estimates({
  
  {0, 1024}, {0, 1024}, {1, 3}});
        // output.set_estimates({
  
  {0, 1024}, {0, 1024}, {1, 3}});
    }
};


HALIDE_REGISTER_GENERATOR(image_f4, image_f4)


int main(int argc, char **argv) {
    return Halide::Internal::generate_filter_main(argc, argv, std::cerr);
}

3、具体说明和注意事项

3.1、生成器使用流程
  • 1、建立基于父类Halide::Generator的核生成器
class image_f4:public Halide::Generator<image_f4>{}
  • 2、声明输出输入buffer信息
// 定义输入buffer,图片数据,三维数据
Input<Buffer<uint8_t>> input{"input", 3};
// 定义输出buffer,图片数据,三维数据,两者shape完全一致。
Output<Buffer<uint8_t>> output{"output", 3};
  • 3、声明核函数的halide计算图实现
    void generate()
    {
        
        Var x, y, c, i, ii, xo, yo, xi, yi;
        Func lut;
        Func curved;
        Func padded;

        lut(i) = cast<uint8_t>(clamp(pow(i / 255.0f, 1.2f) * 255.0f, 0, 255));

        // Augment the input with a boundary condition.
        padded(x, y, c) = input(clamp(x, 0, input.width() - 1),
                                clamp(y, 0, input.height() - 1), c);

        // Cast it to 16-bit to do the math.
        Func padded16;
        padded16(x, y, c) = cast<uint16_t>(padded(x, y, c));

        // Next we sharpen it with a five-tap filter.
        Func sharpen;
        sharpen(x, y, c) = (padded16(x, y, c) * 2 -
                            (padded16(x - 1, y, c) +
                                padded16(x, y - 1, c) +
                                padded16(x + 1, y, c) +
                                padded16(x, y + 1, c)) /
                                4);
        curved(x, y, c) = lut(sharpen(x, y, c));
        /*-----------自定义调度-----------*/
        lut.compute_root();

        Var block, thread;
        lut.split(i, block, thread, 16);
        lut.gpu_blocks(block)
            .gpu_threads(thread);
        /*-----------自定义调度-----------*/
        output(x, y, c) = curved(x, y, c);
    }
  • 4、自动调度设置(可选)
    void schedule()
 
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值