
待废弃 ADXL 数据结构完全解析MemDesc / TransferOpDesc / MemHandle 等核心类型实战指南【免费下载链接】hixlHIXLHuawei Xfer Library是一个灵活、高效的昇腾单边通信库面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixl本文是 CANN hixl 开源仓库中「待废弃 ADXL」接口族的数据结构参考手册。ADXL基于 HIXL 底层引擎的上层单边通信库的对外 APIAdxlEngine::Initialize、RegisterMem、TransferSync、TransferAsync、SendNotify、GetCapability等全部以这些枚举与结构体为参数载体。读完本文你将掌握每个类型的内存布局、语义边界、源码级校验逻辑以及它们在“注册内存 → 建链 → 点对点传输 → 能力探测”完整调用链中的实际作用可直接对照 接口说明 编写可运行代码。一、数据结构在 ADXL 架构中的定位待废弃 ADXL 的数据结构全部定义在头文件 include/adxl/adxl_types.h 中统一位于adxl命名空间。从源码结构看ADXL 并非独立实现而是通过 src/llm_datadist/api/adxl_engine_impl.cc 中的适配层将这些 ADXL 数据结构逐字段转换为 HIXL 底层类型对应定义见 include/hixl/hixl_types.h再交给 src/llm_datadist/adxl/adxl_inner_engine.cc 执行。例如AdxlEngineImpl::TransferSync中会先对op_descs做地址非空校验再通过ToHixlTransferOp/ToHixlTransferOpDescs完成转换后调用底层引擎// src/llm_datadist/api/adxl_engine_impl.cc Status AdxlEngine::AdxlEngineImpl::TransferSync(...) { ADXL_CHK_BOOL_RET_STATUS(engine_ ! nullptr engine_-IsInitialized(), FAILED, AdxlEngine is not initialized); ADXL_CHK_STATUS_RET(CheckTransferOpDescs(op_descs), Failed to check transfer op descs); ADXL_CHK_STATUS_RET(engine_-TransferSync(remote_engine, ToHixlTransferOp(operation), ToHixlTransferOpDescs(op_descs), timeout_in_millis), ...); return SUCCESS; }因此理解这些数据结构是理解整个 ADXL乃至 HIXL传输语义的入口。下表梳理了本仓库中这些类型的双层对应关系| ADXL 类型include/adxl/adxl_types.h | 对应的 HIXL 类型include/hixl/hixl_types.h | 用途 | | -- | -- | -- | |MemDesc|hixl::MemDesc| 描述待注册内存的地址与长度 | |TransferOpDesc|hixl::TransferOpDesc| 描述一次传输的本地/远端地址对 | |TransferOpREAD/WRITE |hixl::TransferOp| 传输方向 | |MemTypeMEM_DEVICE/MEM_HOST |hixl::MemType| 内存归属 | |TransferStatus|hixl::TransferStatus| 异步传输状态 | |TransferArgs|hixl::TransferArgs| 异步传输可选参数 | |NotifyDesc|hixl::NotifyDesc| 进程间 Notify 消息内容 | |ShareableHandle|aclrtMemFabricHandle| Fabric 跨进程共享句柄 |说明deprecated_ADXL-data-structure.md为 ADXL 接口族的数据结构参考文档建议与 deprecated_ADXL-interface.md接口语义、参数约束配合阅读。二、枚举类型MemType 与 TransferOp原文档定义的这两个枚举在adxl命名空间中属于非强类型枚举unscoped enum与 HIXL 侧hixl::MemType、hixl::TransferOp保持同构可直接通过static_cast转换见 src/llm_datadist/api/adxl_engine_impl.cc 中的ToHixlTransferOp。1. MemType内存归属类型内存的类型。enum MemType { MEM_DEVICE, MEM_HOST };MEM_DEVICEDevice 侧内存通常通过aclrtMalloc申请。MEM_HOSTHost 侧内存注册 Host 内存需使用aclrtMallocHost申请该接口申请的内存地址自动对齐满足 RDMA/HCCS 对地址对齐的要求。源码级影响MemType是判断传输方向的关键输入。在 adxl_inner_engine.cc 的GetTransferType中系统会将op_desc的本地/远端地址区间与已注册内存的 Segment 表比对未命中时默认按MEM_HOST处理// src/llm_datadist/adxl/adxl_inner_engine.cc MemType local_mem_type local_segment ! nullptr ? local_segment-GetMemType() : MemType::MEM_HOST; MemType remote_mem_type remote_segment ! nullptr ? remote_segment-GetMemType() : MemType::MEM_HOST;随后DetermineTransferType结合TransferOp与两端MemType组合出 8 种具体传输类型TransferType DetermineTransferType(TransferOp operation, MemType local_mem_type, MemType remote_mem_type) { if (operation TransferOp::READ) { if (local_mem_type MemType::MEM_HOST remote_mem_type MemType::MEM_HOST) return TransferType::kReadRH2H; if (local_mem_type MemType::MEM_HOST remote_mem_type MemType::MEM_DEVICE) return TransferType::kReadRD2H; if (local_mem_type MemType::MEM_DEVICE remote_mem_type MemType::MEM_HOST) return TransferType::kReadRH2D; return TransferType::kReadRD2D; } // WRITE 分支同理得到 kWriteH2RH / kWriteH2RD / kWriteD2RH / kWriteD2RD }这正是接口文档中「TransferSync 默认开启中转内存池op_descs 中本地与远端内存如有一个未注册即判定需要走中转传输且未注册内存按 Host 内存处理」约束的底层来源。2. TransferOp传输操作类型传输操作的类型。enum TransferOp { READ, WRITE };READ将远端内存读到本地Pull。WRITE将本地内存写到远端Push。TransferSync/TransferAsync均通过该枚举决定数据搬移方向在 adxl_inner_engine.cc 的TransferSync中还会据此选择 profiling 类型hixl::HixlProfType type (operation READ ? hixl::HixlProfType::HixlOpBatchRead : hixl::HixlProfType::HixlOpBatchWrite);三、核心结构体MemDesc、TransferOpDesc 与传输相关结构1. MemDesc内存的描述信息struct MemDesc { uintptr_t addr; size_t len; uint8_t reserved[128] {}; };| 字段 | 类型 | 说明 | | -- | -- | -- | |addr|uintptr_t| 内存起始地址整型保存指针便于跨模块传递与区间运算 | |len|size_t| 内存长度字节 | |reserved|uint8_t[128]| 预留字段默认清零用于后续扩展当前置0即可 |使用场景AdxlEngine::RegisterMem(const MemDesc mem, MemType type, MemHandle mem_handle)的参数之一。注册成功后该地址区间会被记录进SegmentTable见 src/llm_datadist/adxl/segment_table.h供后续GetTransferType做「地址是否已注册」的区间查找FindSegment(channel_id, start, end)。也就是说MemDesc中给出的区间是判断走“直传”还是“中转传输”的依据。接口层会先校验addr非空见 adxl_engine_impl.cc 中AdxlEngine::AdxlEngineImpl::RegisterMemADXL_CHK_BOOL_RET_STATUS(reinterpret_castvoid *(mem.addr) ! nullptr, PARAM_INVALID, mem.addr can not be null);约束提示来自接口文档建链前需完成所有本地与远端内存注册建链后再注册不支持远端访问。建议单实例注册内存不超过 4K 个注册数量过多存在 Device OOM 与建链超时风险。最大注册量Device 内存 50GB、Host 内存 20GB注册量越大占用的 OS 内存越多。若通过 HCCS 传输Device 内存需按ACL_MEM_MALLOC_HUGE_ONLY规则分配。2. TransferOpDesc传输操作的描述信息struct TransferOpDesc { uintptr_t local_addr; uintptr_t remote_addr; size_t len; };| 字段 | 类型 | 说明 | | -- | -- | -- | |local_addr|uintptr_t| 本地内存地址发起端视角 | |remote_addr|uintptr_t| 远端内存地址 | |len|size_t| 本次传输的字节数 |使用场景TransferSync/TransferAsync的op_descs为std::vectorTransferOpDesc即一次调用可批量下发多段传输。语义上local_addr必须为本地注册内存的子集地址remote_addr必须为远端注册内存的子集地址。接口层对每个描述符做非空校验adxl_engine_impl.ccStatus CheckTransferOpDescs(const std::vectorTransferOpDesc op_descs) { for (const auto desc : op_descs) { auto local_addr reinterpret_castvoid *(desc.local_addr); auto remote_addr reinterpret_castvoid *(desc.remote_addr); ADXL_CHK_BOOL_RET_STATUS(local_addr ! nullptr, PARAM_INVALID, local addr of desc can not be null.); ADXL_CHK_BOOL_RET_STATUS(remote_addr ! nullptr, PARAM_INVALID, remote addr of desc can not be null.); } return SUCCESS; }中转传输模式下的额外约束来自接口文档默认开启中转内存池若op_descs中存在 256K的数据块默认走中转传输以提升性能否则根据是否有未注册内存决定走中转还是直传。中转模式下所有op_descs的传输类型必须相同例如全部是「本地 Host 写远端 Host」否则返回PARAM_INVALID。该检查在 adxl_inner_engine.cc 的GetTransferType中通过以下逻辑落实if (i 0) { ADXL_CHK_BOOL_RET_STATUS(!need_buffer || (need_buffer cur_type type), PARAM_INVALID, All transfer type need be same in buffer transfer mode.); }3. TransferStatus异步传输状态关联扩展类型原文档数据结构章节虽未列出但异步接口GetTransferStatus的输出参数使用该枚举且它同样定义于 include/adxl/adxl_types.henum class TransferStatus { WAITING, COMPLETED, TIMEOUT, FAILED };| 枚举值 | 含义 | | -- | -- | |WAITING| 传输进行中需继续轮询 | |COMPLETED| 传输完成查询到该状态后相关资源被释放不支持再次查询 | |TIMEOUT| 暂不支持当前接口不返回该值 | |FAILED| 传输失败查询状态与接口返回状态均为FAILED|从 adxl_inner_engine.cc 的GetTransferStatus实现看TransferReq实际是一个自增整数 ID 的封装req reinterpret_castvoid *(static_castuintptr_t(id))引擎通过req_map_反查链路与传输信息当状态不再是WAITING时会清理对应的req_map_条目并上报 profiling 耗时。4. TransferArgs异步传输可选参数预留struct TransferArgs { uint8_t reserved[128] {}; };异步接口TransferAsync的optional_args参数当前为预留结构全零填充。适配层通过memcpy_s将其原样拷贝为hixl::TransferArgs注意 HIXL 侧该结构内含user_data指针见 include/hixl/hixl_types.hStatus ToHixlTransferArgs(const TransferArgs optional_args, hixl::TransferArgs hixl_args) { auto ret memcpy_s(hixl_args, sizeof(hixl_args), optional_args, sizeof(optional_args)); ADXL_CHK_BOOL_RET_STATUS(ret EOK, FAILED, Failed to copy TransferArgs, memcpy_s returned:%d, ret); return SUCCESS; }5. NotifyDescNotify 的描述信息struct NotifyDesc { AscendString name; AscendString notify_msg; };| 字段 | 类型 | 说明 | | -- | -- | -- | |name|AscendString| Notify 名称长度上限 1024 字符 | |notify_msg|AscendString| Notify 消息内容长度上限 1024 字符 |使用场景Client 通过SendNotify(remote_engine, notify, timeout_in_millis)向 Server 发送通知Server 通过GetNotifies(notifies)批量取回并清空已收到的 Notify。发送侧在接口层即校验长度adxl_engine_impl.ccconstexpr uint32_t kMaxNotifyLength 1024U; ADXL_CHK_BOOL_RET_STATUS(notify.name.GetLength() kMaxNotifyLength, PARAM_INVALID, ...); ADXL_CHK_BOOL_RET_STATUS(notify.notify_msg.GetLength() kMaxNotifyLength, PARAM_INVALID, ...);在 adxl_inner_engine.cc 的SendNotify中NotifyDesc会被转换为NotifyMsg并通过控制消息通道下发同时通过notify_cv_等待对端 ACK超时则返回TIMEOUTNotifyMsg notify_msg; notify_msg.req_id next_notify_id_; notify_msg.name notify.name.GetString(); notify_msg.notify_msg notify.notify_msg.GetString();约束提示每条链路最多存在 4096 条 Notify需保证远端及时调用GetNotifies消费防止触发上限导致发送失败。四、句柄与基础类型别名MemHandle / ShareableHandle / TransferReq / Status / AscendString原文档数据结构章节中的其余条目本质上是adxl命名空间下的基础类型别名完整定义见 include/adxl/adxl_types.h 头部namespace adxl { using Status uint32_t; using AscendString ge::AscendString; using TransferReq void *;1. MemHandle注册内存的 Handleusing MemHandle void *;RegisterMem成功时输出DeregisterMem(mem_handle)解注册时作为输入。接口层要求其非空ADXL_CHK_BOOL_RET_STATUS(mem_handle ! nullptr, PARAM_INVALID, ...)。注意解注册前必须先Disconnect断链确保内存不再被使用。2. ShareableHandleFabric 共享句柄using ShareableHandle aclrtMemFabricHandle;用于跨进程共享同一份物理内存。配合MallocMem/ExportToShareableHandle/FreeMem这组静态接口使用MallocMem(MemType type, size_t size, void **ptr)当前只支持申请 Host 内存走 ACL VMM 机制从源码注释看通过hixl::FabricMemTransferService::MallocMem实现见 adxl_engine_impl.cc。ExportToShareableHandle(void *addr, ShareableHandle handle)将MallocMem申请的内存导出为 Fabric 共享句柄同一块内存首次调用时执行导出并缓存后续调用返回已缓存的句柄。要求传入MallocMem返回的起始地址不支持子地址且须在FreeMem之前调用。FreeMem(void *ptr)释放内存。该能力在仓库中与 docs/zh/design/FabricMem.md 描述的 Fabric 内存机制及 src/hixl/fabric_mem 模块直接相关。3. 状态码常量关联扩展Status类型为uint32_t常用取值定义于 include/adxl/adxl_types.hconstexpr Status SUCCESS 0U; constexpr Status PARAM_INVALID 103900U; constexpr Status TIMEOUT 103901U; constexpr Status NOT_CONNECTED 103902U; constexpr Status ALREADY_CONNECTED 103903U; constexpr Status NOTIFY_FAILED 103904U; constexpr Status UNSUPPORTED 103905U; constexpr Status FAILED 503900U; constexpr Status RESOURCE_EXHAUSTED 203900U;各接口的返回值语义SUCCESS / PARAM_INVALID / TIMEOUT / NOT_CONNECTED / ALREADY_CONNECTED / RESOURCE_EXHAUSTED / FAILED 等详见 deprecated_ADXL-interface.md。完整错误码说明可参考 LLM-DataDist-error-code.md。五、能力探测相关FeatureType 与 FEATURE_SUPPORTED / FEATURE_NOT_SUPPORTED1. FeatureType库能力特性类型库能力特性类型用于GetCapability接口查询。枚举值必须显式赋值新增能力仅允许在末尾扩展保持 ABI 稳定enum FeatureType : int32_t { AUTO_CONNECT 0, CLIENT_SERVER_COMM 1, };| 枚举值 | 描述 | | -- | -- | | AUTO_CONNECT | Auto Connect 模式对应 Initialize 时 OPTION_AUTO_CONNECT 选项 | | CLIENT_SERVER_COMM | Client/Server 通信模式即 Server 端监听端口、Client 端发起建链的能力 |GetCapability(FeatureType feature_type, int32_t value)为静态方法无需创建实例、无需 Initialize 即可调用可在初始化前探测当前库是否支持特定能力如 Auto Connect、Client/Server 通信避免硬编码默认值或与旧版.so不兼容函数原型见 include/adxl/adxl_engine.h。底层实现转发至hixl::Hixl::GetCapability见 adxl_engine_impl.cc。返回值约定feature_type为负数时返回PARAM_INVALID未知或不支持的特性类型返回SUCCESS且value为FEATURE_NOT_SUPPORTED。2. FEATURE_SUPPORTED / FEATURE_NOT_SUPPORTEDGetCapability接口输出参数value的取值常量constexpr int32_t FEATURE_SUPPORTED 1; constexpr int32_t FEATURE_NOT_SUPPORTED 0;典型用法int32_t value FEATURE_NOT_SUPPORTED; auto ret adxl::AdxlEngine::GetCapability(adxl::FeatureType::AUTO_CONNECT, value); if (ret adxl::SUCCESS value adxl::FEATURE_SUPPORTED) { // 当前库支持 Auto Connect可开启 OPTION_AUTO_CONNECT }六、与 OPTION 常量及周边类型的边界说明需要说明的是include/adxl/adxl_types.h 中还集中定义了初始化选项字符串常量OPTION_RDMA_TRAFFIC_CLASS adxl.RdmaTrafficClass、OPTION_RDMA_SERVICE_LEVEL adxl.RdmaServiceLevel、OPTION_BUFFER_POOL adxl.BufferPool、OPTION_LOCAL_COMM_RES adxl.LocalCommRes、OPTION_AUTO_CONNECT AutoConnect以及 HIXL 侧的OPTION_GLOBAL_RESOURCE_CONFIG等见 src/llm_datadist/adxl/adxl_inner_engine.h 中LoadGlobalResourceConfig/ParseChannelPoolConfig/ParseBufferPoolParams的解析逻辑。这些选项以std::mapAscendString, AscendString传入Initialize其参数取值表详见 deprecated_ADXL-interface.md 的「表 1 options」本文不再展开。从源码结构看MemDesc、TransferOpDesc、TransferArgs等在 ADXL 与 HIXL 两侧保持一致的「地址 长度 reserved 预留」布局其设计意图是在保持 ABI 兼容的同时为后续能力扩展预留空间reserved数组的存在即为此。这也与FeatureType「仅允许在末尾扩展」的约束相呼应。七、数据结构实战一条完整的 ADXL 传输调用链将上述类型串起来一个最小化的点对点 READ 传输流程伪代码示意具体接口语义见 deprecated_ADXL-interface.md为#include adxl/adxl_engine.h using namespace adxl; // 1. 构造并初始化先 aclrtSetDevice AdxlEngine engine; std::mapAscendString, AscendString options; // options[OPTION_BUFFER_POOL] 4:8; // 默认 4:8单位 MB engine.Initialize(192.168.1.10:18000, options); // host_ip:host_port 标识port0 时为 Server // 2. 注册内存MemDesc MemType - MemHandle void *buf nullptr; // Host 内存用 aclrtMallocHostDevice 内存用 aclrtMalloc MemDesc mem{reinterpret_castuintptr_t(buf), 4096}; MemHandle handle nullptr; engine.RegisterMem(mem, MEM_HOST, handle); // 3. 建链 engine.Connect(192.168.1.11:18000, 1000); // 4. 批量传输TransferOp std::vectorTransferOpDesc std::vectorTransferOpDesc op_descs{{/* local_addr */, /* remote_addr */, 4096}}; engine.TransferSync(remote_engine, READ, op_descs, 1000); // 5. 断链、解注册、清理 engine.Disconnect(remote_engine, 1000); engine.DeregisterMem(handle); engine.Finalize();从 adxl_inner_engine.cc 的TransferSync实现可以印证这一链路的内部走向先取/建 Channel → 尝试走TransferSyncViaBuffer中转内存池路径→ 未命中则走channel-TransferSync直传路径失败时若开启 Auto Connect 会自动断链清理。八、常用约束速查以下约束贯穿所有使用上述数据结构的接口编写代码前建议逐条核对完整约束见 deprecated_ADXL-interface.md初始化配对Initialize与Finalize必须配对初始化前需先aclrtSetDevice。线程上下文RegisterMem、DeregisterMem、Connect、Disconnect、TransferSync、TransferAsync、GetTransferStatus、SendNotify、GetNotifies均需与Initialize同线程跨线程调用需先aclrtGetCurrentContext获取、aclrtSetCurrentContext设置 context。注册先行建链前需完成本地与远端内存注册建链后注册的内存不支持远端访问。数量上限单实例注册内存建议不超过 4K 个最大通信数量为 512。超时建议建链/断链/传输超时默认 1000ms开启 TLS 时建链建议 ≥ 2000ms。异步查询一次TransferAsync后必须用GetTransferStatus查询至COMPLETED或FAILED查询终态后资源即释放不支持重复查询。中转一致性中转传输模式下所有op_descs的传输类型必须一致异步传输当前仅支持直传。Notify 消费每条链路最多 4096 条 Notify对端需及时GetNotifies消费。九、延伸阅读deprecated_ADXL-interface.md待废弃 ADXL 全部接口的函数原型、参数表与约束本文数据结构的直接使用方。deprecated_ADXL-error-code.mdADXL 错误码说明。HIXL-data-structure.mdHIXL 底层数据结构定义ADXL 类型转换的目标。HIXL-interface.mdHIXL 底层接口说明。include/adxl/adxl_types.h 与 include/hixl/hixl_types.h本篇文章所有类型的权威定义出处。src/llm_datadist/adxlADXL 内部引擎实现adxl_inner_engine.cc、segment_table.h、buffer_transfer_service.h等可深入研读数据结构在传输调度中的实际用法。【免费下载链接】hixlHIXLHuawei Xfer Library是一个灵活、高效的昇腾单边通信库面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考