Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
b4156df
Initial prototype of neotrace viewer
alexreinking Jan 27, 2026
8769502
Add local_laplacian_trace / process_viz to build
alexreinking Jun 1, 2026
0e70c05
basic neotrace fixups
alexreinking Jun 1, 2026
e533630
pre-commit after rebase
alexreinking Jun 1, 2026
e93034c
Add profiling; fix render performance
alexreinking Jun 1, 2026
75d685e
Improve scrubbing performance
alexreinking Jun 1, 2026
c7e9632
feat: Initial commit for basic client-server setup for Halidoscope.
Jun 3, 2026
6572d55
feat: Support full playback and forward scrubbing of Halide traces.
Jun 4, 2026
5ab1f1d
feat: Support RGB.
Jun 9, 2026
911249d
feat: Add support for heatmap visualizations of load / store counts.
parkerziegler Jun 16, 2026
78452c0
feat: Migrate to Rust backend and add Histograms.
parkerziegler Jun 19, 2026
7065d1a
feat: Add support for Reuse Distance visualization and highlight live…
parkerziegler Jun 24, 2026
e60ce82
fix: Remove Python backend and shift Tauri app to root directory of a…
parkerziegler Jun 24, 2026
d59f863
Support produce-consume liveness highlighting and refactor backend wi…
parkerziegler Jun 25, 2026
8895c9e
Add CLI for snapshotting Func buffers at packet indices.
parkerziegler Jun 26, 2026
e7d2a37
Add dot subcommand to Halidoscope CLI.
parkerziegler Jul 6, 2026
fd4527b
Adjust packet parsing to accommodate #9192 and report thread count in…
parkerziegler Jul 7, 2026
597ca32
Fix responsive text aliasing issues by using NodeToolbar.
parkerziegler Jul 7, 2026
db31e36
Fix liveness producer-consumer derivation to align more closely with …
parkerziegler Jul 8, 2026
8d22e2d
Adjust liveness color mappings.
parkerziegler Jul 9, 2026
91d9418
Adjust redundant store count metric to mark a redundant store only if…
parkerziegler Jul 9, 2026
a8f8d1f
Add support for normalization modes and real-time histogram rendering.
parkerziegler Jul 13, 2026
5031f91
Add list and stats CLI subcommands.
parkerziegler Jul 13, 2026
3ff2ff8
Adjust halidoscope snapshot subcommand to return values as JSON.
parkerziegler Jul 14, 2026
53e3af1
Add docs on building Halidoscope, using the GUI and CLI, and developi…
parkerziegler Jul 14, 2026
8fcfd6e
Add support for NaN and inf rendering.
parkerziegler Jul 17, 2026
470ca73
Add support for Thread Coverage rendering.
parkerziegler Jul 21, 2026
9f33e4d
Dramatically improve rendering performancefor Load Frequency render m…
parkerziegler Jul 22, 2026
d9ffaf9
Add support for thread filtering and highlighting.
parkerziegler Jul 23, 2026
c15551b
Back out changes to Python tracing infrastructure that are not on mai…
parkerziegler Jul 23, 2026
ec6fbfb
Add support for visualizing information from the Halide profiler.
parkerziegler Jul 26, 2026
2afcb7f
Reduce IPC calls by shifting NaN/Inf overlay computation into the IPC…
parkerziegler Jul 27, 2026
04e798a
Support user-selected colors for NaN and Inf highlighting. Rework UI …
parkerziegler Jul 28, 2026
4ada85b
Ignore demos.
parkerziegler Aug 10, 2026
d0648b8
Add support for Grayscale render mode histograms.
parkerziegler Jul 30, 2026
67c90d0
Add basic support for RGB histograms.
parkerziegler Jul 30, 2026
6a7e5a6
Add .halidoscope method to Pipeline class.
parkerziegler Jul 31, 2026
6013bf1
Support invoking Halidoscope with no arguments.
parkerziegler Aug 3, 2026
83a5c62
Apply clippy recommended fixes.
parkerziegler Aug 4, 2026
7bc6ebf
Reduce trace loading and parsing time 1.25x by combining stats comput…
parkerziegler Aug 4, 2026
95a3130
Adjust and document types for the frontend.
parkerziegler Aug 5, 2026
bf16e34
Add HalidoscopeOptions to allow callers of Pipeline::halidoscope to s…
parkerziegler Aug 5, 2026
4c289f5
Allow callers of Pipeline::halidoscope to specify a non-volatile dire…
parkerziegler Aug 6, 2026
faeb3b2
Fix missing end bin in histogram rendering and shift all render mode …
parkerziegler Aug 6, 2026
4f8cd2b
Only include NaN and Inf overlay buffers when explicitly requested.
parkerziegler Aug 7, 2026
582c997
Only request live Funcs during playback to reduce IPC calls.
parkerziegler Aug 7, 2026
cfcda4f
Add more granular loading feedback to support XL traces.
parkerziegler Aug 10, 2026
77e67e9
Send NaN and Inf buffers as bit masks.
parkerziegler Aug 11, 2026
d703a9e
Fix caching scope bug in FuncNode.
parkerziegler Aug 11, 2026
f4e3b6e
Use bindgen to derive halide_trace_packet_t's field names and offsets…
parkerziegler Aug 11, 2026
be916a4
Introduce RAII type to support accumulating profiler stats in Halidos…
parkerziegler Aug 13, 2026
b97f94c
Standardize styles for Select and Checkbox components and reuse acros…
parkerziegler Aug 16, 2026
2447cfe
Add new Profile UI.
parkerziegler Aug 17, 2026
73ddbe2
Move halidoscope into the tools directory.
parkerziegler Aug 17, 2026
14c8702
Remove erroneously committed files.
parkerziegler Aug 17, 2026
c031137
Fix Halidoscope profiling pass to snapshot profiler stats once just b…
parkerziegler Aug 17, 2026
8195361
Fix clang-tidy warnings.
parkerziegler Aug 18, 2026
9bf55eb
Check in Halidoscope's icon set.
parkerziegler Aug 19, 2026
0ff79de
Misc improvements to tooltips and styling in Profile tab.
parkerziegler Aug 19, 2026
c4c0917
Make sizes a required argument for Pipeline::halidoscope's first over…
parkerziegler Aug 19, 2026
ab3270e
Rework component directory structure for maintainability and clarity.
parkerziegler Aug 19, 2026
05ca790
Standardize Props naming convention.
parkerziegler Aug 19, 2026
4398fe8
Make all HalidoscopeOptions fields optional, and update README.
parkerziegler Aug 20, 2026
9a90222
Add updated icons.
parkerziegler Aug 20, 2026
de78695
Remove unneeded icons.
parkerziegler Aug 20, 2026
2e84415
Add basic tests for Pipeline::halidoscope.
parkerziegler Aug 20, 2026
76fb287
Fix CI error on Windows owing to unreferenced local variable.
parkerziegler Aug 20, 2026
e18cbcd
Only run halidoscope tests with serialization enabled.
parkerziegler Aug 20, 2026
39809fa
[halidoscope] Add pip packaging via maturin
alexreinking Sep 1, 2026
6cef29f
[halidoscope] Fix headless smoke test on Linux, correct README claim
alexreinking Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions .github/workflows/pip-halidoscope.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Build Halidoscope wheels

on:
workflow_dispatch:
pull_request:
paths:
- 'tools/halidoscope/**'
- '.github/workflows/pip-halidoscope.yml'
push:
branches: [ main ]
paths:
- 'tools/halidoscope/**'
- '.github/workflows/pip-halidoscope.yml'

concurrency:
group: '${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true

permissions:
contents: read

# Halidoscope is a companion CLI/GUI packaged independently of Halide's own
# Python wheels (halide, halide-bin, halide-runtime): it doesn't depend on
# them, and this workflow doesn't participate in pip.yml's publish job. Its
# version is kept in sync with Halide's release version via tbump (see
# tool.tbump.file entries for tools/halidoscope/src-tauri/Cargo.toml et al.
# in the top-level pyproject.toml), not via a per-commit dynamic version.
jobs:
build:
name: Build wheel for ${{ matrix.platform_tag }}

runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform_tag: manylinux_x86_64
- os: windows-latest
platform_tag: win_amd64
- os: macos-15-intel
platform_tag: macosx_x86_64
- os: macos-15
platform_tag: macosx_arm64

steps:
- uses: actions/checkout@v7

- name: Install Tauri's Linux system dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf \
build-essential \
libxdo-dev \
libssl-dev \
libsoup-3.0-dev \
xvfb

- uses: dtolnay/rust-toolchain@stable

- uses: pnpm/action-setup@v4
with:
version: 11
package_json_file: tools/halidoscope/package.json

- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
cache-dependency-path: tools/halidoscope/pnpm-lock.yaml

- uses: astral-sh/setup-uv@v7

- name: Build frontend
working-directory: tools/halidoscope
run: |
pnpm install --frozen-lockfile
pnpm build

- name: Build wheel
working-directory: tools/halidoscope
run: uvx maturin build --release --out wheelhouse

- name: Smoke-test wheel
working-directory: tools/halidoscope
shell: bash
run: |
uv venv .smoke-test-venv
uv pip install --python .smoke-test-venv --no-index --find-links wheelhouse halidoscope
if [[ "${{ runner.os }}" == "Windows" ]]; then
./.smoke-test-venv/Scripts/halidoscope --version
elif [[ "${{ runner.os }}" == "Linux" ]]; then
# tauri::Builder::run() initializes tao's GTK-backed event loop
# before dispatching to any CLI subcommand, so even `--version`
# needs a display on Linux.
xvfb-run -a ./.smoke-test-venv/bin/halidoscope --version
else
./.smoke-test-venv/bin/halidoscope --version
fi

- uses: actions/upload-artifact@v7
with:
name: wheels-halidoscope-${{ matrix.platform_tag }}
path: tools/halidoscope/wheelhouse/*.whl
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@
################################################################################
## Halide-specific exclusions

# Images only allowed in apps and directories named "images"
# Images only allowed in apps, directories named "images", and Halidoscope's
# icon set
*.png
!apps/**/*.png
!**/images/**/*.png
!tools/halidoscope/src-tauri/icons/*.png

# Halidoscope is desktop-only; `tauri icon` also emits mobile (Android/iOS)
# assets we don't want to commit.
tools/halidoscope/src-tauri/icons/android/
tools/halidoscope/src-tauri/icons/ios/


# Pre-trained weights only allowed in autoscheduler directories
*.weights
Expand Down
12 changes: 12 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ src = "vcpkg.json"
[[tool.tbump.file]]
src = "apps/vcpkg.json"

[[tool.tbump.file]]
src = "tools/halidoscope/src-tauri/Cargo.toml"
search = 'version = "{current_version}"'

[[tool.tbump.file]]
src = "tools/halidoscope/src-tauri/tauri.conf.json"
search = '"version": "{current_version}"'

[[tool.tbump.file]]
src = "tools/halidoscope/package.json"
search = '"version": "{current_version}"'

[[tool.tbump.file]]
src = "src/runtime/HalideRuntime.h"
version_template = "{major}"
Expand Down
40 changes: 40 additions & 0 deletions python_bindings/halide/src/halide_/PyPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ void define_pipeline(py::module &m) {
return "<halide.AutoschedulerParams>";
});

py::class_<HalidoscopeOptions>(m, "HalidoscopeOptions")
.def(py::init<>())
.def_readwrite("halidoscope_path", &HalidoscopeOptions::halidoscope_path)
.def_readwrite("halidoscope_output_dir", &HalidoscopeOptions::halidoscope_output_dir)
.def_readwrite("halidoscope_profile_runs", &HalidoscopeOptions::halidoscope_profile_runs)
.def("__repr__", [](const HalidoscopeOptions &o) -> std::string {
return "<halide.HalidoscopeOptions halidoscope_path='" + o.halidoscope_path.value_or("halidoscope") +
"' halidoscope_output_dir='" + o.halidoscope_output_dir.value_or("") +
"' halidoscope_profile_runs=" + std::to_string(o.halidoscope_profile_runs.value_or(1)) + ">";
});

auto pipeline_class =
py::class_<Pipeline>(m, "Pipeline")
.def(py::init<>())
Expand Down Expand Up @@ -283,6 +294,35 @@ void define_pipeline(py::module &m) {
},
py::arg("dst"), py::arg("target") = Target())

// Development/debugging aid: see Pipeline::halidoscope() in Pipeline.h.
// Blocks until the Halidoscope window is closed, so the GIL must be
// released for the duration of the call, same as realize() above.
.def("halidoscope", //
[](Pipeline &p, Buffer<> buffer, const HalidoscopeOptions &options, const Target &target) -> void {
py::gil_scoped_release release;
p.halidoscope(Realization(std::move(buffer)), options, target); //
},
py::arg("dst"), py::arg("options") = HalidoscopeOptions(), py::arg("target") = Target())

// See the comment on the corresponding realize() overload above: this
// overload must be declared before the list-of-sizes one, so that an
// empty list [] is resolved as list-of-sizes (a 0-dimensional Buffer)
// rather than as an ambiguous empty list-of-buffers.
.def("halidoscope", //
[](Pipeline &p, std::vector<int32_t> sizes, const HalidoscopeOptions &options, const Target &target) -> void {
py::gil_scoped_release release;
p.halidoscope(std::move(sizes), options, target); //
},
py::arg("sizes") = std::vector<int32_t>{}, py::arg("options") = HalidoscopeOptions(), py::arg("target") = Target())

// This will actually allow a list-of-buffers as well as a tuple-of-buffers, but that's OK.
.def("halidoscope", //
[](Pipeline &p, std::vector<Buffer<>> buffers, const HalidoscopeOptions &options, const Target &target) -> void {
py::gil_scoped_release release;
p.halidoscope(Realization(std::move(buffers)), options, target); //
},
py::arg("dst"), py::arg("options") = HalidoscopeOptions(), py::arg("target") = Target())

.def("infer_input_bounds", //
[](Pipeline &p, const py::object &dst, const Target &target) -> void {
const Target t = to_jit_target(target);
Expand Down
Loading
Loading