如何可视化 Halide 相机管道/生成 Halide 如何编译的 HTML 输出?

How to visualize Halide camera pipeline / generate HTML output of how Halide compiles?

我尝试将以下行添加到 camera_pipe_generator.cpp 的底部以输出 Halide 如何编译成 .html 文件,但我不确定我做错了什么:

processed.compile_to_lowered_stmt("camera_pipe_debugging_trial.html", {}, HTML);

我认为我的第二个参数是错误的,但是我应该在这里传递什么?

或者我可以通过其他方式可视化日程安排吗? 似乎暗示存在 Halide 的可视化工具。有没有关于如何使用它的资源?

谢谢!

编辑:我试过 运行 命令

../../tools/gengen.sh -c c++ -lcurses -l ../../lib/libHalide.a -o tmp/ -e html -s camera_pipe_generator.cpp target=host 

但是,这导致了以下错误:

Undefined symbols for architecture x86_64:
  "_del_curterm", referenced from:
      llvm::sys::Process::FileDescriptorHasColors(int) in libHalide.a(llvm_460_Process.cpp.o)
  "_set_curterm", referenced from:
      llvm::sys::Process::FileDescriptorHasColors(int) in libHalide.a(llvm_460_Process.cpp.o)
  "_setupterm", referenced from:
      llvm::sys::Process::FileDescriptorHasColors(int) in libHalide.a(llvm_460_Process.cpp.o)
  "_tigetnum", referenced from:
      llvm::sys::Process::FileDescriptorHasColors(int) in libHalide.a(llvm_460_Process.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我认为这可能与 mac OSX 10.12.3 上的 运行 有关?

最终编辑:在 gengen.sh 文件中添加了选项“-lcurses”,它起作用了!

到apps/camera_pipe目录下,下面的命令行会生成HTMLstmt文件到/tmp/camera_pipe.html:

../../tools/gengen.sh -c c++ -l ../../lib/libHalide.a -o /tmp/ -e html -s camera_pipe_generator.cpp target=host

要将 Halide 代码可视化为 MPEG 文件,需要以下内容:

  1. 编译为 AOT 二进制的卤化物过滤器
  2. 练习AOT二进制文件的源代码
  3. Bash shell 构建和执行 HalideTraceViz 的脚本
  4. 上述所有资源都在同一文件夹中

关于第 4 点,我确信这可以改变,但对于我进行的试验,这是我能够使事情正常进行的唯一方法;欢迎任何可以分享他们对最后一点的意见的人这样做。

1: 卤化物过滤器编译为 AOT 二进制文件

我使用 halide-lang.org tutorial site 中列出的增亮滤镜来创建下面列出的滤镜并将其编译为可用的二进制文件:

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 binary

的源代码
#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 脚本,其中我:

  1. 构建 HalideTraceViz.cpp 代码
  2. 构建 AOT 生成器和过滤器练习器应用程序
  3. 将二进制文件复制到一个目录中
  4. 使用用于将数据传递到 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

有几点需要注意:

  1. 我使用 Xcode 编译项目,但显然,您可以使用任何您熟悉的工具
  2. HalideTraceViz 在 "Halide/util/" 中带有它自己的 cmake 文件;该文件夹是 Halide git repo
  3. 的一部分
  4. 对于 bash shell 脚本代码,您必须调整文件夹路径以适应您的开发设置
  5. 你在上面看到的所有代码都是现在才创建的,所以我不能保证它能按原样工作:)

希望这可以帮助您入门;如果您有任何问题,请告诉我。