@@ -311,6 +311,160 @@ void addMemcpy2D(experimental::detail::modifiable_command_graph &G, queue &Q,
311311 ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
312312}
313313
314+ // / Tries to add nodes including images bindless copy instructions
315+ // / to the graph G. It tests that an invalid exception has been thrown
316+ // / Since sycl_ext_oneapi_bindless_images extension can not be used
317+ // / along with SYCL Graph.
318+ // /
319+ // / @param G Modifiable graph to add commands to.
320+ // / @param Q Queue to submit nodes to.
321+ // / @param Img Image memory
322+ // / @param HostData Host Pointer to the memory
323+ // / @param ImgUSM USM Pointer to Image memory
324+ // / @param Pitch image pitch
325+ // / @param Desc Image descriptor
326+ template <OperationPath PathKind>
327+ void addImagesCopies (experimental::detail::modifiable_command_graph &G,
328+ queue &Q, sycl::ext::oneapi::experimental::image_mem Img,
329+ std::vector<sycl::float4> HostData, void *ImgUSM,
330+ size_t Pitch,
331+ sycl::ext::oneapi::experimental::image_descriptor Desc) {
332+ // simple copy Host to Device
333+ std::error_code ExceptionCode = make_error_code (sycl::errc::success);
334+ try {
335+ if constexpr (PathKind == OperationPath::RecordReplay) {
336+ Q.submit ([&](handler &CGH) {
337+ CGH.ext_oneapi_copy (HostData.data (), Img.get_handle (), Desc);
338+ });
339+ }
340+ if constexpr (PathKind == OperationPath::Shortcut) {
341+ Q.ext_oneapi_copy (HostData.data (), Img.get_handle (), Desc);
342+ }
343+ if constexpr (PathKind == OperationPath::Explicit) {
344+ G.add ([&](handler &CGH) {
345+ CGH.ext_oneapi_copy (HostData.data (), Img.get_handle (), Desc);
346+ });
347+ }
348+ } catch (exception &Exception) {
349+ ExceptionCode = Exception.code ();
350+ }
351+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
352+
353+ // simple copy Device to Host
354+ ExceptionCode = make_error_code (sycl::errc::success);
355+ try {
356+ if constexpr (PathKind == OperationPath::RecordReplay) {
357+ Q.submit ([&](handler &CGH) {
358+ CGH.ext_oneapi_copy (Img.get_handle (), HostData.data (), Desc);
359+ });
360+ }
361+ if constexpr (PathKind == OperationPath::Shortcut) {
362+ Q.ext_oneapi_copy (Img.get_handle (), HostData.data (), Desc);
363+ }
364+ if constexpr (PathKind == OperationPath::Explicit) {
365+ G.add ([&](handler &CGH) {
366+ CGH.ext_oneapi_copy (Img.get_handle (), HostData.data (), Desc);
367+ });
368+ }
369+ } catch (exception &Exception) {
370+ ExceptionCode = Exception.code ();
371+ }
372+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
373+
374+ // simple copy Host to Device USM
375+ ExceptionCode = make_error_code (sycl::errc::success);
376+ try {
377+ if constexpr (PathKind == OperationPath::RecordReplay) {
378+ Q.submit ([&](handler &CGH) {
379+ CGH.ext_oneapi_copy (HostData.data (), ImgUSM, Desc, Pitch);
380+ });
381+ }
382+ if constexpr (PathKind == OperationPath::Shortcut) {
383+ Q.ext_oneapi_copy (HostData.data (), ImgUSM, Desc, Pitch);
384+ }
385+ if constexpr (PathKind == OperationPath::Explicit) {
386+ G.add ([&](handler &CGH) {
387+ CGH.ext_oneapi_copy (HostData.data (), ImgUSM, Desc, Pitch);
388+ });
389+ }
390+ } catch (exception &Exception) {
391+ ExceptionCode = Exception.code ();
392+ }
393+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
394+
395+ // subregion copy Host to Device
396+ ExceptionCode = make_error_code (sycl::errc::success);
397+ try {
398+ if constexpr (PathKind == OperationPath::RecordReplay) {
399+ Q.submit ([&](handler &CGH) {
400+ CGH.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, {0 , 0 , 0 },
401+ Img.get_handle (), {0 , 0 , 0 }, Desc, {0 , 0 , 0 });
402+ });
403+ }
404+ if constexpr (PathKind == OperationPath::Shortcut) {
405+ Q.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, {0 , 0 , 0 }, Img.get_handle (),
406+ {0 , 0 , 0 }, Desc, {0 , 0 , 0 });
407+ }
408+ if constexpr (PathKind == OperationPath::Explicit) {
409+ G.add ([&](handler &CGH) {
410+ CGH.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, {0 , 0 , 0 },
411+ Img.get_handle (), {0 , 0 , 0 }, Desc, {0 , 0 , 0 });
412+ });
413+ }
414+ } catch (exception &Exception) {
415+ ExceptionCode = Exception.code ();
416+ }
417+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
418+
419+ // subregion copy Device to Host
420+ ExceptionCode = make_error_code (sycl::errc::success);
421+ try {
422+ if constexpr (PathKind == OperationPath::RecordReplay) {
423+ Q.submit ([&](handler &CGH) {
424+ CGH.ext_oneapi_copy (Img.get_handle (), {0 , 0 , 0 }, Desc, HostData.data (),
425+ {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 });
426+ });
427+ }
428+ if constexpr (PathKind == OperationPath::Shortcut) {
429+ Q.ext_oneapi_copy (Img.get_handle (), {0 , 0 , 0 }, Desc, HostData.data (),
430+ {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 });
431+ }
432+ if constexpr (PathKind == OperationPath::Explicit) {
433+ G.add ([&](handler &CGH) {
434+ CGH.ext_oneapi_copy (Img.get_handle (), {0 , 0 , 0 }, Desc, HostData.data (),
435+ {0 , 0 , 0 }, {0 , 0 , 0 }, {0 , 0 , 0 });
436+ });
437+ }
438+ } catch (exception &Exception) {
439+ ExceptionCode = Exception.code ();
440+ }
441+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
442+
443+ // subregion copy Host to Device USM
444+ ExceptionCode = make_error_code (sycl::errc::success);
445+ try {
446+ if constexpr (PathKind == OperationPath::RecordReplay) {
447+ Q.submit ([&](handler &CGH) {
448+ CGH.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, ImgUSM, {0 , 0 , 0 }, Desc,
449+ Pitch, {0 , 0 , 0 }, {0 , 0 , 0 });
450+ });
451+ }
452+ if constexpr (PathKind == OperationPath::Shortcut) {
453+ Q.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, ImgUSM, {0 , 0 , 0 }, Desc,
454+ Pitch, {0 , 0 , 0 }, {0 , 0 , 0 });
455+ }
456+ if constexpr (PathKind == OperationPath::Explicit) {
457+ G.add ([&](handler &CGH) {
458+ CGH.ext_oneapi_copy (HostData.data (), {0 , 0 , 0 }, ImgUSM, {0 , 0 , 0 }, Desc,
459+ Pitch, {0 , 0 , 0 }, {0 , 0 , 0 });
460+ });
461+ }
462+ } catch (exception &Exception) {
463+ ExceptionCode = Exception.code ();
464+ }
465+ ASSERT_EQ (ExceptionCode, sycl::errc::invalid);
466+ }
467+
314468bool depthSearchSuccessorCheck (
315469 std::shared_ptr<sycl::ext::oneapi::experimental::detail::node_impl> Node) {
316470 if (Node->MSuccessors .size () > 1 )
@@ -1238,7 +1392,7 @@ TEST_F(CommandGraphTest, Reductions) {
12381392 {
12391393 try {
12401394 Graph.add ([&](handler &CGH) {
1241- CGH.parallel_for <class TestKernel >(
1395+ CGH.parallel_for <class CustomTestKernel >(
12421396 range<1 >{1 }, reduction (&ReduVar, int {0 }, sycl::plus ()),
12431397 [=](item<1 > idx, auto &Sum) {});
12441398 });
@@ -1250,6 +1404,45 @@ TEST_F(CommandGraphTest, Reductions) {
12501404 sycl::exception);
12511405}
12521406
1407+ TEST_F (CommandGraphTest, BindlessExceptionCheck) {
1408+ auto Ctxt = Queue.get_context ();
1409+
1410+ // declare image data
1411+ size_t Height = 13 ;
1412+ size_t Width = 7 ;
1413+ size_t Depth = 11 ;
1414+ size_t N = Height * Width * Depth;
1415+ std::vector<sycl::float4> DataIn (N);
1416+
1417+ // Extension: image descriptor - can use the same for both images
1418+ sycl::ext::oneapi::experimental::image_descriptor Desc (
1419+ {Width, Height, Depth}, sycl::image_channel_order::rgba,
1420+ sycl::image_channel_type::fp32);
1421+
1422+ // Extension: allocate memory on device and create the handle
1423+ // Input images memory
1424+ sycl::ext::oneapi::experimental::image_mem ImgMem (Desc, Dev, Ctxt);
1425+ // Extension: returns the device pointer to USM allocated pitched memory
1426+ size_t Pitch = 0 ;
1427+ auto ImgMemUSM = sycl::ext::oneapi::experimental::pitched_alloc_device (
1428+ &Pitch, Desc, Queue);
1429+
1430+ Graph.begin_recording (Queue);
1431+
1432+ addImagesCopies<OperationPath::RecordReplay>(Graph, Queue, ImgMem, DataIn,
1433+ ImgMemUSM, Pitch, Desc);
1434+
1435+ addImagesCopies<OperationPath::Shortcut>(Graph, Queue, ImgMem, DataIn,
1436+ ImgMemUSM, Pitch, Desc);
1437+
1438+ Graph.end_recording ();
1439+
1440+ addImagesCopies<OperationPath::Explicit>(Graph, Queue, ImgMem, DataIn,
1441+ ImgMemUSM, Pitch, Desc);
1442+
1443+ sycl::free (ImgMemUSM, Ctxt);
1444+ }
1445+
12531446class MultiThreadGraphTest : public CommandGraphTest {
12541447public:
12551448 MultiThreadGraphTest ()
0 commit comments