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 "recursive_halvingdoubling_base.h"
12 :
13 : namespace hccl {
14 7 : RecursiveHalvingDoublingBase::RecursiveHalvingDoublingBase(const HcclDispatcher dispatcher)
15 : : AlgTemplateBase(dispatcher),
16 7 : blockSize_(0),
17 7 : part1Size_(0),
18 7 : round_(0)
19 7 : {}
20 :
21 7 : RecursiveHalvingDoublingBase::~RecursiveHalvingDoublingBase() {}
22 :
23 0 : HcclResult RecursiveHalvingDoublingBase::CalcPartOneSizeAndBlockSize(const u32 rankSize)
24 : {
25 0 : round_ = 0;
26 0 : u32 base = 1;
27 0 : const u32 minExponent = 1;
28 0 : while ((base << round_) <= rankSize) {
29 0 : round_++;
30 : }
31 0 : if (round_ >= minExponent) {
32 0 : round_ = round_ - minExponent;
33 : }
34 0 : blockSize_ = base << round_;
35 0 : part1Size_ = (rankSize - blockSize_) * 2; // 第一部分是rank数减block数乘2
36 0 : return HCCL_SUCCESS;
37 : }
38 :
39 0 : HcclResult RecursiveHalvingDoublingBase::BuildSubLinks(
40 : const std::vector<LINK>& links, std::vector<LINK>& subLinks, u32 rankSize) const
41 : {
42 0 : std::vector<LINK>::const_iterator iter = links.begin();
43 0 : subLinks.resize(blockSize_);
44 :
45 0 : for (u32 i = 0; i < rankSize; i++) {
46 0 : if (i < part1Size_ && (i % 2) == 1) { // 模2余1代表当前rank在part1的奇数位置上,不参与block内的建链
47 0 : continue;
48 0 : } else if (i < part1Size_ && (i % 2) == 0) { // 模2余0代表当前rank在part1的偶数位置上
49 0 : std::vector<LINK>::const_iterator niter = std::next(iter, i);
50 0 : if (niter != links.end()) {
51 0 : subLinks[i / 2] = *niter; // 除2计算出在block内的rank号
52 : }
53 0 : } else {
54 0 : std::vector<LINK>::const_iterator niter = std::next(iter, i);
55 0 : if (niter != links.end()) {
56 0 : subLinks[i - part1Size_ / 2] = *niter; // rank在part2中,用原始rank减part1除2,计算出在block内的rank号
57 : }
58 : }
59 : }
60 :
61 0 : return HCCL_SUCCESS;
62 : }
63 :
64 0 : HcclResult RecursiveHalvingDoublingBase::CalculateSlices(u64 dataBytes) const
65 : {
66 0 : CHK_PRT_RET(blockSize_ == 0, HCCL_ERROR("[Calculate][Slices]blocksize_ error"), HCCL_E_INTERNAL);
67 :
68 0 : slices_.resize(blockSize_);
69 :
70 0 : u64 bytesPerSlice = dataBytes / blockSize_;
71 0 : u64 reminder = dataBytes % blockSize_;
72 0 : if (reminder != 0) {
73 0 : bytesPerSlice++;
74 : }
75 0 : bytesPerSlice = ((bytesPerSlice + (HCCL_MIN_SLICE_ALIGN - 1)) / HCCL_MIN_SLICE_ALIGN) * HCCL_MIN_SLICE_ALIGN;
76 :
77 0 : u64 bytesLeft = dataBytes;
78 0 : u32 i = 0;
79 0 : while (bytesLeft > 0) {
80 0 : slices_[i].size = bytesPerSlice < bytesLeft ? bytesPerSlice : bytesLeft;
81 0 : slices_[i].offset = dataBytes - bytesLeft;
82 :
83 0 : bytesLeft -= slices_[i].size;
84 0 : i++;
85 : }
86 :
87 0 : while (i < blockSize_) {
88 0 : slices_[i].offset = dataBytes;
89 0 : slices_[i].size = 0;
90 0 : i++;
91 : }
92 :
93 0 : return HCCL_SUCCESS;
94 : }
95 : } // namespace hccl
|