Skip to content

[TENT] Add rule-based transport and device selection #2079

Merged
alogfans merged 12 commits into
kvcache-ai:mainfrom
alogfans:feat/tent-transport-selector
May 27, 2026
Merged

[TENT] Add rule-based transport and device selection #2079
alogfans merged 12 commits into
kvcache-ai:mainfrom
alogfans:feat/tent-transport-selector

Conversation

@alogfans

Copy link
Copy Markdown
Collaborator

Description

Add TransportSelector for flexible, configuration-driven transport selection policy while maintaining full backward compatibility.

Key features:

  • Configuration-driven transport selection via JSON policy rules
  • Support for segment_type filtering, device allocation, and transport priority
  • Legacy mode option (use_legacy_transport_selection) for exact original behavior
  • Default policies match original hardcoded behavior

Changes:

  • Add TransportSelector class with SelectionContext, SelectionPolicy, SelectionResult
  • Integrate TransportSelector into TransferEngineImpl
  • Add legacy mode support to preserve original code path

Module

  • Transfer Engine (mooncake-transfer-engine)
  • Mooncake Store (mooncake-store)
  • Mooncake EP (mooncake-ep)
  • Integration (mooncake-integration)
  • P2P Store (mooncake-p2p-store)
  • Python Wheel (mooncake-wheel)
  • PyTorch Backend (mooncake-pg)
  • Mooncake RL (mooncake-rl)
  • CI/CD
  • Docs
  • Other

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Breaking change
  • Documentation update
  • Other

How Has This Been Tested?

Checklist

  • I have performed a self-review of my own code.
  • I have formatted my own code using ./scripts/code_format.sh before submitting.
  • I have updated the documentation.
  • I have added tests to prove my changes are effective.

Add TransportSelector for flexible, configuration-driven transport selection
policy while maintaining full backward compatibility.

Key features:
- Configuration-driven transport selection via JSON policy rules
- Support for segment_type filtering, device allocation, and transport priority
- Legacy mode option (use_legacy_transport_selection) for exact original behavior
- Default policies match original hardcoded behavior

Changes:
- Add TransportSelector class with SelectionContext, SelectionPolicy, SelectionResult
- Integrate TransportSelector into TransferEngineImpl
- Add legacy mode support to preserve original code path
- Restore TaskInfo fields (xport_priority, failover_count) for backward compatibility
- Add max_failover_attempts configuration option

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a configuration-driven TransportSelector to replace hardcoded transport selection logic, allowing for more flexible policies based on segment type, memory patterns, and transfer size. Key changes include the integration of the selector into TransferEngineImpl, updates to the TaskInfo structure for device masking, and the addition of a legacy selection mode. Feedback focuses on correcting transport capability checks that incorrectly included file-specific flags for memory transfers, improving the robustness of the same_machine verification, handling NPU memory patterns, and ensuring safer JSON parsing when loading policies.

Comment thread mooncake-transfer-engine/tent/src/runtime/transport_selector.cpp Outdated
Comment thread mooncake-transfer-engine/tent/src/runtime/transport_selector.cpp Outdated
Comment on lines +883 to +885
bool same_machine =
(desc->machine_id ==
metadata_->segmentManager().getLocal()->machine_id);

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.

medium

The simplified same_machine check is less robust than the legacy implementation. It lacks checks for empty machine_id strings and does not verify if the local segment descriptor is valid. If machine_id is empty for both segments, they would incorrectly be considered as being on the same machine.

        auto local_desc = metadata_->segmentManager().getLocal();
        bool same_machine = local_desc && !desc->machine_id.empty() &&
                            !local_desc->machine_id.empty() &&
                            desc->machine_id == local_desc->machine_id;

Comment on lines +202 to +226
bool TransportSelector::matchesMemoryPattern(const std::string& pattern,
MemoryType type) const {
if (pattern == kMemoryTypeWildcard) {
return true;
}

// Convert MemoryType to string for comparison
std::string type_str;
switch (type) {
case MTYPE_CPU:
type_str = kMemoryTypeCpu;
break;
case MTYPE_CUDA:
type_str = kMemoryTypeCuda;
break;
case MTYPE_ROCM:
type_str = "rocm";
break;
default:
type_str = "unknown";
break;
}

return pattern == type_str;
}

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.

medium

The pattern matching logic for memory types does not handle the npu pattern, even though kMemoryTypeNpu is defined. Since MTYPE_CUDA is used to represent both CUDA and NPU devices in this context, the npu pattern should be explicitly matched against MTYPE_CUDA.

bool TransportSelector::matchesMemoryPattern(const std::string& pattern,
                                             MemoryType type) const {
    if (pattern == kMemoryTypeWildcard) {
        return true;
    }

    if (pattern == kMemoryTypeNpu && type == MTYPE_CUDA) {
        return true;
    }

    // Convert MemoryType to string for comparison
    std::string type_str;
    switch (type) {
        case MTYPE_CPU:
            type_str = kMemoryTypeCpu;
            break;
        case MTYPE_CUDA:
            type_str = kMemoryTypeCuda;
            break;
        case MTYPE_ROCM:
            type_str = "rocm";
            break;
        default:
            type_str = "unknown";
            break;
    }

    return pattern == type_str;
}

Comment on lines +137 to +141
if (policy_json.contains("same_machine")) {
policy.same_machine = policy_json["same_machine"].get<bool>();
} else {
policy.same_machine = std::nullopt;
}

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.

medium

Using .get<bool>() (and similar .get<T>() calls for min_size, max_size, and priority) without verifying the JSON element's type can lead to a nlohmann::json::type_error exception if the configuration file contains unexpected types. It is safer to use .is_boolean() check or the .value() method with a default value.

alogfans and others added 4 commits May 11, 2026 15:21
Add transport_selector_test.cpp with test coverage for:
- Default policies matching original behavior (File/Memory segments)
- Transport type name parsing
- Legacy mode enable/disable
- Transport availability based on capabilities
- Priority offset for fallback scenarios
- Device mask handling
- NVLINK same-machine constraint
- ROCm memory type support
- GPU-to-GPU, CPU-to-CPU, CPU-to-GPU, GPU-to-CPU transfers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fix compilation error by accessing Transport::caps (protected)
through helper methods instead of a separate public member.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented May 11, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 50.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...r-engine/tests/endpoint_store_integration_test.cpp 50.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@alogfans alogfans changed the title [TENT] Add configuration-driven transport selector [TENT] Add rule-based transport and device selection May 22, 2026
Comment on lines +835 to +838
if (checkAvailability(transport_list_[GDS], local_mtype)) {
if (transport_index-- == 0) result.transport = GDS;
} else if (checkAvailability(transport_list_[IOURING],
local_mtype)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This changes the transport fallback behavior in legacy mode. Is this by design?

const std::vector<TransportType>*
buffer_transports; // Pointer to transports in buffer
size_t transfer_size; // Transfer size in bytes
int priority_level; // Request priority level (higher = more urgent)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The QoS system uses PRIO_HIGH = 0 as the most urgent. The comment "higher = more urgent" is the opposite of the actual encoding.

auto prev_type = task.type;

if (++task.failover_count > max_failover_attempts_) {
if (task.failover_count >= max_failover_attempts_) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why change this condition?

@alogfans

Copy link
Copy Markdown
Collaborator Author

@staryxchen We have addressed your issues by reverting some of the modifcations.

@staryxchen staryxchen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. But CI failed, I'm not sure if it is related with this PR.

alogfans and others added 2 commits May 26, 2026 14:39
When ibv_get_device_list returns a non-NULL list but num_devices == 0,
we need to call ibv_free_device_list before returning to avoid leaking
the allocated memory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alogfans
alogfans merged commit 54411af into kvcache-ai:main May 27, 2026
17 of 19 checks passed
Aionw pushed a commit to Aionw/Mooncake that referenced this pull request May 27, 2026
* [TENT] Add configuration-driven transport selector

Add TransportSelector for flexible, configuration-driven transport selection
policy while maintaining full backward compatibility.

Key features:
- Configuration-driven transport selection via JSON policy rules
- Support for segment_type filtering, device allocation, and transport priority
- Legacy mode option (use_legacy_transport_selection) for exact original behavior
- Default policies match original hardcoded behavior

Changes:
- Add TransportSelector class with SelectionContext, SelectionPolicy, SelectionResult
- Integrate TransportSelector into TransferEngineImpl
- Add legacy mode support to preserve original code path
- Restore TaskInfo fields (xport_priority, failover_count) for backward compatibility
- Add max_failover_attempts configuration option

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [TENT] Add comprehensive unit tests for TransportSelector

Add transport_selector_test.cpp with test coverage for:
- Default policies matching original behavior (File/Memory segments)
- Transport type name parsing
- Legacy mode enable/disable
- Transport availability based on capabilities
- Priority offset for fallback scenarios
- Device mask handling
- NVLINK same-machine constraint
- ROCm memory type support
- GPU-to-GPU, CPU-to-CPU, CPU-to-GPU, GPU-to-CPU transfers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [TENT] Fix FakeTransport to use protected caps member

Fix compilation error by accessing Transport::caps (protected)
through helper methods instead of a separate public member.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix

* fix format issues

* Add priority-based rule

* Reformat

* Fix review comments

* Fix memory leak in endpoint_store_integration_test

When ibv_get_device_list returns a non-NULL list but num_devices == 0,
we need to call ibv_free_device_list before returning to avoid leaking
the allocated memory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Trigger CI

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A-Liuhao pushed a commit to A-Liuhao/Mooncake that referenced this pull request Jun 25, 2026
* [TENT] Add configuration-driven transport selector

Add TransportSelector for flexible, configuration-driven transport selection
policy while maintaining full backward compatibility.

Key features:
- Configuration-driven transport selection via JSON policy rules
- Support for segment_type filtering, device allocation, and transport priority
- Legacy mode option (use_legacy_transport_selection) for exact original behavior
- Default policies match original hardcoded behavior

Changes:
- Add TransportSelector class with SelectionContext, SelectionPolicy, SelectionResult
- Integrate TransportSelector into TransferEngineImpl
- Add legacy mode support to preserve original code path
- Restore TaskInfo fields (xport_priority, failover_count) for backward compatibility
- Add max_failover_attempts configuration option

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [TENT] Add comprehensive unit tests for TransportSelector

Add transport_selector_test.cpp with test coverage for:
- Default policies matching original behavior (File/Memory segments)
- Transport type name parsing
- Legacy mode enable/disable
- Transport availability based on capabilities
- Priority offset for fallback scenarios
- Device mask handling
- NVLINK same-machine constraint
- ROCm memory type support
- GPU-to-GPU, CPU-to-CPU, CPU-to-GPU, GPU-to-CPU transfers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [TENT] Fix FakeTransport to use protected caps member

Fix compilation error by accessing Transport::caps (protected)
through helper methods instead of a separate public member.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix

* fix format issues

* Add priority-based rule

* Reformat

* Fix review comments

* Fix memory leak in endpoint_store_integration_test

When ibv_get_device_list returns a non-NULL list but num_devices == 0,
we need to call ibv_free_device_list before returning to avoid leaking
the allocated memory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Trigger CI

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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