Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ JIT_PIPELINE_FALLBACK ?= 0
# how many unique kernels to batch before triggering a JIT compile
JIT_BATCH_SIZE ?= 16
# how many pending queue events to scan ahead when looking for fusion candidates
FUSION_LOOKAHEAD ?= 32
QUEUE_ABSORB_LIMIT ?= 32
# horizontal fusion: max independent parallel chains per kernel pass
MAX_HFUSE_CHAINS ?= 9
# vertical fusion: max RPN opcodes per chain (caps how deep chains can be fused)
Expand Down Expand Up @@ -176,7 +176,7 @@ reconfigure:
@echo "PERFETTO_HOME=$(PERFETTO_HOME)" >> $(CONFIG_STAMP)
@echo "DEBUG_KEEP_JIT_DIR=$(DEBUG_KEEP_JIT_DIR)" >> $(CONFIG_STAMP)
@echo "ENABLE_PROMOTION_REDUCTIONS=$(ENABLE_PROMOTION_REDUCTIONS)" >> $(CONFIG_STAMP)
@echo "FUSION_LOOKAHEAD=$(FUSION_LOOKAHEAD)" >> $(CONFIG_STAMP)
@echo "QUEUE_ABSORB_LIMIT=$(QUEUE_ABSORB_LIMIT)" >> $(CONFIG_STAMP)
@echo "ENABLE_OOM_RECOVERY=1" >> $(CONFIG_STAMP)
@echo "MAX_HFUSE_CHAINS=$(MAX_HFUSE_CHAINS)" >> $(CONFIG_STAMP)
@echo "MAX_VFUSE_OPS=$(MAX_VFUSE_OPS)" >> $(CONFIG_STAMP)
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/src/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct FusionProfile
end

const FUSION_BUILD_KNOBS = (
"FUSION_LOOKAHEAD",
"QUEUE_ABSORB_LIMIT",
"MAX_HFUSE_CHAINS",
"JIT_BATCH_SIZE",
"MAX_VFUSE_OPS",
Expand Down
17 changes: 10 additions & 7 deletions benchmarks/src/tuning.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const DEFAULT_FUSION_BUILD = Dict(
"FUSION_LOOKAHEAD" => 128,
"QUEUE_ABSORB_LIMIT" => 32,
"MAX_HFUSE_CHAINS" => 9,
"JIT_BATCH_SIZE" => 16,
"MAX_VFUSE_OPS" => 128,
Expand All @@ -8,15 +8,14 @@ const DEFAULT_FUSION_BUILD = Dict(
)

const DEFAULT_FUSION_SEARCH = Dict(
"FUSION_LOOKAHEAD" => [0, 1, 2, 4, 8, 16, 32, 64, 128],
# 9 is the ceiling: a tenth chain overflows WRAM at stack depth 3.
"MAX_HFUSE_CHAINS" => [1, 2, 4, 6, 8, 9],
"JIT_BATCH_SIZE" => [0, 1, 2, 4, 8, 16, 32],
"MAX_VFUSE_OPS" => [1, 8, 16, 32, 64, 96, 128, 192],
)

const CORE_FUSION_KNOBS = (
"FUSION_LOOKAHEAD",
"QUEUE_ABSORB_LIMIT",
"MAX_HFUSE_CHAINS",
"JIT_BATCH_SIZE",
"MAX_VFUSE_OPS",
Expand Down Expand Up @@ -72,6 +71,10 @@ function coordinate_descent(seed::Dict{String,Int}, search, passes::Int,
for pass in 1:passes
changed = false
for knob in CORE_FUSION_KNOBS
# A knob with no candidate list is not swept this run: the absorb
# limit is out of the default search but --absorb-limit puts it
# back, so the order here stays canonical either way.
haskey(search, knob) || continue
local_build, local_result = best, best_result
for candidate in unique([best[knob]; search[knob]])
trial = copy(best)
Expand Down Expand Up @@ -101,7 +104,7 @@ function tune_usage(io::IO = stdout)
--warmup N Override warmup iterations
--iterations N Override measured iterations
--passes N Maximum coordinate-descent passes
--lookahead N[,N...] FUSION_LOOKAHEAD candidates
--absorb-limit N[,N...] QUEUE_ABSORB_LIMIT candidates
--hfuse-chains N[,N...] MAX_HFUSE_CHAINS candidates
--jit-batch N[,N...] JIT_BATCH_SIZE candidates
--vfuse-ops N[,N...] MAX_VFUSE_OPS candidates
Expand Down Expand Up @@ -151,7 +154,7 @@ function parse_tune_args(args)
options.reset = true
options.resume = false
elseif arg in ("--dpus", "--elements-per-dpu", "--warmup", "--iterations",
"--passes", "--lookahead", "--hfuse-chains", "--jit-batch",
"--passes", "--absorb-limit", "--hfuse-chains", "--jit-batch",
"--vfuse-ops", "--workspace", "--profiles", "--checkpoints",
"--timeout", "--build-timeout", "--config")
value = option_value(args, index, arg)
Expand All @@ -167,8 +170,8 @@ function parse_tune_args(args)
elseif arg == "--passes"
options.passes = parse(Int, value)
options.passes > 0 || error("--passes must be positive")
elseif arg == "--lookahead"
options.search["FUSION_LOOKAHEAD"] = nonnegative_list(value)
elseif arg == "--absorb-limit"
options.search["QUEUE_ABSORB_LIMIT"] = nonnegative_list(value)
elseif arg == "--hfuse-chains"
options.search["MAX_HFUSE_CHAINS"] = int_list(value)
elseif arg == "--jit-batch"
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/test/tests/timings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const SAMPLE_APP_TIME =
@test run["min"] == "3.1"
@test run["max"] == "3.4"
@test [run[knob] for knob in BenchmarkRunner.FUSION_BUILD_KNOBS] ==
["128", "9", "16", "128", "11", "4"]
["32", "9", "16", "128", "11", "4"]

sections = csv_records(BenchmarkRunner.sections_csv(path))
@test length(sections) == 4
Expand Down
14 changes: 7 additions & 7 deletions benchmarks/test/tests/tuning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
[1, 2, 4, 6, 8, 9]
seed = copy(BenchmarkRunner.DEFAULT_FUSION_BUILD)
search = Dict(knob => [value] for (knob, value) in seed)
search["FUSION_LOOKAHEAD"] = [1, 2, 3]
search["QUEUE_ABSORB_LIMIT"] = [1, 2, 3]
evaluations = Ref(0)
evaluate = build -> begin
evaluations[] += 1
objective = Float64((build["FUSION_LOOKAHEAD"] - 2)^2 + 1)
objective = Float64((build["QUEUE_ABSORB_LIMIT"] - 2)^2 + 1)
BenchmarkRunner.TuneResult("ok", objective, [objective], [(1, 1)])
end

best, result = BenchmarkRunner.coordinate_descent(seed, search, 3, evaluate)

@test best["FUSION_LOOKAHEAD"] == 2
@test best["QUEUE_ABSORB_LIMIT"] == 2
@test result.objective == 1.0
@test evaluations[] < 3 * sum(length, values(search))
end
Expand All @@ -32,7 +32,7 @@ end
TOML.print(io, profile)
end
loaded = BenchmarkRunner.load_fusion_profile(directory, "elementwise")
@test loaded.build["FUSION_LOOKAHEAD"] == 1
@test loaded.build["QUEUE_ABSORB_LIMIT"] == 1

text = captured_output() do
run_cli([
Expand All @@ -42,7 +42,7 @@ end
])
end
@test occursin("Using fusion profile", text)
@test occursin("FUSION_LOOKAHEAD=1", text)
@test occursin("QUEUE_ABSORB_LIMIT=1", text)
end
end

Expand All @@ -65,7 +65,7 @@ end
result = BenchmarkRunner.TuneResult("ok", 4.5, [4.5], [(2, 64)])
checkpoint = BenchmarkRunner.load_checkpoint(config, spec, options)
@test BenchmarkRunner.record!(
checkpoint, build, result, 1, "FUSION_LOOKAHEAD", 128)
checkpoint, build, result, 1, "QUEUE_ABSORB_LIMIT", 128)

resumed = BenchmarkRunner.load_checkpoint(
config, spec, BenchmarkRunner.TuneOptions(
Expand Down Expand Up @@ -103,7 +103,7 @@ end
failed = BenchmarkRunner.TuneResult(
"runtime_failed", Inf, Float64[], Tuple{Int,Int}[])
BenchmarkRunner.record!(checkpoint, copy(BenchmarkRunner.DEFAULT_FUSION_BUILD),
failed, 1, "FUSION_LOOKAHEAD", 128)
failed, 1, "QUEUE_ABSORB_LIMIT", 128)
resumed = BenchmarkRunner.load_checkpoint(config, spec, options)
@test isempty(resumed.cache)
@test length(resumed.trials) == 1
Expand Down
2 changes: 1 addition & 1 deletion host/detail/queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ void EventQueue::grow_fusion_batch(const std::shared_ptr<Event>& e) {
#if PIPELINE
if (e->op == Event::OperationType::COMPUTE) {
size_t absorbed = 0;
while (absorbed < FUSION_LOOKAHEAD && !operations_.empty()) {
while (absorbed < QUEUE_ABSORB_LIMIT && !operations_.empty()) {
auto next = operations_.front();
if (next->op != Event::OperationType::COMPUTE) break;
if (!try_fuse(e, next)) break;
Expand Down
2 changes: 1 addition & 1 deletion julia/src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function versioninfo(io::IO = stdout)
" batch=", cfg("JIT_BATCH_SIZE")))
_field(io, "Build", string(inst("BUILD_TYPE"), ", ", cfg("CXX_STANDARD"),
", ", inst("CXX")))
_field(io, "Fusion", string("lookahead=", cfg("FUSION_LOOKAHEAD"),
_field(io, "Fusion", string("absorb=", cfg("QUEUE_ABSORB_LIMIT"),
" chains=", cfg("MAX_HFUSE_CHAINS"),
" ops=", cfg("MAX_VFUSE_OPS")))
_field(io, "Slots", string(MAX_VFUSE_INPUTS, " operands, ",
Expand Down
2 changes: 1 addition & 1 deletion test/framework.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void print_build_config() {
<< " MAX_VFUSE_OPS=" << MAX_VFUSE_OPS
<< " MAX_VFUSE_INPUTS=" << MAX_VFUSE_INPUTS
<< "\n MAX_PIPELINE_STACK_DEPTH=" << MAX_PIPELINE_STACK_DEPTH
<< " FUSION_LOOKAHEAD=" << FUSION_LOOKAHEAD
<< " QUEUE_ABSORB_LIMIT=" << QUEUE_ABSORB_LIMIT
<< " BLOCK_SIZE=" << BLOCK_SIZE << " NR_TASKLETS=" << NR_TASKLETS
<< "\n";
}
Expand Down
2 changes: 1 addition & 1 deletion test/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ constexpr size_t max_reduction_chains() {
constexpr size_t max_hfuse_chains() { return (size_t)MAX_HFUSE_CHAINS; }
constexpr size_t max_combined_inputs() { return (size_t)MAX_COMBINED_INPUTS; }
constexpr size_t max_vfuse_ops() { return (size_t)MAX_VFUSE_OPS; }
constexpr size_t fusion_lookahead() { return (size_t)FUSION_LOOKAHEAD; }
constexpr size_t queue_absorb_limit() { return (size_t)QUEUE_ABSORB_LIMIT; }

// Turns a limit into an expected kernel count.
constexpr size_t ceil_div(size_t a, size_t b) { return (a + b - 1) / b; }
Expand Down
Loading