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 128 : IAicpuTsThread::IAicpuTsThread(uint32_t id, uint32_t sqIds, uint32_t phyId, uint32_t logicCqids)
50 : {
51 128 : StreamLite* streamLitePtr = new StreamLite(id, sqIds, phyId, logicCqids, true);
52 128 : if (streamLitePtr == nullptr) {
53 0 : HCCL_ERROR(
54 : "[IAicpuTsThread::%s] new StreamLite failed, id [%u], sqIds [%u], phyId [%u], logicCqids [%u]", __func__,
55 : id, sqIds, phyId, logicCqids);
56 0 : throw std::bad_alloc();
57 : }
58 128 : streamLiteVoidPtr_ = static_cast<void*>(streamLitePtr);
59 128 : }
60 :
61 128 : IAicpuTsThread::~IAicpuTsThread()
62 : {
63 128 : StreamLite* streamLitePtr = static_cast<StreamLite*>(streamLiteVoidPtr_);
64 128 : if (streamLitePtr != nullptr) {
65 128 : delete streamLitePtr;
66 128 : streamLiteVoidPtr_ = nullptr;
67 : }
68 128 : }
69 :
70 1 : void IAicpuTsThread::LaunchTask() const
71 : {
72 1 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
73 :
74 1 : HCCL_INFO(
75 : "[IAicpuTsThread::%s] Launch Task at Stream id [%u]", __func__,
76 : static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId());
77 :
78 1 : rtsqA5->LaunchTask();
79 1 : return;
80 : }
81 :
82 1 : void IAicpuTsThread::TryLaunchTask() const
83 : {
84 1 : HCCL_DEBUG(
85 : "[IAicpuTsThread::%s] TryLaunch Task at Stream id [%u]", __func__,
86 : static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId());
87 :
88 1 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
89 1 : if (rtsqA5 != nullptr) {
90 1 : rtsqA5->TryLaunchTask();
91 : }
92 1 : return;
93 : }
94 :
95 1 : HcclResult IAicpuTsThread::NotifyWait(uint32_t notifyId) const
96 : {
97 1 : return NotifyWait(notifyId, GetKernelExecTimeoutFromEnvConfig());
98 : }
99 :
100 1 : HcclResult IAicpuTsThread::NotifyWait(uint32_t notifyId, uint32_t timeout) const
101 : {
102 1 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
103 :
104 1 : HCCL_INFO(
105 : "[IAicpuTsThread::%s] at Stream id [%u], notifyId [%u], timeout [%u ms]", __func__,
106 : static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId(), notifyId, timeout);
107 :
108 1 : rtsqA5->NotifyWait(notifyId, timeout);
109 :
110 1 : return HCCL_SUCCESS;
111 : }
112 :
113 1 : HcclResult IAicpuTsThread::NotifyRecordLoc(uint32_t notifyId) const
114 : {
115 1 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
116 :
117 1 : HCCL_INFO(
118 : "[IAicpuTsThread::%s] at Stream id [%u], notifyId [%u]", __func__,
119 : static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId(), notifyId);
120 :
121 1 : rtsqA5->NotifyRecordLoc(notifyId);
122 :
123 1 : return HCCL_SUCCESS;
124 : }
125 :
126 2 : HcclResult IAicpuTsThread::SdmaCopy(uint64_t dstAddr, uint64_t srcAddr, uint64_t sizeByte) const
127 : {
128 : // SDMA单个任务最大支持4GB的数据量,超过4GB需要分多次提交
129 : // 为了避免不必要的依赖和复杂性,这里不直接使用DeviceCapacity中定义的SDMA_SEND_MAX_SIZE,而是直接使用4GB的值
130 2 : if (sizeByte > 0x100000000ULL) {
131 1 : HCCL_ERROR("[%s] sizeByte [%llu] exceeds 4GB", __func__, (unsigned long long)sizeByte);
132 1 : return HCCL_E_PARA;
133 : }
134 :
135 1 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
136 :
137 1 : uint32_t sizeByteNarrowed = static_cast<uint32_t>(sizeByte);
138 :
139 1 : HCCL_INFO(
140 : "[IAicpuTsThread::%s] at Stream id [%u], dstAddr [%llx], srcAddr [%llx], sizeByteNarrowed [%u]", __func__,
141 : static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId(), (unsigned long long)dstAddr, (unsigned long long)srcAddr,
142 : sizeByteNarrowed);
143 :
144 1 : rtsqA5->SdmaCopy(srcAddr, dstAddr, sizeByteNarrowed, 0);
145 :
146 1 : return HCCL_SUCCESS;
147 : }
148 :
149 10 : HcclResult IAicpuTsThread::SdmaReduce(
150 : uint64_t dstAddr, uint64_t srcAddr, uint64_t sizeByte, uint32_t dataTypeRaw, uint32_t reduceOpRaw) const
151 : {
152 : // SDMA单个任务最大支持4GB的数据量,超过4GB需要分多次提交
153 : // 为了避免不必要的依赖和复杂性,这里不直接使用DeviceCapacity中定义的SDMA_SEND_MAX_SIZE,而是直接使用4GB的值
154 10 : if (sizeByte > 0x100000000ULL) {
155 1 : HCCL_ERROR("[%s] sizeByte [%llu] exceeds 4GB", __func__, (unsigned long long)sizeByte);
156 1 : return HCCL_E_PARA;
157 : }
158 :
159 9 : RtsqBase* rtsqA5 = static_cast<StreamLite*>(streamLiteVoidPtr_)->GetRtsq();
160 :
161 9 : CHK_RET(CheckDataTypeAndReduceOp(dataTypeRaw, reduceOpRaw));
162 7 : DataType dataType = mapU32ToDataType.at(dataTypeRaw);
163 7 : ReduceOp reduceOp = mapU32ToReduceOp.at(reduceOpRaw);
164 7 : ReduceIn reduceIn{dataType, reduceOp};
165 :
166 7 : uint32_t sizeByteNarrowed = static_cast<uint32_t>(sizeByte);
167 :
168 7 : HCCL_INFO(
169 : "[IAicpuTsThread::%s] at Stream id [%u], dstAddr [%llx], srcAddr [%llx], sizeByteNarrowed [%u], dataType "
170 : "[%u][%s], reduceOp [%u][%s]",
171 : __func__, static_cast<StreamLite*>(streamLiteVoidPtr_)->GetId(), (unsigned long long)dstAddr,
172 : (unsigned long long)srcAddr, sizeByteNarrowed, dataTypeRaw, dataType.Describe().c_str(), reduceOpRaw,
173 : reduceOp.Describe().c_str());
174 :
175 7 : rtsqA5->SdmaReduce(srcAddr, dstAddr, sizeByteNarrowed, 0, reduceIn);
176 :
177 7 : return HCCL_SUCCESS;
178 : }
179 :
180 : } // namespace Hccl
|