[TENT] Add rule-based transport and device selection #2079
Conversation
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>
There was a problem hiding this comment.
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.
| bool same_machine = | ||
| (desc->machine_id == | ||
| metadata_->segmentManager().getLocal()->machine_id); |
There was a problem hiding this comment.
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;| 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; | ||
| } |
There was a problem hiding this comment.
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;
}| if (policy_json.contains("same_machine")) { | ||
| policy.same_machine = policy_json["same_machine"].get<bool>(); | ||
| } else { | ||
| policy.same_machine = std::nullopt; | ||
| } |
There was a problem hiding this comment.
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.
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 Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
| if (checkAvailability(transport_list_[GDS], local_mtype)) { | ||
| if (transport_index-- == 0) result.transport = GDS; | ||
| } else if (checkAvailability(transport_list_[IOURING], | ||
| local_mtype)) { |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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_) { |
There was a problem hiding this comment.
Why change this condition?
|
@staryxchen We have addressed your issues by reverting some of the modifcations. |
staryxchen
left a comment
There was a problem hiding this comment.
LGTM. But CI failed, I'm not sure if it is related with this PR.
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>
* [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>
* [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>
Description
Add TransportSelector for flexible, configuration-driven transport selection policy while maintaining full backward compatibility.
Key features:
Changes:
Module
mooncake-transfer-engine)mooncake-store)mooncake-ep)mooncake-integration)mooncake-p2p-store)mooncake-wheel)mooncake-pg)mooncake-rl)Type of Change
How Has This Been Tested?
Checklist
./scripts/code_format.shbefore submitting.