已合并
engram反向性能优化 #10126
engram反向性能优化 #10126
已合并
luozhonglin创建于 8月15日
共 7 个文件变更+725-263
@@ -119,7 +119,7 @@ struct EngramCommContext {
119 uint32_t rankId = 0;119 uint32_t rankId = 0;
120 uint32_t rankSize = 0;120 uint32_t rankSize = 0;
121 uint64_t virtualAddrList[HCCL_MAX_RANK_SIZE] = {};121 uint64_t virtualAddrList[HCCL_MAX_RANK_SIZE] = {};
122- uint64_t hcommHandle[HCCL_MAX_RANK_SIZE] = {};122+ uint64_t hcommHandle[HCCL_MAX_RANK_SIZE * 2] = {};
123 uint32_t channelsPerRank = 1;123 uint32_t channelsPerRank = 1;
124};124};
125 125 
@@ -392,12 +392,22 @@ private:
392 static void QueryHcclBufferResource(const HcclComm &commHandle, EngramContextResources &resources)392 static void QueryHcclBufferResource(const HcclComm &commHandle, EngramContextResources &resources)
393 {393 {
394 uint32_t rankId = resources.context.rankId;394 uint32_t rankId = resources.context.rankId;
395- constexpr uint32_t channelsPerPeer = 2U;395+ uint32_t rankSize = resources.context.rankSize;
396+ constexpr uint32_t aivNum = 72U;
397+ uint32_t numSendCores = aivNum / 2U;
398+ if (numSendCores == 0U) {
399+ numSendCores = 1U;
400+ }
401+ uint32_t groupSize = numSendCores / rankSize;
402+ if (groupSize == 0U) {
403+ groupSize = 1U;
404+ }
405+ uint32_t channelsPerPeer = groupSize * 2U;
396 resources.context.channelsPerRank = channelsPerPeer;406 resources.context.channelsPerRank = channelsPerPeer;
397- ChannelHandle handlesByRank[HCCL_MAX_RANK_SIZE * 2] = {};407+ 
398- GetHcclCommChannel(commHandle, resources.context.rankSize, rankId, channelsPerPeer, resources.memHandle,408+ std::vector<ChannelHandle> handlesByRank(rankSize * channelsPerPeer);
399- handlesByRank);409+ GetHcclCommChannel(commHandle, rankSize, rankId, channelsPerPeer, resources.memHandle, handlesByRank.data());
400- for (uint32_t peer = 0; peer < resources.context.rankSize; ++peer) {410+ for (uint32_t peer = 0; peer < rankSize; ++peer) {
401 if (peer == rankId)411 if (peer == rankId)
402 continue;412 continue;
403 for (uint32_t ch = 0; ch < channelsPerPeer; ++ch) {413 for (uint32_t ch = 0; ch < channelsPerPeer; ++ch) {
@@ -759,11 +769,26 @@ public:
759 void EngramBarrier(bool useCommStream = true, bool withCpuSync = false);769 void EngramBarrier(bool useCommStream = true, bool withCpuSync = false);
760 void Destroy();770 void Destroy();
761 771 
762- int64_t GetHostBufPtr() const { return reinterpret_cast<int64_t>(engramHostBufPtr_); }772+ int64_t GetHostBufPtr() const
763- const at::Tensor &GetContextTensor() const { return engramContextTensor_; }773+ {
764- const at::Tensor &GetLocalStorageAddrTensor() const { return localStorageAddrTensor_; }774+ return reinterpret_cast<int64_t>(engramHostBufPtr_);
765- int64_t GetCommBufferSize() const { return commBufferSize_; }775+ }
766- uint32_t GetRankSize() const { return engramCommContext_.rankSize; }776+ const at::Tensor &GetContextTensor() const
777+ {
778+ return engramContextTensor_;
779+ }
780+ const at::Tensor &GetLocalStorageAddrTensor() const
781+ {
782+ return localStorageAddrTensor_;
783+ }
784+ int64_t GetCommBufferSize() const
785+ {
786+ return commBufferSize_;
787+ }
788+ uint32_t GetRankSize() const
789+ {
790+ return engramCommContext_.rankSize;
791+ }
767 792 
768 static at::Tensor EngramFetch(const at::Tensor &context, const at::Tensor &indices, int64_t hiddenSize,793 static at::Tensor EngramFetch(const at::Tensor &context, const at::Tensor &indices, int64_t hiddenSize,
769 int64_t numEntries, int64_t dtypeEnum);794 int64_t numEntries, int64_t dtypeEnum);
@@ -778,7 +803,20 @@ public:
778 const at::Tensor &sendCounts, const at::Tensor &recvCounts,803 const at::Tensor &sendCounts, const at::Tensor &recvCounts,
779 const at::Tensor &recvLocalEntry, const at::Tensor &numRecv);804 const at::Tensor &recvLocalEntry, const at::Tensor &numRecv);
780 805 
781- bool IsWithGrad() const { return withGrad_; }806+ // Stateless static method for training backward (graph-mode compatible).
807+ // Outputs: gradUnique [maxR, H], uniqueLocalEntry [maxR], numUnique [1] (NOT narrowed).
808+ // Caller is responsible for narrowing by numUnique.item() outside the graph.
809+ using EngramFetchGradOutput = std::tuple<at::Tensor, at::Tensor, at::Tensor>;
810+ static EngramFetchGradOutput EngramFetchGrad(const at::Tensor &context, const at::Tensor &gradFetched,
811+ const at::Tensor &perm, const at::Tensor &sendCounts,
812+ const at::Tensor &recvCounts, const at::Tensor &recvLocalEntry,
813+ const at::Tensor &numRecv, int64_t numEntries, int64_t commBufferSize,
814+ int64_t numMaxTokensPerRank, int64_t rankSize);
815+ 
816+ bool IsWithGrad() const
817+ {
818+ return withGrad_;
819+ }
782 820 
783 static int64_t GetEngramStorageSizeHint(int64_t numEntries, int64_t hiddenSize,821 static int64_t GetEngramStorageSizeHint(int64_t numEntries, int64_t hiddenSize,
784 at::ScalarType dtype = at::kBFloat16);822 at::ScalarType dtype = at::kBFloat16);
@@ -1062,6 +1100,29 @@ std::tuple<at::Tensor, at::Tensor> ElasticBuffer::EngramFetchGrad(const at::Tens
1062 return {gradUnique, uniqueLocalEntry};1100 return {gradUnique, uniqueLocalEntry};
1063}1101}
1064 1102 
1103+// EngramFetchGrad - stateless static method for training backward (graph-mode compatible).
1104+ElasticBuffer::EngramFetchGradOutput ElasticBuffer::EngramFetchGrad(
1105+ const at::Tensor &context, const at::Tensor &gradFetched, const at::Tensor &perm, const at::Tensor &sendCounts,
1106+ const at::Tensor &recvCounts, const at::Tensor &recvLocalEntry, const at::Tensor &numRecv, int64_t numEntries,
1107+ int64_t commBufferSize, int64_t numMaxTokensPerRank, int64_t rankSize)
1108+{
1109+ int64_t hidden = gradFetched.size(1);
1110+ TORCH_CHECK(rankSize > 0 && numMaxTokensPerRank <= INT64_MAX / rankSize,
1111+ "numMaxTokensPerRank * rankSize overflow, got numMaxTokensPerRank=", numMaxTokensPerRank,
1112+ ", rankSize=", rankSize);
1113+ int64_t maxR = numMaxTokensPerRank * rankSize;
1114+ 
1115+ auto gradUnique =
1116+ at::empty({maxR, hidden}, at::TensorOptions().dtype(gradFetched.dtype()).device(gradFetched.device()));
1117+ auto uniqueLocalEntry = at::empty({maxR}, at::TensorOptions().dtype(at::kInt).device(gradFetched.device()));
1118+ auto numUnique = at::empty({1}, at::TensorOptions().dtype(at::kInt).device(gradFetched.device()));
1119+ 
1120+ ACLNN_CMD(aclnnEngramFetchGrad, context, gradFetched, perm, sendCounts, recvCounts, recvLocalEntry, numRecv,
1121+ gradUnique, uniqueLocalEntry, numUnique, numEntries, commBufferSize);
1122+ 
1123+ return std::make_tuple(gradUnique, uniqueLocalEntry, numUnique);
1124+}
1125+ 
1065// EngramBarrier - cross-rank synchronization1126// EngramBarrier - cross-rank synchronization
1066void ElasticBuffer::EngramBarrier(bool useCommStream, bool withCpuSync)1127void ElasticBuffer::EngramBarrier(bool useCommStream, bool withCpuSync)
1067{1128{
@@ -1179,7 +1240,10 @@ public:
1179 }1240 }
1180 }1241 }
1181 1242 
1182- void Reset() { *reinterpret_cast<volatile int64_t *>(hostPtr_) = -1; }1243+ void Reset()
1244+ {
1245+ *reinterpret_cast<volatile int64_t *>(hostPtr_) = -1;
1246+ }
1183 1247 
1184 int64_t SpinWait()1248 int64_t SpinWait()
1185 {1249 {
@@ -1191,9 +1255,15 @@ public:
1191 }1255 }
1192 }1256 }
1193 1257 
1194- uintptr_t DevicePtr() const { return reinterpret_cast<uintptr_t>(devPtr_); }1258+ uintptr_t DevicePtr() const
1259+ {
1260+ return reinterpret_cast<uintptr_t>(devPtr_);
1261+ }
1195 1262 
1196- uintptr_t HostPtr() const { return reinterpret_cast<uintptr_t>(hostPtr_); }1263+ uintptr_t HostPtr() const
1264+ {
1265+ return reinterpret_cast<uintptr_t>(hostPtr_);
1266+ }
1197 1267 
1198private:1268private:
1199 void *hostPtr_ = nullptr;1269 void *hostPtr_ = nullptr;
@@ -1371,10 +1441,24 @@ PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
1371 pybind11::arg("rank_size"))1441 pybind11::arg("rank_size"))
1372 .def_static("engram_fetch_wait", &Mc2Api::ElasticBuffer::EngramFetchWait, pybind11::arg("context"),1442 .def_static("engram_fetch_wait", &Mc2Api::ElasticBuffer::EngramFetchWait, pybind11::arg("context"),
1373 pybind11::arg("fetched"))1443 pybind11::arg("fetched"))
1374- .def("engram_fetch_grad", &Mc2Api::ElasticBuffer::EngramFetchGrad, pybind11::arg("gradFetched").noconvert(),1444+ .def("engram_fetch_grad",
1375- pybind11::arg("perm").noconvert(), pybind11::arg("sendCounts").noconvert(),1445+ static_cast<std::tuple<at::Tensor, at::Tensor> (Mc2Api::ElasticBuffer::*)(
1376- pybind11::arg("recvCounts").noconvert(), pybind11::arg("recvLocalEntry").noconvert(),1446+ const at::Tensor &, const at::Tensor &, const at::Tensor &, const at::Tensor &, const at::Tensor &,
1377- pybind11::arg("numRecv").noconvert())1447+ const at::Tensor &)>(&Mc2Api::ElasticBuffer::EngramFetchGrad),
1448+ pybind11::arg("gradFetched").noconvert(), pybind11::arg("perm").noconvert(),
1449+ pybind11::arg("sendCounts").noconvert(), pybind11::arg("recvCounts").noconvert(),
1450+ pybind11::arg("recvLocalEntry").noconvert(), pybind11::arg("numRecv").noconvert())
1451+ .def_static(
1452+ "engram_fetch_grad_op",
1453+ static_cast<Mc2Api::ElasticBuffer::EngramFetchGradOutput (*)(
1454+ const at::Tensor &, const at::Tensor &, const at::Tensor &, const at::Tensor &, const at::Tensor &,
1455+ const at::Tensor &, const at::Tensor &, int64_t, int64_t, int64_t, int64_t)>(
1456+ &Mc2Api::ElasticBuffer::EngramFetchGrad),
1457+ pybind11::arg("context"), pybind11::arg("gradFetched").noconvert(), pybind11::arg("perm").noconvert(),
1458+ pybind11::arg("sendCounts").noconvert(), pybind11::arg("recvCounts").noconvert(),
1459+ pybind11::arg("recvLocalEntry").noconvert(), pybind11::arg("numRecv").noconvert(),
1460+ pybind11::arg("numEntries"), pybind11::arg("commBufferSize"), pybind11::arg("numMaxTokensPerRank"),
1461+ pybind11::arg("rankSize"))
1378 .def("engram_barrier", &Mc2Api::ElasticBuffer::EngramBarrier, pybind11::arg("useCommStream") = true,1462 .def("engram_barrier", &Mc2Api::ElasticBuffer::EngramBarrier, pybind11::arg("useCommStream") = true,
1379 pybind11::arg("withCpuSync") = false)1463 pybind11::arg("withCpuSync") = false)
1380 .def("destroy", &Mc2Api::ElasticBuffer::Destroy)1464 .def("destroy", &Mc2Api::ElasticBuffer::Destroy)
@@ -71,6 +71,10 @@ class ElasticBufferOpBuilder(OpBuilder):
71 "int num_max_tokens_per_rank, int comm_buffer_size, int rank_size) "71 "int num_max_tokens_per_rank, int comm_buffer_size, int rank_size) "
72 "-> (Tensor, Tensor, Tensor, Tensor, Tensor, Tensor)",72 "-> (Tensor, Tensor, Tensor, Tensor, Tensor, Tensor)",
73 "engram_fetch_wait(Tensor context, Tensor fetched) -> Tensor",73 "engram_fetch_wait(Tensor context, Tensor fetched) -> Tensor",
74+ "engram_fetch_grad(Tensor context, Tensor grad_fetched, Tensor perm, Tensor send_counts, "
75+ "Tensor recv_counts, Tensor recv_local_entry, Tensor num_recv, int num_entries, "
76+ "int comm_buffer_size, int num_max_tokens_per_rank, int rank_size) "
77+ "-> (Tensor, Tensor, Tensor)",
74 ]78 ]
75 79 
76 def register_meta(self):80 def register_meta(self):
@@ -124,6 +128,34 @@ class ElasticBufferOpBuilder(OpBuilder):
124 def engram_fetch_wait_meta(context, fetched):128 def engram_fetch_wait_meta(context, fetched):
125 return torch.empty_like(fetched, device="meta")129 return torch.empty_like(fetched, device="meta")
126 130 
131+ @impl(get_as_library(), "engram_fetch_grad", "Meta")
132+ def engram_fetch_grad_meta(
133+ context,
134+ grad_fetched,
135+ perm,
136+ send_counts,
137+ recv_counts,
138+ recv_local_entry,
139+ num_recv,
140+ num_entries,
141+ comm_buffer_size,
142+ num_max_tokens_per_rank,
143+ rank_size,
144+ ):
145+ # Outputs are NOT narrowed; full maxR rows. Caller narrows by num_unique.
146+ num_max_tokens_per_rank = (
147+ 1 if num_max_tokens_per_rank <= 0 else num_max_tokens_per_rank
148+ )
149+ max_r = num_max_tokens_per_rank * rank_size
150+ grad_unique = torch.empty(
151+ (max_r, grad_fetched.size(1)),
152+ dtype=grad_fetched.dtype,
153+ device="meta",
154+ )
155+ unique_local_entry = torch.empty((max_r,), dtype=torch.int32, device="meta")
156+ num_unique = torch.empty((1,), dtype=torch.int32, device="meta")
157+ return (grad_unique, unique_local_entry, num_unique)
158+ 
127 def extra_ldflags(self):159 def extra_ldflags(self):
128 """Extra link flags for HCCL and ACL libraries."""160 """Extra link flags for HCCL and ACL libraries."""
129 flags = super().extra_ldflags()161 flags = super().extra_ldflags()
@@ -167,6 +199,36 @@ def engram_fetch_wait(context, fetched):
167 return op_module.ElasticBuffer.engram_fetch_wait(context, fetched)199 return op_module.ElasticBuffer.engram_fetch_wait(context, fetched)
168 200 
169 201 
202+@impl(get_as_library(), "engram_fetch_grad", "PrivateUse1")
203+def engram_fetch_grad(
204+ context,
205+ grad_fetched,
206+ perm,
207+ send_counts,
208+ recv_counts,
209+ recv_local_entry,
210+ num_recv,
211+ num_entries,
212+ comm_buffer_size,
213+ num_max_tokens_per_rank,
214+ rank_size,
215+):
216+ op_module = _elastic_buffer_op_builder.load()
217+ return op_module.ElasticBuffer.engram_fetch_grad_op(
218+ context,
219+ grad_fetched,
220+ perm,
221+ send_counts,
222+ recv_counts,
223+ recv_local_entry,
224+ num_recv,
225+ num_entries,
226+ comm_buffer_size,
227+ num_max_tokens_per_rank,
228+ rank_size,
229+ )
230+ 
231+ 
170def _inline_align(value: int, base: int) -> int:232def _inline_align(value: int, base: int) -> int:
171 return (value + base - 1) // base * base233 return (value + base - 1) // base * base
172 234 
@@ -745,14 +807,31 @@ class ElasticBuffer:
745 f"fetch_ctx.num_recv length ({fetch_ctx.num_recv.size(0)}) must be 1"807 f"fetch_ctx.num_recv length ({fetch_ctx.num_recv.size(0)}) must be 1"
746 ),808 ),
747 )809 )
748- return self._runtime.engram_fetch_grad(810+ grad_unique_full, unique_local_entry_full, num_unique = (
749- grad_fetched,811+ torch.ops.cann_ops_transformer.engram_fetch_grad(
750- fetch_ctx.perm,812+ self._engram_context_tensor,
751- fetch_ctx.send_counts,813+ grad_fetched,
752- fetch_ctx.recv_counts,814+ fetch_ctx.perm,
753- fetch_ctx.recv_local_entry,815+ fetch_ctx.send_counts,
754- fetch_ctx.num_recv,816+ fetch_ctx.recv_counts,
817+ fetch_ctx.recv_local_entry,
818+ fetch_ctx.num_recv,
819+ self._engram_num_entries,
820+ self._comm_buffer_size,
821+ self._num_max_tokens_per_rank,
822+ self._rank_size,
823+ )
755 )824 )
825+ # Narrow to actualK rows outside the graph (.item() syncs; not graph-safe).
826+ actual_k = int(num_unique.item())
827+ max_r = self._num_max_tokens_per_rank * self._rank_size
828+ if actual_k < max_r:
829+ grad_unique = grad_unique_full.narrow(0, 0, actual_k)
830+ unique_local_entry = unique_local_entry_full.narrow(0, 0, actual_k)
831+ else:
832+ grad_unique = grad_unique_full
833+ unique_local_entry = unique_local_entry_full
834+ return grad_unique, unique_local_entry
756 835 
757 def dispatch(836 def dispatch(
758 self,837 self,
@@ -197,8 +197,8 @@ __aicore__ inline void EngramFetchTrainArch35::DrainChecked(uint64_t handle)
197__aicore__ inline void EngramFetchTrainArch35::TimeoutCheck(uint64_t startTime)197__aicore__ inline void EngramFetchTrainArch35::TimeoutCheck(uint64_t startTime)
198{198{
199 uint64_t nowUs = static_cast<uint64_t>(AscendC::GetSystemCycle()) / ENGRAM_CYCLES_PER_US;199 uint64_t nowUs = static_cast<uint64_t>(AscendC::GetSystemCycle()) / ENGRAM_CYCLES_PER_US;
200- ascendc_assert((nowUs - startTime) < ENGRAM_TIMEOUT_US,200+ ascendc_assert((nowUs - startTime) < ENGRAM_TIMEOUT_US, "timeout, rankId=%u, aivId=%u, elapsed=%llu us", rankId_,
201- "timeout, rankId=%u, aivId=%u, elapsed=%llu us", rankId_, aivId_, nowUs - startTime);201+ aivId_, nowUs - startTime);
202}202}
203 203 
204__aicore__ inline GM_ADDR EngramFetchTrainArch35::GetRemoteWinAddr(uint32_t dstRank, uint64_t offset)204__aicore__ inline GM_ADDR EngramFetchTrainArch35::GetRemoteWinAddr(uint32_t dstRank, uint64_t offset)
@@ -208,7 +208,10 @@ __aicore__ inline GM_ADDR EngramFetchTrainArch35::GetRemoteWinAddr(uint32_t dstR
208 208 
209__aicore__ inline uint64_t EngramFetchTrainArch35::GetCommHandle(uint32_t dstRank)209__aicore__ inline uint64_t EngramFetchTrainArch35::GetCommHandle(uint32_t dstRank)
210{210{
211- uint32_t channelIdx = isSender_ ? SENDER_CHANNEL_IDX : RECEIVER_CHANNEL_IDX;211+ uint32_t channelIdx = aivId_ / numRanks_ + 1U;
212+ if (channelIdx >= channelsPerRank_) {
213+ channelIdx = 1U;
214+ }
212 return ctxPtr_->hcommHandle[dstRank * channelsPerRank_ + channelIdx];215 return ctxPtr_->hcommHandle[dstRank * channelsPerRank_ + channelIdx];
213}216}
214 217 
@@ -1049,9 +1052,9 @@ __aicore__ inline void EngramFetchTrainArch35::LocalReadTable()
1049 if (globalIdx < 0) {1052 if (globalIdx < 0) {
1050 continue;1053 continue;
1051 }1054 }
1052- uint32_t localEntryIdx = static_cast<uint32_t>(1055+ uint32_t localEntryIdx =
1053- static_cast<int64_t>(globalIdx) -1056+ static_cast<uint32_t>(static_cast<int64_t>(globalIdx) -
1054- static_cast<int64_t>(rankId_) * static_cast<int64_t>(numEntriesPerRank_));1057+ static_cast<int64_t>(rankId_) * static_cast<int64_t>(numEntriesPerRank_));
1055 if (localEntryIdx >= static_cast<uint32_t>(numEntriesPerRank_)) {1058 if (localEntryIdx >= static_cast<uint32_t>(numEntriesPerRank_)) {
1056 continue;1059 continue;
1057 }1060 }
@@ -45,7 +45,7 @@ struct EngramCommContext {
45 uint32_t rankId;45 uint32_t rankId;
46 uint32_t rankSize;46 uint32_t rankSize;
47 uint64_t commBuffer[HCCL_MAX_RANK_SIZE];47 uint64_t commBuffer[HCCL_MAX_RANK_SIZE];
48- uint64_t hcommHandle[HCCL_MAX_RANK_SIZE];48+ uint64_t hcommHandle[HCCL_MAX_RANK_SIZE * 2];
49 uint32_t channelsPerRank;49 uint32_t channelsPerRank;
50};50};
51 51 
@@ -24,49 +24,49 @@ __aicore__ inline void SyncFunc(AscendC::TPipe &pipe)
24 AscendC::WaitFlag<event>(eventID);24 AscendC::WaitFlag<event>(eventID);
25}25}
26 26 
27+constexpr uint32_t MAX_BLOCK_BYTES = 65535U;
28+ 
27class EngramFetchGradUnique {29class EngramFetchGradUnique {
28public:30public:
29 __aicore__ inline EngramFetchGradUnique() = default;31 __aicore__ inline EngramFetchGradUnique() = default;
30 32 
31- __aicore__ inline void Init(33+ __aicore__ inline void Init(uint32_t aivId, uint32_t totalBlocks, uint32_t rankId, uint32_t numRanks,
32- uint32_t aivId, uint32_t totalBlocks, uint32_t rankId, uint32_t numRanks,34+ int32_t numEntriesPerRank, int64_t hiddenDim, int64_t hiddenBytes, int32_t inputDtype,
33- int32_t numEntriesPerRank, int64_t hiddenDim, int64_t hiddenBytes,35+ int32_t outputDtype, AscendC::TPipe *pipe, AscendC::TBuf<> &pingBuf,
34- int32_t inputDtype, int32_t outputDtype, AscendC::TPipe *pipe,36+ AscendC::TBuf<> &pongBuf, AscendC::TBuf<> &indicesBuf, AscendC::TBuf<> &tempBuf,
35- AscendC::TBuf<> &pingBuf, AscendC::TBuf<> &pongBuf, AscendC::TBuf<> &indicesBuf,37+ AscendC::TBuf<> &statusBuf, AscendC::TBuf<> &gradSumBuf);
36- AscendC::TBuf<> &tempBuf, AscendC::TBuf<> &statusBuf, AscendC::TBuf<> &gradSumBuf);
37 38 
38- __aicore__ inline void Run(uint32_t numRecv,39+ __aicore__ inline void Run(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM,
39- GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR numUniqueOutGM,40+ GM_ADDR numUniqueOutGM, GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM,
40- GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,41+ GM_ADDR recvGradGM, GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM);
41- GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM);
42 42 
43 __aicore__ inline void WriteNumUniqueZero(GM_ADDR numUniqueOutGM);43 __aicore__ inline void WriteNumUniqueZero(GM_ADDR numUniqueOutGM);
44 44 
45private:45private:
46 __aicore__ inline void ZeroGradUnique(uint32_t numRecv, GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM);46 __aicore__ inline void ZeroGradUnique(uint32_t numRecv, GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM);
47- __aicore__ inline void CountUniquesParallel(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM,47+ __aicore__ inline void CountUniquesParallel(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM, GM_ADDR coreStartGM,
48- GM_ADDR coreStartGM, GM_ADDR segCountGM);48+ GM_ADDR segCountGM);
49 __aicore__ inline void FixCoreStartForSkippedCores(GM_ADDR coreStartGM, GM_ADDR segCountGM);49 __aicore__ inline void FixCoreStartForSkippedCores(GM_ADDR coreStartGM, GM_ADDR segCountGM);
50 __aicore__ inline void ScatterAddAtomicParallel(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM,50 __aicore__ inline void ScatterAddAtomicParallel(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM,
51 GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,51 GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,
52- GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,52+ GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM, GM_ADDR coreStartGM,
53- GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM);53+ GM_ADDR segCountGM, GM_ADDR sortCompanionGM);
54- __aicore__ inline void CastGradUniqueToOutput(GM_ADDR segCountGM, GM_ADDR numUniqueOutGM,54+ __aicore__ inline void CastGradUniqueToOutput(GM_ADDR segCountGM, GM_ADDR numUniqueOutGM, GM_ADDR gradUniqueOutGM,
55- GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM);55+ GM_ADDR gradUniqueFp32GM);
56 __aicore__ inline void LoadCoreRange(uint32_t numRecv, GM_ADDR coreStartGM, uint32_t &start, uint32_t &end);56 __aicore__ inline void LoadCoreRange(uint32_t numRecv, GM_ADDR coreStartGM, uint32_t &start, uint32_t &end);
57 __aicore__ inline int32_t ComputePreCoreOffset(GM_ADDR segCountGM);57 __aicore__ inline int32_t ComputePreCoreOffset(GM_ADDR segCountGM);
58- __aicore__ inline uint32_t ProcessScatterBatch(58+ __aicore__ inline uint32_t ProcessScatterBatch(uint32_t cur, uint32_t end, int32_t &runningOffset,
59- uint32_t cur, uint32_t end, int32_t &runningOffset, int32_t &runningUniqueOffset,59+ int32_t &runningUniqueOffset, int32_t &prevEntry,
60- int32_t &prevEntry, bool &isFirstElement,60+ bool &isFirstElement, GM_ADDR recvLocalEntryOutGM,
61- GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,61+ GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,
62- GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM, GM_ADDR sortCompanionGM);62+ GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,
63- __aicore__ inline void ScatterGradSubBatch(uint32_t subStart, uint32_t subLen,63+ GM_ADDR sortCompanionGM);
64- GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM);64+ __aicore__ inline void ScatterGradSubBatch(uint32_t subStart, uint32_t subLen, GM_ADDR gradUniqueOutGM,
65+ GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM);
65 __aicore__ inline void AtomicAddGrad(AscendC::GlobalTensor<float> &atomicDstGM, AscendC::LocalTensor<float> &srcT,66 __aicore__ inline void AtomicAddGrad(AscendC::GlobalTensor<float> &atomicDstGM, AscendC::LocalTensor<float> &srcT,
66 uint32_t subStart, uint32_t subLen);67 uint32_t subStart, uint32_t subLen);
67 __aicore__ inline uint32_t ProcessBatchUnique(uint32_t cur, uint32_t batchLen, int32_t runningOffset,68 __aicore__ inline uint32_t ProcessBatchUnique(uint32_t cur, uint32_t batchLen, int32_t runningOffset,
68- int32_t &prevEntry, bool &isFirstElement,69+ int32_t &prevEntry, bool &isFirstElement, int32_t &inclusiveSum,
69- int32_t &inclusiveSum,
70 GM_ADDR recvLocalEntryOutGM, GM_ADDR sortCompanionGM);70 GM_ADDR recvLocalEntryOutGM, GM_ADDR sortCompanionGM);
71 __aicore__ inline void WriteBatchUnique(uint32_t tileUniqueCnt, int32_t &runningUniqueOffset,71 __aicore__ inline void WriteBatchUnique(uint32_t tileUniqueCnt, int32_t &runningUniqueOffset,
72 GM_ADDR uniqueLocalEntryOutGM);72 GM_ADDR uniqueLocalEntryOutGM);
@@ -89,12 +89,13 @@ private:
89 AscendC::TBuf<> *gradSumBuf_{nullptr};89 AscendC::TBuf<> *gradSumBuf_{nullptr};
90};90};
91 91 
92-__aicore__ inline void EngramFetchGradUnique::Init(92+__aicore__ inline void EngramFetchGradUnique::Init(uint32_t aivId, uint32_t totalBlocks, uint32_t rankId,
93- uint32_t aivId, uint32_t totalBlocks, uint32_t rankId, uint32_t numRanks,93+ uint32_t numRanks, int32_t numEntriesPerRank, int64_t hiddenDim,
94- int32_t numEntriesPerRank, int64_t hiddenDim, int64_t hiddenBytes,94+ int64_t hiddenBytes, int32_t inputDtype, int32_t outputDtype,
95- int32_t inputDtype, int32_t outputDtype, AscendC::TPipe *pipe,95+ AscendC::TPipe *pipe, AscendC::TBuf<> &pingBuf,
96- AscendC::TBuf<> &pingBuf, AscendC::TBuf<> &pongBuf, AscendC::TBuf<> &indicesBuf,96+ AscendC::TBuf<> &pongBuf, AscendC::TBuf<> &indicesBuf,
97- AscendC::TBuf<> &tempBuf, AscendC::TBuf<> &statusBuf, AscendC::TBuf<> &gradSumBuf)97+ AscendC::TBuf<> &tempBuf, AscendC::TBuf<> &statusBuf,
98+ AscendC::TBuf<> &gradSumBuf)
98{99{
99 aivId_ = aivId;100 aivId_ = aivId;
100 totalBlocks_ = totalBlocks;101 totalBlocks_ = totalBlocks;
@@ -114,11 +115,10 @@ __aicore__ inline void EngramFetchGradUnique::Init(
114 gradSumBuf_ = &gradSumBuf;115 gradSumBuf_ = &gradSumBuf;
115}116}
116 117 
117-__aicore__ inline void EngramFetchGradUnique::Run(118+__aicore__ inline void EngramFetchGradUnique::Run(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM,
118- uint32_t numRecv,119+ GM_ADDR uniqueLocalEntryOutGM, GM_ADDR numUniqueOutGM,
119- GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR numUniqueOutGM,120+ GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,
120- GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,121+ GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM)
121- GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM)
122{122{
123 ZeroGradUnique(numRecv, gradUniqueOutGM, gradUniqueFp32GM);123 ZeroGradUnique(numRecv, gradUniqueOutGM, gradUniqueFp32GM);
124 CountUniquesParallel(numRecv, recvLocalEntryOutGM, coreStartGM, segCountGM);124 CountUniquesParallel(numRecv, recvLocalEntryOutGM, coreStartGM, segCountGM);
@@ -127,9 +127,8 @@ __aicore__ inline void EngramFetchGradUnique::Run(
127 FixCoreStartForSkippedCores(coreStartGM, segCountGM);127 FixCoreStartForSkippedCores(coreStartGM, segCountGM);
128 AscendC::SyncAll<true>();128 AscendC::SyncAll<true>();
129 129 
130- ScatterAddAtomicParallel(numRecv, recvLocalEntryOutGM, uniqueLocalEntryOutGM,130+ ScatterAddAtomicParallel(numRecv, recvLocalEntryOutGM, uniqueLocalEntryOutGM, gradUniqueOutGM, gradUniqueFp32GM,
131- gradUniqueOutGM, gradUniqueFp32GM, recvGradGM,131+ recvGradGM, coreStartGM, segCountGM, sortCompanionGM);
132- coreStartGM, segCountGM, sortCompanionGM);
133 AscendC::SyncAll<true>();132 AscendC::SyncAll<true>();
134 133 
135 CastGradUniqueToOutput(segCountGM, numUniqueOutGM, gradUniqueOutGM, gradUniqueFp32GM);134 CastGradUniqueToOutput(segCountGM, numUniqueOutGM, gradUniqueOutGM, gradUniqueFp32GM);
@@ -168,6 +167,10 @@ __aicore__ inline void EngramFetchGradUnique::ZeroGradUnique(uint32_t numRecv, G
168 if (start < end) {167 if (start < end) {
169 AscendC::LocalTensor<float> zeroBuf = pongBuf_->Get<float>();168 AscendC::LocalTensor<float> zeroBuf = pongBuf_->Get<float>();
170 uint32_t tileFloats = Mc2Kernel::TILE_BYTES / sizeof(float);169 uint32_t tileFloats = Mc2Kernel::TILE_BYTES / sizeof(float);
170+ constexpr uint32_t maxBlockFloats = MAX_BLOCK_BYTES / sizeof(float);
171+ if (tileFloats > maxBlockFloats) {
172+ tileFloats = maxBlockFloats;
173+ }
171 AscendC::Duplicate<float>(zeroBuf, 0.0f, tileFloats);174 AscendC::Duplicate<float>(zeroBuf, 0.0f, tileFloats);
172 SyncFunc<AscendC::HardEvent::V_MTE3>(*pipe_);175 SyncFunc<AscendC::HardEvent::V_MTE3>(*pipe_);
173 176 
@@ -186,8 +189,8 @@ __aicore__ inline void EngramFetchGradUnique::ZeroGradUnique(uint32_t numRecv, G
186 }189 }
187}190}
188 191 
189-__aicore__ inline void EngramFetchGradUnique::CountUniquesParallel(192+__aicore__ inline void EngramFetchGradUnique::CountUniquesParallel(uint32_t numRecv, GM_ADDR recvLocalEntryOutGM,
190- uint32_t numRecv, GM_ADDR recvLocalEntryOutGM, GM_ADDR coreStartGM, GM_ADDR segCountGM)193+ GM_ADDR coreStartGM, GM_ADDR segCountGM)
191{194{
192 uint32_t chunk = (numRecv + totalBlocks_ - 1U) / totalBlocks_;195 uint32_t chunk = (numRecv + totalBlocks_ - 1U) / totalBlocks_;
193 uint32_t rawStart = aivId_ * chunk;196 uint32_t rawStart = aivId_ * chunk;
@@ -307,8 +310,8 @@ __aicore__ inline void EngramFetchGradUnique::FixCoreStartForSkippedCores(GM_ADD
307 }310 }
308}311}
309 312 
310-__aicore__ inline void EngramFetchGradUnique::LoadCoreRange(uint32_t numRecv, GM_ADDR coreStartGM,313+__aicore__ inline void EngramFetchGradUnique::LoadCoreRange(uint32_t numRecv, GM_ADDR coreStartGM, uint32_t &start,
311- uint32_t &start, uint32_t &end)314+ uint32_t &end)
312{315{
313 AscendC::GlobalTensor<int32_t> coreStartGM_;316 AscendC::GlobalTensor<int32_t> coreStartGM_;
314 coreStartGM_.SetGlobalBuffer((__gm__ int32_t *)coreStartGM);317 coreStartGM_.SetGlobalBuffer((__gm__ int32_t *)coreStartGM);
@@ -351,12 +354,12 @@ __aicore__ inline int32_t EngramFetchGradUnique::ComputePreCoreOffset(GM_ADDR se
351 return preCoreOffset;354 return preCoreOffset;
352}355}
353 356 
354-__aicore__ inline void EngramFetchGradUnique::AtomicAddGrad(357+__aicore__ inline void EngramFetchGradUnique::AtomicAddGrad(AscendC::GlobalTensor<float> &atomicDstGM,
355- AscendC::GlobalTensor<float> &atomicDstGM, AscendC::LocalTensor<float> &srcT, uint32_t subStart, uint32_t subLen)358+ AscendC::LocalTensor<float> &srcT, uint32_t subStart,
359+ uint32_t subLen)
356{360{
357 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();361 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();
358 AscendC::LocalTensor<int32_t> compactIdxBuf = pingInt32[3 * Mc2Kernel::ENTRY_BATCH_CAP];362 AscendC::LocalTensor<int32_t> compactIdxBuf = pingInt32[3 * Mc2Kernel::ENTRY_BATCH_CAP];
359- constexpr uint32_t MAX_BLOCK_BYTES = 65535U;
360 uint32_t totalBytes = static_cast<uint32_t>(hiddenDim_) * sizeof(float);363 uint32_t totalBytes = static_cast<uint32_t>(hiddenDim_) * sizeof(float);
361 uint32_t numBlocks = (totalBytes + MAX_BLOCK_BYTES - 1U) / MAX_BLOCK_BYTES;364 uint32_t numBlocks = (totalBytes + MAX_BLOCK_BYTES - 1U) / MAX_BLOCK_BYTES;
362 for (uint32_t j = 0; j < subLen; j++) {365 for (uint32_t j = 0; j < subLen; j++) {
@@ -366,8 +369,7 @@ __aicore__ inline void EngramFetchGradUnique::AtomicAddGrad(
366 uint32_t byteOffset = b * MAX_BLOCK_BYTES;369 uint32_t byteOffset = b * MAX_BLOCK_BYTES;
367 uint32_t elemOffset = byteOffset / sizeof(float);370 uint32_t elemOffset = byteOffset / sizeof(float);
368 uint32_t remaining = totalBytes - byteOffset;371 uint32_t remaining = totalBytes - byteOffset;
369- uint16_t blkBytes = static_cast<uint16_t>(372+ uint16_t blkBytes = static_cast<uint16_t>(remaining > MAX_BLOCK_BYTES ? MAX_BLOCK_BYTES : remaining);
370- remaining > MAX_BLOCK_BYTES ? MAX_BLOCK_BYTES : remaining);
371 AscendC::DataCopyParams atomicParams{1U, blkBytes, 0U, 0U};373 AscendC::DataCopyParams atomicParams{1U, blkBytes, 0U, 0U};
372 AscendC::DataCopyPad(atomicDstGM[static_cast<uint64_t>(compactIdx) * hiddenDim_ + elemOffset],374 AscendC::DataCopyPad(atomicDstGM[static_cast<uint64_t>(compactIdx) * hiddenDim_ + elemOffset],
373 srcT[static_cast<uint32_t>(j) * static_cast<uint32_t>(hiddenDim_) + elemOffset],375 srcT[static_cast<uint32_t>(j) * static_cast<uint32_t>(hiddenDim_) + elemOffset],
@@ -377,8 +379,9 @@ __aicore__ inline void EngramFetchGradUnique::AtomicAddGrad(
377 }379 }
378}380}
379 381 
380-__aicore__ inline void EngramFetchGradUnique::ScatterGradSubBatch(382+__aicore__ inline void EngramFetchGradUnique::ScatterGradSubBatch(uint32_t subStart, uint32_t subLen,
381- uint32_t subStart, uint32_t subLen, GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM)383+ GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM,
384+ GM_ADDR recvGradGM)
382{385{
383 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();386 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();
384 AscendC::LocalTensor<int32_t> recvIdxBuf = pingInt32[2 * Mc2Kernel::ENTRY_BATCH_CAP];387 AscendC::LocalTensor<int32_t> recvIdxBuf = pingInt32[2 * Mc2Kernel::ENTRY_BATCH_CAP];
@@ -395,8 +398,8 @@ __aicore__ inline void EngramFetchGradUnique::ScatterGradSubBatch(
395 AscendC::DataCopyExtParams gradParams{1U, static_cast<uint32_t>(hiddenBytes_), 0U, 0U, 0U};398 AscendC::DataCopyExtParams gradParams{1U, static_cast<uint32_t>(hiddenBytes_), 0U, 0U, 0U};
396 AscendC::GlobalTensor<uint8_t> gradSrcGM;399 AscendC::GlobalTensor<uint8_t> gradSrcGM;
397 gradSrcGM.SetGlobalBuffer((__gm__ uint8_t *)gradAddr);400 gradSrcGM.SetGlobalBuffer((__gm__ uint8_t *)gradAddr);
398- AscendC::DataCopyPad(gradRaw[static_cast<uint32_t>(j) * static_cast<uint32_t>(hiddenBytes_)],401+ AscendC::DataCopyPad(gradRaw[static_cast<uint32_t>(j) * static_cast<uint32_t>(hiddenBytes_)], gradSrcGM,
399- gradSrcGM, gradParams, gradPad);402+ gradParams, gradPad);
400 }403 }
401 404 
402 if (inputDtype_ == Mc2Kernel::ENGRAM_DT_FLOAT) {405 if (inputDtype_ == Mc2Kernel::ENGRAM_DT_FLOAT) {
@@ -421,10 +424,11 @@ __aicore__ inline void EngramFetchGradUnique::ScatterGradSubBatch(
421 }424 }
422}425}
423 426 
424-__aicore__ inline uint32_t EngramFetchGradUnique::ProcessBatchUnique(427+__aicore__ inline uint32_t EngramFetchGradUnique::ProcessBatchUnique(uint32_t cur, uint32_t batchLen,
425- uint32_t cur, uint32_t batchLen, int32_t runningOffset,428+ int32_t runningOffset, int32_t &prevEntry,
426- int32_t &prevEntry, bool &isFirstElement, int32_t &inclusiveSum,429+ bool &isFirstElement, int32_t &inclusiveSum,
427- GM_ADDR recvLocalEntryOutGM, GM_ADDR sortCompanionGM)430+ GM_ADDR recvLocalEntryOutGM,
431+ GM_ADDR sortCompanionGM)
428{432{
429 AscendC::LocalTensor<int32_t> entryUb = indicesBuf_->Get<int32_t>();433 AscendC::LocalTensor<int32_t> entryUb = indicesBuf_->Get<int32_t>();
430 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();434 AscendC::LocalTensor<int32_t> pingInt32 = pingBuf_->Get<int32_t>();
@@ -476,9 +480,8 @@ __aicore__ inline void EngramFetchGradUnique::WriteBatchUnique(uint32_t tileUniq
476}480}
477 481 
478__aicore__ inline uint32_t EngramFetchGradUnique::ProcessScatterBatch(482__aicore__ inline uint32_t EngramFetchGradUnique::ProcessScatterBatch(
479- uint32_t cur, uint32_t end, int32_t &runningOffset, int32_t &runningUniqueOffset,483+ uint32_t cur, uint32_t end, int32_t &runningOffset, int32_t &runningUniqueOffset, int32_t &prevEntry,
480- int32_t &prevEntry, bool &isFirstElement,484+ bool &isFirstElement, GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,
481- GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,
482 GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM, GM_ADDR sortCompanionGM)485 GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM, GM_ADDR sortCompanionGM)
483{486{
484 uint32_t batchLen = end - cur;487 uint32_t batchLen = end - cur;
@@ -487,9 +490,8 @@ __aicore__ inline uint32_t EngramFetchGradUnique::ProcessScatterBatch(
487 }490 }
488 491 
489 int32_t inclusiveSum = 0;492 int32_t inclusiveSum = 0;
490- uint32_t tileUniqueCnt = ProcessBatchUnique(493+ uint32_t tileUniqueCnt = ProcessBatchUnique(cur, batchLen, runningOffset, prevEntry, isFirstElement, inclusiveSum,
491- cur, batchLen, runningOffset, prevEntry, isFirstElement, inclusiveSum,494+ recvLocalEntryOutGM, sortCompanionGM);
492- recvLocalEntryOutGM, sortCompanionGM);
493 495 
494 uint32_t maxGradPerBatch = Mc2Kernel::TILE_BYTES / static_cast<uint32_t>(hiddenBytes_);496 uint32_t maxGradPerBatch = Mc2Kernel::TILE_BYTES / static_cast<uint32_t>(hiddenBytes_);
495 if (maxGradPerBatch < 1U) {497 if (maxGradPerBatch < 1U) {
@@ -514,9 +516,8 @@ __aicore__ inline uint32_t EngramFetchGradUnique::ProcessScatterBatch(
514}516}
515 517 
516__aicore__ inline void EngramFetchGradUnique::ScatterAddAtomicParallel(518__aicore__ inline void EngramFetchGradUnique::ScatterAddAtomicParallel(
517- uint32_t numRecv, GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM,519+ uint32_t numRecv, GM_ADDR recvLocalEntryOutGM, GM_ADDR uniqueLocalEntryOutGM, GM_ADDR gradUniqueOutGM,
518- GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM,520+ GM_ADDR gradUniqueFp32GM, GM_ADDR recvGradGM, GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM)
519- GM_ADDR coreStartGM, GM_ADDR segCountGM, GM_ADDR sortCompanionGM)
520{521{
521 uint32_t start;522 uint32_t start;
522 uint32_t end;523 uint32_t end;
@@ -534,13 +535,13 @@ __aicore__ inline void EngramFetchGradUnique::ScatterAddAtomicParallel(
534 uint32_t cur = start;535 uint32_t cur = start;
535 while (cur < end) {536 while (cur < end) {
536 cur = ProcessScatterBatch(cur, end, runningOffset, runningUniqueOffset, prevEntry, isFirstElement,537 cur = ProcessScatterBatch(cur, end, runningOffset, runningUniqueOffset, prevEntry, isFirstElement,
537- recvLocalEntryOutGM, uniqueLocalEntryOutGM, gradUniqueOutGM,538+ recvLocalEntryOutGM, uniqueLocalEntryOutGM, gradUniqueOutGM, gradUniqueFp32GM,
538- gradUniqueFp32GM, recvGradGM, sortCompanionGM);539+ recvGradGM, sortCompanionGM);
539 }540 }
540}541}
541 542 
542-__aicore__ inline void EngramFetchGradUnique::CastGradUniqueToOutput(543+__aicore__ inline void EngramFetchGradUnique::CastGradUniqueToOutput(GM_ADDR segCountGM, GM_ADDR numUniqueOutGM,
543- GM_ADDR segCountGM, GM_ADDR numUniqueOutGM, GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM)544+ GM_ADDR gradUniqueOutGM, GM_ADDR gradUniqueFp32GM)
544{545{
545 AscendC::GlobalTensor<int32_t> segCountGM_;546 AscendC::GlobalTensor<int32_t> segCountGM_;
546 segCountGM_.SetGlobalBuffer((__gm__ int32_t *)segCountGM);547 segCountGM_.SetGlobalBuffer((__gm__ int32_t *)segCountGM);
@@ -20,13 +20,13 @@
20namespace Mc2Kernel {20namespace Mc2Kernel {
21constexpr uint32_t MAX_QP_SIZE = 1024U;21constexpr uint32_t MAX_QP_SIZE = 1024U;
22constexpr uint32_t UB_ALIGN = 32U;22constexpr uint32_t UB_ALIGN = 32U;
23-constexpr uint32_t TILE_BYTES = 32U * 1024U;23+constexpr uint32_t TILE_BYTES = 64U * 1024U;
24constexpr uint32_t HCOMM_INIT_SIZE = 512U;24constexpr uint32_t HCOMM_INIT_SIZE = 512U;
25constexpr int32_t BITS_PER_BYTE = 8;25constexpr int32_t BITS_PER_BYTE = 8;
26constexpr uint32_t ALIGNED_LEN_256 = 256U;26constexpr uint32_t ALIGNED_LEN_256 = 256U;
27 27 
28constexpr uint32_t STATE_OFFSET = 32U;28constexpr uint32_t STATE_OFFSET = 32U;
29-constexpr uint32_t NUM_SLOTS = 4U;29+constexpr uint32_t NUM_SLOTS = 8U;
30constexpr uint32_t SENDER_CHANNEL_IDX = 0U;30constexpr uint32_t SENDER_CHANNEL_IDX = 0U;
31constexpr uint32_t RECEIVER_CHANNEL_IDX = 1U;31constexpr uint32_t RECEIVER_CHANNEL_IDX = 1U;
32 32 
@@ -42,7 +42,7 @@ struct EngramCommContext {
42 uint32_t rankId;42 uint32_t rankId;
43 uint32_t rankSize;43 uint32_t rankSize;
44 uint64_t commBuffer[MAX_QP_SIZE];44 uint64_t commBuffer[MAX_QP_SIZE];
45- uint64_t hcommHandle[MAX_QP_SIZE];45+ uint64_t hcommHandle[MAX_QP_SIZE * 2];
46 uint32_t channelsPerRank;46 uint32_t channelsPerRank;
47};47};
48 48