1 /*
2 * Copyright (C) 2018-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #include "mock_performance_counters.h"
9
10 #include "shared/source/execution_environment/root_device_environment.h"
11 #include "shared/source/os_interface/os_interface.h"
12 #include "shared/test/common/mocks/mock_execution_environment.h"
13 using namespace MetricsLibraryApi;
14
15 namespace NEO {
16 //////////////////////////////////////////////////////
17 // MockMetricsLibrary::open
18 //////////////////////////////////////////////////////
open()19 bool MockMetricsLibrary::open() {
20 if (validOpen) {
21 ++openCount;
22 return true;
23 } else {
24 return false;
25 }
26 }
27
28 //////////////////////////////////////////////////////
29 // MockMetricsLibrary::contextCreate
30 //////////////////////////////////////////////////////
contextCreate(const ClientType_1_0 & client,ClientOptionsSubDeviceData_1_0 & subDevice,ClientOptionsSubDeviceIndexData_1_0 & subDeviceIndex,ClientOptionsSubDeviceCountData_1_0 & subDeviceCount,ClientData_1_0 & clientData,ContextCreateData_1_0 & createData,ContextHandle_1_0 & handle)31 bool MockMetricsLibrary::contextCreate(const ClientType_1_0 &client, ClientOptionsSubDeviceData_1_0 &subDevice, ClientOptionsSubDeviceIndexData_1_0 &subDeviceIndex, ClientOptionsSubDeviceCountData_1_0 &subDeviceCount, ClientData_1_0 &clientData, ContextCreateData_1_0 &createData, ContextHandle_1_0 &handle) {
32 if (client.Api != MetricsLibraryApi::ClientApi::OpenCL) {
33 return false;
34 }
35
36 handle.data = reinterpret_cast<void *>(this);
37 ++contextCount;
38 return true;
39 }
40
41 //////////////////////////////////////////////////////
42 // MockMetricsLibrary::contextDelete
43 //////////////////////////////////////////////////////
contextDelete(const ContextHandle_1_0 & handle)44 bool MockMetricsLibrary::contextDelete(const ContextHandle_1_0 &handle) {
45 if (!handle.IsValid()) {
46 return false;
47 }
48
49 --contextCount;
50 return true;
51 }
52
53 //////////////////////////////////////////////////////
54 // MockMetricsLibrary::hwCountersCreate
55 //////////////////////////////////////////////////////
hwCountersCreate(const ContextHandle_1_0 & context,const uint32_t slots,const ConfigurationHandle_1_0 mmio,QueryHandle_1_0 & handle)56 bool MockMetricsLibrary::hwCountersCreate(const ContextHandle_1_0 &context, const uint32_t slots, const ConfigurationHandle_1_0 mmio, QueryHandle_1_0 &handle) {
57 ++queryCount;
58 return true;
59 };
60
61 //////////////////////////////////////////////////////
62 // MockMetricsLibrary::hwCountersDelete
63 //////////////////////////////////////////////////////
hwCountersDelete(const QueryHandle_1_0 & handle)64 bool MockMetricsLibrary::hwCountersDelete(const QueryHandle_1_0 &handle) {
65 --queryCount;
66 return true;
67 }
68
69 //////////////////////////////////////////////////////
70 // MockMetricsLibrary::hwCountersGetReport
71 //////////////////////////////////////////////////////
hwCountersGetReport(const QueryHandle_1_0 & handle,const uint32_t slot,const uint32_t slotsCount,const uint32_t dataSize,void * data)72 bool MockMetricsLibrary::hwCountersGetReport(const QueryHandle_1_0 &handle, const uint32_t slot, const uint32_t slotsCount, const uint32_t dataSize, void *data) {
73 return validGetData;
74 }
75
76 //////////////////////////////////////////////////////
77 // MockMetricsLibrary::hwCountersGetApiReportSize
78 //////////////////////////////////////////////////////
hwCountersGetApiReportSize()79 uint32_t MockMetricsLibrary::hwCountersGetApiReportSize() {
80 return 1;
81 }
82
83 //////////////////////////////////////////////////////
84 // MockMetricsLibrary::hwCountersGetGpuReportSize
85 //////////////////////////////////////////////////////
hwCountersGetGpuReportSize()86 uint32_t MockMetricsLibrary::hwCountersGetGpuReportSize() {
87 return sizeof(HwPerfCounter);
88 }
89
90 //////////////////////////////////////////////////////
91 // MockMetricsLibrary::commandBufferGet
92 //////////////////////////////////////////////////////
commandBufferGet(CommandBufferData_1_0 & data)93 bool MockMetricsLibrary::commandBufferGet(CommandBufferData_1_0 &data) {
94 MI_REPORT_PERF_COUNT mirpc = {};
95 mirpc.init();
96 DEBUG_BREAK_IF(data.Data == nullptr);
97 memcpy(data.Data, &mirpc, sizeof(mirpc));
98 return true;
99 }
100
101 //////////////////////////////////////////////////////
102 // MockMetricsLibrary::commandBufferGetSize
103 //////////////////////////////////////////////////////
commandBufferGetSize(const CommandBufferData_1_0 & commandBufferData,CommandBufferSize_1_0 & commandBufferSize)104 bool MockMetricsLibrary::commandBufferGetSize(const CommandBufferData_1_0 &commandBufferData, CommandBufferSize_1_0 &commandBufferSize) {
105 commandBufferSize.GpuMemorySize = sizeof(MI_REPORT_PERF_COUNT);
106 return true;
107 }
108
109 //////////////////////////////////////////////////////
110 // MockMetricsLibrary::getProcAddress
111 //////////////////////////////////////////////////////
getProcAddress(const std::string & procName)112 void *MockMetricsLibraryDll::getProcAddress(const std::string &procName) {
113 if (procName == METRICS_LIBRARY_CONTEXT_CREATE_1_0) {
114 return validContextCreate
115 ? reinterpret_cast<void *>(&MockMetricsLibraryValidInterface::ContextCreate)
116 : nullptr;
117 } else if (procName == METRICS_LIBRARY_CONTEXT_DELETE_1_0) {
118 return validContextDelete
119 ? reinterpret_cast<void *>(&MockMetricsLibraryValidInterface::ContextDelete)
120 : nullptr;
121 } else {
122 return nullptr;
123 }
124 }
125
126 //////////////////////////////////////////////////////
127 // MockMetricsLibrary::isLoaded
128 //////////////////////////////////////////////////////
isLoaded()129 bool MockMetricsLibraryDll::isLoaded() {
130 return validIsLoaded;
131 }
132
133 //////////////////////////////////////////////////////
134 // MockMetricsLibraryValidInterface::ContextCreate
135 //////////////////////////////////////////////////////
ContextCreate(ClientType_1_0 clientType,ContextCreateData_1_0 * createData,ContextHandle_1_0 * handle)136 StatusCode MockMetricsLibraryValidInterface::ContextCreate(ClientType_1_0 clientType, ContextCreateData_1_0 *createData, ContextHandle_1_0 *handle) {
137
138 // Validate input.
139 EXPECT_EQ(clientType.Api, ClientApi::OpenCL);
140
141 // Library handle.
142 auto library = new MockMetricsLibraryValidInterface();
143 handle->data = library;
144 EXPECT_TRUE(handle->IsValid());
145
146 // Context count.
147 library->contextCount++;
148 EXPECT_EQ(library->contextCount, 1u);
149
150 return handle->IsValid()
151 ? StatusCode::Success
152 : StatusCode::Failed;
153 }
154
155 //////////////////////////////////////////////////////
156 // MockMetricsLibraryValidInterface::ContextDelete
157 //////////////////////////////////////////////////////
ContextDelete(const ContextHandle_1_0 handle)158 StatusCode MockMetricsLibraryValidInterface::ContextDelete(const ContextHandle_1_0 handle) {
159
160 auto validHandle = handle.IsValid();
161 auto library = static_cast<MockMetricsLibraryValidInterface *>(handle.data);
162
163 // Validate input.
164 EXPECT_TRUE(validHandle);
165 EXPECT_TRUE(validHandle);
166 EXPECT_EQ(--library->contextCount, 0u);
167
168 // Delete handle.
169 delete library;
170
171 return validHandle
172 ? StatusCode::Success
173 : StatusCode::IncorrectObject;
174 }
175
176 //////////////////////////////////////////////////////
177 // MockMetricsLibraryInterface::QueryCreate
178 //////////////////////////////////////////////////////
QueryCreate(const QueryCreateData_1_0 * createData,QueryHandle_1_0 * handle)179 StatusCode MockMetricsLibraryValidInterface::QueryCreate(const QueryCreateData_1_0 *createData, QueryHandle_1_0 *handle) {
180
181 EXPECT_NE(handle, nullptr);
182 EXPECT_NE(createData, nullptr);
183 EXPECT_GE(createData->Slots, 1u);
184 EXPECT_TRUE(createData->HandleContext.IsValid());
185 EXPECT_EQ(createData->Type, ObjectType::QueryHwCounters);
186
187 handle->data = new uint32_t(0);
188 return StatusCode::Success;
189 }
190
191 //////////////////////////////////////////////////////
192 // MockMetricsLibraryValidInterface::QueryDelete
193 //////////////////////////////////////////////////////
QueryDelete(const QueryHandle_1_0 handle)194 StatusCode MockMetricsLibraryValidInterface::QueryDelete(const QueryHandle_1_0 handle) {
195
196 if (handle.IsValid()) {
197 delete (uint32_t *)handle.data;
198 }
199
200 return StatusCode::Success;
201 }
202
203 //////////////////////////////////////////////////////
204 // MockMetricsLibraryValidInterface::CommandBufferGetSize
205 //////////////////////////////////////////////////////
CommandBufferGetSize(const CommandBufferData_1_0 * data,CommandBufferSize_1_0 * size)206 StatusCode MockMetricsLibraryValidInterface::CommandBufferGetSize(const CommandBufferData_1_0 *data, CommandBufferSize_1_0 *size) {
207 auto library = static_cast<MockMetricsLibraryValidInterface *>(data->HandleContext.data);
208 EXPECT_NE(data, nullptr);
209 EXPECT_TRUE(data->HandleContext.IsValid());
210 EXPECT_TRUE(data->QueryHwCounters.Handle.IsValid());
211 EXPECT_EQ(data->Type, GpuCommandBufferType::Render);
212 EXPECT_EQ(data->CommandsType, ObjectType::QueryHwCounters);
213 EXPECT_NE(size, nullptr);
214
215 size->GpuMemorySize = library->validGpuReportSize
216 ? 123
217 : 0;
218 return library->validGpuReportSize
219 ? StatusCode::Success
220 : StatusCode::Failed;
221 }
222
223 //////////////////////////////////////////////////////
224 // MockMetricsLibraryValidInterface::CommandBufferGet
225 //////////////////////////////////////////////////////
CommandBufferGet(const CommandBufferData_1_0 * data)226 StatusCode MockMetricsLibraryValidInterface::CommandBufferGet(const CommandBufferData_1_0 *data) {
227 EXPECT_NE(data, nullptr);
228 EXPECT_TRUE(data->HandleContext.IsValid());
229 EXPECT_TRUE(data->QueryHwCounters.Handle.IsValid());
230 EXPECT_EQ(data->Type, GpuCommandBufferType::Render);
231 EXPECT_EQ(data->CommandsType, ObjectType::QueryHwCounters);
232 EXPECT_NE(data->Data, nullptr);
233 EXPECT_GT(data->Size, 0u);
234 return StatusCode::Success;
235 }
236
237 //////////////////////////////////////////////////////
238 // MockMetricsLibraryValidInterface::CommandBufferGet
239 //////////////////////////////////////////////////////
GetParameter(const ParameterType parameter,ValueType * type,TypedValue_1_0 * value)240 StatusCode MockMetricsLibraryValidInterface::GetParameter(const ParameterType parameter, ValueType *type, TypedValue_1_0 *value) {
241 EXPECT_NE(type, nullptr);
242 EXPECT_NE(value, nullptr);
243 switch (parameter) {
244 case ParameterType::QueryHwCountersReportApiSize:
245 *type = ValueType::Uint32;
246 value->ValueUInt32 = 123;
247 break;
248 case ParameterType::QueryHwCountersReportGpuSize:
249 *type = ValueType::Uint32;
250 value->ValueUInt32 = 123;
251 break;
252 default:
253 EXPECT_TRUE(false);
254 break;
255 }
256 return StatusCode::Success;
257 }
258
259 //////////////////////////////////////////////////////
260 // MockMetricsLibraryValidInterface::ConfigurationCreate
261 //////////////////////////////////////////////////////
ConfigurationCreate(const ConfigurationCreateData_1_0 * createData,ConfigurationHandle_1_0 * handle)262 StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationCreate(const ConfigurationCreateData_1_0 *createData, ConfigurationHandle_1_0 *handle) {
263 EXPECT_NE(createData, nullptr);
264 EXPECT_NE(handle, nullptr);
265 EXPECT_TRUE(createData->HandleContext.IsValid());
266
267 const bool validType = (createData->Type == ObjectType::ConfigurationHwCountersOa) ||
268 (createData->Type == ObjectType::ConfigurationHwCountersUser);
269
270 // Mock overrides
271 auto api = static_cast<MockMetricsLibraryValidInterface *>(createData->HandleContext.data);
272 if (!api->validCreateConfigurationOa && (createData->Type == ObjectType::ConfigurationHwCountersOa)) {
273 return StatusCode::Failed;
274 }
275
276 if (!api->validCreateConfigurationUser && (createData->Type == ObjectType::ConfigurationHwCountersUser)) {
277 return StatusCode::Failed;
278 }
279
280 EXPECT_TRUE(validType);
281
282 handle->data = api;
283 return StatusCode::Success;
284 }
285
286 //////////////////////////////////////////////////////
287 // MockMetricsLibraryValidInterface::ConfigurationActivate
288 //////////////////////////////////////////////////////
ConfigurationActivate(const ConfigurationHandle_1_0 handle,const ConfigurationActivateData_1_0 * activateData)289 StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationActivate(const ConfigurationHandle_1_0 handle, const ConfigurationActivateData_1_0 *activateData) {
290 auto api = static_cast<MockMetricsLibraryValidInterface *>(handle.data);
291 return api->validActivateConfigurationOa
292 ? StatusCode::Success
293 : StatusCode::Failed;
294 }
295
296 //////////////////////////////////////////////////////
297 // MockMetricsLibraryValidInterface::ConfigurationDelete
298 //////////////////////////////////////////////////////
ConfigurationDelete(const ConfigurationHandle_1_0 handle)299 StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationDelete(const ConfigurationHandle_1_0 handle) {
300 EXPECT_TRUE(handle.IsValid());
301
302 return StatusCode::Success;
303 }
304
305 //////////////////////////////////////////////////////
306 // MockMetricsLibraryValidInterface::GetData
307 //////////////////////////////////////////////////////
GetData(GetReportData_1_0 * data)308 StatusCode MockMetricsLibraryValidInterface::GetData(GetReportData_1_0 *data) {
309 EXPECT_NE(data, nullptr);
310 EXPECT_EQ(data->Type, ObjectType::QueryHwCounters);
311 EXPECT_TRUE(data->Query.Handle.IsValid());
312 EXPECT_GE(data->Query.Slot, 0u);
313 EXPECT_GT(data->Query.SlotsCount, 0u);
314 EXPECT_NE(data->Query.Data, nullptr);
315 EXPECT_GT(data->Query.DataSize, 0u);
316 return StatusCode::Success;
317 }
318
319 //////////////////////////////////////////////////////
320 // PerformanceCountersDeviceFixture::SetUp
321 //////////////////////////////////////////////////////
SetUp()322 void PerformanceCountersDeviceFixture::SetUp() {
323 createFunc = Device::createPerformanceCountersFunc;
324 Device::createPerformanceCountersFunc = MockPerformanceCounters::create;
325 }
326
327 //////////////////////////////////////////////////////
328 // PerformanceCountersDeviceFixture::TearDown
329 //////////////////////////////////////////////////////
TearDown()330 void PerformanceCountersDeviceFixture::TearDown() {
331 Device::createPerformanceCountersFunc = createFunc;
332 }
333
334 //////////////////////////////////////////////////////
335 // PerformanceCountersMetricsLibraryFixture::SetUp
336 //////////////////////////////////////////////////////
SetUp()337 void PerformanceCountersMetricsLibraryFixture::SetUp() {
338 PerformanceCountersFixture::SetUp();
339 }
340
341 //////////////////////////////////////////////////////
342 // PerformanceCountersMetricsLibraryFixture::TearDown
343 //////////////////////////////////////////////////////
TearDown()344 void PerformanceCountersMetricsLibraryFixture::TearDown() {
345 device->setPerfCounters(nullptr);
346 PerformanceCountersFixture::TearDown();
347 }
348
349 //////////////////////////////////////////////////////
350 // PerformanceCountersFixture::PerformanceCountersFixture
351 //////////////////////////////////////////////////////
PerformanceCountersFixture()352 PerformanceCountersFixture::PerformanceCountersFixture() {
353 executionEnvironment = std::make_unique<MockExecutionEnvironment>();
354 rootDeviceEnvironment = std::make_unique<RootDeviceEnvironment>(*executionEnvironment);
355 rootDeviceEnvironment->setHwInfo(defaultHwInfo.get());
356 }
357
358 //////////////////////////////////////////////////////
359 // PerformanceCountersFixture::~PerformanceCountersFixture
360 //////////////////////////////////////////////////////
~PerformanceCountersFixture()361 PerformanceCountersFixture::~PerformanceCountersFixture() {
362 }
363
364 //////////////////////////////////////////////////////
365 // PerformanceCountersMetricsLibraryFixture::createPerformanceCounters
366 //////////////////////////////////////////////////////
createPerformanceCounters(const bool validMetricsLibraryApi,const bool mockMetricsLibrary)367 void PerformanceCountersMetricsLibraryFixture::createPerformanceCounters(const bool validMetricsLibraryApi, const bool mockMetricsLibrary) {
368 performanceCountersBase = MockPerformanceCounters::create(&device->getDevice());
369 auto metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface();
370 auto metricsLibraryDll = std::make_unique<MockMetricsLibraryDll>();
371 EXPECT_NE(performanceCountersBase, nullptr);
372 EXPECT_NE(metricsLibraryInterface, nullptr);
373
374 device->setPerfCounters(performanceCountersBase.get());
375
376 // Attached mock version of metrics library interface.
377 if (mockMetricsLibrary) {
378 performanceCountersBase->setMetricsLibraryInterface(std::make_unique<MockMetricsLibrary>());
379 metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface();
380 } else {
381 performanceCountersBase->setMetricsLibraryInterface(std::make_unique<MetricsLibrary>());
382 metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface();
383 }
384
385 if (validMetricsLibraryApi) {
386 metricsLibraryInterface->api = std::make_unique<MockMetricsLibraryValidInterface>();
387 metricsLibraryInterface->osLibrary = std::move(metricsLibraryDll);
388 } else {
389 metricsLibraryDll->validContextCreate = false;
390 metricsLibraryDll->validContextDelete = false;
391 metricsLibraryDll->validIsLoaded = false;
392 metricsLibraryInterface->api = std::make_unique<MockMetricsLibraryInvalidInterface>();
393 metricsLibraryInterface->osLibrary = std::move(metricsLibraryDll);
394 }
395
396 EXPECT_NE(metricsLibraryInterface->api, nullptr);
397 }
398 } // namespace NEO
399