Skip to content

Commit 10f98b4

Browse files
Metrics Add Os specific implementation Structure for IP Sampling
This patch adds OS specific implementation for IP Sampling. Implementation for linux is provided as part of this patch. Related-To: LOCI-2787 --- master-files level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp level_zero/tools/source/metrics/os_metric_ip_sampling.h level_zero/tools/source/metrics/windows/os_metric_ip_sampling_imp_windows.cpp level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_prelim.cpp level_zero/tools/test/unit_tests/sources/metrics/linux/test_metric_ip_sampling_linux_upstream.cpp level_zero/tools/test/unit_tests/sources/metrics/windows/test_metric_ip_sampling_windows.cpp --- master-files Signed-off-by: Joshua Santosh Ranjan <[email protected]>
1 parent 3af1d3f commit 10f98b4

19 files changed

+790
-2
lines changed

level_zero/core/source/device/device_imp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,4 +1184,16 @@ NEO::Device *DeviceImp::getActiveDevice() const {
11841184
return this->neoDevice;
11851185
}
11861186

1187+
uint32_t DeviceImp::getPhysicalSubDeviceId() {
1188+
if (!neoDevice->isSubDevice()) {
1189+
uint32_t deviceBitField = static_cast<uint32_t>(neoDevice->getDeviceBitfield().to_ulong());
1190+
if (neoDevice->getDeviceBitfield().count() > 1) {
1191+
// Clear all set bits other than the right most bit
1192+
deviceBitField &= ~deviceBitField + 1;
1193+
}
1194+
return Math::log2(deviceBitField);
1195+
}
1196+
return static_cast<NEO::SubDevice *>(neoDevice)->getSubDeviceIndex();
1197+
}
1198+
11871199
} // namespace L0

level_zero/core/source/device/device_imp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct DeviceImp : public Device {
100100

101101
bool toPhysicalSliceId(const NEO::TopologyMap &topologyMap, uint32_t &slice, uint32_t &subslice, uint32_t &deviceIndex);
102102
bool toApiSliceId(const NEO::TopologyMap &topologyMap, uint32_t &slice, uint32_t &subslice, uint32_t deviceIndex);
103+
uint32_t getPhysicalSubDeviceId();
103104

104105
bool isSubdevice = false;
105106
void *execEnvironment = nullptr;

level_zero/tools/source/metrics/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ list(APPEND L0_SRCS_TOOLS_METRICS
1616
${CMAKE_CURRENT_SOURCE_DIR}/metric_oa_query_imp.cpp
1717
${CMAKE_CURRENT_SOURCE_DIR}/metric_oa_query_imp.h
1818
${CMAKE_CURRENT_SOURCE_DIR}/metric_oa_source.h
19+
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_ip_sampling.h
1920
)
2021

2122
if(UNIX)

level_zero/tools/source/metrics/linux/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set(L0_SRCS_TOOLS_LINUX
88
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
99
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_oa_query_imp_linux.cpp
1010
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_oa_enumeration_imp_linux.cpp
11+
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_ip_sampling_imp_linux.cpp
1112
)
1213

1314
if(UNIX)
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "shared/source/debug_settings/debug_settings_manager.h"
9+
#include "shared/source/helpers/constants.h"
10+
#include "shared/source/os_interface/linux/drm_neo.h"
11+
#include "shared/source/os_interface/linux/ioctl_helper.h"
12+
#include "shared/source/os_interface/linux/sys_calls.h"
13+
#include "shared/source/os_interface/os_interface.h"
14+
#include "shared/source/xe_hpc_core/hw_cmds_base.h"
15+
16+
#include "level_zero/core/source/device/device.h"
17+
#include "level_zero/core/source/device/device_imp.h"
18+
#include "level_zero/tools/source/metrics/os_metric_ip_sampling.h"
19+
20+
#include <algorithm>
21+
22+
namespace L0 {
23+
24+
constexpr uint32_t maxDssBufferSize = 512 * KB;
25+
constexpr uint32_t defaultPollPeriodNs = 10000000u;
26+
constexpr uint32_t unitReportSize = 64u;
27+
28+
class MetricIpSamplingLinuxImp : public MetricIpSamplingOsInterface {
29+
public:
30+
MetricIpSamplingLinuxImp(Device &device);
31+
~MetricIpSamplingLinuxImp() override = default;
32+
ze_result_t startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) override;
33+
ze_result_t stopMeasurement() override;
34+
ze_result_t readData(uint8_t *pRawData, size_t *pRawDataSize) override;
35+
uint32_t getRequiredBufferSize(const uint32_t maxReportCount) override;
36+
uint32_t getUnitReportSize() override;
37+
bool isNReportsAvailable() override;
38+
bool isDependencyAvailable() override;
39+
40+
private:
41+
int32_t stream = -1;
42+
Device &device;
43+
44+
ze_result_t getNearestSupportedSamplingUnit(uint32_t &samplingPeriodNs, uint32_t &samplingRate);
45+
};
46+
47+
MetricIpSamplingLinuxImp::MetricIpSamplingLinuxImp(Device &device) : device(device) {}
48+
49+
ze_result_t MetricIpSamplingLinuxImp::getNearestSupportedSamplingUnit(uint32_t &samplingPeriodNs, uint32_t &samplingUnit) {
50+
51+
static constexpr uint64_t nsecPerSec = 1000000000ull;
52+
static constexpr uint32_t samplingClockGranularity = 251u;
53+
static constexpr uint32_t minSamplingUnit = 1u;
54+
static constexpr uint32_t maxSamplingUnit = 7u;
55+
const auto drm = device.getOsInterface().getDriverModel()->as<NEO::Drm>();
56+
int32_t gpuTimeStampfrequency = 0;
57+
int32_t ret = drm->getTimestampFrequency(gpuTimeStampfrequency);
58+
if (ret < 0) {
59+
return ZE_RESULT_ERROR_UNKNOWN;
60+
}
61+
62+
uint64_t gpuClockPeriodNs = nsecPerSec / static_cast<uint64_t>(gpuTimeStampfrequency);
63+
uint64_t numberOfClocks = samplingPeriodNs / gpuClockPeriodNs;
64+
65+
samplingUnit = std::clamp(static_cast<uint32_t>(numberOfClocks / samplingClockGranularity), minSamplingUnit, maxSamplingUnit);
66+
samplingPeriodNs = samplingUnit * samplingClockGranularity * static_cast<uint32_t>(gpuClockPeriodNs);
67+
return ZE_RESULT_SUCCESS;
68+
}
69+
70+
ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) {
71+
72+
const auto drm = device.getOsInterface().getDriverModel()->as<NEO::Drm>();
73+
74+
uint32_t samplingUnit = 0;
75+
if (getNearestSupportedSamplingUnit(samplingPeriodNs, samplingUnit) != ZE_RESULT_SUCCESS) {
76+
return ZE_RESULT_ERROR_UNKNOWN;
77+
}
78+
79+
DeviceImp &deviceImp = static_cast<DeviceImp &>(device);
80+
81+
auto ioctlHelper = drm->getIoctlHelper();
82+
uint32_t euStallFdParameter = ioctlHelper->getEuStallFdParameter();
83+
std::array<uint64_t, 10u> properties;
84+
if (!ioctlHelper->getEuStallProperties(properties, maxDssBufferSize, samplingUnit, defaultPollPeriodNs, deviceImp.getPhysicalSubDeviceId())) {
85+
return ZE_RESULT_ERROR_UNKNOWN;
86+
}
87+
88+
struct drm_i915_perf_open_param param = {
89+
.flags = I915_PERF_FLAG_FD_CLOEXEC |
90+
euStallFdParameter |
91+
I915_PERF_FLAG_FD_NONBLOCK,
92+
.num_properties = sizeof(properties) / 16,
93+
.properties_ptr = reinterpret_cast<uintptr_t>(properties.data()),
94+
};
95+
96+
stream = drm->ioctl(DRM_IOCTL_I915_PERF_OPEN, &param);
97+
if (stream < 0) {
98+
return ZE_RESULT_ERROR_UNKNOWN;
99+
}
100+
101+
int32_t ret = NEO::SysCalls::ioctl(stream, I915_PERF_IOCTL_ENABLE, 0);
102+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr,
103+
"PRELIM_I915_PERF_IOCTL_ENABLE failed errno = %d | ret = %d \n", errno, ret);
104+
105+
return (ret == 0) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
106+
}
107+
108+
ze_result_t MetricIpSamplingLinuxImp::stopMeasurement() {
109+
110+
int32_t ret = NEO::SysCalls::close(stream);
111+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, "close() failed errno = %d | ret = %d \n",
112+
errno, ret);
113+
stream = -1;
114+
115+
return (ret == 0) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
116+
}
117+
118+
ze_result_t MetricIpSamplingLinuxImp::readData(uint8_t *pRawData, size_t *pRawDataSize) {
119+
120+
ssize_t ret = NEO::SysCalls::pread(stream, pRawData, *pRawDataSize, 0u);
121+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, "pread() failed errno = %d | ret = %d \n",
122+
errno, ret);
123+
124+
if (ret >= 0) {
125+
*pRawDataSize = ret;
126+
return ZE_RESULT_SUCCESS;
127+
}
128+
129+
*pRawDataSize = 0;
130+
return ZE_RESULT_ERROR_UNKNOWN;
131+
}
132+
133+
uint32_t MetricIpSamplingLinuxImp::getRequiredBufferSize(const uint32_t maxReportCount) {
134+
135+
uint32_t requiredBufferSize = getUnitReportSize() * maxReportCount;
136+
const auto hwInfo = device.getNEODevice()->getHardwareInfo();
137+
return std::min(requiredBufferSize, maxDssBufferSize * hwInfo.gtSystemInfo.MaxDualSubSlicesSupported);
138+
}
139+
140+
uint32_t MetricIpSamplingLinuxImp::getUnitReportSize() {
141+
return unitReportSize;
142+
}
143+
144+
bool MetricIpSamplingLinuxImp::isNReportsAvailable() {
145+
struct pollfd pollParams;
146+
memset(&pollParams, 0, sizeof(pollParams));
147+
148+
DEBUG_BREAK_IF(stream == -1);
149+
150+
pollParams.fd = stream;
151+
pollParams.revents = 0;
152+
pollParams.events = POLLIN;
153+
154+
int32_t pollResult = NEO::SysCalls::poll(&pollParams, 1, 0u);
155+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (pollResult < 0), stderr, "poll() failed errno = %d | pollResult = %d \n",
156+
errno, pollResult);
157+
158+
if (pollResult > 0) {
159+
return true;
160+
}
161+
return false;
162+
}
163+
164+
bool MetricIpSamplingLinuxImp::isDependencyAvailable() {
165+
166+
auto hwInfo = device.getNEODevice()->getHardwareInfo();
167+
auto isSupportedDevice = false;
168+
169+
if (hwInfo.platform.eProductFamily == IGFX_PVC) {
170+
if (hwInfo.platform.usDeviceID == NEO::XE_HPC_CORE::pvcXtDeviceIds[0] ||
171+
hwInfo.platform.usDeviceID == NEO::XE_HPC_CORE::pvcXtDeviceIds[1] ||
172+
hwInfo.platform.usDeviceID == NEO::XE_HPC_CORE::pvcXtDeviceIds[2] ||
173+
hwInfo.platform.usDeviceID == NEO::XE_HPC_CORE::pvcXtDeviceIds[3] ||
174+
hwInfo.platform.usDeviceID == NEO::XE_HPC_CORE::pvcXtDeviceIds[4]) {
175+
isSupportedDevice = true;
176+
}
177+
}
178+
179+
if (!isSupportedDevice) {
180+
return false;
181+
}
182+
183+
uint32_t notifyEveryNReports = 1u;
184+
uint32_t samplingPeriod = 100;
185+
186+
ze_result_t status = startMeasurement(notifyEveryNReports, samplingPeriod);
187+
if (stream != -1) {
188+
stopMeasurement();
189+
}
190+
return status == ZE_RESULT_SUCCESS ? true : false;
191+
}
192+
193+
std::unique_ptr<MetricIpSamplingOsInterface> MetricIpSamplingOsInterface::create(Device &device) {
194+
return std::make_unique<MetricIpSamplingLinuxImp>(device);
195+
}
196+
197+
} // namespace L0
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include <level_zero/zet_api.h>
9+
10+
#include <memory>
11+
12+
namespace L0 {
13+
14+
struct Device;
15+
16+
class MetricIpSamplingOsInterface {
17+
public:
18+
virtual ~MetricIpSamplingOsInterface() = default;
19+
virtual ze_result_t startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) = 0;
20+
virtual ze_result_t stopMeasurement() = 0;
21+
virtual ze_result_t readData(uint8_t *pRawData, size_t *pRawDataSize) = 0;
22+
virtual uint32_t getRequiredBufferSize(const uint32_t maxReportCount) = 0;
23+
virtual uint32_t getUnitReportSize() = 0;
24+
virtual bool isNReportsAvailable() = 0;
25+
virtual bool isDependencyAvailable() = 0;
26+
static std::unique_ptr<MetricIpSamplingOsInterface> create(Device &device);
27+
};
28+
29+
} // namespace L0

level_zero/tools/source/metrics/windows/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set(L0_SRCS_TOOLS_WINDOWS
88
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
99
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_oa_query_imp_windows.cpp
1010
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_oa_enumeration_imp_windows.cpp
11+
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_ip_sampling_imp_windows.cpp
1112
)
1213

1314
if(WIN32)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "level_zero/core/source/device/device.h"
9+
#include "level_zero/tools/source/metrics/os_metric_ip_sampling.h"
10+
11+
namespace L0 {
12+
13+
class MetricIpSamplingWindowsImp : public MetricIpSamplingOsInterface {
14+
public:
15+
MetricIpSamplingWindowsImp() {}
16+
ze_result_t startMeasurement(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs) override {
17+
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
18+
}
19+
ze_result_t stopMeasurement() override {
20+
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
21+
}
22+
ze_result_t readData(uint8_t *pRawData, size_t *pRawDataSize) override {
23+
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
24+
}
25+
uint32_t getRequiredBufferSize(const uint32_t maxReportCount) override {
26+
return 0u;
27+
}
28+
uint32_t getUnitReportSize() override {
29+
return 0u;
30+
}
31+
bool isNReportsAvailable() override {
32+
return false;
33+
}
34+
bool isDependencyAvailable() override {
35+
return false;
36+
}
37+
};
38+
39+
std::unique_ptr<MetricIpSamplingOsInterface> MetricIpSamplingOsInterface::create(Device &device) {
40+
return std::make_unique<MetricIpSamplingWindowsImp>();
41+
}
42+
43+
} // namespace L0

level_zero/tools/test/unit_tests/sources/metrics/linux/CMakeLists.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,25 @@
44
# SPDX-License-Identifier: MIT
55
#
66

7+
set(L0_TOOLS_METRICS_LINUX_TESTS_LINUX
8+
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
9+
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_oa_query_pool_linux.cpp
10+
)
11+
12+
if(NEO_ENABLE_i915_PRELIM_DETECTION)
13+
list(APPEND L0_TOOLS_METRICS_LINUX_TESTS_LINUX
14+
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_ip_sampling_linux_prelim.cpp
15+
)
16+
endif()
17+
18+
if("${BRANCH_TYPE}" STREQUAL "")
19+
list(APPEND L0_TOOLS_METRICS_LINUX_TESTS_LINUX
20+
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_ip_sampling_linux_upstream.cpp
21+
)
22+
endif()
23+
724
if(UNIX)
825
target_sources(${TARGET_NAME} PRIVATE
9-
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_oa_query_pool_linux.cpp
26+
${L0_TOOLS_METRICS_LINUX_TESTS_LINUX}
1027
)
1128
endif()

0 commit comments

Comments
 (0)