File: topology.cpp

package info (click to toggle)
intel-compute-runtime 25.35.35096.9-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 79,324 kB
  • sloc: cpp: 926,243; lisp: 3,433; sh: 715; makefile: 162; python: 21
file content (120 lines) | stat: -rw-r--r-- 4,158 bytes parent folder | download
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