Halide学习笔记----Halide tutorial源码阅读10
来源:互联网 发布:php权限管理建表思路 编辑:程序博客网 时间:2024/05/16 09:39
Halide入门教程10
// Halide tutorial lesson 10: AOT compilation part 1 // Halide入门教程第十课:提前编译 // This lesson demonstrates how to use Halide as an more traditional // ahead-of-time (AOT) compiler. // 本课程展示了如何用Halide来充当一个传统的提前编译器 // This lesson is split across two files. The first (this one), builds // a Halide pipeline and compiles it to a static library and // header. The second (lesson_10_aot_compilation_run.cpp), uses that // static library to actually run the pipeline. This means that // compiling this code is a multi-step process. // 本课程拆分成两个文件,第一个建立Halide pipeline,并且将它编译成静态链接库和相应的头文件, // 第二个文件使用静态链接库来运行整个pipeline。这意味着编译这些代码要多个阶段的流程。 // On linux, you can compile and run it like so: // g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate // LD_LIBRARY_PATH=../bin ./lesson_10_generate // g++ lesson_10*run.cpp lesson_10_halide.a -std=c++11 -I ../include -lpthread -ldl -o lesson_10_run // ./lesson_10_run // The benefits of this approach are that the final program: // - Doesn't do any jit compilation at runtime, so it's fast. // - Doesn't depend on libHalide at all, so it's a small, easy-to-deploy binary. // 这种放出的好处是,最终生成的程序: // 1.不需要做任何即时编译,因此很快 // 2.不依赖libHalide库,因此可执行程序很小,容易部署二进制文件 #include "Halide.h" #include <stdio.h> using namespace Halide; int main(int argc, char **argv) { // We'll define a simple one-stage pipeline: Func brighter; Var x, y; // The pipeline will depend on one scalar parameter. // 定义输入变量 Param<uint8_t> offset; // And take one grayscale 8-bit input buffer. The first // constructor argument gives the type of a pixel, and the second // specifies the number of dimensions (not the number of // channels!). For a grayscale image this is two; for a color // image it's three. Currently, four dimensions is the maximum for // inputs and outputs. // 定义输入图像,构造函数的第一个变量定义图像数据类型,第二个变量定义图像通道数。 // 灰度图像为2通道的。当前Halide最大支持4通道的输入输出。 ImageParam input(type_of<uint8_t>(), 2); // If we were jit-compiling, these would just be an int and a // Buffer, but because we want to compile the pipeline once and // have it work for any value of the parameter, we need to make a // Param object, which can be used like an Expr, and an ImageParam // object, which can be used like a Buffer. // 如果是即时编译的话,这些就是int类型数据和Buffer,但是由于一次编译pipeline,然后对任何参数 // 都能工作,我们需要Param对象,它可以当做表达式一样使用,ImageParam可以当做Buffer一样使用 // Define the Func. brighter(x, y) = input(x, y) + offset; // Schedule it. brighter.vectorize(x, 16).parallel(y); // This time, instead of calling brighter.realize(...), which // would compile and run the pipeline immediately, we'll call a // method that compiles the pipeline to a static library and header. // 显式调用函数来编译成静态链接库和对应的头文件 // For AOT-compiled code, we need to explicitly declare the // arguments to the routine. This routine takes two. Arguments are // usually Params or ImageParams. // 对于提前便已代码,我们需要显示生命对应的输入参数。 brighter.compile_to_static_library("lesson_10_halide", {input, offset}, "brighter"); printf("Halide pipeline compiled, but not yet run.\n"); // To continue this lesson, look in the file lesson_10_aot_compilation_run.cpp return 0; }
这里需要特别说明的是compile_to_static_library函数,它的声明如下
EXPORT void Halide::Pipeline::compile_to_static_library ( const std::string &filename_prefix, //静态链接库和头文件名字的前缀 const std::vector< Argument > & args, // 函数的参数 const std::string & fn_name, // 函数名称 const Target & target = get_target_from_environment() // 指定编译成哪种平台的代码, x86/arm/... ) //Compile to static-library file and header pair, with the given arguments. // 在给定参数的情况下将对应文件编译成静态链接库和头文件
// Halide tutorial lesson 10: AOT compilation part 2 // Halide入门教程第十课:提前编译 // Before reading this file, see lesson_10_aot_compilation_generate.cpp // This is the code that actually uses the Halide pipeline we've // compiled. It does not depend on libHalide, so we won't be including // Halide.h. // 这部分代码才是实际上使用已经编译过的Halide pipeline.它并不依赖与libHalide。 // Instead, it depends on the header file that lesson_10_generate // produced when we ran it: // 但是它依赖于生成器生成的静态链接库和头文件 #include "lesson_10_halide.h" // We want to continue to use our Halide::Buffer with AOT-compiled // code, so we explicitly include it. It's a header-only class, and // doesn't require libHalide. #include "HalideBuffer.h" #include <stdio.h> int main(int argc, char **argv) { // Have a look in the header file above (it won't exist until you've run // lesson_10_generate). At the bottom is the signature of the function we generated: // int brighter(halide_buffer_t *_input_buffer, uint8_t _offset, halide_buffer_t *_brighter_buffer); // 查看生成器生成的头文件中函数的声明格式,按此格式调用函数。 // The ImageParam inputs have become pointers to "halide_buffer_t" // structs. This is struct that Halide uses to represent arrays of // data. Unless you're calling the Halide pipeline from pure C // code, you don't want to use it // directly. Halide::Runtime::Buffer is a simple wrapper around // halide_buffer_t that will implicitly convert to a // halide_buffer_t *. We will pass Halide::Runtime::Buffer objects // in those slots. // The Halide::Buffer class we have been using in JIT code is in // fact just a shared pointer to the simpler // Halide::Runtime::Buffer class. They share the same API. // Finally, the return value of "brighter" is an error code. It's // zero on success. // Let's make a buffer for our input and output. Halide::Runtime::Buffer<uint8_t> input(640, 480), output(640, 480); // Halide::Runtime::Buffer also has constructors that wrap // existing data instead of allocating new memory. Use these if // you have your own Image type that you want to use. int offset = 5; int error = brighter(input, offset, output); // 调用静态库中的代码 if (error) { printf("Halide returned an error: %d\n", error); return -1; } // Now let's check the filter performed as advertised. It was // supposed to add the offset to every input pixel. for (int y = 0; y < 480; y++) { for (int x = 0; x < 640; x++) { uint8_t input_val = input(x, y); uint8_t output_val = output(x, y); uint8_t correct_val = input_val + offset; if (output_val != correct_val) { printf("output(%d, %d) was %d instead of %d\n", x, y, output_val, correct_val); return -1; } } } // Everything worked! printf("Success!\n"); return 0; }
可以按照第一部分中代码提到的那样,在终端中逐步执行对应的命令,最后得到运行代码。
由于步骤繁多,在这里写成shell脚本,方便执行:
#!/usr/bin/bash########################################################################## File Name: lesson_10_compile.sh# Author: xxx# Created Time: Fri 22 Dec 2017 09:56:20 PM CST#########################################################################echo "1. compile generator"g++ lesson_10*generate.cpp -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generateecho "2. generate static library"./lesson_10_generateecho "3. compile run to generate executive file"g++ lesson_10*run.cpp lesson_10_halide.a -std=c++11 -I ../include -lpthread -ldl -o lesson_10_runecho "4. test executive file"./lesson_10_run
在终端中运行shell脚本
$ sh lesson_10_compile.sh
执行shell脚本
生成的生成器、静态链接库、头文件和可执行文件
阅读全文
0 0
- Halide学习笔记----Halide tutorial源码阅读10
- Halide学习笔记----Halide tutorial源码阅读1
- Halide学习笔记----Halide tutorial源码阅读2
- Halide学习笔记----Halide tutorial源码阅读3
- Halide学习笔记----Halide tutorial源码阅读4
- Halide学习笔记----Halide tutorial源码阅读5
- Halide学习笔记----Halide tutorial源码阅读6
- Halide学习笔记----Halide tutorial源码阅读7
- Halide学习笔记----Halide tutorial源码阅读8
- Halide学习笔记----Halide tutorial源码阅读9
- Halide学习笔记----Halide tutorial源码阅读11
- Halide学习笔记----Halide tutorial源码阅读12
- Halide学习笔记----Halide tutorial源码阅读13
- Halide学习笔记----Halide tutorial源码阅读14
- Halide学习笔记----Halide tutorial源码阅读15
- Halide学习笔记----Halide tutorial源码阅读16
- Halide学习笔记----Halide tutorial源码阅读17
- Halide学习笔记----Halide tutorial源码阅读18
- 数据结构实验之查找七:线性之哈希表
- [51Nod 1587] 半现串
- Ubuntu 升级内核 以及 开启BBR
- c指针
- 教大家一键锁定计算机
- Halide学习笔记----Halide tutorial源码阅读10
- 知识学习——Java对象的生命周期
- 179. Largest Number
- 知识图谱大咖云集阿里,他们都说了啥
- 从苦逼到牛逼,详解Linux运维工程师的打怪升级之路
- Angular、React、Vue.js 等 6 大主流前端框架都有什么优缺点?
- HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法
- 用input输入框实现好看的复选框效果(css+jq)
- Excel手册 人手一份