Repository navigation
Pass the SYCL submission error to SyclKernelSubmitError #2414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,7 @@ from ._backend cimport ( # noqa: E211 | |
| DPCTLQueue_GetBackend, | ||
| DPCTLQueue_GetContext, | ||
| DPCTLQueue_GetDevice, | ||
| DPCTLQueue_GetLastSubmitError, | ||
| DPCTLQueue_HasEnableProfiling, | ||
| DPCTLQueue_Hash, | ||
| DPCTLQueue_IsInOrder, | ||
|
|
@@ -1459,7 +1460,8 @@ cdef class SyclQueue(_SyclQueue): | |
| of arguments the kernel takes. | ||
| SyclKernelSubmitError: | ||
| If ``kernel`` does not reference a ``sycl::kernel``, or if | ||
| submission to the queue fails. | ||
| submission to the queue fails. The message includes the | ||
| reason reported by the SYCL runtime, if any. | ||
| """ | ||
| cdef void **kargs = NULL | ||
| cdef _arg_data_type *kargty = NULL | ||
|
|
@@ -1591,8 +1593,13 @@ cdef class SyclQueue(_SyclQueue): | |
| free(depEvents) | ||
|
|
||
| if Eref is NULL: | ||
| # the C API keeps the reason, e.g. the text of the SYCL exception | ||
| reason = DPCTLQueue_GetLastSubmitError().decode( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing between the submit and this read touches the thread-local now, but reading the error right after |
||
| "utf-8", errors="replace" | ||
| ) | ||
| msg = "Kernel submission to Sycl queue failed" | ||
| raise SyclKernelSubmitError( | ||
| "Kernel submission to Sycl queue failed." | ||
| f"{msg}: {reason}" if reason else f"{msg}." | ||
| ) | ||
|
|
||
| return SyclEvent._create(Eref) | ||
|
|
@@ -1637,7 +1644,8 @@ cdef class SyclQueue(_SyclQueue): | |
| of arguments the kernel takes. | ||
| SyclKernelSubmitError: | ||
| If ``kernel`` does not reference a ``sycl::kernel``, or if | ||
| submission to the queue fails. | ||
| submission to the queue fails. The message includes the | ||
| reason reported by the SYCL runtime, if any. | ||
| """ | ||
| cdef SyclEvent e = self.submit_async(kernel, args, gS, lS, dEvents) | ||
| e.wait() | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,6 +39,7 @@ | |||||||
| #include <exception> | ||||||||
| #include <sstream> | ||||||||
| #include <stdexcept> | ||||||||
| #include <string> | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| #include <sycl/sycl.hpp> /* SYCL headers */ | ||||||||
| #include <utility> | ||||||||
| #include <vector> | ||||||||
|
|
@@ -120,6 +121,22 @@ using namespace sycl; | |||||||
| } \ | ||||||||
| } while (0); | ||||||||
|
|
||||||||
| namespace | ||||||||
| { | ||||||||
| // Reason for the last failed DPCTLQueue_SubmitRange or | ||||||||
| // DPCTLQueue_SubmitNDRange call in the calling thread, or an empty string if | ||||||||
| // the last call succeeded. | ||||||||
| thread_local std::string last_submit_error; | ||||||||
|
|
||||||||
| std::nullptr_t | ||||||||
| submit_failed(const std::string &Msg, const char *func_name, int line_num) | ||||||||
| { | ||||||||
| last_submit_error = Msg; | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This runs inside the |
||||||||
| error_handler(Msg, __FILE__, func_name, line_num, error_level::error); | ||||||||
| return nullptr; | ||||||||
| } | ||||||||
| } // namespace | ||||||||
|
|
||||||||
| namespace | ||||||||
| { | ||||||||
| static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED, | ||||||||
|
|
@@ -498,16 +515,15 @@ DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef, | |||||||
| __dpctl_keep const DPCTLSyclEventRef *DepEvents, | ||||||||
| size_t NDepEvents) | ||||||||
| { | ||||||||
| if (!KRef) { | ||||||||
| error_handler("Cannot submit the kernel as the kernel is a nullptr.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| } | ||||||||
| if (!QRef) { | ||||||||
| error_handler("Cannot submit the kernel as the queue is a nullptr.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| } | ||||||||
| last_submit_error.clear(); | ||||||||
| if (!KRef) | ||||||||
| return submit_failed( | ||||||||
| "Cannot submit the kernel as the kernel is a nullptr.", __func__, | ||||||||
| __LINE__); | ||||||||
| if (!QRef) | ||||||||
| return submit_failed( | ||||||||
| "Cannot submit the kernel as the queue is a nullptr.", __func__, | ||||||||
| __LINE__); | ||||||||
|
|
||||||||
| auto Kernel = unwrap<kernel>(KRef); | ||||||||
| auto Queue = unwrap<queue>(QRef); | ||||||||
|
|
@@ -547,18 +563,15 @@ DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef, | |||||||
| return wrap<event>(new event(std::move(e))); | ||||||||
| } | ||||||||
| default: | ||||||||
| error_handler("Range cannot be greater than three " | ||||||||
| "dimensions.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed("Range cannot be greater than three " | ||||||||
| "dimensions.", | ||||||||
| __func__, __LINE__); | ||||||||
| } | ||||||||
| } catch (std::exception const &e) { | ||||||||
| error_handler(e, __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed(e.what(), __func__, __LINE__); | ||||||||
| } catch (...) { | ||||||||
| error_handler("Unknown exception encountered", __FILE__, __func__, | ||||||||
| __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed("Unknown exception encountered", __func__, | ||||||||
| __LINE__); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -574,16 +587,15 @@ DPCTLQueue_SubmitNDRange(__dpctl_keep const DPCTLSyclKernelRef KRef, | |||||||
| __dpctl_keep const DPCTLSyclEventRef *DepEvents, | ||||||||
| size_t NDepEvents) | ||||||||
| { | ||||||||
| if (!KRef) { | ||||||||
| error_handler("Cannot submit the kernel as the kernel is a nullptr.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| } | ||||||||
| if (!QRef) { | ||||||||
| error_handler("Cannot submit the kernel as the queue is a nullptr.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| } | ||||||||
| last_submit_error.clear(); | ||||||||
| if (!KRef) | ||||||||
| return submit_failed( | ||||||||
| "Cannot submit the kernel as the kernel is a nullptr.", __func__, | ||||||||
| __LINE__); | ||||||||
| if (!QRef) | ||||||||
| return submit_failed( | ||||||||
| "Cannot submit the kernel as the queue is a nullptr.", __func__, | ||||||||
| __LINE__); | ||||||||
|
|
||||||||
| auto Kernel = unwrap<kernel>(KRef); | ||||||||
| auto Queue = unwrap<queue>(QRef); | ||||||||
|
|
@@ -627,21 +639,23 @@ DPCTLQueue_SubmitNDRange(__dpctl_keep const DPCTLSyclKernelRef KRef, | |||||||
| return wrap<event>(new event(std::move(e))); | ||||||||
| } | ||||||||
| default: | ||||||||
| error_handler("Range cannot be greater than three " | ||||||||
| "dimensions.", | ||||||||
| __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed("Range cannot be greater than three " | ||||||||
| "dimensions.", | ||||||||
| __func__, __LINE__); | ||||||||
| } | ||||||||
| } catch (std::exception const &e) { | ||||||||
| error_handler(e, __FILE__, __func__, __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed(e.what(), __func__, __LINE__); | ||||||||
| } catch (...) { | ||||||||
| error_handler("Unknown exception encountered", __FILE__, __func__, | ||||||||
| __LINE__, error_level::error); | ||||||||
| return nullptr; | ||||||||
| return submit_failed("Unknown exception encountered", __func__, | ||||||||
| __LINE__); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| const char *DPCTLQueue_GetLastSubmitError(void) | ||||||||
| { | ||||||||
| return last_submit_error.c_str(); | ||||||||
| } | ||||||||
|
|
||||||||
| void DPCTLQueue_Wait(__dpctl_keep DPCTLSyclQueueRef QRef) | ||||||||
| { | ||||||||
| // \todo what happens if the QRef is null or a pointer to a valid sycl | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -400,11 +400,65 @@ TEST_F(TestQueueSubmit, CheckForNullKernel) | |
| ERef = DPCTLQueue_SubmitRange(nullptr, QRef, nullptr, nullptr, 0, Range, | ||
| RANGE_NDIMS, nullptr, 0)); | ||
| ASSERT_TRUE(ERef == nullptr); | ||
| EXPECT_STRNE(DPCTLQueue_GetLastSubmitError(), ""); | ||
|
|
||
| EXPECT_NO_FATAL_FAILURE(ERef = DPCTLQueue_SubmitNDRange( | ||
| nullptr, QRef, nullptr, nullptr, 0, Range, | ||
| lRange, RANGE_NDIMS, nullptr, 0)); | ||
| ASSERT_TRUE(ERef == nullptr); | ||
| EXPECT_STRNE(DPCTLQueue_GetLastSubmitError(), ""); | ||
| } | ||
|
|
||
| TEST_F(TestQueueSubmit, CheckLastSubmitError) | ||
| { | ||
| // a local range that exceeds the device's maximum work-group size makes | ||
| // sycl::queue::submit throw; a global range that is not a multiple of | ||
| // the local range does not, as OpenCL devices may support non-uniform | ||
| // work-groups | ||
| auto DRef = DPCTLQueue_GetDevice(QRef); | ||
| ASSERT_TRUE(DRef != nullptr); | ||
| std::size_t maxWGSize = DPCTLDevice_GetMaxWorkGroupSize(DRef); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef)); | ||
| ASSERT_TRUE(maxWGSize > 0); | ||
|
|
||
| std::size_t gRange[] = {2 * maxWGSize}; | ||
| std::size_t lRange[] = {2 * maxWGSize}; | ||
| std::size_t Range[] = {SIZE}; | ||
| std::size_t RANGE_NDIMS = 1; | ||
| DPCTLSyclEventRef ERef = nullptr; | ||
|
|
||
| auto kernel = DPCTLKernelBundle_GetKernel(KBRef, "_ZTS11RangeKernelIiE"); | ||
| ASSERT_TRUE(kernel != nullptr); | ||
|
|
||
| auto a = DPCTLmalloc_shared(SIZE * sizeof(int), QRef); | ||
| auto b = DPCTLmalloc_shared(SIZE * sizeof(int), QRef); | ||
| auto c = DPCTLmalloc_shared(SIZE * sizeof(int), QRef); | ||
| ASSERT_TRUE(a && b && c); | ||
| int scalarVal = 3; | ||
| void *args[] = {unwrap<void>(a), unwrap<void>(b), unwrap<void>(c), | ||
| (void *)&scalarVal}; | ||
| DPCTLKernelArgType argTypes[] = {DPCTL_VOID_PTR, DPCTL_VOID_PTR, | ||
| DPCTL_VOID_PTR, DPCTL_INT32_T}; | ||
|
|
||
| EXPECT_NO_FATAL_FAILURE( | ||
| ERef = DPCTLQueue_SubmitNDRange(kernel, QRef, args, argTypes, 4, gRange, | ||
| lRange, RANGE_NDIMS, nullptr, 0)); | ||
| ASSERT_TRUE(ERef == nullptr); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this or the |
||
| EXPECT_STRNE(DPCTLQueue_GetLastSubmitError(), ""); | ||
|
|
||
| // a successful submission clears the error | ||
| EXPECT_NO_FATAL_FAILURE( | ||
| ERef = DPCTLQueue_SubmitRange(kernel, QRef, args, argTypes, 4, Range, | ||
| RANGE_NDIMS, nullptr, 0)); | ||
| ASSERT_TRUE(ERef != nullptr); | ||
| EXPECT_STREQ(DPCTLQueue_GetLastSubmitError(), ""); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Wait(ERef)); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Delete(ERef)); | ||
|
|
||
| EXPECT_NO_FATAL_FAILURE(DPCTLfree_with_queue(a, QRef)); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLfree_with_queue(b, QRef)); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLfree_with_queue(c, QRef)); | ||
| EXPECT_NO_FATAL_FAILURE(DPCTLKernel_Delete(kernel)); | ||
| } | ||
|
|
||
| TEST_F(TestQueueSubmit, CheckForNullQueue) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are two separate changes, can we split them into two entries?