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 : #include "ccu_instance.h"
12 :
13 : #include <algorithm>
14 :
15 : #include "log.h"
16 : #include "ccu_log.h"
17 :
18 : #include "hcom_common.h"
19 :
20 : #include "ccu_res_pack.h"
21 : #include "ccu_kernel_mgr.h"
22 :
23 : namespace hcomm {
24 :
25 27 : CcuInstance::~CcuInstance()
26 : {
27 : // 主动释放资源保证时序,不得随意调整顺序
28 46 : for (auto &kernelHandle : kernelHandles_) {
29 19 : if (kernelHandle != 0) {
30 19 : (void)CcuKernelMgr::GetInstance(devLogicId_).UnRegister(kernelHandle);
31 19 : kernelHandle = 0;
32 : }
33 : }
34 27 : kernelHandles_.clear();
35 :
36 27 : resPack_ = nullptr; // 释放通信域持有CCU资源
37 27 : if (ccuDrvHandle_) {
38 27 : ccuDrvHandle_ = nullptr; // 先减少引用计数,再尝试关闭
39 27 : (void)CcuDeinitFeature(devLogicId_);
40 : // 尝试关闭CCU功能,最后一个通信域调用时会关闭CCU驱动
41 : }
42 27 : }
43 :
44 27 : CcuResult CcuInstance::Init()
45 : {
46 27 : if (insType_ >= CcuInstanceType::CCU_UNUSED) {
47 0 : HCCL_ERROR("[CcuInstance][%s] failed, CcuInstanceType[%d] is invalid.",
48 : __func__, insType_);
49 0 : return CcuResult::CCU_E_PARA;
50 : }
51 :
52 27 : devLogicId_ = HcclGetThreadDeviceId();
53 :
54 27 : if (!ccuDrvHandle_) {
55 27 : CCU_CHK_RET(CcuInitFeature(devLogicId_, ccuDrvHandle_));
56 : }
57 :
58 27 : if (!resPack_) {
59 27 : resPack_.reset(new (std::nothrow) CcuResPack(insType_));
60 27 : CCU_CHK_PTR_NULL(resPack_);
61 27 : CCU_CHK_RET(resPack_->Init());
62 : }
63 :
64 27 : return CcuResult::CCU_SUCCESS;
65 : }
66 :
67 26 : CcuResult CcuInstance::Reset()
68 : {
69 26 : if (!resPack_) {
70 0 : return CcuResult::CCU_SUCCESS;
71 : }
72 :
73 26 : untranslatedKernelHandles_.clear();
74 26 : CCU_CHK_RET(resPack_->Reset());
75 26 : return CcuResult::CCU_SUCCESS;
76 : }
77 :
78 26 : CcuResPack *CcuInstance::GetResPack()
79 : {
80 26 : return resPack_.get();
81 : }
82 :
83 19 : CcuResult CcuInstance::SaveKernel(const CcuKernelHandle kernelHandle)
84 : {
85 19 : kernelHandles_.push_back(kernelHandle);
86 19 : untranslatedKernelHandles_.push_back(kernelHandle);
87 19 : return CcuResult::CCU_SUCCESS;
88 : }
89 :
90 19 : const std::vector<CcuKernelHandle> &CcuInstance::GetUntranslatedKernels()
91 : {
92 19 : return untranslatedKernelHandles_;
93 : }
94 :
95 26 : CcuResult CcuInstance::BeginRegister()
96 : {
97 26 : if (registerState_ == RegisterState::REGISTERING) {
98 0 : HCCL_ERROR("[CcuInstance][%s] failed, previous register round is not ended, "
99 : "HcommCcuKernelRegisterEnd is missing before a new HcommCcuKernelRegisterStart.", __func__);
100 0 : return CcuResult::CCU_E_INTERNAL;
101 : }
102 26 : registerState_ = RegisterState::REGISTERING;
103 26 : return CcuResult::CCU_SUCCESS;
104 : }
105 :
106 26 : CcuResult CcuInstance::CheckRegistering() const
107 : {
108 26 : if (registerState_ != RegisterState::REGISTERING) {
109 0 : HCCL_ERROR("[CcuInstance][%s] failed, HcommCcuKernelRegister must be called between "
110 : "HcommCcuKernelRegisterStart and HcommCcuKernelRegisterEnd.", __func__);
111 0 : return CcuResult::CCU_E_INTERNAL;
112 : }
113 26 : return CcuResult::CCU_SUCCESS;
114 : }
115 :
116 19 : CcuResult CcuInstance::EndRegister()
117 : {
118 19 : if (registerState_ == RegisterState::IDLE) {
119 0 : HCCL_ERROR("[CcuInstance][%s] failed, HcommCcuKernelRegisterEnd is called without a matching "
120 : "HcommCcuKernelRegisterStart.", __func__);
121 0 : return CcuResult::CCU_E_INTERNAL;
122 : }
123 19 : if (registerState_ == RegisterState::REGISTER_ABORTED) {
124 0 : HCCL_WARNING("[CcuInstance][%s] previous register round was aborted due to error, "
125 : "close it to keep Start/End paired, no kernel will be translated.", __func__);
126 : }
127 19 : registerState_ = RegisterState::IDLE;
128 19 : return CcuResult::CCU_SUCCESS;
129 : }
130 :
131 7 : void CcuInstance::AbortRegister()
132 : {
133 7 : for (auto kernelHandle : untranslatedKernelHandles_) {
134 0 : if (kernelHandle == 0) {
135 0 : continue;
136 : }
137 0 : (void)CcuKernelMgr::GetInstance(devLogicId_).UnRegister(kernelHandle);
138 0 : auto it = std::find(kernelHandles_.begin(), kernelHandles_.end(), kernelHandle);
139 0 : if (it != kernelHandles_.end()) {
140 0 : kernelHandles_.erase(it);
141 : }
142 : }
143 7 : untranslatedKernelHandles_.clear();
144 7 : registerState_ = RegisterState::REGISTER_ABORTED;
145 7 : }
146 :
147 : } // namespace hcomm
|