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 "aicpu_ts_thread_interface.h"
12 :
13 : #include <memory>
14 : #include <limits>
15 :
16 : #include "stream_lite.h"
17 : #include "sqe_build_a5.h"
18 :
19 : namespace Hccl {
20 :
21 : namespace { // make the definitions file-scoped
22 :
23 : std::unordered_map<uint32_t, ReduceOp> mapU32ToReduceOp
24 : = {{0, ReduceOp::SUM}, {1, ReduceOp::PROD}, {2, ReduceOp::MAX}, {3, ReduceOp::MIN}};
25 :
26 : std::unordered_map<uint32_t, DataType> mapU32ToDataType
27 : = {{0, DataType::INT8}, {1, DataType::INT16}, {2, DataType::INT32}, {3, DataType::FP16},
28 : {4, DataType::FP32}, {5, DataType::INT64}, {6, DataType::UINT64}, {7, DataType::UINT8},
29 : {8, DataType::UINT16}, {9, DataType::UINT32}, {10, DataType::FP64}, {11, DataType::BFP16},
30 : {12, DataType::INT128}, {14, DataType::HIF8}, {15, DataType::FP8E4M3}, {16, DataType::FP8E5M2},
31 : {17, DataType::FP8E8M0}};
32 :
33 9 : inline HcclResult CheckDataTypeAndReduceOp(uint32_t dataType, uint32_t reduceOp)
34 : {
35 9 : if (mapU32ToDataType.find(dataType) == mapU32ToDataType.end()) {
36 1 : HCCL_ERROR("[IAicpuTsThread][%s] type[%u] is not supported.", __func__, dataType);
37 1 : return HCCL_E_PARA;
38 : }
39 8 : if (mapU32ToReduceOp.find(reduceOp) == mapU32ToReduceOp.end()) {
40 1 : HCCL_ERROR("[IAicpuTsThread][%s] op[%u] is not supported.", __func__, reduceOp);
41 1 : return HCCL_E_PARA;
42 : }
43 7 : return HCCL_SUCCESS;
44 : }
45 :
46 : } // namespace
47 :
48 : // 此处失败的原因只可能是内存分配失败,所以可以直接抛出标准异常
49 124 : IAicpuTsThread::IAicpuTsThread(uint32_t id, uint32_t sqIds, uint32_t phyId, uint32_t logicCqids)
50 : {
51 124 : StreamLite *streamLitePtr = new StreamLite(id, sqIds, phyId, logicCqids, true);
52 124 : if (streamLitePtr == nullptr) {
53 0 : HCCL_ERROR("[IAicpuTsThread::%s] new StreamLite failed, id [%u], sqIds [%u], phyId [%u], logicCqids [%u]",
54 : __func__, id, sqIds, phyId, logicCqids);
55 0 : throw std::bad_alloc();
56 : }
57 124 : streamLiteVoidPtr_ = static_cast<void *>(streamLitePtr);
58 124 : }
59 :
60 124 : IAicpuTsThread::~IAicpuTsThread()
61 : {
62 124 : StreamLite *streamLitePtr = static_cast<StreamLite *>(streamLiteVoidPtr_);
63 124 : if(streamLitePtr != nullptr){
64 124 : delete streamLitePtr;
65 124 : streamLiteVoidPtr_ = nullptr;
66 : }
67 124 : }
68 :
69 1 : void IAicpuTsThread::LaunchTask() const
70 : {
71 1 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
72 :
73 1 : HCCL_INFO("[IAicpuTsThread::%s] Launch Task at Stream id [%u]", __func__,
74 : static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId());
75 :
76 1 : rtsqA5->LaunchTask();
77 1 : return;
78 : }
79 :
80 1 : void IAicpuTsThread::TryLaunchTask() const
81 : {
82 1 : HCCL_DEBUG("[IAicpuTsThread::%s] TryLaunch Task at Stream id [%u]", __func__,
83 : static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId());
84 :
85 1 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
86 1 : if (rtsqA5 != nullptr) {
87 1 : rtsqA5->TryLaunchTask();
88 : }
89 1 : return;
90 : }
91 :
92 1 : HcclResult IAicpuTsThread::NotifyWait(uint32_t notifyId) const
93 : {
94 1 : return NotifyWait(notifyId, GetKernelExecTimeoutFromEnvConfig());
95 : }
96 :
97 1 : HcclResult IAicpuTsThread::NotifyWait(uint32_t notifyId, uint32_t timeout) const
98 : {
99 1 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
100 :
101 1 : HCCL_INFO("[IAicpuTsThread::%s] at Stream id [%u], notifyId [%u], timeout [%u ms]", __func__,
102 : static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId(), notifyId, timeout);
103 :
104 1 : rtsqA5->NotifyWait(notifyId, timeout);
105 :
106 1 : return HCCL_SUCCESS;
107 : }
108 :
109 1 : HcclResult IAicpuTsThread::NotifyRecordLoc(uint32_t notifyId) const
110 : {
111 1 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
112 :
113 1 : HCCL_INFO("[IAicpuTsThread::%s] at Stream id [%u], notifyId [%u]", __func__,
114 : static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId(), notifyId);
115 :
116 1 : rtsqA5->NotifyRecordLoc(notifyId);
117 :
118 1 : return HCCL_SUCCESS;
119 : }
120 :
121 2 : HcclResult IAicpuTsThread::SdmaCopy(uint64_t dstAddr, uint64_t srcAddr, uint64_t sizeByte) const
122 : {
123 : // SDMA单个任务最大支持4GB的数据量,超过4GB需要分多次提交
124 : // 为了避免不必要的依赖和复杂性,这里不直接使用DeviceCapacity中定义的SDMA_SEND_MAX_SIZE,而是直接使用4GB的值
125 2 : if (sizeByte > 0x100000000ULL) {
126 1 : HCCL_ERROR("[%s] sizeByte [%llu] exceeds 4GB", __func__, (unsigned long long)sizeByte);
127 1 : return HCCL_E_PARA;
128 : }
129 :
130 1 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
131 :
132 1 : uint32_t sizeByteNarrowed = static_cast<uint32_t>(sizeByte);
133 :
134 1 : HCCL_INFO("[IAicpuTsThread::%s] at Stream id [%u], dstAddr [%llx], srcAddr [%llx], sizeByteNarrowed [%u]", __func__,
135 : static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId(), (unsigned long long)dstAddr, (unsigned long long)srcAddr,
136 : sizeByteNarrowed);
137 :
138 1 : rtsqA5->SdmaCopy(srcAddr, dstAddr, sizeByteNarrowed, 0);
139 :
140 1 : return HCCL_SUCCESS;
141 : }
142 :
143 10 : HcclResult IAicpuTsThread::SdmaReduce(uint64_t dstAddr, uint64_t srcAddr, uint64_t sizeByte, uint32_t dataTypeRaw,
144 : uint32_t reduceOpRaw) const
145 : {
146 : // SDMA单个任务最大支持4GB的数据量,超过4GB需要分多次提交
147 : // 为了避免不必要的依赖和复杂性,这里不直接使用DeviceCapacity中定义的SDMA_SEND_MAX_SIZE,而是直接使用4GB的值
148 10 : if (sizeByte > 0x100000000ULL) {
149 1 : HCCL_ERROR("[%s] sizeByte [%llu] exceeds 4GB", __func__, (unsigned long long)sizeByte);
150 1 : return HCCL_E_PARA;
151 : }
152 :
153 9 : RtsqBase *rtsqA5 = static_cast<StreamLite *>(streamLiteVoidPtr_)->GetRtsq();
154 :
155 9 : CHK_RET(CheckDataTypeAndReduceOp(dataTypeRaw, reduceOpRaw));
156 7 : DataType dataType = mapU32ToDataType.at(dataTypeRaw);
157 7 : ReduceOp reduceOp = mapU32ToReduceOp.at(reduceOpRaw);
158 7 : ReduceIn reduceIn{dataType, reduceOp};
159 :
160 7 : uint32_t sizeByteNarrowed = static_cast<uint32_t>(sizeByte);
161 :
162 7 : HCCL_INFO("[IAicpuTsThread::%s] at Stream id [%u], dstAddr [%llx], srcAddr [%llx], sizeByteNarrowed [%u], dataType "
163 : "[%u][%s], reduceOp [%u][%s]",
164 : __func__, static_cast<StreamLite *>(streamLiteVoidPtr_)->GetId(), (unsigned long long)dstAddr,
165 : (unsigned long long)srcAddr, sizeByteNarrowed,
166 : dataTypeRaw, dataType.Describe().c_str(), reduceOpRaw, reduceOp.Describe().c_str());
167 :
168 7 : rtsqA5->SdmaReduce(srcAddr, dstAddr, sizeByteNarrowed, 0, reduceIn);
169 :
170 7 : return HCCL_SUCCESS;
171 : }
172 :
173 : } // namespace Hccl
|