Skip to content

Commit e5c50ea

Browse files
Add DPCTLEvent_GetWaitList func (#510)
1 parent 893f1f6 commit e5c50ea

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

dpctl-capi/include/dpctl_sycl_event_interface.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,18 @@
3131
#include "dpctl_data_types.h"
3232
#include "dpctl_sycl_enum_types.h"
3333
#include "dpctl_sycl_types.h"
34+
#include "dpctl_vector.h"
3435

3536
DPCTL_C_EXTERN_C_BEGIN
3637

3738
/**
3839
* @defgroup EventInterface Event class C wrapper
3940
*/
4041

42+
// Declares a set of types and functions to deal with vectors of
43+
// DPCTLSyclEventRef. Refer dpctl_vector_macros.h
44+
DPCTL_DECLARE_VECTOR(Event)
45+
4146
/*!
4247
* @brief A wrapper for ``sycl::event`` contructor to construct a new event.
4348
*
@@ -150,4 +155,16 @@ uint64_t DPCTLEvent_GetProfilingInfoStart(__dpctl_keep DPCTLSyclEventRef ERef);
150155
DPCTL_API
151156
uint64_t DPCTLEvent_GetProfilingInfoEnd(__dpctl_keep DPCTLSyclEventRef ERef);
152157

158+
/*!
159+
* @brief C-API wrapper for ``sycl::event::get_wait_list``.
160+
* Returns a vector of events that this event still waits for.
161+
*
162+
* @param ERef Opaque pointer to a ``sycl::event``.
163+
* @return A DPCTLEventVectorRef of DPCTLSyclEventRef objects.
164+
* @ingroup EventInterface
165+
*/
166+
DPCTL_API
167+
__dpctl_give DPCTLEventVectorRef
168+
DPCTLEvent_GetWaitList(__dpctl_keep DPCTLSyclEventRef ERef);
169+
153170
DPCTL_C_EXTERN_C_END

dpctl-capi/source/dpctl_sycl_event_interface.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ namespace
3737
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(event, DPCTLSyclEventRef)
3838
} /* end of anonymous namespace */
3939

40+
#undef EL
41+
#define EL Event
42+
#include "dpctl_vector_templ.cpp"
43+
#undef EL
44+
4045
__dpctl_give DPCTLSyclEventRef DPCTLEvent_Create()
4146
{
4247
DPCTLSyclEventRef ERef = nullptr;
@@ -182,3 +187,39 @@ uint64_t DPCTLEvent_GetProfilingInfoEnd(__dpctl_keep DPCTLSyclEventRef ERef)
182187
}
183188
return profilingInfoEnd;
184189
}
190+
191+
__dpctl_give DPCTLEventVectorRef
192+
DPCTLEvent_GetWaitList(__dpctl_keep DPCTLSyclEventRef ERef)
193+
{
194+
auto E = unwrap(ERef);
195+
if (!E) {
196+
std::cerr << "Cannot get wait list as input is a nullptr\n";
197+
return nullptr;
198+
}
199+
vector_class<DPCTLSyclEventRef> *EventsVectorPtr = nullptr;
200+
try {
201+
EventsVectorPtr = new vector_class<DPCTLSyclEventRef>();
202+
} catch (std::bad_alloc const &ba) {
203+
// \todo log error
204+
std::cerr << ba.what() << '\n';
205+
return nullptr;
206+
}
207+
try {
208+
auto Events = E->get_wait_list();
209+
EventsVectorPtr->reserve(Events.size());
210+
for (const auto &Ev : Events) {
211+
EventsVectorPtr->emplace_back(wrap(new event(Ev)));
212+
}
213+
return wrap(EventsVectorPtr);
214+
} catch (std::bad_alloc const &ba) {
215+
delete EventsVectorPtr;
216+
// \todo log error
217+
std::cerr << ba.what() << '\n';
218+
return nullptr;
219+
} catch (const runtime_error &re) {
220+
delete EventsVectorPtr;
221+
// \todo log error
222+
std::cerr << re.what() << '\n';
223+
return nullptr;
224+
}
225+
}

dpctl-capi/tests/test_sycl_event_interface.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,39 @@
2626

2727
#include "Support/CBindingWrapping.h"
2828
#include "dpctl_sycl_event_interface.h"
29+
#include "dpctl_sycl_types.h"
2930
#include <CL/sycl.hpp>
3031
#include <gtest/gtest.h>
3132

3233
using namespace cl::sycl;
3334

3435
namespace
3536
{
36-
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(event, DPCTLSyclEventRef)
37+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(event, DPCTLSyclEventRef);
38+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(vector_class<DPCTLSyclEventRef>,
39+
DPCTLEventVectorRef);
40+
41+
#ifndef DPCTL_COVERAGE
42+
sycl::event produce_event(sycl::queue &Q, sycl::buffer<int> &data)
43+
{
44+
int N = data.get_range()[0];
45+
46+
auto e1 = Q.submit([&](sycl::handler &h) {
47+
sycl::accessor a{data, h, sycl::write_only, sycl::noinit};
48+
h.parallel_for(N, [=](sycl::id<1> i) { a[i] = 1; });
49+
});
50+
51+
auto e2 = Q.submit([&](sycl::handler &h) {
52+
sycl::accessor a{data, h};
53+
h.single_task([=]() {
54+
for (int i = 1; i < N; i++)
55+
a[0] += a[i];
56+
});
57+
});
58+
59+
return e2;
60+
}
61+
#endif
3762
} // namespace
3863

3964
struct TestDPCTLSyclEventInterface : public ::testing::Test
@@ -163,3 +188,28 @@ TEST_F(TestDPCTLSyclEventInterface, CheckGetProfiling_Invalid)
163188
EXPECT_FALSE(eEnd);
164189
EXPECT_FALSE(eSubmit);
165190
}
191+
192+
TEST_F(TestDPCTLSyclEventInterface, CheckGetWaitList)
193+
{
194+
DPCTLEventVectorRef EVRef = nullptr;
195+
EXPECT_NO_FATAL_FAILURE(EVRef = DPCTLEvent_GetWaitList(ERef));
196+
ASSERT_TRUE(EVRef);
197+
EXPECT_NO_FATAL_FAILURE(DPCTLEventVector_Clear(EVRef));
198+
EXPECT_NO_FATAL_FAILURE(DPCTLEventVector_Delete(EVRef));
199+
}
200+
201+
#ifndef DPCTL_COVERAGE
202+
TEST_F(TestDPCTLSyclEventInterface, CheckGetWaitListSYCL)
203+
{
204+
sycl::queue q;
205+
sycl::buffer<int> data{42};
206+
sycl::event eD;
207+
DPCTLEventVectorRef EVRef = nullptr;
208+
209+
EXPECT_NO_FATAL_FAILURE(eD = produce_event(q, data));
210+
DPCTLSyclEventRef ERef = reinterpret_cast<DPCTLSyclEventRef>(&eD);
211+
EXPECT_NO_FATAL_FAILURE(EVRef = DPCTLEvent_GetWaitList(ERef));
212+
ASSERT_TRUE(DPCTLEventVector_Size(EVRef) > 0);
213+
DPCTLEventVector_Delete(EVRef);
214+
}
215+
#endif

0 commit comments

Comments
 (0)