Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,17 @@ jobs:
run: ./scripts/ci/run_transfer_engine_rust_smoke.sh
shell: bash

- name: Smoke test TENT UB benchmark CLI
if: matrix.name == 'ub-mock'
run: |
cd build-tent
help_output="$(./mooncake-transfer-engine/benchmark/tebench \
--backend=tent --xport_type=ub --tent_transport_hint=ub \
--help 2>&1 || true)"
grep -q 'iouring|ub|sunrise_link' <<< "${help_output}"
grep -q 'ascend|ub|sunrise_link' <<< "${help_output}"
shell: bash

- name: Run sccache stat for check
if: ${{ env.SCCACHE_PATH != '' }}
shell: bash
Expand Down
2 changes: 2 additions & 0 deletions mooncake-transfer-engine/benchmark/tent_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ std::shared_ptr<Config> loadConfig() {
{"gds", "gds"},
{"mnnvl", "mnnvl"},
{"nvlink", "nvlink"},
{"ub", "ub"},
{"sunrise_link", "sunrise_link"},
{"mpcomm", "mpcomm"}};

Expand All @@ -91,6 +92,7 @@ static TransportType getTransportType(const std::string& xport_type) {
if (xport_type == "nvlink") return NVLINK;
if (xport_type == "tcp") return TCP;
if (xport_type == "iouring") return IOURING;
if (xport_type == "ub") return UB;
if (xport_type == "sunrise_link") return SUNRISE_LINK;
if (xport_type == "mpcomm") return MPCOMM;
return UNSPEC;
Expand Down
6 changes: 4 additions & 2 deletions mooncake-transfer-engine/benchmark/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@ DEFINE_int32(
"RPC server port used for p2p metadata service (0 = auto-select).");
DEFINE_string(xport_type, "",
"Transport type: "
"rdma|shm|mnnvl|gds|iouring|sunrise_link|mpcomm|flagcx");
"rdma|tcp|shm|mnnvl|nvlink|gds|iouring|ub|sunrise_link|mpcomm|"
"flagcx");
DEFINE_string(backend, "tent", "Transport backend: classic|tent");
DEFINE_bool(notifi, false,
"Enable RDMA notification for performance measurement.");
DEFINE_string(
tent_transport_hint, "unspec",
"tent only: per-request transport_hint. "
"unspec|rdma|tcp|shm|nvlink|gds|io_uring|mnnvl|ascend|sunrise_link|mpcomm");
"unspec|rdma|tcp|shm|nvlink|gds|io_uring|mnnvl|ascend|ub|sunrise_link|"
"mpcomm");
DEFINE_string(tent_intent_type, "unspec",
"tent only: intent_type attached to every benchmark request. "
"unspec|foreground_get|background_prefetch|migration|checkpoint|"
Expand Down
2 changes: 2 additions & 0 deletions mooncake-transfer-engine/tent/include/tent/rpc/rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ enum RpcFuncID {
Unpin,
SubscribeSegmentUpdate,
NotifySegmentUpdated,
// Appended to preserve the numeric values of the existing RPCs.
BootstrapUb,
};

class ClientPool;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <functional>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <string>
#include <thread>
#include <unordered_map>
Expand All @@ -48,7 +49,7 @@ struct BootstrapDesc {
// RDMA address of local_nic_path.
uint16_t local_lid = 0;
std::string local_gid;
std::string reply_msg; // non-empty means the bootstrap callback failed
std::string reply_msg; // on error
uint32_t notify_qp_num = 0; // Notification QP number (0 = not supported)

public:
Expand All @@ -57,6 +58,65 @@ struct BootstrapDesc {
notify_qp_num);
};

// UB/URMA has Jetty, JFC and EID concepts that are not wire-compatible with
// RDMA QPs, CQs and GIDs. Keep a dedicated bootstrap envelope so neither
// transport has to smuggle native identifiers through the other's fields.
struct UbBootstrapDesc {
uint32_t protocol_version = 1;
std::string segment_name;
std::string local_nic_path;
std::string peer_nic_path;
std::string local_device_name;
int local_device_id = -1;
int local_eid_index = -1;
std::string local_eid;
std::vector<uint32_t> jetty_ids;
// UASID is part of urma_jetty_id_t on providers that use nonzero address
// spaces. Kept parallel to jetty_ids for protocol-v1 compatibility.
std::vector<uint32_t> jetty_uasids;
uint64_t endpoint_generation = 0;
uint64_t segment_generation = 0;
std::vector<std::string> capabilities;
std::string reply_msg;
};

inline void to_json(nlohmann::json& j, const UbBootstrapDesc& desc) {
j = nlohmann::json{{"protocol_version", desc.protocol_version},
{"segment_name", desc.segment_name},
{"local_nic_path", desc.local_nic_path},
{"peer_nic_path", desc.peer_nic_path},
{"local_device_name", desc.local_device_name},
{"local_device_id", desc.local_device_id},
{"local_eid_index", desc.local_eid_index},
{"local_eid", desc.local_eid},
{"jetty_ids", desc.jetty_ids},
{"jetty_uasids", desc.jetty_uasids},
{"endpoint_generation", desc.endpoint_generation},
{"segment_generation", desc.segment_generation},
{"capabilities", desc.capabilities},
{"reply_msg", desc.reply_msg}};
}

inline void from_json(const nlohmann::json& j, UbBootstrapDesc& desc) {
desc.protocol_version = j.value("protocol_version", 0u);
if (desc.protocol_version != 1) {
throw std::invalid_argument("unsupported UB bootstrap version");
}
desc.segment_name = j.value("segment_name", "");
desc.local_nic_path = j.value("local_nic_path", "");
desc.peer_nic_path = j.value("peer_nic_path", "");
desc.local_device_name = j.value("local_device_name", "");
desc.local_device_id = j.value("local_device_id", -1);
desc.local_eid_index = j.value("local_eid_index", -1);
desc.local_eid = j.value("local_eid", "");
desc.jetty_ids = j.value("jetty_ids", std::vector<uint32_t>{});
desc.jetty_uasids = j.value("jetty_uasids", std::vector<uint32_t>{});
desc.endpoint_generation = j.value("endpoint_generation", uint64_t{0});
desc.segment_generation = j.value("segment_generation", uint64_t{0});
desc.capabilities = j.value("capabilities", std::vector<std::string>{});
desc.reply_msg = j.value("reply_msg", "");
}

struct XferDataDesc {
uint64_t peer_mem_addr;
size_t length;
Expand All @@ -65,6 +125,9 @@ struct XferDataDesc {
using OnReceiveBootstrap =
std::function<int(const BootstrapDesc& request, BootstrapDesc& response)>;

using OnReceiveUbBootstrap = std::function<int(const UbBootstrapDesc& request,
UbBootstrapDesc& response)>;

using OnNotify = std::function<int(const Notification&)>;

class ControlClient {
Expand All @@ -86,6 +149,10 @@ class ControlClient {
static Status decodeBootstrapResponse(const std::string& response_raw,
BootstrapDesc& response);

static Status bootstrapUb(const std::string& server_addr,
const UbBootstrapDesc& request,
UbBootstrapDesc& response);

static Status sendData(const std::string& server_addr,
uint64_t peer_mem_addr, void* local_mem_addr,
size_t length);
Expand Down Expand Up @@ -141,6 +208,11 @@ class ControlService {

void setBootstrapRdmaCallback(const OnReceiveBootstrap& callback);

void setBootstrapUbCallback(const OnReceiveUbBootstrap& callback) {
std::lock_guard<std::mutex> lock(ub_bootstrap_callback_mutex_);
ub_bootstrap_callback_ = callback;
}

void setNotifyCallback(const OnNotify& callback);

Status start(uint16_t& port, bool ipv6_ = false, size_t threads = 1);
Expand All @@ -152,6 +224,8 @@ class ControlService {
void onBootstrapRdma(const std::string_view& request,
std::string& response);

void onBootstrapUb(const std::string_view& request, std::string& response);

void onSendData(const std::string_view& request, std::string& response);

void onRecvData(const std::string_view& request, std::string& response);
Expand Down Expand Up @@ -189,6 +263,9 @@ class ControlService {
OnReceiveBootstrap bootstrap_callback_;
static thread_local const ControlService* active_bootstrap_service_;

std::mutex ub_bootstrap_callback_mutex_;
OnReceiveUbBootstrap ub_bootstrap_callback_;

std::mutex notify_cb_mutex_;
std::condition_variable notify_cb_cv_;
size_t notify_callbacks_in_flight_ = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2026 KVCache.AI
// SPDX-License-Identifier: Apache-2.0

#ifndef TENT_TRANSPORT_UB_DEVICE_SELECTION_H_
#define TENT_TRANSPORT_UB_DEVICE_SELECTION_H_

#include <algorithm>
#include <cctype>
#include <string>
#include <string_view>
#include <vector>

#include "tent/transport/ub/urma_adapter.h"

namespace mooncake {
namespace tent {
namespace ub {

// Heuristic used when device_filter is empty: prefer UBAGG bonding devices
// over underlying physical ports (e.g. udmac*) that appear alongside them.
inline bool isBondingDeviceName(std::string_view name) {
std::string lower(name);
std::transform(
lower.begin(), lower.end(), lower.begin(),
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
if (lower.rfind("bonding", 0) == 0) return true;
if (lower.find(":bonding") != std::string::npos) return true;
if (lower.find("_bond") != std::string::npos) return true;
if (lower.find("-bond") != std::string::npos) return true;
return false;
}

inline bool isBondingDevice(const DeviceInfo& device) {
return isBondingDeviceName(device.native_device_name) ||
isBondingDeviceName(device.topology_name);
}

// When explicit_filter is true, returns devices unchanged (caller already
// applied device_filter). When false and at least one bonding device is
// present, returns only bonding devices; otherwise returns all devices.
inline std::vector<DeviceInfo> preferBondingDevicesIfPresent(
const std::vector<DeviceInfo>& devices, bool explicit_filter) {
if (explicit_filter || devices.empty()) return devices;
const bool has_bonding =
std::any_of(devices.begin(), devices.end(),
[](const DeviceInfo& d) { return isBondingDevice(d); });
if (!has_bonding) return devices;

std::vector<DeviceInfo> selected;
selected.reserve(devices.size());
for (const auto& device : devices) {
if (isBondingDevice(device)) selected.push_back(device);
}
return selected;
}

} // namespace ub
} // namespace tent
} // namespace mooncake

#endif // TENT_TRANSPORT_UB_DEVICE_SELECTION_H_
Loading
Loading