Skip to content

ci: run TPC-DS SF1 with 1 and 4 partitions per task - #2197

Merged
andygrove merged 1 commit into
apache:mainfrom
andygrove:ci/tpcds-static-partition-matrix
Jul 28, 2026
Merged

ci: run TPC-DS SF1 with 1 and 4 partitions per task#2197
andygrove merged 1 commit into
apache:mainfrom
andygrove:ci/tpcds-static-partition-matrix

Conversation

@andygrove

@andygrove andygrove commented Jul 28, 2026

Copy link
Copy Markdown
Member

Which issue does this PR close?

Part of #2092.

Rationale for this change

The TPC-DS gate runs exactly one configuration: the static planner at 16 partitions with the default one-task-per-input-partition packing. Multi-partition tasks — where the scheduler packs several input partitions into a single task's partition_slice — have no TPC-DS coverage at all.

That packing is not a cosmetic scheduling detail. It changes how a task's plan is rewritten (restrict_plan_to_partitions), how many vcores a task reserves, and how much of the executor's memory pool the task is handed. TPC-H covers it (tpch.yml has an "AQE on, multi-partition tasks" leg); TPC-DS, which is the broader query set by a wide margin, does not.

What changes are included in this PR?

Replaces the single job with a two-leg matrix over ballista.scheduler.max_partitions_per_task, following the shape tpch.yml already uses. Both legs run the static planner at --partitions 16; only the task-packing cap differs.

Leg max_partitions_per_task
mpt1 1 (default) existing coverage
mpt4 4 new
  • Per-leg label / task_args / slug, matching tpch.yml's convention.
  • fail-fast: false, so one red leg does not mask the other.
  • Both legs share one swatinem/rust-cache entry via shared-key: tpcds-sf1, so the binaries are compiled once and restored by the second leg rather than built twice. This mirrors tpch.yml's shared-key: tpch-sf10.
  • The run_suite shell helper is inlined, since each leg now runs exactly one invocation.
  • The cluster-log artifact is named per leg so failures do not collide.

Why the cap is 4 and not higher

bind_one clamps the slice to the executor's free vcores:

let max_partitions = if is_collapse { usize::MAX } else { (budget.vcores as usize).min(cap) };

budget.vcores comes from the executor's --concurrent-tasks, which this workflow sets to 4. Any cap above 4 is therefore unreachable here and would only make the leg's name overstate what it covers. 4 is the largest slice this cluster can actually build, and it is 4x the default — enough to exercise the multi-partition path.

max_partitions_per_task=0 (unbounded, as tpch.yml uses) would behave identically at this vcore count, but naming the number keeps the leg honest about what it tests.

Adaptive-planner coverage is deliberately out of scope; it is tracked separately in #2182 and still fails on known bugs.

How are these changes tested?

Both legs were run locally at SF1 against a single-process DataFusion oracle, using this workflow's exact cluster configuration (--concurrent-tasks 4 --memory-pool-size 2GB, --partitions 16 --verify, prefer_hash_join=false):

  • max_partitions_per_task=1 — 97/97 pass
  • max_partitions_per_task=4 — 97/97 pass

The matrix is green as it stands; it is a regression gate, not a tracker for known failures.

The new leg was also checked for being a no-op, since a config that silently fails to apply would leave a green leg covering nothing. Running q1 alone and counting Execute task lines in the executor log:

max_partitions_per_task tasks executed for q1
1 149
4 58

Fewer than a clean 4x reduction because collapse stages always pack their full pending queue regardless of the cap, and some stages have fewer than 4 partitions to begin with — but the setting is unambiguously taking effect.

Are there any user-facing changes?

No. CI coverage only.

The TPC-DS gate runs one configuration: the static planner at 16 partitions
with the default one-task-per-input-partition packing. Multi-partition tasks
have no TPC-DS coverage, even though packing several input partitions into a
task changes how the task's plan is rewritten, how many vcores it reserves,
and how much of the executor memory pool it is handed. tpch.yml covers this;
TPC-DS, the far broader query set, does not.

Adds a second leg setting ballista.scheduler.max_partitions_per_task=4, with
--partitions 16 held constant across both legs. The cap is 4 rather than
higher because bind_one clamps the slice to the executor's free vcores and
this workflow runs --concurrent-tasks 4, so a larger cap would be unreachable.

Both legs verified locally at SF1 against a single-process DataFusion oracle:
97/97 pass under each.
@andygrove
andygrove force-pushed the ci/tpcds-static-partition-matrix branch from c236ba0 to ce7bfe5 Compare July 28, 2026 00:58
@andygrove andygrove changed the title ci: run TPC-DS SF1 at 1 and 16 partitions under the static planner ci: run TPC-DS SF1 with 1 and 4 partitions per task Jul 28, 2026
@andygrove
andygrove marked this pull request as ready for review July 28, 2026 00:59
@andygrove
andygrove requested a review from avantgardnerio July 28, 2026 01:04
@andygrove
andygrove merged commit 2b04f83 into apache:main Jul 28, 2026
9 checks passed
@andygrove
andygrove deleted the ci/tpcds-static-partition-matrix branch July 28, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants