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