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 : #include "launch_context.h"
11 : #include "new/hccl_primitive_local.h"
12 :
13 : constexpr u32 THREAD_VECTOR_DEFAULT_SIZE = 128; // 设置vector初始长度,避免频繁扩容
14 : constexpr u32 NOTIFY_WAIT_TIMEOUT_OFFSET = 27; // AICPU device侧notify等待超时偏移量
15 :
16 : extern HcclResult CommTaskLaunch(ThreadHandle *threads, uint32_t threadNum); // host ffts+或aicpu stars使用"
17 : extern HcclResult CommTaskPrepare(char *key, uint32_t keyLen); // host ffts+使用
18 : extern HcclResult DispatchAllStreams(ThreadHandle *threads, uint32_t threadNum);
19 :
20 5 : LaunchContext::LaunchContext()
21 : {
22 5 : threadVec_.reserve(THREAD_VECTOR_DEFAULT_SIZE);
23 5 : }
24 :
25 1 : HcclResult LaunchContext::HandleEagerMode()
26 : {
27 : // 带launchTag部分
28 1 : if (!launchModeMap_.empty()) {
29 1 : auto it = launchModeMap_.find(launchTag_);
30 1 : if (it != launchModeMap_.end()) {
31 1 : std::vector<ThreadHandle> threadVec(it->second.begin(), it->second.end());
32 1 : CHK_RET(CommTaskLaunch(threadVec.data(), threadVec.size()));
33 1 : HCCL_INFO("[%s]success, launchTag[%s], size[%zu]", __func__, launchTag_.c_str(), threadVec.size());
34 1 : }
35 : }
36 :
37 : // 不带launchTag部分
38 1 : if (!threadVec_.empty()) {
39 1 : CHK_RET(CommTaskLaunch(threadVec_.data(), threadVec_.size()));
40 1 : HCCL_INFO("[%s]success, size[%zu]", __func__, threadVec_.size());
41 : }
42 1 : return HCCL_SUCCESS;
43 : }
44 :
45 2 : HcclResult LaunchContext::HandleDispatchAllStreams()
46 : {
47 : // 带launchTag部分
48 2 : if (!launchModeMap_.empty()) {
49 1 : auto it = launchModeMap_.find(launchTag_);
50 1 : if (it != launchModeMap_.end()) {
51 1 : std::vector<ThreadHandle> threadVec(it->second.begin(), it->second.end());
52 1 : CHK_RET(DispatchAllStreams(threadVec.data(), threadVec.size()));
53 1 : }
54 : }
55 :
56 : // 不带launchTag部分
57 2 : if (!threadVec_.empty()) {
58 1 : CHK_RET(DispatchAllStreams(threadVec_.data(), threadVec_.size()));
59 : }
60 2 : return HCCL_SUCCESS;
61 : }
62 :
63 2 : HcclResult LaunchContext::HandleClear()
64 : {
65 2 : threadVec_.clear();
66 2 : if (!launchModeMap_.empty()) {
67 2 : launchModeMap_.erase(launchTag_);
68 : }
69 2 : HCCL_INFO("[%s] begin clear, launchTag[%s], launchMode[%d].",
70 : __func__, launchTag_.c_str(), static_cast<int32_t>(mode_));
71 :
72 2 : DevType devType = DevType::DEV_TYPE_COUNT;
73 2 : hrtGetDeviceType(devType);
74 2 : if (devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
75 2 : HCCL_INFO("[%s] Running on A5/A6, HcclTaskClear skipped.", __func__);
76 2 : return HCCL_SUCCESS;
77 : }
78 0 : return HcclTaskClear(launchTag_);
79 : }
80 :
81 5 : HcclResult LaunchContext::SetNotifyWaitTimeOut(uint32_t timeout)
82 : {
83 5 : notifyWaitTimeoutConfig_.notifyWaitTimeout = timeout;
84 5 : notifyWaitTimeoutConfig_.isSet = true;
85 5 : return HCCL_SUCCESS;
86 : }
87 :
88 5 : HcclResult LaunchContext::GetNotifyWaitTimeOut(uint32_t& timeout)
89 : {
90 5 : timeout = notifyWaitTimeoutConfig_.notifyWaitTimeout;
91 : #ifndef CCL_KERNEL_AICPU
92 5 : if (!notifyWaitTimeoutConfig_.isSet) {
93 0 : timeout = timeout + NOTIFY_WAIT_TIMEOUT_OFFSET;
94 : }
95 : #endif
96 5 : return HCCL_SUCCESS;
97 : }
98 :
99 3 : HcclResult LaunchContext::SetSqFullTimeOut(uint32_t timeout)
100 : {
101 3 : sqFullTimeoutConfig_.sqFullTimeout = timeout;
102 3 : sqFullTimeoutConfig_.isSet = true;
103 3 : return HCCL_SUCCESS;
104 : }
105 :
106 0 : uint32_t LaunchContext::GetSqFullTimeOut()
107 : {
108 0 : return sqFullTimeoutConfig_.sqFullTimeout;
109 : }
110 :
111 : /*
112 : 1 AICPU_TS模式
113 : AICPU上执行
114 : 告知后面的CommWrite等任务进入批量模式,(只写任务的SQE,但是不触发执行)
115 : 举例:
116 : HcommSetLaunchMode("abc", HCOMM_LAUNCH_MODE_BATCH);
117 : HcommAclrtNotifyWaitOnThread(thread, notifyId, 0);
118 : HcommAclrtNotifyRecordOnThread(thread, notifyId);
119 : HcommSetLaunchMode("abc", HCOMM_LAUNCH_MODE_EAGER);
120 :
121 : 2 CPU_TS模式
122 : FFTS+子图,最后批量提交。在HOST CPU上执行
123 : 告知后面的CommWrite等任务进入批量模式(开始ffts+子图)
124 :
125 : 1)复用task子图缓存
126 : 增加 launchTag 的原因,进入批量模式之后,缓存要执行的一些task,最后提交。缓
127 : 存的标识采用launchTag。在第二次执行想要复用子图执行时,只需要拿着相同的
128 : launchTag,调用 HcommSetLaunchMode接口,传入HCOMM_LAUNCH_MODE_EAGER参数,即可复用执行。
129 : 比如下面的: HcommSetLaunchMode ("abc", HCOMM_LAUNCH_MODE_EAGER);
130 : 执行之前缓存到"abc"下的几个数据面操作。
131 :
132 : 2)清理
133 : 如果不需要"abc"标识的这个子图的task 缓存了,可以采用如下方式清理该子图内容:
134 : HcommSetLaunchMode ("abc", HCOMM_LAUNCH_MODE_RESERVED)
135 :
136 : 3)缺省 launchTag
137 : launchTag 如果为 nullptr,表示缺省值,标识不需要缓存到 FFTS+子图。
138 : */
139 2 : HcclResult LaunchContext::SetLaunchMode(const char* launchTag, HcommLaunchMode mode)
140 : {
141 2 : mode_ = mode;
142 : // 统一处理 launchTag
143 2 : bool defaultTag = (launchTag == nullptr);
144 6 : launchTag_ = defaultTag ? "" : std::string(launchTag);
145 2 : HCCL_INFO("[%s] SetLaunchMode begin, launchTag[%s], launchMode[%d].",
146 : __func__, launchTag_.c_str(), static_cast<int32_t>(mode));
147 :
148 : #ifndef CCL_KERNEL_AICPU
149 2 : DevType devType = DevType::DEV_TYPE_COUNT;
150 : #endif
151 2 : switch (mode_) {
152 2 : case HCOMM_LAUNCH_MODE_BATCH:
153 : #ifndef CCL_KERNEL_AICPU
154 2 : hrtGetDeviceType(devType);
155 2 : if (devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
156 2 : HCCL_INFO("[%s] Running on A5, CommTaskPrepare skipped.", __func__);
157 2 : return HCCL_SUCCESS;
158 : }
159 0 : HCCL_INFO("[%s]host mode, need CommTaskPrepare", __func__);
160 0 : if (!defaultTag) {
161 : // 仅非缺省 tag 需要准备任务缓存
162 0 : return CommTaskPrepare(const_cast<char*>(launchTag_.c_str()), launchTag_.length());
163 : }
164 : #endif
165 0 : return HCCL_SUCCESS;
166 0 : case HCOMM_LAUNCH_MODE_EAGER:
167 0 : CHK_RET(HandleEagerMode());
168 : // 缺省 tag 模式下清理缓存
169 0 : return HandleClear();
170 0 : case HCOMM_LAUNCH_MODE_RESERVED:
171 0 : if (!defaultTag) {
172 0 : return HandleClear();
173 : }
174 0 : return HCCL_SUCCESS;
175 0 : default:
176 0 : return HCCL_SUCCESS;
177 : }
178 : }
179 :
|