要将您的 Halide 代码可视化为 MPEG 文件,需要以下内容:
- 卤化物过滤器编译为 AOT 二进制文件
- 练习 AOT 二进制的源代码
- 用于构建和执行 HalideTraceViz 的 Bash shell 脚本
- 上述所有资产在同一个文件夹中
关于第 4 点,我确信这可以改变,但对于我进行的试验,这是我能够让事情正常进行的唯一方法;欢迎任何可以就最后一点分享意见的人这样做。
1:卤化物过滤器编译为 AOT 二进制
我使用 halide-lang.org 教程网站上列出的增亮过滤器来创建下面列出的过滤器并将其编译为可用的二进制文件:
http://halide-lang.org/tutorials/tutorial_lesson_10_aot_compilation_generate.html
#include "Halide.h"
#include <iostream>
namespace
{
auto input = Halide::ImageParam(Halide::type_of< uint8_t >(), 2, std::string{"input_image"});
auto offset = Halide::Param< uint8_t >{"offset"};
} // anonymous namespace
auto create_filter() -> Halide::Func
{
auto x = Halide::Var{"x"};
auto y = Halide::Var{"y"};
auto brighten = Halide::Func{"filter_output"};
brighten(x, y) = input(x, y) + offset;
return brighten;
}
auto schedule_filter(Halide::Func filter_ref) { filter_ref.vectorize(x, 16).parallel(y); }
auto create_aot_binary()
{
auto args = std::vector< Halide::Argument >{input, offset};
brighten.compile_to_file("brighten", args);
}
int main(int argc, const char* argv[])
{
printf("brighten filter AOT binary generator\n");
auto brighten = create_filter();
schedule_filter(brighten);
create_aot_binary();
return 0;
}
2.练习AOT二进制的源码
#include "brighten.h" // header file created by aot generator in step 1
#include <cassert>
#include <vector>
namespace
{
constexpr auto width = 16 * 4;
constexpr auto height = 16 * 4;
} // anonymous namespace
auto create_input_image() -> std::vector< uint8_t >
{
auto image = std::vector< uint8_t >(width * height, 0);
for (auto y = 0; y < width; y++)
{
for (auto x = 0; x < height; x++)
{
const auto val = x ^ (y + 1);
const auto index = y * height + x;
image[index] = val;
}
}
return image;
}
auto create_buffer_t_with_data(const std::vector< uint8_t >& image) -> buffer_t
{
auto buff = buffer_t{0};
buff.host = image.data();
buff.stride[0] = 1;
buff.stride[1] = width;
buff.extent[0] = width;
buff.extent[1] = height;
buff.elem_size = 1;
}
int main(int argc, const char* argv[])
{
printf("brighten filter exercise\n");
auto input_image = create_input_image();
assert(input_image.size() != 0);
auto input_buf = create_buffer_t_with_data(input_image);
auto output_image = std::vector< uint8_t >(width * height, 0);
assert(output_image.size() != 0);
auto output_buf = create_buffer_t_with_data(output_image);
const auto offset = 1;
auto error = brighten(&input_buf, offset, &output_buf);
(void)error;
return 0;
}
3. Bash shell脚本构建和执行HalideTraceViz
现在,这是 bash shell 脚本,我在其中:
- 构建 HalideTraceViz.cpp 代码
- 构建 AOT 生成器和过滤器练习器应用程序
- 将二进制文件复制到一个目录中
- 调用具有特殊参数的应用程序,这些参数用于将数据传递到 HalideTraceViz 应用程序
#!/bin/bash
set -e
set -u
function build_binaries()
{
printf "${FUNCNAME[0]}\n"
printf "Building HalideTraceViz\n"
xcodebuild -project visualize_brighten.xcodeproj -scheme HalideTraceViz CONFIGURATION_BUILD_DIR=build/Debug -configuration "Debug" clean build
printf "Building generate_brighten_aot\n"
xcodebuild -project visualize_brighten.xcodeproj -scheme generate_brighten_aot CONFIGURATION_BUILD_DIR=build/Debug -configuration "Debug" clean build
printf "Generating AOT in order to build exercise app\n"
cd build/Debug
HL_TRACE=3 ./generate_brighten_aot
cd $CURRENT_PATH
printf "Building app to exercise brighten filter\n"
xcodebuild -project visualize_brighten.xcodeproj -scheme exercise_brighten_aot CONFIGURATION_BUILD_DIR=build/Debug -configuration "Debug" clean build
cd $CURRENT_PATH
}
function copy_binaries()
{
printf "${FUNCNAME[0]}\n"
if [[ -d $CURRENT_PATH/halide_visualizer ]]; then
rm -Rv $CURRENT_PATH/halide_visualizer
fi
mkdir $CURRENT_PATH/halide_visualizer
cp -Rv $CURRENT_PATH/build/Debug $CURRENT_PATH/halide_visualizer/Debug
}
function visualize_function()
{
printf "${FUNCNAME[0]}\n"
local BLANK=0
local DIMENSIONS=1
local ZOOM=8
local COST=4
local STRIDE0="1 0"
local STRIDE1="0 1"
local FFMPEG_BIN_PATH="YOU_HAVE_TO_DOWNLOAD_THIS_BIN_AND_SET_THE_PATH_HERE"
cd $CURRENT_PATH/halide_visualizer/Debug
echo "About to start visualizing brighten filter"
HL_TRACE=3 ./generate_brighten_aot && \
HL_TRACE_FILE=/dev/stdout ./exercise_brighten_aot | \
$CURRENT_PATH/build/Debug/HalideTraceViz -s 1024 516 -t 1 -d 100 \
-f brighten:input_image 0 255 $BLANK $ZOOM $COST 0 0 $STRIDE0 $STRIDE1 |\
$FFMPEG_BIN_PATH/ffmpeg -r 30 -f rawvideo -pix_fmt bgra -s 1024X516 -i - -y -pix_fmt yuv420p $CURRENT_PATH/movies/brighten_schedule.mp4
cd $CURRENT_PATH
}
main()
{
printf "${FUNCNAME[0]}\n"
CURRENT_PATH=$PWD
build_binaries
copy_binaries
visualize_function
printf "All done\n"
}
printf "Starting ${0##*/}\n"
main
有几点需要注意:
- 我使用 Xcode 编译项目,但显然,您可以使用任何您熟悉的工具
- HalideTraceViz 在“Halide/util/”中带有它自己的 cmake 文件;该文件夹是 Halide git repo 的一部分
- 对于 bash shell 脚本代码,您必须调整文件夹路径以使用您的开发设置
- 您在上面看到的所有代码都是刚刚创建的,所以我不能保证它按原样工作:)
希望这可以帮助您入门;如果您有任何问题,请告诉我。