diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ba5ce9697f0..388ac969b41f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ Halide_feature( DEPENDS WITH_TUTORIALS AND WITH_PYTHON_BINDINGS ) Halide_feature( - WITH_UTILS "Optional utility programs for Halide, including HalideTraceViz" TOP_LEVEL + WITH_UTILS "Optional utility programs for Halide, including HalideTraceDump" TOP_LEVEL ) diff --git a/Makefile b/Makefile index 8d22bc10e1dc..ff0a420bf574 100644 --- a/Makefile +++ b/Makefile @@ -2517,7 +2517,6 @@ $(DISTRIB_DIR)/lib/libHalide.$(SHARED_EXT): \ cp $(ROOT_DIR)/tools/halide_malloc_trace.h $(DISTRIB_DIR)/tools cp $(ROOT_DIR)/tools/halide_thread_pool.h $(DISTRIB_DIR)/tools cp $(ROOT_DIR)/tools/halide_trace_compression.h $(DISTRIB_DIR)/tools - cp $(ROOT_DIR)/tools/halide_trace_config.h $(DISTRIB_DIR)/tools cp $(ROOT_DIR)/README*.md $(DISTRIB_DIR) cp $(BUILD_DIR)/halide_config.* $(DISTRIB_DIR) ifeq ($(UNAME), Darwin) @@ -2591,9 +2590,6 @@ $(DISTRIB_DIR)/halide.tgz: distrib rm -rf halide mv $(BUILD_DIR)/halide.tgz $(DISTRIB_DIR)/halide.tgz -$(BIN_DIR)/HalideTraceViz: $(ROOT_DIR)/util/HalideTraceViz.cpp $(INCLUDE_DIR)/HalideRuntime.h $(ROOT_DIR)/tools/halide_image_io.h $(ROOT_DIR)/tools/halide_trace_config.h - $(CXX) $(OPTIMIZE) -std=c++17 $(filter %.cpp,$^) -I$(INCLUDE_DIR) -I$(ROOT_DIR)/tools -L$(BIN_DIR) -o $@ - $(BIN_DIR)/HalideTraceDump: $(ROOT_DIR)/util/HalideTraceDump.cpp $(ROOT_DIR)/util/HalideTraceUtils.cpp $(INCLUDE_DIR)/HalideRuntime.h $(ROOT_DIR)/tools/halide_image_io.h $(CXX) $(OPTIMIZE) -std=c++17 $(filter %.cpp,$^) -I$(INCLUDE_DIR) -I$(ROOT_DIR)/tools -I$(ROOT_DIR)/src/runtime -L$(BIN_DIR) $(IMAGE_IO_CXX_FLAGS) $(IMAGE_IO_LIBS) -o $@ diff --git a/README.md b/README.md index 81b1184aad1f..fcd51aedcfc9 100644 --- a/README.md +++ b/README.md @@ -522,8 +522,8 @@ default, the number of cores on the host is used.) `HL_TRACE_FILE=...` specifies a binary target file to dump tracing data into (ignored unless at least one `trace_` feature is enabled in the target). The -output can be parsed programmatically by starting from the code in -`utils/HalideTraceViz.cpp`. +output can be visualized with `tools/halidoscope`, or parsed programmatically by +starting from the code in `util/HalideTraceDump.cpp`. `HL_CACHE_DIR=...` enables the opt-in generator compile cache, restoring a generator's previously emitted artifacts instead of recompiling when its inputs diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index afc90b173081..969775a008f5 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -41,7 +41,6 @@ if (Halide_TARGET MATCHES "wasm") endif () # keep-sorted start case=no ignore_prefixes=# -add_app(auto_viz) add_app(bgu) add_app(bilateral_grid) add_app(blur) diff --git a/apps/auto_viz/CMakeLists.txt b/apps/auto_viz/CMakeLists.txt deleted file mode 100644 index a19b15bc7896..000000000000 --- a/apps/auto_viz/CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -cmake_minimum_required(VERSION 3.28) -project(auto_viz) - -enable_testing() - -# Set up language settings -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED YES) -set(CMAKE_CXX_EXTENSIONS NO) - -# Find Halide -find_package(Halide REQUIRED) - -# Generator -add_halide_generator(auto_viz_demo.generator SOURCES auto_viz_demo_generator.cpp) - -# Filters: one library per (schedule, direction) pair, all built with tracing -# enabled so the pipelines can be visualized with HalideTraceViz. -set(variants "") -foreach (schedule IN ITEMS naive lessnaive complex) - add_halide_library( - auto_viz_demo_${schedule}_up - FROM auto_viz_demo.generator - GENERATOR auto_viz_demo - FEATURES trace_all - PARAMS schedule_type=${schedule} upsample=true - ) - add_halide_library( - auto_viz_demo_${schedule}_down - FROM auto_viz_demo.generator - GENERATOR auto_viz_demo - FEATURES trace_all - PARAMS schedule_type=${schedule} upsample=false - ) - list(APPEND variants auto_viz_demo_${schedule}_up auto_viz_demo_${schedule}_down) -endforeach () - -# Main executable -add_executable(auto_viz auto_viz_demo.cpp) -target_link_libraries(auto_viz PRIVATE Halide::ImageIO ${variants}) - -# Test that the app actually works! - -if (WIN32) - set(_auto_viz_trace_sink "NUL") -else () - set(_auto_viz_trace_sink "/dev/null") -endif () - -set(IMAGE ${CMAKE_CURRENT_LIST_DIR}/../images/rgb_small.png) -if (EXISTS ${IMAGE}) - foreach (schedule IN ITEMS naive lessnaive complex) - add_test( - NAME auto_viz_demo_${schedule}_up - COMMAND auto_viz ${IMAGE} out_${schedule}_up.png -s ${schedule} -f 4.0 - ) - add_test( - NAME auto_viz_demo_${schedule}_down - COMMAND auto_viz ${IMAGE} out_${schedule}_down.png -s ${schedule} -f 0.25 - ) - set_tests_properties( - auto_viz_demo_${schedule}_up auto_viz_demo_${schedule}_down - PROPERTIES - LABELS auto_viz - ENVIRONMENT "HL_TRACE_FILE=${_auto_viz_trace_sink}" - SKIP_REGULAR_EXPRESSION "\\[SKIP\\]" - ) - endforeach () -endif () diff --git a/apps/auto_viz/Makefile b/apps/auto_viz/Makefile deleted file mode 100644 index 9dac634c1105..000000000000 --- a/apps/auto_viz/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -include ../support/Makefile.inc - -VARIANTS = naive lessnaive complex - -OUTPUTS = $(foreach V,$(VARIANTS),$(BIN)/$(HL_TARGET)/out_$(V)_up.png $(BIN)/$(HL_TARGET)/out_$(V)_down.png) - -all: $(OUTPUTS) - -$(GENERATOR_BIN)/auto_viz_demo.generator: auto_viz_demo_generator.cpp $(GENERATOR_DEPS) - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) $(filter-out %.h,$^) -o $@ $(LIBHALIDE_LDFLAGS) - -# Can't have multiple wildcards in Make, so we'll use a macro -# to stamp out all the rules we need -define GEN_RULES -$$(BIN)/%/auto_viz_demo_$(1)_up.a: $$(GENERATOR_BIN)/auto_viz_demo.generator - @mkdir -p $$(@D) - $$^ -g auto_viz_demo -o $$(@D) -f auto_viz_demo_$(1)_up \ - -e $$(GENERATOR_OUTPUTS) \ - target=$$*-no_runtime-trace_all \ - schedule_type=$$$$(echo $(1) | cut -d_ -f1) \ - upsample=true - -$$(BIN)/%/auto_viz_demo_$(1)_down.a: $$(GENERATOR_BIN)/auto_viz_demo.generator - @mkdir -p $$(@D) - $$^ -g auto_viz_demo -o $$(@D) -f auto_viz_demo_$(1)_down \ - -e $$(GENERATOR_OUTPUTS) \ - target=$$*-no_runtime-trace_all \ - schedule_type=$$$$(echo $(1) | cut -d_ -f1) \ - upsample=false - -$$(BIN)/%/out_$(1)_up.png: $$(BIN)/%/auto_viz_demo - @mkdir -p $$(@D) - @echo Creating out_$(1)_up.png... - @$$< \ - $$(IMAGES)/rgb_small.png \ - $$@ \ - -s $$$$(echo $(1) | cut -d_ -f1) \ - -f 4.0 - -$$(BIN)/%/out_$(1)_down.png: $$(BIN)/%/auto_viz_demo - @mkdir -p $$(@D) - @echo Creating out_$(1)_down.png... - @$$< \ - $$(IMAGES)/rgb.png \ - $$@ \ - -s $$$$(echo $(1) | cut -d_ -f1) \ - -f 0.5 - -$$(BIN)/%/viz_$(1).mp4: $$(BIN)/%/auto_viz_demo ../support/viz_auto.sh ../../bin/HalideTraceViz - @mkdir -p $$(@D) - HL_AVCONV=$$(HL_AVCONV) bash ../support/viz_auto.sh \ - "$$< $$(IMAGES)/rgb_small.png /tmp/$(1).png -s $(1) -f 0.5 " \ - "../../bin/HalideTraceViz --auto_layout" \ - $$@ -endef - -$(foreach V,$(VARIANTS),$(eval $(call GEN_RULES,$(V)))) - -$(BIN)/%/runtime.a: $(GENERATOR_BIN)/auto_viz_demo.generator - @mkdir -p $(@D) - $^ -r runtime -o $(@D) target=$* - -LIBRARIES = $(foreach V,$(VARIANTS),$(BIN)/%/auto_viz_demo_$(V)_up.a $(BIN)/%/auto_viz_demo_$(V)_down.a) -$(BIN)/%/auto_viz_demo: auto_viz_demo.cpp $(BIN)/%/runtime.a $(LIBRARIES) - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -I$(BIN)/$* $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS) - -clean: - rm -rf $(BIN) - -test: all - -../../bin/HalideTraceViz: ../../util/HalideTraceViz.cpp - $(MAKE) -C ../../ bin/HalideTraceViz - -# make viz_naive -# make viz_lessnaive -# make viz_complex -viz_%: $(BIN)/$(HL_TARGET)/viz_%.mp4 - $(HL_VIDEOPLAYER) $^ - -viz: viz_naive viz_lessnaive viz_complex diff --git a/apps/auto_viz/auto_viz_demo.cpp b/apps/auto_viz/auto_viz_demo.cpp deleted file mode 100644 index 180c0e13aaad..000000000000 --- a/apps/auto_viz/auto_viz_demo.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include - -#include "HalideBuffer.h" -#include "halide_image_io.h" - -#include "auto_viz_demo_complex_down.h" -#include "auto_viz_demo_complex_up.h" -#include "auto_viz_demo_lessnaive_down.h" -#include "auto_viz_demo_lessnaive_up.h" -#include "auto_viz_demo_naive_down.h" -#include "auto_viz_demo_naive_up.h" - -std::string infile, outfile, schedule_type; -float scale_factor = 1.0f; -int benchmark_iters = 10; - -void show_usage_and_exit() { - fprintf(stderr, - "Usage:\n" - "\t./resample [-f scalefactor] " - "[-s naive|lessnaive|complex] " - "in.png out.png\n"); - exit(1); -} - -void parse_commandline(int argc, char **argv) { - for (int i = 1; i < argc; i++) { - std::string arg = argv[i]; - if (arg == "-f" && i + 1 < argc) { - scale_factor = atof(argv[++i]); - } else if (arg == "-s" && i + 1 < argc) { - schedule_type = argv[++i]; - } else if (infile.empty()) { - infile = arg; - } else if (outfile.empty()) { - outfile = arg; - } else { - fprintf(stderr, "Unexpected command line option '%s'.\n", arg.c_str()); - show_usage_and_exit(); - } - } - - if (infile.empty() || outfile.empty() || schedule_type.empty()) { - show_usage_and_exit(); - } -} - -int main(int argc, char **argv) { - parse_commandline(argc, argv); - - Halide::Runtime::Buffer in = Halide::Tools::load_and_convert_image(infile); - int out_width = in.width() * scale_factor; - int out_height = in.height() * scale_factor; - Halide::Runtime::Buffer out(out_width, out_height, 3); - - decltype(&auto_viz_demo_naive_up) variants[2][3] = - { - {&auto_viz_demo_naive_up, - &auto_viz_demo_lessnaive_up, - &auto_viz_demo_complex_up}, - {&auto_viz_demo_naive_down, - &auto_viz_demo_lessnaive_down, - &auto_viz_demo_complex_down}, - }; - - int schedule_idx = 0; - if (schedule_type == "naive") { - schedule_idx = 0; - } else if (schedule_type == "lessnaive") { - schedule_idx = 1; - } else if (schedule_type == "complex") { - schedule_idx = 2; - } else { - fprintf(stderr, "Unknown schedule type: %s\n", schedule_type.c_str()); - show_usage_and_exit(); - } - - int upsample_idx = scale_factor > 1.0f ? 0 : 1; - - auto fn = variants[upsample_idx][schedule_idx]; - - fn(in, scale_factor, out); - - Halide::Tools::convert_and_save_image(out, outfile); - - return 0; -} diff --git a/apps/auto_viz/auto_viz_demo_generator.cpp b/apps/auto_viz/auto_viz_demo_generator.cpp deleted file mode 100644 index fc670f2a8ac8..000000000000 --- a/apps/auto_viz/auto_viz_demo_generator.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "Halide.h" - -using namespace Halide; - -enum ScheduleType { - Naive, - LessNaive, - Complex -}; - -// This is a dumbed-down version of the Resize generator, intended solely -// to demonstrate use of HalideTraceViz auto-layout mode; it has multiple -// schedule, ranging from 'naive' to 'complex', intended to demonstrate -// how even basic auto-layout of tracing can be useful. -// -// The approach of using an enum for 'naive-of-complex-schedule' is an expedient -// for this purpose; it shouldn't me mimicked in most real-world code. -class AutoVizDemo : public Halide::Generator { -public: - GeneratorParam schedule_type{"schedule_type", Naive, {{"naive", Naive}, {"lessnaive", LessNaive}, {"complex", Complex}}}; - - // If we statically know whether we're upsampling or downsampling, - // we can generate different pipelines (we want to reorder the - // resample in x and in y). - GeneratorParam upsample{"upsample", false}; - - Input> input{"input"}; - Input scale_factor{"scale_factor"}; - Output> output{"output"}; - - // Common Vars - Var x, y, c, k; - - // Intermediate Funcs - Func as_float, clamped, resized_x, resized_y, - unnormalized_kernel_x, unnormalized_kernel_y, - kernel_x, kernel_y, - kernel_sum_x, kernel_sum_y; - - void generate() { - - clamped = BoundaryConditions::repeat_edge(input, - {{input.dim(0).min(), input.dim(0).extent()}, - {input.dim(1).min(), input.dim(1).extent()}}); - - // Handle different types by just casting to float - as_float(x, y, c) = cast(clamped(x, y, c)); - - // For downscaling, widen the interpolation kernel to perform lowpass - // filtering. - - Expr kernel_scaling = upsample ? Expr(1.0f) : scale_factor; - - Expr kernel_radius = 0.5f / kernel_scaling; - - Expr kernel_taps = ceil(1.0f / kernel_scaling); - - // source[xy] are the (non-integer) coordinates inside the source image - Expr sourcex = (x + 0.5f) / scale_factor - 0.5f; - Expr sourcey = (y + 0.5f) / scale_factor - 0.5f; - - // Initialize interpolation kernels. Since we allow an arbitrary - // scaling factor, the filter coefficients are different for each x - // and y coordinate. - Expr beginx = cast(ceil(sourcex - kernel_radius)); - Expr beginy = cast(ceil(sourcey - kernel_radius)); - - RDom r(0, cast(kernel_taps)); - - auto kernel = [](Expr x) -> Expr { - Expr xx = abs(x); - return select(abs(x) <= 0.5f, 1.0f, 0.0f); - }; - unnormalized_kernel_x(x, k) = kernel((k + beginx - sourcex) * kernel_scaling); - unnormalized_kernel_y(y, k) = kernel((k + beginy - sourcey) * kernel_scaling); - - kernel_sum_x(x) = sum(unnormalized_kernel_x(x, r), "kernel_sum_x"); - kernel_sum_y(y) = sum(unnormalized_kernel_y(y, r), "kernel_sum_y"); - - kernel_x(x, k) = unnormalized_kernel_x(x, k) / kernel_sum_x(x); - kernel_y(y, k) = unnormalized_kernel_y(y, k) / kernel_sum_y(y); - - // Perform separable resizing. The resize in x vectorizes - // poorly compared to the resize in y, so do it first if we're - // upsampling, and do it second if we're downsampling. - Func resized; - if (upsample) { - resized_x(x, y, c) = sum(kernel_x(x, r) * as_float(r + beginx, y, c), "resized_x"); - resized_y(x, y, c) = sum(kernel_y(y, r) * resized_x(x, r + beginy, c), "resized_y"); - resized = resized_y; - } else { - resized_y(x, y, c) = sum(kernel_y(y, r) * as_float(x, r + beginy, c), "resized_y"); - resized_x(x, y, c) = sum(kernel_x(x, r) * resized_y(r + beginx, y, c), "resized_x"); - resized = resized_x; - } - - if (input.type().is_float()) { - output(x, y, c) = clamp(resized(x, y, c), 0.0f, 1.0f); - } else { - output(x, y, c) = saturating_cast(input.type(), resized(x, y, c)); - } - } - - void schedule() { - Var xi, yi; - if (schedule_type == Naive) { - // naive: compute_root() everything - unnormalized_kernel_x - .compute_root(); - kernel_sum_x - .compute_root(); - kernel_x - .compute_root(); - unnormalized_kernel_y - .compute_root(); - kernel_sum_y - .compute_root(); - kernel_y - .compute_root(); - as_float - .compute_root(); - resized_x - .compute_root(); - output - .compute_root(); - } else if (schedule_type == LessNaive) { - // less-naive: add vectorization and parallelism to 'large' realizations; - // use compute_at for as_float calculation - unnormalized_kernel_x - .compute_root(); - kernel_sum_x - .compute_root(); - kernel_x - .compute_root(); - - unnormalized_kernel_y - .compute_root(); - kernel_sum_y - .compute_root(); - kernel_y - .compute_root(); - - as_float - .compute_at(resized_x, y); - resized_x - .compute_root() - .parallel(y); - output - .compute_root() - .parallel(y) - .vectorize(x, 8); - } else if (schedule_type == Complex) { - // complex: use compute_at() and tiling intelligently. - unnormalized_kernel_x - .compute_at(kernel_x, x) - .vectorize(x); - kernel_sum_x - .compute_at(kernel_x, x) - .vectorize(x); - kernel_x - .compute_root() - .reorder(k, x) - .vectorize(x, 8); - - unnormalized_kernel_y - .compute_at(kernel_y, y) - .vectorize(y, 8); - kernel_sum_y - .compute_at(kernel_y, y) - .vectorize(y); - kernel_y - .compute_at(output, y) - .reorder(k, y) - .vectorize(y, 8); - - if (upsample) { - as_float - .compute_at(output, y) - .vectorize(x, 8); - resized_x - .compute_at(output, x) - .vectorize(x, 8); - output - .tile(x, y, xi, yi, 16, 64) - .parallel(y) - .vectorize(xi); - } else { - resized_y - .compute_at(output, y) - .vectorize(x, 8); - resized_x - .compute_at(output, xi); - output - .tile(x, y, xi, yi, 32, 8) - .parallel(y) - .vectorize(xi); - } - } - } -}; - -HALIDE_REGISTER_GENERATOR(AutoVizDemo, auto_viz_demo); diff --git a/apps/bilateral_grid/Makefile b/apps/bilateral_grid/Makefile index 11d79fbcd946..cda6eae38606 100644 --- a/apps/bilateral_grid/Makefile +++ b/apps/bilateral_grid/Makefile @@ -20,17 +20,6 @@ $(BIN)/%/filter: filter.cpp $(BIN)/%/bilateral_grid.a $(BIN)/%/bilateral_grid_au @mkdir -p $(@D) $(CXX) $(CXXFLAGS) -I$(BIN)/$* $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS) -$(BIN)/%/filter_viz: filter.cpp $(BIN)/%-trace_all/bilateral_grid.a - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -DNO_AUTO_SCHEDULE -I$(BIN)/$*-trace_all $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS) - -../../bin/HalideTraceViz: ../../util/HalideTraceViz.cpp - $(MAKE) -C ../../ bin/HalideTraceViz - -$(BIN)/%/bilateral_grid.mp4: $(BIN)/%/filter_viz viz.sh ../../bin/HalideTraceViz - @mkdir -p $(@D) - HL_AVCONV=$(HL_AVCONV) bash viz.sh $(BIN)/$* - $(BIN)/%/out.png: $(BIN)/%/filter @mkdir -p $(@D) $< $(IMAGES)/gray.png $@ 0.1 10 @@ -43,13 +32,3 @@ clean: rm -rf $(BIN) test: $(BIN)/$(HL_TARGET)/out.png $(BIN)/$(HL_TARGET)/out.tiff - -viz: $(BIN)/$(HL_TARGET)/bilateral_grid.mp4 - $(HL_VIDEOPLAYER) $^ - -$(BIN)/%/viz_auto.mp4: $(BIN)/%/filter_viz ../support/viz_auto.sh ../../bin/HalideTraceViz - @mkdir -p $(@D) - HL_AVCONV=$(HL_AVCONV) bash ../support/viz_auto.sh "$(BIN)/$*/filter_viz $(IMAGES)/gray_small.png $(BIN)/$*/out_small.png 0.2 0" ../../bin/HalideTraceViz $@ - -viz_auto: $(BIN)/$(HL_TARGET)/viz_auto.mp4 - $(HL_VIDEOPLAYER) $^ diff --git a/apps/bilateral_grid/bilateral_grid_generator.cpp b/apps/bilateral_grid/bilateral_grid_generator.cpp index ce0c6659403d..0b50f1f389fb 100644 --- a/apps/bilateral_grid/bilateral_grid_generator.cpp +++ b/apps/bilateral_grid/bilateral_grid_generator.cpp @@ -1,5 +1,4 @@ #include "Halide.h" -#include "halide_trace_config.h" namespace { @@ -148,53 +147,6 @@ class BilateralGrid : public Halide::Generator { .parallel(y, 8) .vectorize(x, 8); } - - /* Optional tags to specify layout for HalideTraceViz */ - { - Halide::Trace::FuncConfig cfg; - cfg.pos.x = 100; - cfg.pos.y = 300; - input.add_trace_tag(cfg.to_trace_tag()); - - cfg.pos.x = 1564; - bilateral_grid.add_trace_tag(cfg.to_trace_tag()); - } - { - Halide::Trace::FuncConfig cfg; - cfg.strides = {{1, 0}, {0, 1}, {40, 0}}; - cfg.zoom = 3; - - cfg.max = 32; - cfg.pos.x = 550; - cfg.pos.y = 100; - histogram.add_trace_tag(cfg.to_trace_tag()); - - cfg.max = 512; - cfg.pos.y = 300; - blurz.add_trace_tag(cfg.to_trace_tag()); - - cfg.max = 8192; - cfg.pos.y = 500; - blurx.add_trace_tag(cfg.to_trace_tag()); - - cfg.max = 131072; - cfg.pos.y = 700; - blury.add_trace_tag(cfg.to_trace_tag()); - } - { - // GlobalConfig applies to the entire visualization pipeline; - // you can set this tag on any Func that is realized, but only - // the last one seen will be used. (Since the tags are emitted in - // an arbitrary order, emitting only one such tag is the best practice). - // Note also that since the global settings are often context-dependent - // (eg the output size and timestep may vary depending on the - // input data), it's often more useful to specify these on the - // command line. - Halide::Trace::GlobalConfig global_cfg; - global_cfg.timestep = 1000; - - bilateral_grid.add_trace_tag(global_cfg.to_trace_tag()); - } } }; diff --git a/apps/bilateral_grid/viz.sh b/apps/bilateral_grid/viz.sh deleted file mode 100755 index 549c29d28ed8..000000000000 --- a/apps/bilateral_grid/viz.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -echo HL_AVCONV is "${HL_AVCONV}" -export HL_TRACE_FILE=/dev/stdout -export HL_NUMTHREADS=4 -rm -f "$1"/bilateral_grid.mp4 -set -euo pipefail -make "$1"/filter_viz && - "$1"/filter_viz ../images/gray_small.png "$1"/out_small.png 0.2 0 | - ../../bin/HalideTraceViz --size 1920 1080 | - ${HL_AVCONV} -f rawvideo -pix_fmt bgr32 -s 1920x1080 -i /dev/stdin -c:v h264 "$1"/bilateral_grid.mp4 -#mplayer -demuxer rawvideo -rawvideo w=1920:h=1080:format=rgba:fps=30 -idle -fixed-vo - diff --git a/apps/camera_pipe/Makefile b/apps/camera_pipe/Makefile index 630337ba2197..9cedd4201ca8 100644 --- a/apps/camera_pipe/Makefile +++ b/apps/camera_pipe/Makefile @@ -22,31 +22,11 @@ $(BIN)/%/process: process.cpp $(BIN)/%/camera_pipe.a $(BIN)/%/camera_pipe_auto_s @mkdir -p $(@D) $(CXX) $(CXXFLAGS) -Wall -I$(BIN)/$* $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS) -$(BIN)/%/process_viz: process.cpp $(BIN)/%-trace_all/camera_pipe.a - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -DNO_AUTO_SCHEDULE -Wall -I$(BIN)/$*-trace_all $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS) - $(BIN)/%/out.png: $(BIN)/%/process @mkdir -p $(@D) $(BIN)/$*/process $(IMAGES)/bayer_raw.png 3700 2.0 50 1.0 $(TIMING_ITERATIONS) $@ $(BIN)/$*/h_auto.png -../../bin/HalideTraceViz: ../../util/HalideTraceViz.cpp - $(MAKE) -C ../../ bin/HalideTraceViz - -$(BIN)/%/camera_pipe.mp4: $(BIN)/%/process_viz viz.sh $(HALIDE_TRACE_VIZ) ../../bin/HalideTraceViz - HL_AVCONV=$(HL_AVCONV) bash viz.sh $(@D) - clean: rm -rf $(BIN) test: $(BIN)/$(HL_TARGET)/out.png - -viz: $(BIN)/$(HL_TARGET)/camera_pipe.mp4 - $(HL_VIDEOPLAYER) $^ - -$(BIN)/%/viz_auto.mp4: $(BIN)/%/process_viz ../support/viz_auto.sh ../../bin/HalideTraceViz - @mkdir -p $(@D) - HL_AVCONV=$(HL_AVCONV) bash ../support/viz_auto.sh "$(BIN)/$*/process_viz $(IMAGES)/bayer_small.png 3700 1.8 50 1 1 $(BIN)/$*/out.png" ../../bin/HalideTraceViz $@ - -viz_auto: $(BIN)/$(HL_TARGET)/viz_auto.mp4 - $(HL_VIDEOPLAYER) $^ diff --git a/apps/camera_pipe/camera_pipe_generator.cpp b/apps/camera_pipe/camera_pipe_generator.cpp index 3897184490fe..093d82ee9226 100644 --- a/apps/camera_pipe/camera_pipe_generator.cpp +++ b/apps/camera_pipe/camera_pipe_generator.cpp @@ -1,5 +1,4 @@ #include "Halide.h" -#include "halide_trace_config.h" #include namespace { @@ -191,18 +190,6 @@ class Demosaic : public Halide::Generator { } } } - - /* Optional tags to specify layout for HalideTraceViz */ - Halide::Trace::FuncConfig cfg; - cfg.pos = {860, 340 - 220}; - cfg.max = 1024; - for (Func f : intermediates) { - std::string label = f.name(); - std::replace(label.begin(), label.end(), '_', '@'); - cfg.pos.y += 220; - cfg.labels = {{label}}; - f.add_trace_tag(cfg.to_trace_tag()); - } } private: @@ -340,14 +327,6 @@ Func CameraPipe::apply_curve(Func input) { } } - /* Optional tags to specify layout for HalideTraceViz */ - { - Halide::Trace::FuncConfig cfg; - cfg.labels = {{"tone curve"}}; - cfg.pos = {580, 1000}; - curve.add_trace_tag(cfg.to_trace_tag()); - } - Func curved; if (lutResample == 1) { @@ -377,14 +356,6 @@ Func CameraPipe::sharpen(Func input) { } } - /* Optional tags to specify layout for HalideTraceViz */ - { - Halide::Trace::FuncConfig cfg; - cfg.labels = {{"sharpen strength"}}; - cfg.pos = {10, 1000}; - sharpen_strength_x32.add_trace_tag(cfg.to_trace_tag()); - } - // Make an unsharp mask by blurring in y, then in x. Func unsharp_y("unsharp_y"); unsharp_y(x, y, c) = blur121(input(x, y - 1, c), input(x, y, c), input(x, y + 1, c)); @@ -575,45 +546,6 @@ void CameraPipe::generate() { .bound(c, 0, 3) .bound(x, 0, ((out_width) / (2 * vec)) * (2 * vec)) .bound(y, 0, (out_height / strip_size) * strip_size); - - /* Optional tags to specify layout for HalideTraceViz */ - { - Halide::Trace::FuncConfig cfg; - cfg.max = 1024; - cfg.pos = {10, 348}; - cfg.labels = {{"input"}}; - input.add_trace_tag(cfg.to_trace_tag()); - - cfg.pos = {305, 360}; - cfg.labels = {{"denoised"}}; - denoised.add_trace_tag(cfg.to_trace_tag()); - - cfg.pos = {580, 120}; - const int y_offset = 220; - cfg.strides = {{1, 0}, {0, 1}, {0, y_offset}}; - cfg.labels = { - {"gr", {0, 0 * y_offset}}, - {"r", {0, 1 * y_offset}}, - {"b", {0, 2 * y_offset}}, - {"gb", {0, 3 * y_offset}}, - }; - deinterleaved.add_trace_tag(cfg.to_trace_tag()); - - cfg.color_dim = 2; - cfg.strides = {{1, 0}, {0, 1}, {0, 0}}; - cfg.pos = {1140, 360}; - cfg.labels = {{"demosaiced"}}; - processed.add_trace_tag(cfg.to_trace_tag()); - - cfg.pos = {1400, 360}; - cfg.labels = {{"color-corrected"}}; - corrected.add_trace_tag(cfg.to_trace_tag()); - - cfg.max = 256; - cfg.pos = {1660, 360}; - cfg.labels = {{"gamma-corrected"}}; - curved.add_trace_tag(cfg.to_trace_tag()); - } } }; diff --git a/apps/camera_pipe/viz.sh b/apps/camera_pipe/viz.sh deleted file mode 100755 index 29283234c609..000000000000 --- a/apps/camera_pipe/viz.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -export HL_TRACE_FILE=/dev/stdout -export HL_NUMTHREADS=4 -rm -f "$1"/camera_pipe.mp4 -set -euo pipefail -# Do trivial partial-overrides of trace settings via flags -# (--zoom and --rlabel) just to demonstrate that it works. -"$1"/process_viz ../images/bayer_small.png 3700 1.8 50 1 1 "$1"/out.png | - ../../bin/HalideTraceViz --timestep 1000 --size 1920 1080 \ - --zoom 4 --func sharpen_strength_x32 \ - --rlabel curve "tone curve LUT" 0 0 10 | - ${HL_AVCONV} -f rawvideo -pix_fmt bgr32 -s 1920x1080 -i /dev/stdin -c:v h264 "$1"/camera_pipe.mp4 -#mplayer -demuxer rawvideo -rawvideo w=1920:h=1080:format=rgba:fps=30 -idle -fixed-vo - diff --git a/apps/local_laplacian/Makefile b/apps/local_laplacian/Makefile index a2c9991151f8..29cef56e1dff 100644 --- a/apps/local_laplacian/Makefile +++ b/apps/local_laplacian/Makefile @@ -29,28 +29,7 @@ $(BIN)/%/out.tiff: $(BIN)/%/process @mkdir -p $(@D) $< $(IMAGES)/rgb.png 8 1 1 10 $@ -$(BIN)/%/process_viz: process.cpp $(BIN)/%-trace_all/local_laplacian.a - @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) -DNO_AUTO_SCHEDULE -I$(BIN)/$*-trace_all -Wall $^ -o $@ $(LDFLAGS) $(IMAGE_IO_FLAGS) $(CUDA_LDFLAGS) $(OPENCL_LDFLAGS) - -../../bin/HalideTraceViz: ../../util/HalideTraceViz.cpp - $(MAKE) -C ../../ bin/HalideTraceViz - -$(BIN)/%/local_laplacian.mp4: $(BIN)/%/process_viz ../../bin/HalideTraceViz - @mkdir -p $(@D) - HL_AVCONV=$(HL_AVCONV) bash viz.sh $( { outGPyramid[j].compute_root(); } } - - /* Optional tags to specify layout for HalideTraceViz */ - { - Halide::Trace::FuncConfig cfg; - cfg.color_dim = 2; - cfg.max = 65535; - cfg.pos.x = 30; - cfg.pos.y = 100; - input.add_trace_tag(cfg.to_trace_tag()); - - cfg.pos.x = 1700; - output.add_trace_tag(cfg.to_trace_tag()); - } - - { - Halide::Trace::FuncConfig cfg; - cfg.store_cost = 5; - cfg.pos.x = 370; - cfg.pos.y = 100; - cfg.labels = {{"input pyramid", {-90, -68}}}; - gray.add_trace_tag(cfg.to_trace_tag()); - } - - for (int i = 0; i < pyramid_levels; ++i) { - int y = 100; - for (int j = 0; j < i; ++j) { - y += 500 >> j; - } - { - int x = 370; - int store_cost = 1 << (i + 1); - Halide::Trace::FuncConfig cfg; - cfg.pos = {x, y}; - cfg.store_cost = store_cost; - inGPyramid[i].add_trace_tag(cfg.to_trace_tag()); - } - { - int x = 720; - int store_cost = 1 << i; - Halide::Trace::FuncConfig cfg; - cfg.strides = {{1, 0}, {0, 1}, {200, 0}}; - cfg.pos = {x, y}; - cfg.store_cost = store_cost; - if (i == 1) { - cfg.labels = {{"differently curved intermediate pyramids"}}; - } - gPyramid[i].add_trace_tag(cfg.to_trace_tag()); - } - { - int x = 1500; - int store_cost = (1 << i) * 10; - Halide::Trace::FuncConfig cfg; - cfg.pos = {x, y}; - cfg.store_cost = store_cost; - if (i == 0) { - cfg.labels = {{"output pyramids"}}; - cfg.pos = {x, 100}; - } - outGPyramid[i].add_trace_tag(cfg.to_trace_tag()); - } - } } private: diff --git a/apps/local_laplacian/viz.sh b/apps/local_laplacian/viz.sh deleted file mode 100755 index 74e0cc78d427..000000000000 --- a/apps/local_laplacian/viz.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -export HL_TRACE_FILE=/dev/stdout -export HL_NUM_THREADS=4 -rm -f "$1"/local_laplacian.mp4 -set -euo pipefail -make "$1"/process_viz && - ./"$1"/process_viz ../images/rgb_small.png 4 1 1 0 ./"$1"/out_small.png | - ../../bin/HalideTraceViz \ - --size 1920 1080 --timestep 3000 | - ${HL_AVCONV} -f rawvideo -pix_fmt bgr32 -s 1920x1080 -i /dev/stdin -c:v h264 ./"$1"/local_laplacian.mp4 -#mplayer -demuxer rawvideo -rawvideo w=1920:h=1080:format=rgba:fps=30 -idle -fixed-vo - diff --git a/apps/resize/Makefile b/apps/resize/Makefile index f21f84cfd2a5..29d79d4ba49d 100644 --- a/apps/resize/Makefile +++ b/apps/resize/Makefile @@ -81,17 +81,4 @@ $(BIN)/$(HL_TARGET)/out_%_down.png: $(BIN)/$(HL_TARGET)/resize clean: rm -rf $(BIN) -../../bin/HalideTraceViz: ../../util/HalideTraceViz.cpp - $(MAKE) -C ../../ bin/HalideTraceViz - .SECONDARY: - -$(BIN)/$(HL_TARGET)/viz_auto_%.mp4: $(BIN)/$(HL_TARGET)-trace_all/resize ../support/viz_auto.sh ../../bin/HalideTraceViz - @mkdir -p $(@D) - HL_AVCONV=$(HL_AVCONV) bash ../support/viz_auto.sh \ - "$(BIN)/$(HL_TARGET)-trace_all/resize $(IMAGES)/rgb_small.png /tmp/$*.png -p 0 -b 1 -i $* -t float32 -f 0.5" \ - "../../bin/HalideTraceViz --timestep 1000" \ - $@ - -viz_auto_%: $(BIN)/$(HL_TARGET)/viz_auto_%.mp4 - $(HL_VIDEOPLAYER) $^ diff --git a/apps/support/Makefile.inc b/apps/support/Makefile.inc index 91a9ad87541e..fc19f52bffb2 100644 --- a/apps/support/Makefile.inc +++ b/apps/support/Makefile.inc @@ -214,12 +214,6 @@ ifneq (, $(findstring metal,$(HL_TARGET))) LDFLAGS += -framework Metal -framework Foundation endif -# Utility to convert raw video -> h264. HL_AVCONV=ffmpeg will work too. -HL_AVCONV ?= avconv - -# Utility to show h264 video -HL_VIDEOPLAYER ?= mplayer - # ------- RunGen/Benchmark support # Really, .SECONDARY is what we want instead of .PRECIOUS (here and elsewhere), diff --git a/apps/support/viz_auto.sh b/apps/support/viz_auto.sh deleted file mode 100755 index fd0b37f58461..000000000000 --- a/apps/support/viz_auto.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# -# $1 = filter cmd to run, including args -# $2 = HalideTraceViz executable -# $3 = path to output mp4 - -set -euo pipefail - -rm -rf "$3" - -# Use a named pipe for the $1 -> HTV pipe, just in case -# the exe in $1 writes any random output to stdout. -PIPE=/tmp/halide_viz_auto_pipe -rm -rf $PIPE -mkfifo $PIPE - -HL_TRACE_FILE=${PIPE} HL_NUMTHREADS=8 $1 & - -$2 --auto_layout --ignore_tags 0<${PIPE} | - ${HL_AVCONV} -y -f rawvideo -pix_fmt bgr32 -s 1920x1080 -i /dev/stdin -c:v h264 "$3" diff --git a/pyproject.toml b/pyproject.toml index 1c75ad65101c..7443ea4b0c62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,9 +36,11 @@ docs = [ "sphinxcontrib-video>=0.4", "sphinx-design>=0.6", ] +figures = ["imageio-ffmpeg>=0.5", "numpy>=1.26", "pillow>=10.1"] ci-base = [ { include-group = "dev" }, { include-group = "apps" }, + { include-group = "figures" }, { include-group = "tools" }, ] ci-llvm-main = [{ include-group = "ci-base" }, "halide-llvm>=24.0.0.dev0,<25"] diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index fe4b30d94bcc..6a39adcd6e36 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -102,7 +102,6 @@ target_sources( halide_image_info.h halide_malloc_trace.h halide_trace_compression.h - halide_trace_config.h ) ## diff --git a/tools/halide_trace_config.h b/tools/halide_trace_config.h deleted file mode 100644 index 6f95d439f016..000000000000 --- a/tools/halide_trace_config.h +++ /dev/null @@ -1,576 +0,0 @@ -#ifndef HALIDE_TRACE_CONFIG_H -#define HALIDE_TRACE_CONFIG_H - -#include -#include -#include -#include -#include -#include -#include - -#include "HalideRuntime.h" - -namespace Halide { -namespace Trace { - -using ErrorFunc = std::function; - -inline void default_error(const std::string &err) { - std::cerr << "Error: " << err << "\n"; - exit(1); -} - -inline std::string replace_all(const std::string &str, const std::string &find, const std::string &replace) { - size_t pos = 0; - std::string result = str; - while ((pos = result.find(find, pos)) != std::string::npos) { - result.replace(pos, find.length(), replace); - pos += replace.length(); - } - return result; -} - -inline std::string escape_spaces(const std::string &str) { - // Note: if the source string already contains '\x20', we'll - // end up unescaping that back into a space. That's acceptable. - return replace_all(str, " ", "\\x20"); -} - -inline std::string unescape_spaces(const std::string &str) { - // Note: if the source string already contains '\x20', we'll - // end up unescaping that back into a space. That's acceptable. - return replace_all(str, "\\x20", " "); -} - -inline std::ostream &write_halide_type(std::ostream &os, const halide_type_t &t) { - os << (int)t.code << " " << (int)t.bits; - return os; -} - -inline std::istream &read_halide_type(std::istream &is, halide_type_t &t) { - // type.code is an enum; type.bits is a uint8 and might be read as char. - int type_code, type_bits; - is >> type_code >> type_bits; - t.code = (halide_type_code_t)type_code; - t.bits = (uint8_t)type_bits; - return is; -} - -template -std::ostream &operator<<(std::ostream &os, const std::vector &v) { - os << v.size() << " "; - for (const T &t : v) { - os << t << " "; - } - return os; -} - -inline std::ostream &operator<<(std::ostream &os, const std::vector &v) { - os << v.size() << " "; - for (const halide_type_t &t : v) { - write_halide_type(os, t) << " "; - } - return os; -} - -template -std::istream &operator>>(std::istream &is, std::vector &v) { - v.clear(); - size_t size; - is >> size; - for (size_t i = 0; i < size; ++i) { - T tmp; - is >> tmp; - v.push_back(tmp); - } - return is; -} - -inline std::istream &operator>>(std::istream &is, std::vector &v) { - v.clear(); - size_t size; - is >> size; - for (size_t i = 0; i < size; ++i) { - halide_type_t tmp; - read_halide_type(is, tmp); - v.push_back(tmp); - } - return is; -} - -struct Point { - int x = 0, y = 0; - - Point() = default; - Point(int x, int y) - : x(x), y(y) { - } - - friend std::ostream &operator<<(std::ostream &os, const Point &pt) { - os << pt.x << " " << pt.y; - return os; - } - - friend std::istream &operator>>(std::istream &is, Point &pt) { - is >> pt.x >> pt.y; - return is; - } -}; - -// A struct specifying a text label that will appear on the screen at some point. -struct Label { - std::string text; - Point pos; - int fade_in_frames = 0; - float h_scale = 1.0f; - - Label() = default; - Label(const std::string &text, const Point &pos = {0, 0}, int fade_in_frames = 0, float h_scale = 1.f) - : text(text), pos(pos), fade_in_frames(fade_in_frames), h_scale(h_scale) { - } - - friend std::ostream &operator<<(std::ostream &os, const Label &label) { - os << escape_spaces(label.text) << " " << label.pos << " " << label.fade_in_frames << " " << label.h_scale; - return os; - } - - friend std::istream &operator>>(std::istream &is, Label &label) { - is >> label.text >> label.pos >> label.fade_in_frames >> label.h_scale; - label.text = unescape_spaces(label.text); - return is; - } -}; - -// Configuration for how a func should be rendered in HalideTraceViz. -struct FuncConfig { - // Note that every field in this struct is initialized to a value which - // means "no value specified"; this is allows us to merge configs - // from several sources (auto-layout, embedded trace-tags, and command-line) - // in a way that we can selectively add or override some-but-not-all configuration - // values (e.g., use auto-layout's positioning, but customizing labels - // and changing rgb vs gray rendering). In all cases, if a field is - // the initial "no value specified" value at rendering time, HalideTraceViz - // will choose a reasonable value for that field. - - // Each value of a Func will draw as a zoom x zoom - // box in the output. Fractional values are allowed. - // - // Valid values: 0.0 < zoom <= HUGEVAL or so - float zoom = -1.f; - - // Each load from a Func costs the given number of ticks. - // Legal values are 0.0 < zoom <= 1000 or so - // - // Valid values: load_cost >= 0 - int load_cost = -1; - - // Each store to a Func costs the given number of ticks. - // - // Valid values: store_cost >= 0 - int store_cost = -1; - - // The position on the screen corresponding to the Func's 0, 0 coordinate. - // - // Valid values: pos.x and pos.y > std::numeric_limits::lowest() - Point pos = {std::numeric_limits::lowest(), std::numeric_limits::lowest()}; - - // Specifies the matrix that maps the coordinates of the - // Func to screen pixels. Specified column major. For example, - // { {1, 0}, {0, 1}, {0, 0} } specifies that the Func has three - // dimensions where the first one maps to screen-space x - // coordinates, the second one maps to screen-space y coordinates, - // and the third one does not affect screen-space coordinates. - // - // Valid values: strize.size() > 0 - std::vector strides; - - // Specify the dimension to use for rendering the color channels of the Func. - // - // Valid values: color_dim == -1 -> render as grayscale - // color_dim >= 0 -> render as RGB using that dimension as color channel - int color_dim = -2; - - // The minimum value taken on by a Func; maps to black. - // TODO: this doesn't give enough range to allow for the full range of int64 or uint64. Do we care? - // - // Valid values: min-of-type <= min <= max-of-type - double min = std::numeric_limits::quiet_NaN(); - - // The maximum value taken on by a Func; maps to white. - // TODO: this doesn't give enough range to allow for the full range of int64 or uint64. Do we care? - // - // Valid values: min-of-type <= min <= max-of-type - double max = std::numeric_limits::quiet_NaN(); - - // Label(s) to be rendered with the Func. The Label's position - // is an offset from the Func's position, so (0, 0) means render - // at the top-left of the Func itself. - // - // Valid values: Any - std::vector