Skip to content

[VL] Use a dedicated CPU thread pool for parallel broadcast hash-table build - #13115

Merged
philo-he merged 1 commit into
apache:mainfrom
yikf:topn-hashtable-build-executor
Oct 16, 2026
Merged

philo-he merged 1 commit into
apache:mainfrom
yikf:topn-hashtable-build-executor

Conversation

@yikf

@yikf yikf commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

The parallel broadcast hash-table build path (numThreads > 1 in HashJoinBuilder.nativeBuild) dispatched its CPU-bound build tasks onto VeloxBackend::ioExecutor(). That executor is reserved for async IO tasks (split preloading, DirectBufferedInput).

// FIXME: This reuses the io executor which is supposed to only serve async IO tasks.
auto executor = VeloxBackend::get()->ioExecutor();
Running CPU-heavy hash-table build work on the IO pool makes it contend with
genuine IO work on the same threads.

This PR introduces a dedicated CPU thread pool (VeloxBackend:: broadcastHashTableBuildExecutor()), following the existing getReaderThreadPool() std::call_once pattern, and switches both places that previously reused the io executor:

  1. the parallel build task dispatch (folly::via(executor, ...)), and
  2. the parallel join-table merge passed to prepareJoinTable(...).

The pool size is controlled by a new native config key spark.gluten.sql.columnar.backend.velox.broadcastHashTableBuildThreads. if miss this config falls back to kNumTaskSlotsPerExecutor, i.e. the same sizing this path previously inherited from the io executor. So default behavior is unchanged — this is a pool-isolation change, not a concurrency change. The key is native-only and passed through via the spark.gluten.sql.columnar.backend.velox. prefix, mirroring how spillThreadNum is handled.

How was this patch tested?

GA.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude claude-opus-4-8

Copilot AI lite review requested due to automatic review settings September 24, 2026 08:26
@github-actions github-actions Bot added the VELOX label Sep 24, 2026
@yikf
yikf force-pushed the topn-hashtable-build-executor branch from 1a20b07 to 9416aa4 Compare September 24, 2026 08:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Two critical executor initialization issues and a moderate fallback-sizing issue remain unresolved; documentation also needs updating.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity

Open (2)
What changed in this PR

This PR adds a dedicated, configurable CPU executor for parallel broadcast hash-table construction, separating it from Velox’s I/O pool.

Changes:

  • Routes parallel build and merge work through the new executor.
  • Adds native thread-count configuration.
  • Adds executor lifecycle management.
File Summary
cpp/​velox/​jni/​VeloxJniWrapper.cc Uses the dedicated executor for hash-table build and merge operations.
cpp/​velox/​config/​VeloxConfig.h Defines the new pool-size configuration key.
cpp/​velox/​compute/​VeloxBackend.h Declares executor access and ownership.
cpp/​velox/​compute/​VeloxBackend.cc Creates and tears down the executor; lifecycle, zero-thread fallback, and compatibility sizing require changes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cpp/velox/compute/VeloxBackend.cc Outdated
Comment thread cpp/velox/compute/VeloxBackend.cc Outdated
Copilot AI review requested due to automatic review settings September 24, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate issues affect executor reinitialization, compatibility, zero-worker behavior, and test coverage.

Review effort: Lite
Findings: 2 High severity

Open (2)

@yikf

yikf commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

@zhztheplayer Could you please take a look if you find a time, thanks.

Copilot AI review requested due to automatic review settings September 24, 2026 08:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Address the executor reinitialization and default thread-count compatibility issues; document the new configuration key.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (1)

Copilot AI review requested due to automatic review settings September 28, 2026 02:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Backend reinitialization and IO-thread fallback behavior need correction before approval.

Review effort: Lite
Findings: 1 High severity

Open (1)

@yikf
yikf force-pushed the topn-hashtable-build-executor branch from 5ae1189 to b1c95b6 Compare September 28, 2026 03:31
Copilot AI review requested due to automatic review settings September 28, 2026 03:31
@github-actions github-actions Bot added the CORE works for Gluten Core label Sep 28, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Address the IO-thread fallback compatibility issue and add coverage for positive thread-count configuration.

Review effort: Lite
Findings: None

Resolved since last review (1)

@zhztheplayer zhztheplayer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the improvement.

cc @JkSelf

Comment thread cpp/velox/compute/VeloxBackend.cc Outdated
Comment on lines +332 to +342
folly::Executor* VeloxBackend::hashTableBuildExecutor() {
std::call_once(hashTableBuildExecutorInit_, [this] {
auto numThreads = backendConf_->get<int32_t>(kHashTableBuildThreads, kHashTableBuildThreadsDefault);
if (numThreads <= 0) {
// Parallel builds still need a worker when there are no task slots.
numThreads = std::max<int32_t>(1, backendConf_->get<int32_t>(kNumTaskSlotsPerExecutor, 1));
}
hashTableBuildExecutor_ = std::make_unique<folly::CPUThreadPoolExecutor>(numThreads);
});
return hashTableBuildExecutor_.get();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor questions:

  1. Can we initialize hashTableBuildExecutor_ in VeloxBackend::init()?
  2. Should we set the default value as numTaskSlotsPerExecutor?

@yikf yikf Sep 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhztheplayer Thanks for your suggestion!

  1. hashTableBuildExecutor_ is only used during native build, so lazy initialization is a better choice here, what do you think?

  2. Sounds good! Updated accordingly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hashTableBuildExecutor_ is only used during native build, so lazy initialization is a better choice here, what do you think?

The thread creation should already be lazy in folly::CPUThreadPoolExecutor, so I assume std::make_unique<folly::CPUThreadPoolExecutor>(numThreads) is a cheap operation?

I asked the question mainly because it's not aligned with initialization code of other executors.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we set the default value as numTaskSlotsPerExecutor?

Since the driver and executor build hash table share same code path, we need to distinguish the numTaskSlotsPerExecutor and numTaskSlotPerDriver.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default value has been updated, and we now distinguish between numTaskSlotsPerExecutor and numTaskSlotPerDriver.

Copilot AI review requested due to automatic review settings September 28, 2026 08:31
@yikf
yikf force-pushed the topn-hashtable-build-executor branch from b1c95b6 to 7dd4248 Compare September 28, 2026 08:31
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Resolve the non-positive thread-count fallback before approval.

Review effort: Lite
Findings: 1 Medium severity

Open (1)

Comment thread cpp/velox/compute/VeloxBackend.cc Outdated
Copilot AI review requested due to automatic review settings September 28, 2026 08:40
@yikf
yikf force-pushed the topn-hashtable-build-executor branch from 7dd4248 to bcbe53a Compare September 28, 2026 08:40
Copilot AI lite review requested due to automatic review settings October 15, 2026 02:23
@yikf
yikf force-pushed the topn-hashtable-build-executor branch from ae64f89 to 8d70bdf Compare October 15, 2026 02:23
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Copilot review overview

15 open findings
3 resolved since last review

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Copilot AI lite review requested due to automatic review settings October 15, 2026 02:53
Copilot stopped reviewing on behalf of yikf due to an error October 15, 2026 03:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Copilot review overview

19 open findings

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread docs/velox-configuration.md
Copilot AI lite review requested due to automatic review settings October 15, 2026 07:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

16 open findings
7 resolved since last review

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread cpp/velox/tests/VeloxBackendTest.cc
Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread docs/velox-configuration.md
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI lite review requested due to automatic review settings October 15, 2026 08:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

18 open findings
1 resolved since last review

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread cpp/velox/jni/VeloxJniWrapper.cc
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Copilot AI lite review requested due to automatic review settings October 15, 2026 12:20
@yikf
yikf force-pushed the topn-hashtable-build-executor branch from 88bb5a8 to bd472a6 Compare October 15, 2026 12:20
@github-actions github-actions Bot removed the CORE works for Gluten Core label Oct 15, 2026
Copilot stopped reviewing on behalf of yikf due to an error October 15, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Copilot review overview

13 open findings
7 resolved since last review

🧠 Review effort: Lite

Comment on lines +259 to +260
std::max<int32_t>(1, backendConf_->get<int32_t>(kBroadcastHashTableBuildThreads, numTaskSlotsPerExecutor));
broadcastHashTableBuildExecutor_ = std::make_unique<folly::CPUThreadPoolExecutor>(broadcastHashTableBuildThreads);

const auto broadcastHashTableBuildThreads =
std::max<int32_t>(1, backendConf_->get<int32_t>(kBroadcastHashTableBuildThreads, numTaskSlotsPerExecutor));
broadcastHashTableBuildExecutor_ = std::make_unique<folly::CPUThreadPoolExecutor>(broadcastHashTableBuildThreads);
Copilot AI lite review requested due to automatic review settings October 15, 2026 12:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Copilot review overview

16 open findings

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread cpp/velox/tests/VeloxBackendTest.cc

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

21 open findings

And 1 more that still need to be addressed.

🧠 Review effort: Lite

Comment thread cpp/velox/compute/VeloxBackend.cc
Comment thread cpp/velox/compute/VeloxBackend.cc
Comment on lines +59 to +60
folly::Executor* broadcastHashTableBuildExecutor() const {
return broadcastHashTableBuildExecutor_.get();
Comment thread cpp/velox/tests/VeloxBackendTest.cc

@philo-he philo-he left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks.

@JkSelf JkSelf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for your fix.

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.

5 participants