diff --git a/dpctl-capi/include/dpctl_sycl_event_interface.h b/dpctl-capi/include/dpctl_sycl_event_interface.h index 92b3d27c5e..2845e30eb2 100644 --- a/dpctl-capi/include/dpctl_sycl_event_interface.h +++ b/dpctl-capi/include/dpctl_sycl_event_interface.h @@ -37,6 +37,15 @@ DPCTL_C_EXTERN_C_BEGIN * @defgroup EventInterface Event class C wrapper */ +/*! + * @brief A wrapper for ``sycl::event`` contructor to construct a new event. + * + * @return An opaque DPCTLSyclEventRef pointer wrapping a ``sycl::event``. + * @ingroup EventInterface + */ +DPCTL_API +__dpctl_give DPCTLSyclEventRef DPCTLEvent_Create(void); + /*! * @brief C-API wrapper for sycl::event.wait. * @@ -48,7 +57,7 @@ DPCTL_API void DPCTLEvent_Wait(__dpctl_keep DPCTLSyclEventRef ERef); /*! - * @brief Deletes the DPCTLSyclEventRef after casting it to a sycl::event. + * @brief Deletes the DPCTLSyclEventRef after casting it to a ``sycl::event``. * * @param ERef An opaque DPCTLSyclEventRef pointer that would be * freed. @@ -57,4 +66,16 @@ void DPCTLEvent_Wait(__dpctl_keep DPCTLSyclEventRef ERef); DPCTL_API void DPCTLEvent_Delete(__dpctl_take DPCTLSyclEventRef ERef); +/*! + * @brief Returns a copy of the DPCTLSyclEventRef object. + * + * @param ERef DPCTLSyclEventRef object to be copied. + * @return A new DPCTLSyclEventRef created by copying the passed in + * DPCTLSyclEventRef object. + * @ingroup EventInterface + */ +DPCTL_API +__dpctl_give DPCTLSyclEventRef +DPCTLEvent_Copy(__dpctl_keep const DPCTLSyclEventRef ERef); + DPCTL_C_EXTERN_C_END diff --git a/dpctl-capi/source/dpctl_sycl_event_interface.cpp b/dpctl-capi/source/dpctl_sycl_event_interface.cpp index 151de75416..7c279df02f 100644 --- a/dpctl-capi/source/dpctl_sycl_event_interface.cpp +++ b/dpctl-capi/source/dpctl_sycl_event_interface.cpp @@ -36,6 +36,18 @@ namespace DEFINE_SIMPLE_CONVERSION_FUNCTIONS(event, DPCTLSyclEventRef) } /* end of anonymous namespace */ +__dpctl_give DPCTLSyclEventRef DPCTLEvent_Create() +{ + DPCTLSyclEventRef ERef = nullptr; + try { + auto E = new event(); + ERef = wrap(E); + } catch (std::bad_alloc const &ba) { + std::cerr << ba.what() << '\n'; + } + return ERef; +} + void DPCTLEvent_Wait(__dpctl_keep DPCTLSyclEventRef ERef) { // \todo How to handle errors? E.g. when ERef is null or not a valid event. @@ -47,3 +59,21 @@ void DPCTLEvent_Delete(__dpctl_take DPCTLSyclEventRef ERef) { delete unwrap(ERef); } + +__dpctl_give DPCTLSyclEventRef +DPCTLEvent_Copy(__dpctl_keep DPCTLSyclEventRef ERef) +{ + auto SyclEvent = unwrap(ERef); + if (!SyclEvent) { + std::cerr << "Cannot copy DPCTLSyclEventRef as input is a nullptr\n"; + return nullptr; + } + try { + auto CopiedSyclEvent = new event(*SyclEvent); + return wrap(CopiedSyclEvent); + } catch (std::bad_alloc const &ba) { + // \todo log error + std::cerr << ba.what() << '\n'; + return nullptr; + } +} diff --git a/dpctl-capi/tests/test_sycl_event_interface.cpp b/dpctl-capi/tests/test_sycl_event_interface.cpp new file mode 100644 index 0000000000..7ebe081b9f --- /dev/null +++ b/dpctl-capi/tests/test_sycl_event_interface.cpp @@ -0,0 +1,74 @@ +//===------ test_sycl_event_interface.cpp - Test cases for event interface ===// +// +// Data Parallel Control (dpctl) +// +// Copyright 2020-2021 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file has unit test cases for functions defined in +/// dpctl_sycl_event_interface.h. +/// +//===----------------------------------------------------------------------===// + +#include "Support/CBindingWrapping.h" +#include "dpctl_sycl_event_interface.h" +#include +#include + +using namespace cl::sycl; + +namespace +{ +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(event, DPCTLSyclEventRef) +} // namespace + +struct TestDPCTLSyclEventInterface : public ::testing::Test +{ + DPCTLSyclEventRef ERef = nullptr; + + TestDPCTLSyclEventInterface() + { + EXPECT_NO_FATAL_FAILURE(ERef = DPCTLEvent_Create()); + } + + void SetUp() + { + ASSERT_TRUE(ERef); + } + + ~TestDPCTLSyclEventInterface() + { + EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Delete(ERef)); + } +}; + +TEST_F(TestDPCTLSyclEventInterface, CheckEvent_Copy) +{ + DPCTLSyclEventRef Copied_ERef = nullptr; + EXPECT_NO_FATAL_FAILURE(Copied_ERef = DPCTLEvent_Copy(ERef)); + EXPECT_TRUE(bool(Copied_ERef)); + EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Delete(Copied_ERef)); +} + +TEST_F(TestDPCTLSyclEventInterface, CheckCopy_Invalid) +{ + DPCTLSyclEventRef E1 = nullptr; + DPCTLSyclEventRef E2 = nullptr; + EXPECT_NO_FATAL_FAILURE(E2 = DPCTLEvent_Copy(E1)); + EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Delete(E1)); + EXPECT_NO_FATAL_FAILURE(DPCTLEvent_Delete(E2)); +}