diff --git a/dpctl-capi/include/dpctl_sycl_queue_interface.h b/dpctl-capi/include/dpctl_sycl_queue_interface.h index f4e4d0b7e6..104c3ed5d5 100644 --- a/dpctl-capi/include/dpctl_sycl_queue_interface.h +++ b/dpctl-capi/include/dpctl_sycl_queue_interface.h @@ -333,6 +333,17 @@ void DPCTLQueue_MemAdvise(__dpctl_keep DPCTLSyclQueueRef QRef, DPCTL_API bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef); +/*! + * @brief C-API wrapper for + * sycl::queue::has_property() that + * indicates whether the referenced queue was constructed with this property. + * + * @param QRef An opaque pointer to the ``sycl::queue``. + * @ingroup QueueInterface + */ +DPCTL_API +bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef); + /*! * @brief C-API wrapper for std::hash's operator(). * diff --git a/dpctl-capi/source/dpctl_sycl_queue_interface.cpp b/dpctl-capi/source/dpctl_sycl_queue_interface.cpp index 6a3ffb15fd..adb60035ae 100644 --- a/dpctl-capi/source/dpctl_sycl_queue_interface.cpp +++ b/dpctl-capi/source/dpctl_sycl_queue_interface.cpp @@ -520,6 +520,16 @@ bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef) return false; } +bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef) +{ + auto Q = unwrap(QRef); + if (Q) { + return Q->has_property(); + } + else + return false; +} + size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef) { auto Q = unwrap(QRef); diff --git a/dpctl-capi/tests/test_sycl_queue_interface.cpp b/dpctl-capi/tests/test_sycl_queue_interface.cpp index 5aa25bc18b..219373bc1f 100644 --- a/dpctl-capi/tests/test_sycl_queue_interface.cpp +++ b/dpctl-capi/tests/test_sycl_queue_interface.cpp @@ -115,7 +115,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckCopy) EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef)); } -TEST(TestDPCTLSyclQueueInterface, CheckCopy_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckCopyInvalid) { DPCTLSyclQueueRef Q1 = nullptr; DPCTLSyclQueueRef Q2 = nullptr; @@ -125,7 +125,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckCopy_Invalid) EXPECT_NO_FATAL_FAILURE(DPCTLQueue_Delete(Q2)); } -TEST(TestDPCTLSyclQueueInterface, CheckAreEq_False) +TEST(TestDPCTLSyclQueueInterface, CheckAreEqFalse) { DPCTLSyclDeviceSelectorRef DSRef = nullptr; DPCTLSyclDeviceRef DRef = nullptr; @@ -152,7 +152,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckAreEq_False) EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef)); } -TEST(TestDPCTLSyclQueueInterface, CheckAreEq_True) +TEST(TestDPCTLSyclQueueInterface, CheckAreEqTrue) { DPCTLSyclDeviceSelectorRef DSRef = nullptr; DPCTLSyclDeviceRef DRef = nullptr; @@ -172,7 +172,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckAreEq_True) EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef)); } -TEST(TestDPCTLSyclQueueInterface, CheckAreEq_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckAreEqInvalid) { DPCTLSyclDeviceSelectorRef DSRef = nullptr; DPCTLSyclDeviceRef DRef = nullptr; @@ -192,7 +192,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckAreEq_Invalid) EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef)); } -TEST(TestDPCTLSyclQueueInterface, CheckHash_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckHashInvalid) { DPCTLSyclQueueRef Q1 = nullptr; DPCTLSyclQueueRef Q2 = nullptr; @@ -200,7 +200,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckHash_Invalid) EXPECT_TRUE(DPCTLQueue_Hash(Q2) == 0); } -TEST(TestDPCTLSyclQueueInterface, CheckGetBackend_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckGetBackendInvalid) { DPCTLSyclQueueRef Q = nullptr; DPCTLSyclBackendType Bty = DPCTL_UNKNOWN_BACKEND; @@ -208,7 +208,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckGetBackend_Invalid) EXPECT_TRUE(Bty == DPCTL_UNKNOWN_BACKEND); } -TEST(TestDPCTLSyclQueueInterface, CheckGetContext_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckGetContextInvalid) { DPCTLSyclQueueRef Q = nullptr; DPCTLSyclContextRef CRef = nullptr; @@ -216,7 +216,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckGetContext_Invalid) EXPECT_TRUE(CRef == nullptr); } -TEST(TestDPCTLSyclQueueInterface, CheckGetDevice_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckGetDeviceInvalid) { DPCTLSyclQueueRef Q = nullptr; DPCTLSyclDeviceRef DRef = nullptr; @@ -250,7 +250,7 @@ TEST(TestDPCTLSyclQueueInterface, CheckIsInOrder) EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef)); } -TEST(TestDPCTLSyclQueueInterface, CheckIsInOrder_Invalid) +TEST(TestDPCTLSyclQueueInterface, CheckIsInOrderInvalid) { bool ioq = true; DPCTLSyclQueueRef Q1 = nullptr; @@ -258,6 +258,40 @@ TEST(TestDPCTLSyclQueueInterface, CheckIsInOrder_Invalid) EXPECT_FALSE(ioq); } +TEST(TestDPCTLSyclQueueInterface, CheckHasEnableProfiling) +{ + bool ioq = true; + DPCTLSyclDeviceSelectorRef DSRef = nullptr; + DPCTLSyclDeviceRef DRef = nullptr; + DPCTLSyclQueueRef Q1 = nullptr; + DPCTLSyclQueueRef Q2 = nullptr; + + EXPECT_NO_FATAL_FAILURE(DSRef = DPCTLDefaultSelector_Create()); + EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef)); + EXPECT_NO_FATAL_FAILURE( + Q1 = DPCTLQueue_CreateForDevice(DRef, nullptr, DPCTL_DEFAULT_PROPERTY)); + EXPECT_NO_FATAL_FAILURE(ioq = DPCTLQueue_HasEnableProfiling(Q1)); + EXPECT_FALSE(ioq); + + EXPECT_NO_FATAL_FAILURE( + Q2 = DPCTLQueue_CreateForDevice(DRef, nullptr, DPCTL_ENABLE_PROFILING)); + EXPECT_NO_FATAL_FAILURE(ioq = DPCTLQueue_HasEnableProfiling(Q2)); + EXPECT_TRUE(ioq); + + EXPECT_NO_FATAL_FAILURE(DPCTLQueue_Delete(Q1)); + EXPECT_NO_FATAL_FAILURE(DPCTLQueue_Delete(Q2)); + EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef)); + EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef)); +} + +TEST(TestDPCTLSyclQueueInterface, CheckHasEnableProfilingInvalid) +{ + bool ioq = true; + DPCTLSyclQueueRef Q1 = nullptr; + EXPECT_NO_FATAL_FAILURE(ioq = DPCTLQueue_HasEnableProfiling(Q1)); + EXPECT_FALSE(ioq); +} + TEST_P(TestDPCTLQueueMemberFunctions, CheckGetBackend) { auto q = unwrap(QRef); diff --git a/dpctl/_backend.pxd b/dpctl/_backend.pxd index d514d064b9..4b6ca0303b 100644 --- a/dpctl/_backend.pxd +++ b/dpctl/_backend.pxd @@ -353,6 +353,7 @@ cdef extern from "dpctl_sycl_queue_interface.h": const DPCTLSyclQueueRef QRef, const DPCTLSyclEventRef *DepEvents, size_t NDepEvents) + cdef bool DPCTLQueue_HasEnableProfiling(const DPCTLSyclQueueRef QRef) cdef extern from "dpctl_sycl_queue_manager.h": diff --git a/dpctl/_sycl_queue.pyx b/dpctl/_sycl_queue.pyx index 198584280d..05a6a6ccdd 100644 --- a/dpctl/_sycl_queue.pyx +++ b/dpctl/_sycl_queue.pyx @@ -38,6 +38,7 @@ from ._backend cimport ( # noqa: E211 DPCTLQueue_GetBackend, DPCTLQueue_GetContext, DPCTLQueue_GetDevice, + DPCTLQueue_HasEnableProfiling, DPCTLQueue_Hash, DPCTLQueue_IsInOrder, DPCTLQueue_MemAdvise, @@ -851,17 +852,29 @@ cdef class SyclQueue(_SyclQueue): """True if SyclQueue is in-order, False if it is out-of-order.""" return DPCTLQueue_IsInOrder(self._queue_ref) + @property + def has_enable_profiling(self): + """True if SyclQueue was constructed with enabled_profiling property, + False otherwise.""" + return DPCTLQueue_HasEnableProfiling(self._queue_ref) + @property def __name__(self): return "SyclQueue" def __repr__(self): cdef cpp_bool in_order = DPCTLQueue_IsInOrder(self._queue_ref) - if in_order: + cdef cpp_bool en_prof = DPCTLQueue_HasEnableProfiling(self._queue_ref) + if in_order or en_prof: + prop = [] + if in_order: + prop.append("in_order") + if en_prof: + prop.append("enable_profiling") return ( "".format(hex(id(self))) + + " at {}, property={}>".format(hex(id(self)), prop) ) else: return "".format(hex(id(self))) diff --git a/dpctl/tests/test_sycl_queue.py b/dpctl/tests/test_sycl_queue.py index 0422368629..8957d578f8 100644 --- a/dpctl/tests/test_sycl_queue.py +++ b/dpctl/tests/test_sycl_queue.py @@ -373,6 +373,14 @@ def test_context_equals(): assert hash(ctx0) == hash(ctx1) +def test_has_enable_profiling(): + try: + q = dpctl.SyclQueue(property="enable_profiling") + except dpctl.SyclQueueCreationError: + pytest.skip() + assert q.has_enable_profiling + + def test_hashing_of_queue(): """ Test that a :class:`dpctl.SyclQueue` object can be used as