@@ -108,17 +108,6 @@ inline ur_result_t redefinedProgramCreateEAM(void *pParams) {
108108 return UR_RESULT_SUCCESS;
109109}
110110
111- mock::dummy_handle_t_ FixedHandle;
112- inline ur_result_t setFixedProgramPtr (void *pParams) {
113- auto params = *static_cast <ur_program_create_with_il_params_t *>(pParams);
114- **params.pphProgram = reinterpret_cast <ur_program_handle_t >(&FixedHandle);
115- return UR_RESULT_SUCCESS;
116- }
117- inline ur_result_t releaseFixedProgramPtr (void *pParams) {
118- // Do nothing
119- return UR_RESULT_SUCCESS;
120- }
121-
122111class MockHandler : public sycl ::handler {
123112
124113public:
@@ -217,6 +206,41 @@ TEST(EliminatedArgMask, KernelBundleWith2Kernels) {
217206 EXPECT_EQ (*EliminatedArgMask, ExpElimArgMask);
218207}
219208
209+ std::vector<std::unique_ptr<mock::dummy_handle_t_>> UsedProgramHandles;
210+ std::vector<std::unique_ptr<mock::dummy_handle_t_>> ProgramHandlesToReuse;
211+
212+ inline ur_result_t setFixedProgramPtr (void *pParams) {
213+ auto params = *static_cast <ur_program_create_with_il_params_t *>(pParams);
214+ if (ProgramHandlesToReuse.size ())
215+ {
216+ auto it = ProgramHandlesToReuse.begin ()+1 ;
217+ std::move (ProgramHandlesToReuse.begin (), it, std::back_inserter (UsedProgramHandles));
218+ ProgramHandlesToReuse.erase (ProgramHandlesToReuse.begin (), it);
219+ }
220+ else
221+ UsedProgramHandles.push_back (std::make_unique<mock::dummy_handle_t_>(mock::createDummyHandle<ur_program_handle_t >(sizeof (unsigned ))));
222+ **params.pphProgram = *reinterpret_cast <ur_program_handle_t *>(UsedProgramHandles.back ().get ());
223+ std::cout << " **params.pphProgram = " << **params.pphProgram << std::endl;
224+ return UR_RESULT_SUCCESS;
225+ }
226+ inline ur_result_t releaseFixedProgramPtr (void *pParams) {
227+ ur_program_handle_t & params = *static_cast <ur_program_handle_t *>(pParams);
228+ {
229+ auto it = std::find_if (UsedProgramHandles.begin (), UsedProgramHandles.end (), [¶ms](const std::unique_ptr<mock::dummy_handle_t_>& item){ return *reinterpret_cast <ur_program_handle_t *>(item.get ()) == params; });
230+ if (it == UsedProgramHandles.end ())
231+ return UR_RESULT_SUCCESS;
232+ std::cout << " releaseFixedProgramPtr = " << params << std::endl;
233+ std::move (it, it + 1 , std::back_inserter (ProgramHandlesToReuse));
234+ UsedProgramHandles.erase (it, it +1 );
235+ }
236+ return UR_RESULT_SUCCESS;
237+ }
238+
239+ inline ur_result_t customProgramRetain (void *pParams) {
240+ // do nothing
241+ return UR_RESULT_SUCCESS;
242+ }
243+
220244// It's possible for the same handle to be reused for multiple distinct programs
221245// This can happen if a program is released (freeing underlying memory) and then
222246// a new program happens to get given that same memory for its handle.
@@ -237,6 +261,8 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
237261 &setFixedProgramPtr);
238262 mock::getCallbacks ().set_replace_callback (" urProgramRelease" ,
239263 &releaseFixedProgramPtr);
264+ mock::getCallbacks ().set_replace_callback (" urProgramRetain" ,
265+ &customProgramRetain);
240266
241267 const sycl::device Dev = Plt.get_devices ()[0 ];
242268 sycl::queue Queue{Dev};
@@ -246,6 +272,7 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
246272 auto Mask = PM.getEliminatedKernelArgMask (ProgBefore, Name);
247273 EXPECT_NE (Mask, nullptr );
248274 EXPECT_EQ (Mask->at (0 ), 1 );
275+ EXPECT_EQ (UsedProgramHandles.size (), 1u );
249276 }
250277
251278 {
@@ -256,6 +283,8 @@ TEST(EliminatedArgMask, ReuseOfHandleValues) {
256283 &setFixedProgramPtr);
257284 mock::getCallbacks ().set_replace_callback (" urProgramRelease" ,
258285 &releaseFixedProgramPtr);
286+ mock::getCallbacks ().set_replace_callback (" urProgramRetain" ,
287+ &customProgramRetain);
259288
260289 const sycl::device Dev = Plt.get_devices ()[0 ];
261290 sycl::queue Queue{Dev};
0 commit comments