-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: report multi-hop fabric connections
In additon to physical connections we should also report multi-hop logical connections (MDFI + XeLink) as have positive bandwidth. Use a modified BFS algorithm to try to find a path between fabric vertices that are not directly connected together because the KMD always try to use MDFI link first, then go to XeLink. Multi-hop connections are bi-directional but might not be symmetric, so for every pair of vertices A & B that are not directly connected, we need to try to find both `A -> B` and `B -> A`. Related-To: GSD-7126 Signed-off-by: Wenbin Lu <wenbin.lu@intel.com>
- Loading branch information
1 parent
a04c67e
commit a0faad6
Showing
15 changed files
with
1,623 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* Copyright (C) 2024 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
*/ | ||
|
||
#include "level_zero/core/source/fabric/fabric.h" | ||
|
||
#include "shared/source/helpers/debug_helpers.h" | ||
|
||
#include <algorithm> | ||
#include <cstring> | ||
#include <deque> | ||
#include <limits> | ||
#include <map> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace L0 { | ||
|
||
void FabricEdge::createEdgesFromVertices(const std::vector<FabricVertex *> &vertices, std::vector<FabricEdge *> &edges, std::vector<FabricEdge *> &indirectEdges) { | ||
|
||
// Get all vertices and sub-vertices | ||
std::vector<FabricVertex *> allVertices = {}; | ||
for (auto &fabricVertex : vertices) { | ||
allVertices.push_back(fabricVertex); | ||
for (auto &fabricSubVertex : fabricVertex->subVertices) { | ||
allVertices.push_back(fabricSubVertex); | ||
} | ||
} | ||
|
||
// Get direct physical edges between all vertices | ||
std::map<uint32_t, std::vector<std::pair<uint32_t, ze_fabric_edge_exp_properties_t *>>> adjacentVerticesMap; | ||
std::map<uint32_t, std::vector<uint32_t>> nonAdjacentVerticesMap; | ||
for (uint32_t vertexAIndex = 0; vertexAIndex < allVertices.size(); vertexAIndex++) { | ||
for (uint32_t vertexBIndex = vertexAIndex + 1; vertexBIndex < allVertices.size(); vertexBIndex++) { | ||
bool isAdjacent = false; | ||
auto vertexA = allVertices[vertexAIndex]; | ||
auto vertexB = allVertices[vertexBIndex]; | ||
ze_fabric_edge_exp_properties_t edgeProperty = {}; | ||
|
||
for (auto const &fabricDeviceInterface : vertexA->pFabricDeviceInterfaces) { | ||
bool isConnected = | ||
fabricDeviceInterface.second->getEdgeProperty(vertexB, edgeProperty); | ||
if (isConnected) { | ||
edges.push_back(create(vertexA, vertexB, edgeProperty)); | ||
adjacentVerticesMap[vertexAIndex].emplace_back(vertexBIndex, &edges.back()->properties); | ||
adjacentVerticesMap[vertexBIndex].emplace_back(vertexAIndex, &edges.back()->properties); | ||
isAdjacent = true; | ||
} | ||
} | ||
if (!isAdjacent) { | ||
auto &subVerticesOfA = vertexA->subVertices; | ||
if (std::find(subVerticesOfA.begin(), subVerticesOfA.end(), vertexB) == subVerticesOfA.end()) { | ||
nonAdjacentVerticesMap[vertexAIndex].push_back(vertexBIndex); | ||
nonAdjacentVerticesMap[vertexBIndex].push_back(vertexAIndex); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Find logical multi-hop edges between vertices not directly connected | ||
for (const auto &[vertexAIndex, nonAdjacentVertices] : nonAdjacentVerticesMap) { | ||
for (auto vertexBIndex : nonAdjacentVertices) { | ||
std::map<uint32_t, uint32_t> visited; | ||
visited[vertexAIndex] = vertexAIndex; | ||
|
||
std::deque<uint32_t> toVisit; | ||
toVisit.push_back(vertexAIndex); | ||
|
||
uint32_t currVertexIndex = vertexAIndex; | ||
|
||
while (true) { | ||
std::deque<uint32_t> toVisitIaf, toVisitMdfi; | ||
while (!toVisit.empty()) { | ||
currVertexIndex = toVisit.front(); | ||
toVisit.pop_front(); | ||
if (currVertexIndex == vertexBIndex) { | ||
break; | ||
} | ||
|
||
for (auto [vertexIndex, edgeProperty] : adjacentVerticesMap[currVertexIndex]) { | ||
if (visited.find(vertexIndex) == visited.end()) { | ||
if (strncmp(edgeProperty->model, "XeLink", 7) == 0) { | ||
toVisitIaf.push_back(vertexIndex); | ||
} else { | ||
DEBUG_BREAK_IF(strncmp(edgeProperty->model, "MDFI", 5) != 0); | ||
toVisitMdfi.push_back(vertexIndex); | ||
} | ||
visited[vertexIndex] = currVertexIndex; | ||
} | ||
} | ||
} | ||
|
||
if (currVertexIndex != vertexBIndex) { | ||
if (toVisitIaf.size() + toVisitMdfi.size() != 0) { | ||
toVisit = toVisitMdfi; | ||
toVisit.insert(toVisit.end(), toVisitIaf.begin(), toVisitIaf.end()); | ||
} else { | ||
break; | ||
} | ||
} else { | ||
std::string path = ""; | ||
ze_fabric_edge_exp_properties_t properties = {}; | ||
properties.stype = ZE_STRUCTURE_TYPE_FABRIC_EDGE_EXP_PROPERTIES; | ||
properties.pNext = nullptr; | ||
memset(properties.uuid.id, 0, ZE_MAX_UUID_SIZE); | ||
memset(properties.model, 0, ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE); | ||
properties.bandwidth = std::numeric_limits<uint32_t>::max(); | ||
properties.bandwidthUnit = ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC; | ||
properties.latency = std::numeric_limits<uint32_t>::max(); | ||
properties.latencyUnit = ZE_LATENCY_UNIT_UNKNOWN; | ||
properties.duplexity = ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX; | ||
|
||
while (true) { | ||
const auto parentIndex = visited[currVertexIndex]; | ||
ze_fabric_edge_exp_properties_t *currEdgeProperty = nullptr; | ||
for (const auto &[vertexIndex, edgeProperty] : adjacentVerticesMap[parentIndex]) { | ||
if (vertexIndex == currVertexIndex) { | ||
currEdgeProperty = edgeProperty; | ||
break; | ||
} | ||
} | ||
UNRECOVERABLE_IF(currEdgeProperty == nullptr); | ||
path = std::string(currEdgeProperty->model) + path; | ||
if ((strncmp(currEdgeProperty->model, "XeLink", 7) == 0) && | ||
(currEdgeProperty->bandwidth < properties.bandwidth)) { | ||
properties.bandwidth = currEdgeProperty->bandwidth; | ||
} | ||
|
||
currVertexIndex = parentIndex; | ||
if (currVertexIndex == vertexAIndex) { | ||
path.resize(ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE - 1, '\0'); | ||
path.copy(properties.model, path.size()); | ||
break; | ||
} else { | ||
path = '-' + path; | ||
} | ||
} | ||
indirectEdges.push_back(create(allVertices[vertexAIndex], allVertices[vertexBIndex], properties)); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // namespace L0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (C) 2024 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
*/ | ||
|
||
#include "level_zero/core/source/fabric/fabric.h" | ||
|
||
#include <vector> | ||
|
||
namespace L0 { | ||
|
||
void FabricEdge::createEdgesFromVertices(const std::vector<FabricVertex *> &vertices, std::vector<FabricEdge *> &edges, std::vector<FabricEdge *> &) { | ||
|
||
// Get all vertices and sub-vertices | ||
std::vector<FabricVertex *> allVertices = {}; | ||
for (auto &fabricVertex : vertices) { | ||
allVertices.push_back(fabricVertex); | ||
for (auto &fabricSubVertex : fabricVertex->subVertices) { | ||
allVertices.push_back(fabricSubVertex); | ||
} | ||
} | ||
|
||
// Get direct physical edges between all vertices | ||
for (uint32_t vertexAIndex = 0; vertexAIndex < allVertices.size(); vertexAIndex++) { | ||
for (uint32_t vertexBIndex = vertexAIndex + 1; vertexBIndex < allVertices.size(); vertexBIndex++) { | ||
auto vertexA = allVertices[vertexAIndex]; | ||
auto vertexB = allVertices[vertexBIndex]; | ||
ze_fabric_edge_exp_properties_t edgeProperty = {}; | ||
|
||
for (auto const &fabricDeviceInterface : vertexA->pFabricDeviceInterfaces) { | ||
bool isConnected = | ||
fabricDeviceInterface.second->getEdgeProperty(vertexB, edgeProperty); | ||
if (isConnected) { | ||
edges.push_back(create(vertexA, vertexB, edgeProperty)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // namespace L0 |
Oops, something went wrong.