在工业生产环境中,算法从设计到落地一般跨度比较大。尤其是计算密集的图像处理算法,要达到比较高的效率,就必须要在数据临近、数据复用、计算并行等方面做均衡,算法实现者通常需要深入了解该算法,才能取得比较好的优化。为了降低算法实现过程中开发者的负担,要把算法设计和实现相分离开来,已经有多重解决案例,其中较为典型的就是Halide。

Halide就不多介绍了,毕竟是在Pixel2 HDR Plus上用过的,官网:https://halide-lang.org,上面有很多详细的教程和文档。Halide主要分为两部分,第一部分是要描述需要计算的内容(计算在算法层面的流程),第二部分是规划计算,把计算并行起来、分块儿、数据复用、顺序重排,以实现更高的性能。博主认为第一部分是比较容易的,官网的教程看一遍就可以理解,自己再跑下demo,而第二分部取决于使用的硬件,如果调试优化,需要更多时间去摸索(毕竟我们使用halide是为了获得比较高的性能,减少部署开销)。

这篇博客主要介绍windows下配置halide开发环境,linux配置开发环境比较简单,并且官网已经写的很详细了,只在最后会简要讲下linux配置开发环境步骤中官网没有提及的部分。

虽然这篇博客是windows环境配置教程,但是博主还是建议在linux上使用,一方面是halide开发者使用的ubuntu,支持天然友好,windows在JIT模式中,部分功能不支持,第二方面linux有很多官方的调试工具和可视化工具,可以在Halide的github找到,而windows的debug基本没啥用(库的配置习惯也导致debug切换起来常常有问题,比如llvm、clang在windows上库名字都是不区分的),导致调试模式切换比较繁琐(进debug去调太麻烦,直接release看log吧),第三方面是linux上配置开发环境比windows简单。

虽然不建议使用Windows(博主最后也没有使用windows版本),但是也有可能需要部署在windows上,博主已经把环境配好了,干脆记录下来。

〇、重要参考

Halide官网

github主页

github-cmake页面(使用cmake构建工程必看)

Halid-Github所有仓库(有一些调试工具)

博主自己也整理一些demo和代码,不断学习中:(博主使用cmake link halide,如果有这方面的问题,也可以参考这份代码)

[show-repo src=”gitee” user=”P-Chao” repo=”halide-zoon”]

一、下载源码

在halide官网的目录下下载源码:(博主推荐从源码编译,而不是直接使用二进制包,从源码编译可以在工程中直接打开demo工程,省去了一些查阅demo代码的功夫)

GitHub 仓库挂件 WordPress 插件

halide / Halide

a language for fast, portable data-parallel computation

https://halide-lang.org

同时也要下载llvm和clang的源码:下载地址   (halide是以来llvm和clang的,llvm和clang的二进制包里没有cmake,还是要自己编译)下载llvm-project一个就可以了,里面包含了所有子工程的源码。

二、配置依赖,llvm、clang、libpng和libjpeg

(方式一:vcpkg)

需要通过vcpkg来配置(或者你之前已经安装过Libpng、libjpeg,能通过find_package找到也可以,这步就可以跳过)

64位系统,设置shell环境

D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64

安装vcpkg

D:\> git clone https://github.com/Microsoft/vcpkg.git
D:\> cd vcpkg
D:\> .\bootstrap-vcpkg.bat
D:\vcpkg> .\vcpkg integrate install
...
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake"

安装依赖

D:\vcpkg> .\vcpkg install libpng:x64-windows libjpeg-turbo:x64-windows llvm[target-all,clang-tools-extra]:x64-windows

 

(方式二:手动安装)

如果你要自己手动编译安装,也是可以的:

下载llvmproject工程源码,在llvm目录下新建build文件夹,使用cmake构建即可(这里最好检查下cmake版本,halide似乎要求cmake版本比较高)

这里要留意两个地方,一是install的目录,二是Debug和Release的选择,如果要使用Release库,在进入VS后记得切换即可,这里切换了,后面编译clang、halide以及自己调用halide的工程,也都需要是相同的release。(这就是windows的蛋疼之处,也有办法可以解决,编译出debug和release动态切换,不过博主没有动力去解决,不深入halide内部的话用release就够了)

生成工程之后首先切换DEBUG/RELEASE ,  然后ALL_BUILD,最后INSTALL,在install的时候如果install不成功,有可能是没有复制文件的权限,用管理员模式重启vs工程再install即可

编译clang的话也是一样,直接进入clang目录,用cmake生成工程,之后同样切换成debug release进行编译和安装即可。

 

三、编译halide

方式一:官方给的命令行cmake,可以直接用vcpkg配置(如果不需要绑定Python,-G Ninja可以不要),如果LLVM_DIR没有找到,也需要在命令里设置下

                 cmake -G Ninja ^
                       -DCMAKE_BUILD_TYPE=Release ^
                       -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake ^
                       ..\Halide

方式二:我们也可以通过cmake-gui来构建halide,这时要主要LLVM_DIR和CLANG_DIR是不是和前面设置的install目录一样,切换Debug Release

如果像下图这样出现DIR-NOTFOUND,那么需要检查下llvm和clang是否正确安装了。

我们在构建库的时候也可以看到教程,可以好好学习一下:

 

四、使用cmake引用halide

我们可以在自己 的工程中使用cmake轻而易举的引用halide,简单易懂,直接放CMakeLists:

若果你需要读取png或者jpeg,那么就要链接libpng和libjpeg,下面的CMakeLists里面是默认注释的,这个主意一下

cmake_minimum_required(VERSION 3.16)
project(HalideExample)

set(CMAKE_CXX_STANDARD 11)  # or newer
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

find_package(Halide REQUIRED)

# link image io 3rdparty library
##add_definitions(-DHALIDE_NO_PNG -DHALIDE_NO_JPEG)
#include_directories(${PNG_INCLUDE_DIRS})
#include_directories(${JPEG_INCLUDE_DIRS})
#link_libraries(STATUS PNG: ${PNG_LIBRARIES})
#link_libraries(STATUS JPEG: ${JPEG_LIBRARIES})

add_executable(my_halide_app main.cpp)
target_link_libraries(my_halide_app PRIVATE Halide::Halide)

AOT模式,参照官方文档

关于cmake  find_package(Halide REQUIRED) 产生的一些变量可能会有用,直接粘贴了:

First, Halide expects to find LLVM and Clang through the CONFIG mode of find_package. You can tell Halide where to find these dependencies by setting the corresponding _DIR variables:

Variable Description
LLVM_DIR Path to the directory containing LLVMConfig.cmake
Clang_DIR Path to the directory containing ClangConfig.cmake

When using CMake 3.18 or above, some of Halide’s tests will search for CUDA using the FindCUDAToolkit module. If it doesn’t find your CUDA installation automatically, you can point it to it by setting:

Variable Description
CUDAToolkit_ROOT Path to the directory containing bin/nvcc[.exe]
CUDA_PATH Environment variable, same as above.

If the CMake version is lower than 3.18, the deprecated FindCUDA module will be used instead. It reads the variable CUDA_TOOLKIT_ROOT_DIR instead of CUDAToolkit_ROOT above.

When targeting OpenGL, the FindOpenGL and FindX11 modules will be used to link AOT generated binaries. These modules can be overridden by setting the following variables:

Variable Description
OPENGL_egl_LIBRARY Path to the EGL library.
OPENGL_glu_LIBRARY Path to the GLU library.
OPENGL_glx_LIBRARY Path to the GLVND GLX library.
OPENGL_opengl_LIBRARY Path to the GLVND OpenGL library
OPENGL_gl_LIBRARY Path to the OpenGL library.

The OpenGL paths will need to be set if you intend to use OpenGL with X11 on macOS.

Halide also searches for libpng and libjpeg-turbo through the FindPNG and FindJPEG modules, respectively. They can be overridden by setting the following variables.

Variable Description
PNG_LIBRARIES Paths to the libraries to link against to use PNG.
PNG_INCLUDE_DIRS Path to png.h, etc.
JPEG_LIBRARIES Paths to the libraries needed to use JPEG.
JPEG_INCLUDE_DIRS Paths to jpeglib.h, etc.

When WITH_DOCS is set to ON, Halide searches for Doxygen using the FindDoxygen module. It can be overridden by setting the following variable.

Variable Description
DOXYGEN_EXECUTABLE Path to the Doxygen executable.

When compiling for an OpenCL target, Halide uses the FindOpenCL target to locate the libraries and include paths. These can be overridden by setting the following variables:

Variable Description
OpenCL_LIBRARIES Paths to the libraries to link against to use OpenCL.
OpenCL_INCLUDE_DIRS Include directories for OpenCL.

Lastly, Halide searches for Python 3 using the FindPython3 module, not the deprecated FindPythonInterp and FindPythonLibs modules, like other projects you might have encountered. You can select which Python installation to use by setting the following variable.

Variable Description
Python3_ROOT_DIR Define the root directory of a Python 3 installation.

 

五、配置环境变量

把Halide/bin所在目录添加到系统环境变量

对linux来说就是

export LD_LIBRARY_PATH=/usr/local/lib

六、Linux配置开发环境

官方文档已经说得很清楚,也是先编译llvm、然后编译halide。如果你是ubuntu,可以直接通过如下命令安装依赖

sudo apt install \
                  clang-tools lld llvm-dev libclang-dev liblld-10-dev \
                  libpng-dev libjpeg-dev libgl-dev \
                  python3-dev python3-numpy python3-scipy python3-imageio python3-pybind11 \
                  libopenblas-dev libeigen3-dev libatlas-base-dev \
                  doxygen ninja-build

再编译halide(下面目录记得换成自己的)

cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_DIR=/path/to/llvm-install/lib/cmake/llvm /path/to/Halide
cmake --build .

 

如果不绑定Python,-G Ninja选项可以不要

博主再补充一下,在库构建好之后,需要把libhalide.so所在的目录添加到环境(否则程序会提示缺少libhalide.so):

export LD_LIBRARY_PATH=/usr/local/lib

 

博主自己正在整理一些Halide的实现,持续更新中(也包括官网的教程在里面):

OK, See You Next Chapter !

发表评论

邮箱地址不会被公开。 必填项已用*标注