6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
+ #include < detail/config.hpp>
9
10
#include < detail/handler_impl.hpp>
10
11
#include < detail/kernel_bundle_impl.hpp>
12
+ #include < detail/program_manager/program_manager.hpp>
11
13
#include < detail/queue_impl.hpp>
12
14
#include < detail/scheduler/commands.hpp>
13
15
#include < sycl/sycl.hpp>
14
16
15
17
#include < helpers/MockDeviceImage.hpp>
16
18
#include < helpers/MockKernelInfo.hpp>
19
+ #include < helpers/ScopedEnvVar.hpp>
17
20
#include < helpers/UrMock.hpp>
18
21
19
22
#include < gtest/gtest.h>
@@ -98,28 +101,17 @@ static sycl::unittest::MockDeviceImageArray<1> EAMImgArray{&EAMImg};
98
101
static sycl::unittest::MockDeviceImageArray<1 > EAM2ImgArray{&EAM2Img};
99
102
static sycl::unittest::MockDeviceImageArray<1 > EAM3ImgArray{&EAM3Img};
100
103
101
- // ur_program_handle_t address is used as a key for ProgramManager::NativePrograms
102
- // storage. redefinedProgramLinkCommon makes ur_program_handle_t address equal to 0x1.
103
- // Make sure that size of Bin is different for device images used in these tests
104
- // and greater than 1.
104
+ // ur_program_handle_t address is used as a key for
105
+ // ProgramManager::NativePrograms storage. redefinedProgramLinkCommon makes
106
+ // ur_program_handle_t address equal to 0x1. Make sure that size of Bin is
107
+ // different for device images used in these tests and greater than 1.
105
108
inline ur_result_t redefinedProgramCreateEAM (void *pParams) {
106
109
auto params = *static_cast <ur_program_create_with_il_params_t *>(pParams);
107
110
static size_t UrProgramAddr = 2 ;
108
111
**params.pphProgram = reinterpret_cast <ur_program_handle_t >(UrProgramAddr++);
109
112
return UR_RESULT_SUCCESS;
110
113
}
111
114
112
- mock::dummy_handle_t_ FixedHandle;
113
- inline ur_result_t setFixedProgramPtr (void *pParams) {
114
- auto params = *static_cast <ur_program_create_with_il_params_t *>(pParams);
115
- **params.pphProgram = reinterpret_cast <ur_program_handle_t >(&FixedHandle);
116
- return UR_RESULT_SUCCESS;
117
- }
118
- inline ur_result_t releaseFixedProgramPtr (void *pParams) {
119
- // Do nothing
120
- return UR_RESULT_SUCCESS;
121
- }
122
-
123
115
class MockHandler : public sycl ::handler {
124
116
125
117
public:
@@ -218,6 +210,53 @@ TEST(EliminatedArgMask, KernelBundleWith2Kernels) {
218
210
EXPECT_EQ (*EliminatedArgMask, ExpElimArgMask);
219
211
}
220
212
213
+ std::vector<std::unique_ptr<mock::dummy_handle_t_>> UsedProgramHandles;
214
+ std::vector<std::unique_ptr<mock::dummy_handle_t_>> ProgramHandlesToReuse;
215
+ inline ur_result_t setFixedProgramPtr (void *pParams) {
216
+ auto params = *static_cast <ur_program_create_with_il_params_t *>(pParams);
217
+ if (!ProgramHandlesToReuse.empty ()) {
218
+ auto it = ProgramHandlesToReuse.begin () + 1 ;
219
+ std::move (ProgramHandlesToReuse.begin (), it,
220
+ std::back_inserter (UsedProgramHandles));
221
+ ProgramHandlesToReuse.erase (ProgramHandlesToReuse.begin (), it);
222
+ } else
223
+ UsedProgramHandles.push_back (
224
+ std::make_unique<mock::dummy_handle_t_>(sizeof (unsigned )));
225
+ **params.pphProgram =
226
+ reinterpret_cast <ur_program_handle_t >(UsedProgramHandles.back ().get ());
227
+ return UR_RESULT_SUCCESS;
228
+ }
229
+ inline ur_result_t releaseFixedProgramPtr (void *pParams) {
230
+ auto params = *static_cast <ur_program_release_params_t *>(pParams);
231
+ {
232
+ auto it = std::find_if (
233
+ UsedProgramHandles.begin (), UsedProgramHandles.end (),
234
+ [¶ms](const std::unique_ptr<mock::dummy_handle_t_> &item) {
235
+ return reinterpret_cast <ur_program_handle_t >(item.get ()) ==
236
+ *params.phProgram ;
237
+ });
238
+ if (it == UsedProgramHandles.end ())
239
+ return UR_RESULT_SUCCESS;
240
+ std::move (it, it + 1 , std::back_inserter (ProgramHandlesToReuse));
241
+ UsedProgramHandles.erase (it, it + 1 );
242
+ }
243
+ return UR_RESULT_SUCCESS;
244
+ }
245
+
246
+ inline ur_result_t customProgramRetain (void *pParams) {
247
+ // do nothing
248
+ return UR_RESULT_SUCCESS;
249
+ }
250
+
251
+ class ProgramManagerTest {
252
+ public:
253
+ static std::unordered_multimap<ur_program_handle_t ,
254
+ const sycl::detail::RTDeviceBinaryImage *> &
255
+ getNativePrograms () {
256
+ return sycl::detail::ProgramManager::getInstance ().NativePrograms ;
257
+ }
258
+ };
259
+
221
260
// It's possible for the same handle to be reused for multiple distinct programs
222
261
// This can happen if a program is released (freeing underlying memory) and then
223
262
// a new program happens to get given that same memory for its handle.
@@ -227,6 +266,7 @@ TEST(EliminatedArgMask, KernelBundleWith2Kernels) {
227
266
TEST (EliminatedArgMask, ReuseOfHandleValues) {
228
267
sycl::detail::ProgramManager &PM =
229
268
sycl::detail::ProgramManager::getInstance ();
269
+ auto &NativePrograms = ProgramManagerTest::getNativePrograms ();
230
270
231
271
ur_program_handle_t ProgBefore = nullptr ;
232
272
ur_program_handle_t ProgAfter = nullptr ;
@@ -238,6 +278,8 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
238
278
&setFixedProgramPtr);
239
279
mock::getCallbacks ().set_replace_callback (" urProgramRelease" ,
240
280
&releaseFixedProgramPtr);
281
+ mock::getCallbacks ().set_replace_callback (" urProgramRetain" ,
282
+ &customProgramRetain);
241
283
242
284
const sycl::device Dev = Plt.get_devices ()[0 ];
243
285
sycl::queue Queue{Dev};
@@ -247,8 +289,12 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
247
289
auto Mask = PM.getEliminatedKernelArgMask (ProgBefore, Name);
248
290
EXPECT_NE (Mask, nullptr );
249
291
EXPECT_EQ (Mask->at (0 ), 1 );
292
+ EXPECT_EQ (UsedProgramHandles.size (), 1u );
293
+ EXPECT_EQ (NativePrograms.count (ProgBefore), 1u );
250
294
}
251
295
296
+ EXPECT_EQ (UsedProgramHandles.size (), 0u );
297
+
252
298
{
253
299
auto Name = sycl::detail::KernelInfo<EAMTestKernel3>::getName ();
254
300
sycl::unittest::UrMock<> Mock;
@@ -257,6 +303,8 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
257
303
&setFixedProgramPtr);
258
304
mock::getCallbacks ().set_replace_callback (" urProgramRelease" ,
259
305
&releaseFixedProgramPtr);
306
+ mock::getCallbacks ().set_replace_callback (" urProgramRetain" ,
307
+ &customProgramRetain);
260
308
261
309
const sycl::device Dev = Plt.get_devices ()[0 ];
262
310
sycl::queue Queue{Dev};
@@ -266,6 +314,8 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
266
314
auto Mask = PM.getEliminatedKernelArgMask (ProgAfter, Name);
267
315
EXPECT_NE (Mask, nullptr );
268
316
EXPECT_EQ (Mask->at (0 ), 0 );
317
+ EXPECT_EQ (UsedProgramHandles.size (), 1u );
318
+ EXPECT_EQ (NativePrograms.count (ProgBefore), 1u );
269
319
}
270
320
271
321
// Verify that the test is behaving correctly and that the pointer is being
0 commit comments