* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#ifndef SEARCH_PATH_H
#define SEARCH_PATH_H
class SearchPath {
public:
std::vector<u32> Search(const std::vector<u32> &nicList, bool isDoubleRingMap = false)
{
if (isDoubleRingMap && nicList.size() <= 1) {
return {};
}
if (nicList.size() == 0 || nicList.size() == 1) {
return nicList;
}
result_.clear();
std::vector<bool> arrived(nicList.size(), 0);
nicSet_.clear();
for (auto i : nicList) {
nicSet_.insert(i);
}
if (dfs(nicList, arrived, 0, nicList[0], isDoubleRingMap)) {
return result_;
} else {
return {};
}
}
private:
bool dfs(const std::vector<u32> &nicList, std::vector<bool> &arrived, u32 idx, u32 nowNicIdx, bool isDoubleRingMap)
{
std::map<int, std::vector<u32>> reachableMap = isDoubleRingMap ? reachableDoubleRing_ : reachableRank_;
if (idx == nicList.size() - 1) {
for (auto i : reachableMap[nowNicIdx]) {
if (i == result_[0]) {
result_.push_back(nowNicIdx);
std::string valueStr = "";
for (auto j : result_) {
valueStr.append(std::to_string(j));
}
HCCL_INFO("find path success: %s",valueStr.c_str());
return true;
}
}
return false;
}
arrived[nowNicIdx] = true;
result_.push_back(nowNicIdx);
for (auto i : reachableMap[nowNicIdx]) {
if (nicSet_.count(i) == 0 || arrived[i]) {
continue;
}
if (dfs(nicList, arrived, idx + 1, i, isDoubleRingMap)) {
return true;
}
}
arrived[nowNicIdx] = false;
result_.pop_back();
return false;
}
std::vector<u32> result_;
std::set<u32> nicSet_;
std::map<int, std::vector<u32>> reachableRank_ = {
{0, {1, 2, 4, 6, 8, 10, 12, 14}},
{1, {0, 3, 5, 7, 9, 11, 13, 15}},
{2, {3, 4, 6, 8, 10, 12, 14, 0}},
{3, {2, 5, 7, 9, 11, 13, 15, 1}},
{4, {5, 6, 8, 10, 12, 14, 0, 2}},
{5, {4, 7, 9, 11, 13, 15, 1, 3}},
{6, {7, 8, 10, 12, 14, 0, 2, 4}},
{7, {6, 9, 11, 13, 15, 1, 3, 5}},
{8, {9, 10, 12, 14, 0, 2, 4, 6}},
{9, {8, 11, 13, 15, 1, 3, 5, 7}},
{10, {11, 12, 14, 0, 2, 4, 6, 8}},
{11, {10, 13, 15, 1, 3, 5, 7, 9}},
{12, {13, 14, 0, 2, 4, 6, 8, 10}},
{13, {12, 15, 1, 3, 5, 7, 9, 11}},
{14, {15, 0, 2, 4, 6, 8, 10, 12}},
{15, {14, 1, 3, 5, 7, 9, 11, 13}}};
std::map<int, std::vector<u32>> reachableDoubleRing_ = {
{0, {1}},
{1, {0, 2, 4, 6, 8, 10, 12, 14}},
{2, {3}},
{3, {4, 6, 8, 10, 12, 14, 0, 2}},
{4, {5}},
{5, {6, 8, 10, 12, 14, 0, 2, 4}},
{6, {7}},
{7, {8, 10, 12, 14, 0, 2, 4, 6}},
{8, {9}},
{9, {10, 12, 14, 0, 2, 4, 6, 8}},
{10, {11}},
{11, {12, 14, 0, 2, 4, 6, 8, 10}},
{12, {13}},
{13, {14, 0, 2, 4, 6, 8, 10, 12}},
{14, {15}},
{15, {0, 2, 4, 6, 8, 10, 12,14}}};
};
#endif