Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 : #include "hcomm_primitives.h"
12 :
13 : #include <cstring>
14 :
15 : #include "dtype_common.h"
16 : #include "aicpu_task_cache_manager.h"
17 : #include "log.h"
18 :
19 : using namespace hcomm;
20 :
21 10 : HcommResult HcommAicpuTsTaskCacheLookup(const char* tag, bool* isHit)
22 : {
23 : DevType deviceType;
24 10 : CHK_RET(hrtGetDeviceType(deviceType));
25 10 : if (deviceType != DevType::DEV_TYPE_950) {
26 1 : HCCL_ERROR("[%s] deviceType[%d] is not support", __func__, deviceType);
27 1 : return HCCL_E_NOT_SUPPORT;
28 : }
29 :
30 9 : CHK_PTR_NULL(tag);
31 8 : CHK_PTR_NULL(isHit);
32 :
33 : // 记录当前tag, 后续校验tag一致性
34 7 : AicpuTaskCacheManager::cacheTag = tag;
35 :
36 : // 注意: 相同tag的算子一定不会被多个aicpu kernel threads同时展开,
37 : // 否则后续threads可能命中第一个thread插入的不完整的cache entry 例如: tag中有commId时,
38 : // 相同tag的算子一定属于同一个通信域, 必定按序展开 因此, FindEntry和AddEntry不需要统一成单个接口, 即FindEntry后,
39 : // 当前tag的缓存状态不会被其他threads改变, 可以直接AddEntry
40 :
41 : // 查询tag对应的cache entry
42 7 : AicpuTaskCacheManager::cacheEntryPtr = nullptr;
43 7 : CHK_RET(AicpuTaskCacheManager::aicpuTaskCache.FindEntry(tag, &AicpuTaskCacheManager::cacheEntryPtr));
44 :
45 : // 判断并记录是否为cache hit
46 7 : AicpuTaskCacheManager::isHit = (AicpuTaskCacheManager::cacheEntryPtr != nullptr);
47 7 : *isHit = AicpuTaskCacheManager::isHit;
48 :
49 : // 如果是cache miss, 尝试添加cache entry
50 : // 注意: 如果aicpu task cache容量已满, 不会添加新的cache entry, AicpuTaskCacheManager::cacheEntryPtr被设置为nullptr
51 7 : if (!(*isHit)) {
52 5 : CHK_RET(AicpuTaskCacheManager::aicpuTaskCache.AddEntry(tag, &AicpuTaskCacheManager::cacheEntryPtr));
53 : }
54 :
55 7 : return HCCL_SUCCESS;
56 : }
57 :
58 10 : HcommResult HcommAicpuTsTaskCacheStart(const char* tag, void** addrs, uint64_t* sizes, uint64_t count)
59 : {
60 : DevType deviceType;
61 10 : CHK_RET(hrtGetDeviceType(deviceType));
62 10 : if (deviceType != DevType::DEV_TYPE_950) {
63 1 : HCCL_ERROR("[HcommAicpuTsTaskCacheStart] deviceType[%d] is not support", deviceType);
64 1 : return HCCL_E_NOT_SUPPORT;
65 : }
66 :
67 9 : CHK_PTR_NULL(tag);
68 8 : CHK_PTR_NULL(addrs);
69 7 : CHK_PTR_NULL(sizes);
70 :
71 : // 校验tag一致性 (即Submit对应的tag一定与Lookup对应的tag一致)
72 6 : CHK_PRT_RET(
73 : strcmp(AicpuTaskCacheManager::cacheTag.c_str(), tag) != 0,
74 : HCCL_ERROR(
75 : "[HcommAicpuTsTaskCacheStart] submit's tag[%s] != lookup's tag[%s]", tag,
76 : AicpuTaskCacheManager::cacheTag.c_str()),
77 : HCCL_E_PARA);
78 :
79 : // 一定是cache miss
80 5 : CHK_PRT_RET(
81 : AicpuTaskCacheManager::isHit, HCCL_ERROR("[HcommAicpuTsTaskCacheStart] cache hit, but should be miss"),
82 : HCCL_E_INTERNAL);
83 :
84 : // Aicpu task cache容量未满
85 4 : if (AicpuTaskCacheManager::cacheEntryPtr != nullptr) {
86 : // 保存地址信息到cache entry
87 3 : CHK_RET(AicpuTaskCacheManager::cacheEntryPtr->InitCacheEntry(
88 : reinterpret_cast<const uint64_t*>(addrs), sizes, count));
89 : }
90 :
91 3 : return HCCL_SUCCESS;
92 : }
93 :
94 8 : HcommResult HcommAicpuTsTaskCacheEnd(const char* tag)
95 : {
96 : DevType deviceType;
97 8 : CHK_RET(hrtGetDeviceType(deviceType));
98 8 : if (deviceType != DevType::DEV_TYPE_950) {
99 1 : HCCL_ERROR("[HcommAicpuTsTaskCacheEnd] deviceType[%d] is not support", deviceType);
100 1 : return HCCL_E_NOT_SUPPORT;
101 : }
102 :
103 7 : CHK_PTR_NULL(tag);
104 :
105 : // 校验tag一致性 (即Submit对应的tag一定与Lookup对应的tag一致)
106 6 : CHK_PRT_RET(
107 : strcmp(AicpuTaskCacheManager::cacheTag.c_str(), tag) != 0,
108 : HCCL_ERROR(
109 : "[HcommAicpuTsTaskCacheEnd] submit's tag[%s] != lookup's tag[%s]", tag,
110 : AicpuTaskCacheManager::cacheTag.c_str()),
111 : HCCL_E_PARA);
112 :
113 : // 一定是cache miss
114 5 : CHK_PRT_RET(
115 : AicpuTaskCacheManager::isHit, HCCL_ERROR("[HcommAicpuTsTaskCacheEnd] cache hit, but should be miss"),
116 : HCCL_E_INTERNAL);
117 :
118 4 : HcclResult ret = HCCL_SUCCESS;
119 : do {
120 : // Aicpu task cache容量未满
121 4 : if (AicpuTaskCacheManager::cacheEntryPtr != nullptr) {
122 : // 提交cache entry, 更新cache entry内部信息
123 3 : ret = AicpuTaskCacheManager::cacheEntryPtr->SubmitCacheEntry();
124 3 : CHK_PRT_BREAK(
125 : ret != HCCL_SUCCESS, HCCL_ERROR("[HcommAicpuTsTaskCacheEnd] SubmitCacheEntry error,ret[%d]", ret),
126 : (void)0);
127 :
128 : // 更新cache空间消耗
129 2 : const uint64_t entryBytes = AicpuTaskCacheManager::cacheEntryPtr->GetEntryBytes();
130 2 : ret = AicpuTaskCacheManager::aicpuTaskCache.IncCacheBytes(
131 2 : AicpuTaskCacheManager::cacheTag.c_str(), entryBytes);
132 2 : CHK_PRT_BREAK(
133 : ret != HCCL_SUCCESS, HCCL_ERROR("[HcommAicpuTsTaskCacheEnd] IncCacheBytes error, ret[%d]", ret),
134 : (void)0);
135 : }
136 : } while (0);
137 :
138 : // 重置cache上下文
139 4 : AicpuTaskCacheManager::cacheTag.clear();
140 4 : AicpuTaskCacheManager::isHit = false;
141 4 : AicpuTaskCacheManager::cacheEntryPtr = nullptr;
142 :
143 4 : return ret;
144 : }
145 :
146 9 : HcommResult HcommAicpuTsTaskCacheExecute(const char* tag, void** addrs, uint64_t* sizes, uint64_t count)
147 : {
148 : DevType deviceType;
149 9 : CHK_RET(hrtGetDeviceType(deviceType));
150 9 : if (deviceType != DevType::DEV_TYPE_950) {
151 1 : HCCL_ERROR("[HcommAicpuTsTaskCacheExecute] deviceType[%d] is not support", deviceType);
152 1 : return HCCL_E_NOT_SUPPORT;
153 : }
154 :
155 8 : CHK_PTR_NULL(tag);
156 7 : CHK_PTR_NULL(addrs);
157 6 : CHK_PTR_NULL(sizes);
158 :
159 : // 校验tag一致性 (即Submit对应的tag一定与Lookup对应的tag一致)
160 5 : CHK_PRT_RET(
161 : strcmp(AicpuTaskCacheManager::cacheTag.c_str(), tag) != 0,
162 : HCCL_ERROR(
163 : "[HcommAicpuTsTaskCacheExecute] submit's tag[%s] != lookup's tag[%s]", tag,
164 : AicpuTaskCacheManager::cacheTag.c_str()),
165 : HCCL_E_PARA);
166 :
167 : // 一定是cache hit
168 4 : CHK_PRT_RET(
169 : !AicpuTaskCacheManager::isHit, HCCL_ERROR("[HcommAicpuTsTaskCacheExecute] cache miss, but should be hit"),
170 : HCCL_E_INTERNAL);
171 :
172 : // cache hit一定存在对应的cache entry
173 3 : CHK_PTR_NULL(AicpuTaskCacheManager::cacheEntryPtr);
174 :
175 : // 刷新并下发task
176 2 : HcclResult ret = AicpuTaskCacheManager::cacheEntryPtr->RefreshAndLaunch(
177 : reinterpret_cast<const uint64_t*>(addrs), sizes, count);
178 2 : if (ret != HCCL_SUCCESS) {
179 2 : HCCL_ERROR("[HcommAicpuTsTaskCacheExecute] RefreshAndLaunch error, ret[%d]", ret);
180 : }
181 :
182 : // 重置cache上下文
183 2 : AicpuTaskCacheManager::cacheTag.clear();
184 2 : AicpuTaskCacheManager::isHit = false;
185 2 : AicpuTaskCacheManager::cacheEntryPtr = nullptr;
186 :
187 2 : return ret;
188 : }
189 :
190 4 : HcommResult HcommAicpuTsTaskCacheClear(const char* tag)
191 : {
192 : DevType deviceType;
193 4 : CHK_RET(hrtGetDeviceType(deviceType));
194 4 : if (deviceType != DevType::DEV_TYPE_950) {
195 1 : HCCL_ERROR("[%s] deviceType[%d] is not support", __func__, deviceType);
196 1 : return HCCL_E_NOT_SUPPORT;
197 : }
198 :
199 3 : CHK_PTR_NULL(tag);
200 :
201 : // 清除tag对应的cache entry (if any)
202 2 : CHK_RET(AicpuTaskCacheManager::aicpuTaskCache.ClearEntry(tag));
203 2 : if (strcmp(AicpuTaskCacheManager::cacheTag.c_str(), tag) == 0) {
204 : // 重置cache上下文
205 0 : AicpuTaskCacheManager::cacheTag.clear();
206 0 : AicpuTaskCacheManager::isHit = false;
207 0 : AicpuTaskCacheManager::cacheEntryPtr = nullptr;
208 : }
209 :
210 2 : return HCCL_SUCCESS;
211 : }
|