1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/topology.h"
#include <bit>
#include <cstdint>
#include <numeric>
#include <span>
#include <vector>
namespace NEO {
TopologyInfo getTopologyInfo(const TopologyBitmap &topologyBitmap, const TopologyLimits &topologyLimits, TopologyMapping &topologyMapping) {
TopologyInfo topologyInfo{};
std::vector<int> sliceIndices;
sliceIndices.reserve(topologyLimits.maxSlices);
std::vector<int> subSliceIndices;
subSliceIndices.reserve(topologyLimits.maxSubSlicesPerSlice);
auto processSubSlices = [&](const std::span<const uint8_t> &subSliceBitmap) -> std::pair<int, int> {
int sliceCount = 0;
int subSliceCountTotal = 0;
for (auto sliceId = 0; sliceId < topologyLimits.maxSlices; ++sliceId) {
int subSliceCount = 0;
for (auto subSliceId = 0; subSliceId < topologyLimits.maxSubSlicesPerSlice; ++subSliceId) {
const auto idx = sliceId * topologyLimits.maxSubSlicesPerSlice + subSliceId;
const auto byte = idx / 8u;
const auto bit = idx % 8u;
if (idx >= std::ssize(subSliceBitmap) * 8) {
break;
}
if (subSliceBitmap[byte] & (1u << bit)) {
subSliceIndices.push_back(subSliceId);
subSliceCount += 1;
}
}
if (subSliceCount) {
sliceIndices.push_back(sliceId);
sliceCount += 1;
subSliceCountTotal += subSliceCount;
}
if (sliceCount == 1) {
topologyMapping.subsliceIndices = std::move(subSliceIndices);
}
subSliceIndices.clear();
}
return {sliceCount, subSliceCountTotal};
};
auto [sliceCount, subSliceCount] = processSubSlices(topologyBitmap.dssCompute);
if (!subSliceCount) {
std::tie(sliceCount, subSliceCount) = processSubSlices(topologyBitmap.dssGeometry);
}
topologyMapping.sliceIndices = std::move(sliceIndices);
if (sliceCount != 1) {
topologyMapping.subsliceIndices.clear();
}
auto bitmapCount = [](const std::span<const uint8_t> &bitmap) {
return std::transform_reduce(bitmap.begin(), bitmap.end(), 0, std::plus{}, std::popcount<uint8_t>);
};
topologyInfo.sliceCount = sliceCount;
topologyInfo.subSliceCount = subSliceCount;
topologyInfo.euCount = bitmapCount(topologyBitmap.eu) * topologyInfo.subSliceCount;
topologyInfo.l3BankCount = bitmapCount(topologyBitmap.l3Banks);
return topologyInfo;
}
TopologyInfo getTopologyInfoMultiTile(const std::span<TopologyBitmap> &topologyBitmap, const TopologyLimits &topologyLimits, TopologyMap &topologyMap) {
const auto numTiles = std::ssize(topologyBitmap);
if (0 == numTiles)
return TopologyInfo{};
std::vector<TopologyInfo> topologyInfos;
topologyInfos.reserve(numTiles);
for (auto i = 0; i < numTiles; ++i) {
topologyInfos.push_back(getTopologyInfo(topologyBitmap[i], topologyLimits, topologyMap[i]));
}
TopologyInfo topologyInfo{
.sliceCount = std::numeric_limits<decltype(TopologyInfo::sliceCount)>::max(),
.subSliceCount = std::numeric_limits<decltype(TopologyInfo::subSliceCount)>::max(),
.euCount = std::numeric_limits<decltype(TopologyInfo::euCount)>::max(),
.l3BankCount = std::numeric_limits<decltype(TopologyInfo::l3BankCount)>::max(),
};
topologyInfo = std::reduce(topologyInfos.cbegin(), topologyInfos.cend(), topologyInfo, [](const TopologyInfo &topoInfo1, const TopologyInfo &topoInfo2) {
return TopologyInfo{
.sliceCount = std::min(topoInfo1.sliceCount, topoInfo2.sliceCount),
.subSliceCount = std::min(topoInfo1.subSliceCount, topoInfo2.subSliceCount),
.euCount = std::min(topoInfo1.euCount, topoInfo2.euCount),
.l3BankCount = std::min(topoInfo1.l3BankCount, topoInfo2.l3BankCount),
};
});
return topologyInfo;
}
} // namespace NEO
|