Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef HCOMM_NIC_PLUGIN_MANAGER_H
12 : #define HCOMM_NIC_PLUGIN_MANAGER_H
13 :
14 : #include <stddef.h>
15 : #include <stdint.h>
16 :
17 : #include "hcomm_c_adpt.h"
18 : #include "hcomm_nic_plugin.h"
19 :
20 : namespace hcomm {
21 :
22 : struct NicPluginEntry {
23 : void* soHandle;
24 : const HcommNicPluginInfo* info;
25 : HcommNicPluginCreateEndpointFunc createEndpoint;
26 : HcommNicPluginCreateChannelFunc createChannel;
27 : };
28 :
29 : constexpr uintptr_t HCOMM_PLUGIN_HANDLE_FLAG = (static_cast<uintptr_t>(1) << 63);
30 : constexpr int32_t COMM_PROTOCOL_CUSTOM_BASE = 1000;
31 :
32 : #define IS_PLUGIN_HANDLE(h) ((((uintptr_t)(h)) & ::hcomm::HCOMM_PLUGIN_HANDLE_FLAG) != 0)
33 : #define MAKE_PLUGIN_CH_HANDLE(p) \
34 : (static_cast<ChannelHandle>((reinterpret_cast<uintptr_t>(p)) | ::hcomm::HCOMM_PLUGIN_HANDLE_FLAG))
35 : #define CHANNEL_FROM_HANDLE(h) \
36 : (reinterpret_cast<::hcomm::Channel*>( \
37 : (static_cast<uintptr_t>(h)) & ~static_cast<uintptr_t>(::hcomm::HCOMM_PLUGIN_HANDLE_FLAG)))
38 :
39 : void LoadAllNicPlugins();
40 : const NicPluginEntry* FindHostNicPlugin(CommProtocol protocol);
41 : bool ValidatePluginInfo(
42 : const char* soPath, const HcommNicPluginInfo* info, HcommNicPluginCreateEndpointFunc createEndpoint,
43 : HcommNicPluginCreateChannelFunc createChannel);
44 :
45 : HcommResult FillDefaultEndpointOps(const HcommNicEndpointOps* src, HcommNicEndpointOps** outOps);
46 :
47 : int32_t DefaultEndpointInit(void* ctx);
48 : int32_t DefaultEndpointRegisterMemory(void* ctx, const CommMem* mem, const char* tag, void** handle);
49 : int32_t DefaultEndpointUnregisterMemory(void* ctx, void* handle);
50 : int32_t DefaultEndpointMemoryExport(void* ctx, void* handle, void** desc, uint32_t* descLen);
51 : int32_t DefaultEndpointMemoryImport(void* ctx, const void* desc, uint32_t descLen, CommMem* outMem);
52 : int32_t DefaultEndpointMemoryUnimport(void* ctx, const void* desc, uint32_t descLen);
53 : int32_t DefaultEndpointGetListenPort(void* ctx, uint32_t* port);
54 :
55 : // HcommNicEndpointOps 新增成员时,在此追加一行 F(op字段名, 默认实现函数) 即可,destroy要求插件必须实现
56 : #define FOR_EACH_ENDPOINT_OP_DEFAULT(F) \
57 : F(init, DefaultEndpointInit) \
58 : F(registerMemory, DefaultEndpointRegisterMemory) \
59 : F(unregisterMemory, DefaultEndpointUnregisterMemory) \
60 : F(memoryExport, DefaultEndpointMemoryExport) \
61 : F(memoryImport, DefaultEndpointMemoryImport) \
62 : F(memoryUnimport, DefaultEndpointMemoryUnimport) \
63 : F(getListenPort, DefaultEndpointGetListenPort)
64 :
65 : // 供 FOR_EACH_ENDPOINT_OP_DEFAULT 使用的填充器
66 : #define FILL_ENDPOINT_OP_DEFAULT(op, defaultFunc) \
67 : if (!IsPluginOpAvailable(dst, offsetof(HcommNicEndpointOps, op), sizeof(dst->op)) || dst->op == nullptr) { \
68 : dst->op = defaultFunc; \
69 : }
70 :
71 : HcommResult FillDefaultChannelOps(const HcommNicChannelOps* src, HcommNicChannelOps** outOps);
72 :
73 : int32_t DefaultChannelInit(void* ctx);
74 : int32_t DefaultChannelGetStatus(void* ctx, int32_t* status);
75 : int32_t DefaultChannelWriteNbi(void* ctx, void* dst, const void* src, uint64_t len);
76 : int32_t DefaultChannelWriteNbiOnThread(void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len);
77 : int32_t DefaultChannelWriteOnThread(void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len);
78 : int32_t DefaultChannelWriteWithNotifyNbi(void* ctx, void* dst, const void* src, uint64_t len, uint32_t remoteNotifyIdx);
79 : int32_t DefaultChannelWriteWithNotifyNbiOnThread(
80 : void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len, uint32_t remoteNotifyIdx);
81 : int32_t DefaultChannelWriteWithNotifyOnThread(
82 : void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len, uint32_t remoteNotifyIdx);
83 : int32_t DefaultChannelWriteReduceOnThread(
84 : void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t count, HcommDataType dataType,
85 : HcommReduceOp reduceOp);
86 : int32_t DefaultChannelWriteReduceWithNotifyOnThread(
87 : void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t count, HcommDataType dataType,
88 : HcommReduceOp reduceOp, uint32_t remoteNotifyIdx);
89 : int32_t DefaultChannelReadNbi(void* ctx, void* dst, const void* src, uint64_t len);
90 : int32_t DefaultChannelReadNbiOnThread(void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len);
91 : int32_t DefaultChannelReadOnThread(void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t len);
92 : int32_t DefaultChannelReadReduceOnThread(
93 : void* ctx, ThreadHandle thread, void* dst, const void* src, uint64_t count, HcommDataType dataType,
94 : HcommReduceOp reduceOp);
95 : int32_t DefaultChannelNotifyRecord(void* ctx, uint32_t remoteNotifyIdx);
96 : int32_t DefaultChannelNotifyRecordOnThread(void* ctx, ThreadHandle thread, uint32_t remoteNotifyIdx);
97 : int32_t DefaultChannelNotifyWait(void* ctx, uint32_t localNotifyIdx, uint32_t timeOut);
98 : int32_t DefaultChannelNotifyWaitOnThread(void* ctx, ThreadHandle thread, uint32_t localNotifyIdx, uint32_t timeOut);
99 : int32_t DefaultChannelNotifyWaitOnThreadWithDefaultTimeout(void* ctx, ThreadHandle thread, uint32_t localNotifyIdx);
100 : int32_t DefaultChannelBatchTransferOnThread(
101 : void* ctx, ThreadHandle thread, const HcommBatchTransferDesc* transferDescs, uint32_t transferDescNum);
102 : int32_t DefaultChannelFence(void* ctx);
103 : int32_t DefaultChannelFenceOnThread(void* ctx, ThreadHandle thread);
104 : int32_t DefaultChannelDrainOnThread(void* ctx, ThreadHandle thread);
105 :
106 : // HcommNicChannelOps 新增成员时,在此追加一行 F(op字段名, 默认实现函数) 即可,destroy要求插件必须实现
107 : #define FOR_EACH_CHANNEL_OP_DEFAULT(F) \
108 : F(init, DefaultChannelInit) \
109 : F(getStatus, DefaultChannelGetStatus) \
110 : F(writeNbi, DefaultChannelWriteNbi) \
111 : F(writeNbiOnThread, DefaultChannelWriteNbiOnThread) \
112 : F(writeOnThread, DefaultChannelWriteOnThread) \
113 : F(writeWithNotifyNbi, DefaultChannelWriteWithNotifyNbi) \
114 : F(writeWithNotifyNbiOnThread, DefaultChannelWriteWithNotifyNbiOnThread) \
115 : F(writeWithNotifyOnThread, DefaultChannelWriteWithNotifyOnThread) \
116 : F(writeReduceOnThread, DefaultChannelWriteReduceOnThread) \
117 : F(writeReduceWithNotifyOnThread, DefaultChannelWriteReduceWithNotifyOnThread) \
118 : F(readNbi, DefaultChannelReadNbi) \
119 : F(readNbiOnThread, DefaultChannelReadNbiOnThread) \
120 : F(readOnThread, DefaultChannelReadOnThread) \
121 : F(readReduceOnThread, DefaultChannelReadReduceOnThread) \
122 : F(notifyRecord, DefaultChannelNotifyRecord) \
123 : F(notifyRecordOnThread, DefaultChannelNotifyRecordOnThread) \
124 : F(notifyWait, DefaultChannelNotifyWait) \
125 : F(notifyWaitOnThread, DefaultChannelNotifyWaitOnThread) \
126 : F(notifyWaitOnThreadWithDefaultTimeout, DefaultChannelNotifyWaitOnThreadWithDefaultTimeout) \
127 : F(batchTransferOnThread, DefaultChannelBatchTransferOnThread) \
128 : F(fence, DefaultChannelFence) \
129 : F(fenceOnThread, DefaultChannelFenceOnThread) \
130 : F(drainOnThread, DefaultChannelDrainOnThread)
131 :
132 : // 供 FOR_EACH_CHANNEL_OP_DEFAULT 使用的填充器
133 : #define FILL_CHANNEL_OP_DEFAULT(op, defaultFunc) \
134 : if (!IsPluginOpAvailable(dst, offsetof(HcommNicChannelOps, op), sizeof(dst->op)) || dst->op == nullptr) { \
135 : dst->op = defaultFunc; \
136 : }
137 :
138 : bool ValidateEndpointOps(const HcommNicEndpointOps* ops);
139 : bool ValidateChannelOps(const HcommNicChannelOps* ops);
140 :
141 : template <typename PluginOps>
142 80 : bool IsPluginOpAvailable(const PluginOps* ops, size_t opOffset, size_t opSize)
143 : {
144 80 : return ops != nullptr && ops->header.size >= opOffset + opSize;
145 : }
146 :
147 : template <typename PluginOps>
148 : void DestroyPluginCtx(PluginOps* ops, void* pluginCtx)
149 : {
150 : if (ops != nullptr && IsPluginOpAvailable(ops, offsetof(PluginOps, destroy), sizeof(ops->destroy))
151 : && ops->destroy != nullptr) {
152 : int32_t ret = ops->destroy(pluginCtx);
153 : if (ret != HCCL_SUCCESS) {
154 : HCCL_WARNING("[%s] plugin destroy failed, ret[%d].", __func__, ret);
155 : }
156 : }
157 : }
158 :
159 : } // namespace hcomm
160 :
161 : #endif // HCOMM_NIC_PLUGIN_MANAGER_H
|