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