Running the compiled pipeline#
// Halide tutorial lesson 21: Auto-Scheduler: running the compiled pipeline
// Before reading this file, see lesson_21_auto_scheduler_generate.cpp
// This is the code that actually uses the Halide pipeline we've
// compiled. It does not depend on libHalide, so we won't be including
// Halide.h.
//
// Instead, it depends on the header files that lesson_21_auto_scheduler_generator produced.
#include "auto_schedule_false.h"
#include "auto_schedule_true.h"
// We'll use the Halide::Runtime::Buffer class for passing data into and out of
// the pipeline.
#include "HalideBuffer.h"
#include "halide_benchmark.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <random>
int main() {
// Let's declare and initialize the input images
Halide::Runtime::Buffer<float> input(1024, 1024, 3);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> dis(0.0f, 1.0f);
for (int c = 0; c < input.channels(); ++c) {
for (int y = 0; y < input.height(); ++y) {
for (int x = 0; x < input.width(); ++x) {
input(x, y, c) = dis(gen);
}
}
}
Halide::Runtime::Buffer<float> output1(1024, 1024);
Halide::Runtime::Buffer<float> output2(1024, 1024);
// Run each version of the codes (with no auto-schedule and with
// auto-schedule) multiple times for benchmarking.
double auto_schedule_off = Halide::Tools::benchmark(2, 5, [&]() {
auto_schedule_false(input, 2.0f, output1, output2);
});
printf("Manual schedule: %gms\n", auto_schedule_off * 1e3);
double auto_schedule_on = Halide::Tools::benchmark(2, 5, [&]() {
auto_schedule_true(input, 2.0f, output1, output2);
});
printf("Auto schedule: %gms\n", auto_schedule_on * 1e3);
// auto_schedule_on should be faster since in the auto_schedule_off version,
// the schedule is very simple.
if (!(auto_schedule_on < auto_schedule_off)) {
fprintf(stderr, "Warning: expected auto_schedule_on < auto_schedule_off , "
"saw auto_schedule_on=%f auto_schedule_off=%f\n", auto_schedule_on, auto_schedule_off); \
}
return 0;
}
#!/usr/bin/python3
# Halide tutorial lesson 21: Auto-Scheduler: running the compiled pipeline
# Before reading this file, see lesson_21_auto_scheduler_generate.py
# This is the code that actually uses the Halide pipeline we've
# compiled. It does not depend on libHalide, so we won't do
# "import halide".
#
# Instead, it depends on the Python extension modules that
# lesson_21_auto_scheduler_generate produced when we ran it:
import random
import time
import auto_schedule_false
import auto_schedule_true
import halide as hl
def benchmark(samples, iterations, op):
"""A minimal stand-in for Halide::Tools::benchmark(): runs `op`
`iterations` times per sample, and returns the minimum time (in
seconds) for one iteration, over `samples` samples."""
best = None
for _ in range(samples):
start = time.perf_counter()
for _ in range(iterations):
op()
elapsed = (time.perf_counter() - start) / iterations
if best is None or elapsed < best:
best = elapsed
return best
def main():
# Let's declare and initialize the input images
input = hl.Buffer(hl.Float(32), [1024, 1024, 3])
for c in range(input.channels()):
for y in range(input.height()):
for x in range(input.width()):
input[x, y, c] = random.random()
output1 = hl.Buffer(hl.Float(32), [1024, 1024])
output2 = hl.Buffer(hl.Float(32), [1024, 1024])
# Run each version of the codes (with no auto-schedule and with
# auto-schedule) multiple times for benchmarking.
auto_schedule_off = benchmark(
2,
5,
lambda: auto_schedule_false.auto_schedule_false(input, 2.0, output1, output2),
)
print(f"Manual schedule: {auto_schedule_off * 1e3}ms")
auto_schedule_on = benchmark(
2,
5,
lambda: auto_schedule_true.auto_schedule_true(input, 2.0, output1, output2),
)
print(f"Auto schedule: {auto_schedule_on * 1e3}ms")
# auto_schedule_on should be faster since in the auto_schedule_off
# version, the schedule is very simple.
if not (auto_schedule_on < auto_schedule_off):
print(
"Warning: expected auto_schedule_on < auto_schedule_off, saw "
f"auto_schedule_on={auto_schedule_on} auto_schedule_off={auto_schedule_off}"
)
return 0
if __name__ == "__main__":
main()