1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 #include "level_zero/core/source/device/device_imp.h"
10 #include "level_zero/core/source/driver/driver_handle_imp.h"
11 #include "level_zero/core/source/driver/host_pointer_manager.h"
12 #include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
13 #include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
14 #include "level_zero/core/test/unit_tests/mocks/mock_device.h"
15 #include "level_zero/core/test/unit_tests/mocks/mock_driver.h"
16 #include "level_zero/core/test/unit_tests/mocks/mock_memory_manager.h"
17 #include "level_zero/core/test/unit_tests/mocks/mock_module.h"
18 #include "level_zero/experimental/source/tracing/tracing.h"
19 #include "level_zero/experimental/source/tracing/tracing_imp.h"
20 #include <level_zero/zet_api.h>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 
25 #include <array>
26 #include <iostream>
27 
28 using ::testing::_;
29 using ::testing::Return;
30 
31 namespace L0 {
32 
33 extern struct APITracerContextImp *pGlobalAPITracerContextImp;
34 
35 namespace ult {
36 template <typename TFunctionPointer, typename... Args>
callHandleTracerRecursion(TFunctionPointer zeApiPtr,Args &&...args)37 ze_result_t callHandleTracerRecursion(TFunctionPointer zeApiPtr, Args &&...args) {
38     ZE_HANDLE_TRACER_RECURSION(zeApiPtr, args...);
39     return ZE_RESULT_ERROR_UNKNOWN;
40 }
41 
42 class ZeAPITracingCoreTestsFixture {
43   public:
ZeAPITracingCoreTestsFixture()44     ZeAPITracingCoreTestsFixture(){};
45 
46   protected:
SetUp()47     virtual void SetUp() { //NOLINT
48         driver_ddiTable.enableTracing = true;
49         myThreadPrivateTracerData.onList = false;
50         myThreadPrivateTracerData.isInitialized = false;
51         myThreadPrivateTracerData.testAndSetThreadTracerDataInitializedAndOnList();
52     }
53 
TearDown()54     virtual void TearDown() { //NOLINT
55         myThreadPrivateTracerData.removeThreadTracerDataFromList();
56         driver_ddiTable.enableTracing = false;
57     }
58 };
59 
60 class zeAPITracingCoreTests : public ZeAPITracingCoreTestsFixture, public ::testing::Test {
61 
62   protected:
SetUp()63     void SetUp() override { //NOLINT
64         ZeAPITracingCoreTestsFixture::SetUp();
65     }
66 
TearDown()67     void TearDown() override { //NOLINT
68         ZeAPITracingCoreTestsFixture::TearDown();
69     }
70 };
71 
72 class zeAPITracingRuntimeTests : public ZeAPITracingCoreTestsFixture, public ::testing::Test {
73 
74   protected:
75     zet_core_callbacks_t prologCbs = {};
76     zet_core_callbacks_t epilogCbs = {};
77     zet_tracer_exp_handle_t apiTracerHandle;
78     zet_tracer_exp_desc_t tracerDesc;
79     int defaultUserData = 0;
80     void *userData;
81 
SetUp()82     void SetUp() override { //NOLINT
83         ze_result_t result;
84 
85         ZeAPITracingCoreTestsFixture::SetUp();
86         userData = &defaultUserData;
87         tracerDesc.pUserData = userData;
88         result = zetTracerExpCreate(nullptr, &tracerDesc, &apiTracerHandle);
89         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
90         EXPECT_NE(nullptr, apiTracerHandle);
91     }
92 
TearDown()93     void TearDown() override { //NOLINT
94         ze_result_t result;
95 
96         result = zetTracerExpSetEnabled(apiTracerHandle, false);
97         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
98         result = zetTracerExpDestroy(apiTracerHandle);
99         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
100         ZeAPITracingCoreTestsFixture::TearDown();
101     }
102 
setTracerCallbacksAndEnableTracer()103     void setTracerCallbacksAndEnableTracer() {
104         ze_result_t result;
105         result = zetTracerExpSetPrologues(apiTracerHandle, &prologCbs);
106         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
107 
108         result = zetTracerExpSetEpilogues(apiTracerHandle, &epilogCbs);
109         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
110 
111         result = zetTracerExpSetEnabled(apiTracerHandle, true);
112         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
113     }
114 };
115 
116 class zeAPITracingRuntimeMultipleArgumentsTests : public ZeAPITracingCoreTestsFixture, public ::testing::Test {
117 
118   protected:
119     zet_core_callbacks_t prologCbs0 = {};
120     zet_core_callbacks_t epilogCbs0 = {};
121     zet_core_callbacks_t prologCbs1 = {};
122     zet_core_callbacks_t epilogCbs2 = {};
123     zet_core_callbacks_t prologCbs3 = {};
124     zet_core_callbacks_t epilogCbs3 = {};
125     zet_tracer_exp_handle_t apiTracerHandle0;
126     zet_tracer_exp_handle_t apiTracerHandle1;
127     zet_tracer_exp_handle_t apiTracerHandle2;
128     zet_tracer_exp_handle_t apiTracerHandle3;
129     zet_tracer_exp_desc_t tracerDesc0;
130     zet_tracer_exp_desc_t tracerDesc1;
131     zet_tracer_exp_desc_t tracerDesc2;
132     zet_tracer_exp_desc_t tracerDesc3;
133     int defaultUserData0 = 1;
134     void *pUserData0;
135     int defaultUserData1 = 11;
136     void *pUserData1;
137     int defaultUserdata2 = 21;
138     void *pUserData2;
139     int defaultUserData3 = 31;
140     void *pUserData3;
141 
SetUp()142     void SetUp() override { //NOLINT
143         ze_result_t result;
144 
145         ZeAPITracingCoreTestsFixture::SetUp();
146 
147         pUserData0 = &defaultUserData0;
148         tracerDesc0.pUserData = pUserData0;
149         result = zetTracerExpCreate(nullptr, &tracerDesc0, &apiTracerHandle0);
150         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
151         EXPECT_NE(nullptr, apiTracerHandle0);
152 
153         pUserData1 = &defaultUserData1;
154         tracerDesc1.pUserData = pUserData1;
155         result = zetTracerExpCreate(nullptr, &tracerDesc1, &apiTracerHandle1);
156         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
157         EXPECT_NE(nullptr, apiTracerHandle1);
158 
159         pUserData2 = &defaultUserdata2;
160         tracerDesc2.pUserData = pUserData2;
161         result = zetTracerExpCreate(nullptr, &tracerDesc2, &apiTracerHandle2);
162         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
163         EXPECT_NE(nullptr, apiTracerHandle2);
164 
165         pUserData3 = &defaultUserData3;
166         tracerDesc3.pUserData = pUserData3;
167         result = zetTracerExpCreate(nullptr, &tracerDesc3, &apiTracerHandle3);
168         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
169         EXPECT_NE(nullptr, apiTracerHandle3);
170     }
171 
TearDown()172     void TearDown() override { //NOLINT
173         ze_result_t result;
174         result = zetTracerExpSetEnabled(apiTracerHandle0, false);
175         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
176         result = zetTracerExpDestroy(apiTracerHandle0);
177         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
178 
179         result = zetTracerExpSetEnabled(apiTracerHandle1, false);
180         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
181         result = zetTracerExpDestroy(apiTracerHandle1);
182         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
183 
184         result = zetTracerExpSetEnabled(apiTracerHandle2, false);
185         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
186         result = zetTracerExpDestroy(apiTracerHandle2);
187         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
188 
189         result = zetTracerExpSetEnabled(apiTracerHandle3, false);
190         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
191         result = zetTracerExpDestroy(apiTracerHandle3);
192         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
193 
194         ZeAPITracingCoreTestsFixture::TearDown();
195     }
196 
setTracerCallbacksAndEnableTracer()197     void setTracerCallbacksAndEnableTracer() {
198         ze_result_t result;
199 
200         /* Both prolog and epilog, pass instance data from prolog to epilog */
201         result = zetTracerExpSetPrologues(apiTracerHandle0, &prologCbs0);
202         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
203         result = zetTracerExpSetEpilogues(apiTracerHandle0, &epilogCbs0);
204         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
205         result = zetTracerExpSetEnabled(apiTracerHandle0, true);
206         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
207 
208         /* prolog only */
209         result = zetTracerExpSetPrologues(apiTracerHandle1, &prologCbs1);
210         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
211         result = zetTracerExpSetEnabled(apiTracerHandle1, true);
212         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
213 
214         /* epilog only */
215         result = zetTracerExpSetEpilogues(apiTracerHandle2, &epilogCbs2);
216         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
217         result = zetTracerExpSetEnabled(apiTracerHandle2, true);
218         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
219 
220         /* Both prolog and epilog, pass instance data from prolog to epilog */
221         result = zetTracerExpSetPrologues(apiTracerHandle3, &prologCbs3);
222         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
223         result = zetTracerExpSetEpilogues(apiTracerHandle3, &epilogCbs3);
224         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
225         result = zetTracerExpSetEnabled(apiTracerHandle3, true);
226         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
227     }
228 
validateDefaultUserDataFinal()229     void validateDefaultUserDataFinal() {
230         EXPECT_EQ(defaultUserData0, 3);
231         EXPECT_EQ(defaultUserData1, 22);
232         EXPECT_EQ(defaultUserdata2, 42);
233         EXPECT_EQ(defaultUserData3, 93);
234     }
235 };
236 
237 template <typename Tparams>
genericPrologCallbackPtr(Tparams params,ze_result_t result,void * pTracerUserData,void ** ppTracerInstanceUserData)238 void genericPrologCallbackPtr(Tparams params, ze_result_t result, void *pTracerUserData, void **ppTracerInstanceUserData) {
239     EXPECT_NE(nullptr, pTracerUserData);
240     int *val = static_cast<int *>(pTracerUserData);
241     *val += 1;
242 }
243 
244 template <typename Tparams>
genericEpilogCallbackPtr(Tparams params,ze_result_t result,void * pTracerUserData,void ** ppTracerInstanceUserData)245 void genericEpilogCallbackPtr(Tparams params, ze_result_t result, void *pTracerUserData, void **ppTracerInstanceUserData) {
246     EXPECT_NE(nullptr, pTracerUserData);
247     int *val = static_cast<int *>(pTracerUserData);
248     EXPECT_EQ(*val, 1);
249 }
250 
251 template <typename THandleType>
generateRandomHandle()252 THandleType generateRandomHandle() {
253     return reinterpret_cast<THandleType>(static_cast<uint64_t>(rand() % (RAND_MAX - 1) + 1));
254 }
255 
256 template <typename TSizeType>
generateRandomSize()257 TSizeType generateRandomSize() {
258     return static_cast<TSizeType>(rand());
259 }
260 
261 struct instanceDataStruct {
262     void *instanceDataValue;
263 };
264 
265 } // namespace ult
266 } // namespace L0
267