add dsl algorithms support to bench collective - #887
RJ Souza (Empyreus) wants to merge 28 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Adds multi-node DSL collective autotuning and CI coverage for AllReduce, AllGather, and ReduceScatter.
Changes:
- Compiles and tunes runtime DSL variants with configurable launch geometry.
- Adds ReduceScatter benchmarking and correctness validation.
- Reworks multi-node CI to exercise DSL collectives.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
test/deploy/run_tests.sh |
Adds manual multi-node DSL test helpers. |
python/mscclpp/default_algos/reducescatter_multi_nodes.py |
Adds a plan-generation CLI. |
python/mscclpp_benchmark/tuner.py |
Supports candidate-specific tuning dimensions. |
python/mscclpp_benchmark/correctness.py |
Validates ReduceScatter output. |
python/mscclpp_benchmark/comm.py |
Compiles and executes DSL variants. |
python/mscclpp_benchmark/bench_collective.py |
Adds DSL candidates and ReduceScatter benchmarking. |
.azure-pipelines/multi-nodes-test.yml |
Adds three multi-node DSL benchmark jobs. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Suppressed comments (2)
python/mscclpp_benchmark/comm.py:203
- Every compiled DSL plan is hard-coded as in-place, but
--enable-dslcan be combined with--buffer-mode out-of-place, and_dsl_candidate_specsdoes not filter byalgorithm.buffer_mode. For out-of-place AllReduce/AllGather, the tuner therefore executes plans whose buffer layout assumes aliasing, causing incorrect output before falling into its default fallback. Either compile the requested mode where the builder supports it, or reject/filter DSL candidates whose mode does not match the case.
collective=collective_op,
nranks_per_node=nranks_per_node,
world_size=world_size,
in_place=True,
python/mscclpp_benchmark/bench_collective.py:405
- The accepted
buffer_modeargument is ignored for ReduceScatter: requestingout-of-placestill returns an aliased input/output case. This silently benchmarks a different layout than the CLI requested. Since the registered ReduceScatter DSL algorithm is in-place-only, reject this combination explicitly.
if collective == _REDUCESCATTER:
# The DSL reducescatter is compiled in-place, so the per-rank output chunk always aliases the
# matching slice of the full input buffer (mirrors python/test/executor_test.py build_bufs).
input_buffer = _mscclpp().GpuBuffer(nelems * comm_group.nranks, dtype=dtype_spec.cupy_dtype)
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
🟡 Changes recommended
BF16 ReduceScatter validation is incorrect, multi-node safety is bypassable, and the new CI checks are non-gating.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
python/mscclpp_benchmark/bench_collective.py:506
- ReduceScatter silently ignores an
out-of-placerequest and returns a case labeled in-place. MeanwhileCommskips compiling ReduceScatter DSL plans for that requested mode, so autotuning reports no candidates and exits successfully without benchmarking anything. Reject this unsupported mode explicitly (or implement matching out-of-place buffers).
if collective == _REDUCESCATTER:
# The DSL reducescatter is compiled in-place, so the per-rank output chunk always aliases the
# matching slice of the full input buffer (mirrors python/test/executor_test.py build_bufs).
input_buffer = _mscclpp().GpuBuffer(nelems * comm_group.nranks, dtype=dtype_spec.cupy_dtype)
.azure-pipelines/multi-nodes-test.yml:110
- With
continueOnError: true, failures from this new AllGather correctness benchmark do not fail the pipeline. Since this step is intended as a multi-node test, it needs to be gating.
name: RunBenchCollectiveAllgatherTest
displayName: Run multi-nodes bench_collective DSL allgather
continueOnError: true
.azure-pipelines/multi-nodes-test.yml:128
- With
continueOnError: true, failures from this new ReduceScatter correctness benchmark do not fail the pipeline. Since this step is intended as a multi-node test, it needs to be gating.
name: RunBenchCollectiveReduceScatterTest
displayName: Run multi-nodes bench_collective DSL reducescatter
continueOnError: true
- Files reviewed: 6/6 changed files
- Comments generated: 4
- Review effort level: Balanced
| # The tuner falls back here when every candidate fails, which bypasses the multi-node filter | ||
| # in _candidate_algorithms. Only the compiled DSL plans work across nodes; the native | ||
| # algorithms _default_tuned_config prefers are single-node CUDA-IPC and would hang. | ||
| if self._comm_group.nranks > self._comm_group.nranks_per_node: | ||
| if default_config.algorithm not in self._dsl_algorithms: |
| reduced = sum(values.astype(cp.float32).reshape(-1)[start : start + chunk] for values in encoded_inputs) | ||
| return _encode_reduced_output(case, reduced), None |
| displayName: Run multi-nodes mscclpp-test | ||
| name: RunBenchCollectiveAllreduceTest | ||
| displayName: Run multi-nodes bench_collective DSL allreduce | ||
| continueOnError: true |
| for tbg in tbg_values: | ||
| for tpb in tpb_values: | ||
| spec = AlgoSpec( |
Binyang Li (Binyang2014)
left a comment
There was a problem hiding this comment.
Can we move DSL related function to another python file? Make it easy to understand
| # DSL algorithms execute through the Executor and fail without one; native algorithms | ||
| # ignore it, so it is safe to pass unconditionally in run(). |
There was a problem hiding this comment.
Remove this comment?
| # reducescatter_multi_nodes lays out its thread block groups from this value. | ||
| pass_thread_block_group_size = True | ||
| else: | ||
| return |
There was a problem hiding this comment.
Log and throw error here?
| builder = allgather_multi_nodes | ||
| collective_op = AllGather(world_size, 1, in_place) | ||
| name_prefix = "dsl_allgather" | ||
| tags = {"default": 1} |
There was a problem hiding this comment.
Why set tags here
| dtype_override: Any | None = None, | ||
| accum_dtype: Any | None = None, | ||
| symmetric_memory: bool = False, | ||
| ) -> TunedConfig: |
There was a problem hiding this comment.
Do we need to change tuned_config to support dsl algo? Now how to persist dsl algo parameters to tuned config
| num_threads_per_block=tpb, | ||
| reuse_resources=True, | ||
| use_double_scratch_buffer=True, | ||
| min_message_size=tbg * (1 << 10), |
There was a problem hiding this comment.
Why min message size is tbg * (1 << 10)
Uh oh!
There was an error while loading. Please reload this page.