[Doc] improve Transfer Engine C++ API Reference (#1467)

* [Doc] improve Transfer Engine C++ API Reference

* Update docs/source/design/transfer-engine/cpp-api.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update docs/source/design/transfer-engine/cpp-api.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update docs/source/design/transfer-engine/index.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update docs/source/design/transfer-engine/cpp-api.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
fatSheep 2026-02-02 15:12:05 +08:00 committed by GitHub
parent 53f4f9ccb4
commit 9b242111aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 568 additions and 154 deletions

View File

@ -0,0 +1,556 @@
# Transfer Engine C++ API Reference
## Overview
This page summarizes the C++ APIs in `mooncake-transfer-engine/include/transfer_engine.h`.
It follows the same narrative style as the design doc, while covering the full set of public C++ APIs.
For conceptual background, see [Transfer Engine](index.md).
**Core APIs vs Advanced APIs**
- Core APIs form the minimal path to move data: initialize the engine, register memory, open segments, submit transfers, and query status.
- Advanced APIs are optional; they help with transport control, notifications, metadata/cache maintenance, topology discovery, and debugging.
## Core APIs
### Core Usage Path (C++)
Most integrations follow a short, repeatable path: initialize the engine, register local memory, open a target segment, submit a batch transfer, poll status, and finally free resources (batch, segment, memory). A minimal example is shown below.
```cpp
#include "transfer_engine.h"
using mooncake::TransferEngine;
using mooncake::TransferRequest;
using mooncake::TransferStatus;
TransferEngine engine(true);
engine.init("etcd://127.0.0.1:2379", "node0");
void *local_addr = /* local buffer address */;
size_t length = /* bytes to transfer */;
uint64_t remote_addr = /* remote address or file offset */;
engine.registerLocalMemory(local_addr, length, "cpu:0", true);
auto segment = engine.openSegment("node1");
auto batch = engine.allocateBatchID(1);
TransferRequest req{};
req.opcode = TransferRequest::WRITE;
req.source = local_addr;
req.target_id = segment;
req.target_offset = remote_addr;
req.length = length;
engine.submitTransfer(batch, {req});
TransferStatus status{};
engine.getTransferStatus(batch, 0, status);
engine.freeBatchID(batch);
engine.closeSegment(segment);
engine.unregisterLocalMemory(local_addr);
```
### Constructors
```cpp
TransferEngine(bool auto_discover = false);
TransferEngine(bool auto_discover, const std::vector<std::string>& filter);
```
Constructs a Transfer Engine instance. `auto_discover` enables topology discovery; `filter` constrains discovery or device selection with a whitelist.
### Data Transfer
#### TransferEngine::TransferRequest
The core API provided by Mooncake Transfer Engine is submitting a group of asynchronous `TransferRequest` tasks through the `submitTransfer` interface, and querying their status through the `getTransferStatus` interface. Each `TransferRequest` specifies reading or writing a continuous data space of `length` starting from the local starting address `source`, to the position starting at `target_offset` in the segment corresponding to `target_id`.
The `TransferRequest` structure is defined as follows:
```cpp
struct TransferRequest
{
enum OpCode { READ, WRITE };
OpCode opcode;
void *source;
SegmentID target_id; // The ID of the target segment, which may correspond to local or remote DRAM/VRAM/NVMeof, with the specific routing logic hidden
uint64_t target_offset;
size_t length;
int advise_retry_cnt = 0;
};
```
- `opcode` takes the values `READ` or `WRITE`. `READ` indicates that data is copied from the target address indicated by `<target_id, target_offset>` to the local starting address `source`; `WRITE` indicates that data is copied from `source` to the address indicated by `<target_id, target_offset>`.
- `source` represents the DRAM/VRAM buffer managed by the current `TransferEngine`, which must have been registered in advance by the `registerLocalMemory` interface.
- `target_id` represents the segment ID of the transfer target. The segment ID is obtained using the `openSegment` interface. Segments are divided into the following types:
- RAM space type, covering DRAM/VRAM. As mentioned earlier, there is only one segment under the same process (or `TransferEngine` instance), which contains various types of Buffers (DRAM/VRAM). In this case, the segment name passed to the `openSegment` interface is equivalent to the server hostname. `target_offset` is the virtual address of the target server.
- NVMeOF space type, where each file corresponds to a segment. In this case, the segment name passed to the `openSegment` interface is equivalent to the unique identifier of the file. `target_offset` is the offset of the target file.
- `length` represents the amount of data transferred. TransferEngine may further split this into multiple read/write requests internally.
#### TransferEngine::allocateBatchID
```cpp
BatchID allocateBatchID(size_t batch_size);
```
Allocates a `BatchID`. A maximum of `batch_size` `TransferRequest`s can be submitted under the same `BatchID`.
- `batch_size`: The maximum number of `TransferRequest`s that can be submitted under the same `BatchID`;
- Return value: If successful, returns a `BatchID`; on failure, returns an invalid handle (for example `INVALID_BATCH_ID`).
#### TransferEngine::submitTransfer
```cpp
Status submitTransfer(BatchID batch_id,
const std::vector<TransferRequest> &entries);
```
Submits new `TransferRequest` tasks to `batch_id`. The task is asynchronously submitted to the background thread pool. The total number of `entries` accumulated under the same `batch_id` should not exceed the `batch_size` defined at creation.
- `batch_id`: The `BatchID` it belongs to;
- `entries`: Array of `TransferRequest`;
- Return value: If successful, returns an OK status; otherwise, returns a non-OK status.
#### TransferEngine::getTransferStatus
```cpp
enum TransferStatusEnum
{
WAITING, // In the transfer phase
PENDING, // Not supported
INVALID, // Invalid parameters
CANCELED, // Not supported
COMPLETED, // Transfer completed
TIMEOUT, // Not supported
FAILED // Transfer failed even after retries
};
struct TransferStatus {
TransferStatusEnum s;
size_t transferred_bytes; // How much data has been successfully transferred (not necessarily an accurate value, but it is a lower bound)
};
Status getTransferStatus(BatchID batch_id, size_t task_id, TransferStatus &status)
```
Obtains the running status of the `TransferRequest` with `task_id` in `batch_id`.
- `batch_id`: The `BatchID` it belongs to;
- `task_id`: The sequence number of the `TransferRequest` to query;
- `status`: Output Transfer status;
- Return value: If successful, returns an OK status; otherwise, returns a non-OK status.
#### TransferEngine::getBatchTransferStatus
```cpp
Status getBatchTransferStatus(BatchID batch_id, TransferStatus& status);
```
Obtains the aggregated status of the batch and the total transferred bytes.
- `batch_id`: The `BatchID` it belongs to;
- `status`: Output Transfer status;
- Return value: If successful, returns an OK status; otherwise, returns a non-OK status.
#### TransferEngine::freeBatchID
```cpp
Status freeBatchID(BatchID batch_id);
```
Recycles `BatchID`, and subsequent operations on `submitTransfer` and `getTransferStatus` are undefined. If there are still `TransferRequest`s pending completion in the `BatchID`, the operation is refused.
- `batch_id`: The `BatchID` it belongs to;
- Return value: If successful, returns an OK status; otherwise, returns a non-OK status.
### Space Registration
For the RDMA transfer process, the source pointer `TransferRequest::source` must be registered in advance as an RDMA readable/writable Memory Region space, that is, included as part of the RAM Segment of the current process. Therefore, the following functions are needed:
#### TransferEngine::registerLocalMemory
```cpp
int registerLocalMemory(void *addr,
size_t length,
const std::string& location = kWildcardLocation,
bool remote_accessible = true,
bool update_metadata = true);
```
Registers a space starting at address `addr` with a length of `length` on the local DRAM/VRAM.
- `addr`: The starting address of the registration space;
- `length`: The length of the registration space;
- `location`: The `device` corresponding to this memory segment, such as `cuda:0` indicating the GPU device, `cpu:0` indicating the CPU socket, by matching with the network card priority order table (see `installTransport`), the preferred network card is identified. You can also use `*`, Transfer Engine will try to automatically recognize the `device` corresponding to `addr`, if it fails to recognize the device, it will print a `WARNING` level log and use all network cards, no preferred network cards.
- `remote_accessible`: Indicates whether this memory can be accessed by remote nodes.
- `update_metadata`: Whether to publish the registration to the metadata service.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::unregisterLocalMemory
```cpp
int unregisterLocalMemory(void *addr, bool update_metadata = true);
```
Unregisters the region.
- `addr`: The starting address of the registration space;
- `update_metadata`: Whether to publish the unregistration to the metadata service.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::registerLocalMemoryBatch
```cpp
int registerLocalMemoryBatch(const std::vector<BufferEntry>& buffer_list,
const std::string& location);
```
Registers multiple buffers in one call to reduce registration overhead.
- `buffer_list`: A list of `{addr, length}` entries.
- `location`: The `device` corresponding to these buffers.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::unregisterLocalMemoryBatch
```cpp
int unregisterLocalMemoryBatch(const std::vector<void*>& addr_list);
```
Unregisters multiple buffers in one call.
- `addr_list`: A list of buffer start addresses.
- Return value: If successful, returns 0; otherwise, returns a negative value.
### Segment Management and Metadata Format
TransferEngine provides the `openSegment` function, which obtains a `SegmentHandle` for subsequent `Transport` transfers.
```cpp
SegmentHandle openSegment(const std::string& segment_name);
```
- `segment_name`: The unique identifier of the segment. For RAM Segment, this needs to be consistent with the `server_name` filled in by the peer process when initializing the TransferEngine object.
- Return value: If successful, returns the corresponding `SegmentHandle`; otherwise, returns an invalid handle.
```cpp
int closeSegment(SegmentHandle segment_id);
```
- `segment_id`: The unique identifier of the segment.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::removeLocalSegment
```cpp
int removeLocalSegment(const std::string& segment_name);
```
Removes local segment metadata entries.
- `segment_name`: The local segment name to remove.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::CheckSegmentStatus
```cpp
Status CheckSegmentStatus(SegmentID sid);
```
Checks whether a segment is reachable and valid.
- `sid`: The segment identifier.
- Return value: If successful, returns an OK status; otherwise, returns a non-OK status.
<details>
<summary><strong>Metadata Format</strong></summary>
```
// Used to find the communicable address and exposed rpc port based on server_name.
// Created: when calling TransferEngine::init().
// Deleted: when TransferEngine is destructed.
Key = mooncake/rpc_meta/[server_name]
Value = {
'ip_or_host_name': 'node01'
'rpc_port': 12345
}
// For segments, the key naming method of mooncake/[proto]/[segment_name] is used, and the segment name can use the Server Name.
// A segment corresponds to a machine, and a buffer corresponds to different segments of memory or different files or different disks on the machine. Different buffers of the same segment are in the same fault domain.
// RAM Segment, used by RDMA Transport to obtain transfer information.
// Created: command line tool register.py, at this time buffers are empty, only fill in the information that can be known in advance.
// Modified: TransferEngine at runtime through register / unregister to add or delete Buffer.
Key = mooncake/ram/[segment_name]
Value = {
'server_name': server_name,
'protocol': rdma,
'devices': [
{ 'name': 'mlx5_2', 'lid': 17, 'gid': 'fe:00:...' },
{ 'name': 'mlx5_3', 'lid': 22, 'gid': 'fe:00:...' }
],
'priority_matrix': {
"cpu:0": [["mlx5_2"], ["mlx5_3"]],
"cpu:1": [["mlx5_3"], ["mlx5_2"]],
"cuda:0": [["mlx5_2"], ["mlx5_3"]],
},
'buffers': [
{
'name': 'cpu:0',
'addr': 0x7fa16bdf5000,
'length': 1073741824,
'rkey': [1fe000, 1fdf00, ...], // The length is the same as the number of elements in the 'devices' field
},
],
}
// Created: command line tool register.py, determine the file path that can be mounted.
// Modified: command line tool mount.py, add a mapping of the machine mounting the file to the file path on the mounting machine to the buffers.local_path_map.
Key = mooncake/nvmeof/[segment_name]
Value = {
'server_name': server_name,
'protocol': nvmeof,
'buffers':[{
'length': 1073741824,
'file_path': "/mnt/nvme0" // The file path on this machine
'local_path_map': {
"node01": "/mnt/transfer_engine/node01/nvme0", // The machine mounting the file -> The file path on the mounting machine
...
},
},
{
'length': 1073741824,
'file_path': "/mnt/nvme1",
'local_path_map': {
"node02": "/mnt/transfer_engine/node02/nvme1",
...
},
}
]
}
```
</details>
### HTTP Metadata Server
The HTTP server should implement three following RESTful APIs, while the metadata server configured to `http://host:port/metadata` as an example:
1. `GET /metadata?key=$KEY`: Get the metadata corresponding to `$KEY`.
2. `PUT /metadata?key=$KEY`: Update the metadata corresponding to `$KEY` to the value of the request body.
3. `DELETE /metadata?key=$KEY`: Delete the metadata corresponding to `$KEY`.
For specific implementation, refer to the demo service implemented in Golang at [mooncake-transfer-engine/example/http-metadata-server](../../../mooncake-transfer-engine/example/http-metadata-server).
### Initialization
TransferEngine needs to be initialized by calling the `init` method before further actions:
```cpp
TransferEngine();
int init(const std::string &metadata_conn_string,
const std::string &local_server_name);
```
There is also an extended form to override RPC binding:
```cpp
int init(const std::string &metadata_conn_string,
const std::string &local_server_name,
const std::string &ip_or_host_name,
uint64_t rpc_port);
```
- `metadata_conn_string`: Connecting string of metadata storage servers, i.e., the IP address/hostname of `etcd`/`redis` or the URI of the http service.
The general form is `[proto]://[hostname:port]`. For example, the following metadata server addresses are legal:
- Using `etcd` as a metadata storage service: `"10.0.0.1:2379"` or `"etcd://10.0.0.1:2379"`.
- Using `redis` as a metadata storage service: `"redis://10.0.0.1:6379"`
- Using `http` as a metadata storage service: `"http://10.0.0.1:8080/metadata"`
- `local_server_name`: The local server name, ensuring uniqueness within the cluster. It also serves as the name of the RAM Segment that other nodes refer to the current instance (i.e., Segment Name).
- `ip_or_host_name`: Optional explicit bind address or hostname for the RPC service.
- `rpc_port`: Optional explicit RPC port.
```cpp
~TransferEngine();
```
Reclaims all allocated resources and also deletes the global metadata server information.
#### TransferEngine::freeEngine
```cpp
int freeEngine();
```
Releases resources early without waiting for destruction.
## Advanced APIs
These APIs are optional; use them when you need manual transport control, coordination notifications, metadata/cache refresh, topology discovery, or debugging. They are not required for the basic data path.
### Multi-Transport Management
The `TransferEngine` class internally manages multiple backend `Transport` classes.
And it will discover the topology between CPU/CUDA and RDMA devices automatically
(more device types are working in progress, feedbacks are welcome when the automatic discovery mechanism is not accurate),
and it will install `Transport` automatically based on the topology.
#### TransferEngine::installTransport
```cpp
Transport* installTransport(const std::string& proto, void** args);
```
Installs a transport backend explicitly.
- `proto`: Transport protocol name, such as `rdma`, `tcp`, or `nvmeof`.
- `args`: Transport-specific arguments.
> Note: In TENT, `installTransport` is not exposed (removed from the public API, including compatibility surfaces). Transport selection is internal to TENT.
#### TransferEngine::uninstallTransport
```cpp
int uninstallTransport(const std::string& proto);
```
Uninstalls a transport backend.
- `proto`: Transport protocol name.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::getTransport
```cpp
Transport* getTransport(const std::string& proto);
```
Returns a transport instance by protocol name, mainly for advanced inspection or debugging.
### Notifications
TransferEngine can send and receive lightweight notifications across segments to coordinate data movement.
#### TransferEngine::submitTransferWithNotify
```cpp
Status submitTransferWithNotify(BatchID batch_id,
const std::vector<TransferRequest>& entries,
TransferMetadata::NotifyDesc notify_msg);
```
Submits a batch transfer and delivers a notification upon completion.
- `notify_msg`: A `{name, msg}` payload delivered to the receiver.
- Typical use: signal that a transferred buffer or KV-cache slice is ready to consume on the receiver side.
#### TransferEngine::getNotifies
```cpp
int getNotifies(std::vector<TransferMetadata::NotifyDesc>& notifies);
```
Gets pending notifications from peers.
- Return value: If successful, returns 0; otherwise, returns a negative value.
- Typical use: receiver-side polling loop to trigger follow-up actions (e.g., attaching the transferred buffer to a scheduler or cache).
#### TransferEngine::sendNotifyByID
```cpp
int sendNotifyByID(SegmentID target_id, TransferMetadata::NotifyDesc notify_msg);
```
Sends a notification to a specific segment by ID.
- Typical use: control-plane message such as "ready", "invalidate", or "retry" tied to a known segment handle.
#### TransferEngine::sendNotifyByName
```cpp
int sendNotifyByName(std::string remote_agent, TransferMetadata::NotifyDesc notify_msg);
```
Sends a notification to a remote agent by name.
- Typical use: best-effort coordination when you only know the peer's name (segment name), not the handle.
### Segment Cache and Metadata Access
#### TransferEngine::syncSegmentCache
```cpp
int syncSegmentCache(const std::string& segment_name = "");
```
Synchronizes local segment cache from the metadata service.
- `segment_name`: If empty, refreshes all segments; otherwise, refreshes the specified segment.
- Typical use: when peers dynamically register/unregister buffers and you need to refresh before opening or submitting transfers.
#### TransferEngine::getMetadata
```cpp
std::shared_ptr<TransferMetadata> getMetadata();
```
Returns the metadata subsystem instance for advanced workflows.
- Typical use: advanced integration or debugging of metadata content beyond the standard APIs.
### Topology and Discovery
#### TransferEngine::setAutoDiscover
```cpp
void setAutoDiscover(bool auto_discover);
```
Enables or disables topology discovery.
- Typical use: controlled environments or debugging where auto discovery is not desired.
#### TransferEngine::setWhitelistFilters
```cpp
void setWhitelistFilters(std::vector<std::string>&& filters);
```
Sets the device whitelist used during topology discovery.
- Typical use: restrict transfers to a subset of NICs or GPUs for performance isolation or testing.
#### TransferEngine::numContexts
```cpp
int numContexts() const;
```
Returns the number of active transport contexts.
- Typical use: introspection and resource monitoring.
#### TransferEngine::getLocalTopology
```cpp
std::shared_ptr<Topology> getLocalTopology();
```
Returns the local topology model used for path selection.
- Typical use: diagnose path selection or export topology to a scheduler.
### Introspection and Safety
#### TransferEngine::getLocalIpAndPort
```cpp
std::string getLocalIpAndPort();
```
Returns the resolved local RPC address.
- Typical use: publish the resolved address to external components or logs.
#### TransferEngine::getRpcPort
```cpp
int getRpcPort();
```
Returns the active RPC port.
- Typical use: verify port binding when dynamic ports are used.
#### TransferEngine::checkOverlap
```cpp
bool checkOverlap(void* addr, uint64_t length);
```
Checks whether a given address range overlaps with existing registered buffers.
- Typical use: validate registration plans before calling `registerLocalMemory` in complex buffer managers.

View File

@ -157,94 +157,10 @@ The following video shows a normal run as described above, with the Target on th
## Transfer Engine C/C++ API
Transfer Engine provides interfaces through the `TransferEngine` class (located in `mooncake-transfer-engine/include/transfer_engine.h`), where the specific data transfer functions for different backends are implemented by the `Transport` class, currently supporting `TcpTransport`, `RdmaTransport`, `NVMeoFTransport`, `NvlinkTransport` (for NVIDIA GPUs), `IntraNodeNvlinkTransport` (for NVIDIA GPUs), and `HipTransport` (for AMD GPUs).
For a complete C++ API reference, see [Transfer Engine C++ API Reference](cpp-api.md).
### Data Transfer
#### TransferEngine::TransferRequest
The core API provided by Mooncake Transfer Engine is submitting a group of asynchronous `TransferRequest` tasks through the `submitTransfer` interface, and querying their status through the `getTransferStatus` interface. Each `TransferRequest` specifies reading or writing a continuous data space of `length` starting from the local starting address `source`, to the position starting at `target_offset` in the segment corresponding to `target_id`.
The `TransferRequest` structure is defined as follows:
```cpp
using SegmentID = int32_t;
struct TransferRequest
{
enum OpCode { READ, WRITE };
OpCode opcode;
void *source;
SegmentID target_id; // The ID of the target segment, which may correspond to local or remote DRAM/VRAM/NVMeof, with the specific routing logic hidden
size_t target_offset;
size_t length;
};
```
- `opcode` takes the values `READ` or `WRITE`. `READ` indicates that data is copied from the target address indicated by `<target_id, target_offset>` to the local starting address `source`; `WRITE` indicates that data is copied from `source` to the address indicated by `<target_id, target_offset>`.
- `source` represents the DRAM/VRAM buffer managed by the current `TransferEngine`, which must have been registered in advance by the `registerLocalMemory` interface.
- `target_id` represents the segment ID of the transfer target. The segment ID is obtained using the `openSegment` interface. Segments are divided into the following types:
- RAM space type, covering DRAM/VRAM. As mentioned earlier, there is only one segment under the same process (or `TransferEngine` instance), which contains various types of Buffers (DRAM/VRAM). In this case, the segment name passed to the `openSegment` interface is equivalent to the server hostname. `target_offset` is the virtual address of the target server.
- NVMeOF space type, where each file corresponds to a segment. In this case, the segment name passed to the `openSegment` interface is equivalent to the unique identifier of the file. `target_offset` is the offset of the target file.
- `length` represents the amount of data transferred. TransferEngine may further split this into multiple read/write requests internally.
#### TransferEngine::allocateBatchID
```cpp
BatchID allocateBatchID(size_t batch_size);
```
Allocates a `BatchID`. A maximum of `batch_size` `TransferRequest`s can be submitted under the same `BatchID`.
- `batch_size`: The maximum number of `TransferRequest`s that can be submitted under the same `BatchID`;
- Return value: If successful, returns `BatchID` (non-negative); otherwise, returns a negative value.
#### TransferEngine::submitTransfer
```cpp
int submitTransfer(BatchID batch_id, const std::vector<TransferRequest> &entries);
```
Submits new `TransferRequest` tasks to `batch_id`. The task is asynchronously submitted to the background thread pool. The total number of `entries` accumulated under the same `batch_id` should not exceed the `batch_size` defined at creation.
- `batch_id`: The `BatchID` it belongs to;
- `entries`: Array of `TransferRequest`;
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::getTransferStatus
```cpp
enum TaskStatus
{
WAITING, // In the transfer phase
PENDING, // Not supported
INVALID, // Ilvalid parameters
CANCELED, // Not supported
COMPLETED, // Transfer completed
TIMEOUT, // Not supported
FAILED // Transfer failed even after retries
};
struct TransferStatus {
TaskStatus s;
size_t transferred; // How much data has been successfully transferred (not necessarily an accurate value, but it is a lower bound)
};
int getTransferStatus(BatchID batch_id, size_t task_id, TransferStatus &status)
```
Obtains the running status of the `TransferRequest` with `task_id` in `batch_id`.
- `batch_id`: The `BatchID` it belongs to;
- `task_id`: The sequence number of the `TransferRequest` to query;
- `status`: Output Transfer status;
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::freeBatchID
```cpp
int freeBatchID(BatchID batch_id);
```
Recycles `BatchID`, and subsequent operations on `submitTransfer` and `getTransferStatus` are undefined. If there are still `TransferRequest`s pending completion in the `BatchID`, the operation is refused.
- `batch_id`: The `BatchID` it belongs to;
- Return value: If successful, returns 0; otherwise, returns a negative value.
Transfer Engine provides batch-based read/write transfers between segments (DRAM/VRAM/NVMeof). A typical flow is: register local memory, open a target segment, submit a batch, and poll status. Detailed function signatures and usage are documented in the C++ API reference.
### Multi-Transport Management
@ -253,51 +169,8 @@ And it will discover the toplogy between CPU/CUDA and RDMA devices automatically
(more device types are working in progress, feedbacks are welcome when the automatic discovery mechanism is not accurate),
and it will install `Transport` automatically based on the topology.
### Space Registration
For the RDMA transfer process, the source pointer `TransferRequest::source` must be registered in advance as an RDMA readable/writable Memory Region space, that is, included as part of the RAM Segment of the current process. Therefore, the following functions are needed:
#### TransferEngine::registerLocalMemory
```cpp
int registerLocalMemory(void *addr, size_t size, string location, bool remote_accessible);
```
Registers a space starting at address `addr` with a length of `size` on the local DRAM/VRAM.
- `addr`: The starting address of the registration space;
- `size`: The length of the registration space;
- `location`: The `device` corresponding to this memory segment, such as `cuda:0` indicating the GPU device, `cpu:0` indicating the CPU socket, by matching with the network card priority order table (see `installTransport`), the preferred network card is identified. You can also use `*`, Transfer Engine will try to automatically recognize the `device` corresponding to `addr`, if it fails to recognize the device, it will print a `WARNING` level log and use all network cards, no preferred network cards.
- `remote_accessible`: Indicates whether this memory can be accessed by remote nodes.
- Return value: If successful, returns 0; otherwise, returns a negative value.
#### TransferEngine::unregisterLocalMemory
```cpp
int unregisterLocalMemory(void *addr);
```
Unregisters the region.
- `addr`: The starting address of the registration space;
- Return value: If successful, returns 0; otherwise, returns a negative value.
### Segment Management and Metadata Format
TransferEngine provides the `openSegment` function, which obtains a `SegmentHandle` for subsequent `Transport` transfers.
```cpp
SegmentHandle openSegment(const std::string& segment_name);
```
- `segment_name`: The unique identifier of the segment. For RAM Segment, this needs to be consistent with the `server_name` filled in by the peer process when initializing the TransferEngine object.
- Return value: If successful, returns the corresponding `SegmentHandle`; otherwise, returns a negative value.
```cpp
int closeSegment(SegmentHandle segment_id);
```
- `segment_id`: The unique identifier of the segment.
- Return value: If successful, returns 0; otherwise, returns a negative value.
Segment metadata is stored in the metadata service. The following format is provided for reference.
<details>
<summary><strong>Metadata Format</strong></summary>
@ -379,29 +252,6 @@ The HTTP server should implement three following RESTful APIs, while the metadat
For specific implementation, refer to the demo service implemented in Golang at [mooncake-transfer-engine/example/http-metadata-server](../../../mooncake-transfer-engine/example/http-metadata-server).
### Initialization
TransferEngine needs to initializing by calling the `init` method before further actions:
```cpp
TransferEngine();
int init(const std::string &metadata_conn_string,
const std::string &local_server_name);
```
- `metadata_conn_string`: Connecting string of metadata storage servers, i.e., the IP address/hostname of `etcd`/`redis` or the URI of the http service.
The general form is `[proto]://[hostname:port]`. For example, the following metadata server addresses are legal:
- Using `etcd` as a metadata storage service: `“10.0.0.1:2379”` or `“etcd://10.0.0.1:2379”`.
- Using `redis` as a metadata storage service: `“redis://10.0.0.1:6379”`
- Using `http` as a metadata storage service: `“http://10.0.0.1:8080/metadata”`
- `local_server_name`: The local server name, ensuring uniqueness within the cluster. It also serves as the name of the RAM Segment that other nodes refer to the current instance (i.e., Segment Name).
```cpp
~TransferEngine();
```
Reclaims all allocated resources and also deletes the global meta data server information.
## Using Transfer Engine to Your Projects
### Using C/C++ Interface
@ -453,6 +303,14 @@ For advanced users, TransferEngine provides the following advanced runtime optio
- `MC_PATH_ROUNDROBIN` Use round-robin mode in the RDMA path selection. This may be beneficial for transferring large bulks.
- `MC_ENDPOINT_STORE_TYPE` Choose FIFO Endpoint Store (`FIFO`) or Sieve Endpoint Store (`SIEVE`), default is `SIEVE`.
## C++ API Reference
::::{toctree}
:maxdepth: 1
cpp-api
::::
## Ascend Transport Component
:::{toctree}