diff --git a/SYCL/WeakObject/weak_object_copy.cpp b/SYCL/WeakObject/weak_object_copy.cpp new file mode 100644 index 0000000000..865ce036e4 --- /dev/null +++ b/SYCL/WeakObject/weak_object_copy.cpp @@ -0,0 +1,30 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of the copy ctor and assignment operator for +// `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckCopy { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + + sycl::ext::oneapi::weak_object WeakObjCopyCtor{WeakObj}; + sycl::ext::oneapi::weak_object WeakObjCopyAssign = WeakObj; + + assert(!WeakObjCopyCtor.expired()); + assert(!WeakObjCopyAssign.expired()); + + assert(WeakObjCopyCtor.lock() == Obj); + assert(WeakObjCopyAssign.lock() == Obj); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_expired.cpp b/SYCL/WeakObject/weak_object_expired.cpp new file mode 100644 index 0000000000..21b29a8078 --- /dev/null +++ b/SYCL/WeakObject/weak_object_expired.cpp @@ -0,0 +1,24 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of `expired()` for `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckExpired { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + + assert(!WeakObj.expired()); + assert(NullWeakObj.expired()); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_lock.cpp b/SYCL/WeakObject/weak_object_lock.cpp new file mode 100644 index 0000000000..5991952edd --- /dev/null +++ b/SYCL/WeakObject/weak_object_lock.cpp @@ -0,0 +1,32 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of `lock()` for `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckLock { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + + SyclObjT LObj = WeakObj.lock(); + assert(LObj == Obj); + + try { + SyclObjT LNull = NullWeakObj.lock(); + assert(false && "Locking empty weak object did not throw."); + } catch (sycl::exception &E) { + assert(E.code() == sycl::make_error_code(sycl::errc::invalid) && + "Unexpected thrown error code."); + } + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_move.cpp b/SYCL/WeakObject/weak_object_move.cpp new file mode 100644 index 0000000000..e5f70dbf07 --- /dev/null +++ b/SYCL/WeakObject/weak_object_move.cpp @@ -0,0 +1,33 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of the copy ctor and assignment operator for +// `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckMove { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj1{Obj}; + sycl::ext::oneapi::weak_object WeakObj2{Obj}; + + sycl::ext::oneapi::weak_object WeakObjMoveCtor{ + std::move(WeakObj1)}; + sycl::ext::oneapi::weak_object WeakObjMoveAssign = + std::move(WeakObj2); + + assert(!WeakObjMoveCtor.expired()); + assert(!WeakObjMoveAssign.expired()); + + assert(WeakObjMoveCtor.lock() == Obj); + assert(WeakObjMoveAssign.lock() == Obj); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_owner_before.cpp b/SYCL/WeakObject/weak_object_owner_before.cpp new file mode 100644 index 0000000000..28085bbf8e --- /dev/null +++ b/SYCL/WeakObject/weak_object_owner_before.cpp @@ -0,0 +1,54 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of owner_before semantics for `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckOwnerBefore { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + + assert((WeakObj.owner_before(NullWeakObj) && + !NullWeakObj.owner_before(WeakObj)) || + (NullWeakObj.owner_before(WeakObj) && + !WeakObj.owner_before(NullWeakObj))); + + assert(!WeakObj.owner_before(Obj)); + assert(!Obj.ext_oneapi_owner_before(WeakObj)); + + assert(!Obj.ext_oneapi_owner_before(Obj)); + } +}; + +template struct WeakObjectCheckOwnerBeforeMulti { + void operator()(SyclObjT Obj1, SyclObjT Obj2) { + sycl::ext::oneapi::weak_object WeakObj1{Obj1}; + sycl::ext::oneapi::weak_object WeakObj2{Obj2}; + + assert( + (WeakObj1.owner_before(WeakObj2) && !WeakObj2.owner_before(WeakObj1)) || + (WeakObj2.owner_before(WeakObj1) && !WeakObj1.owner_before(WeakObj2))); + + assert(!WeakObj1.owner_before(Obj1)); + assert(!Obj1.ext_oneapi_owner_before(WeakObj1)); + + assert(!WeakObj2.owner_before(Obj2)); + assert(!Obj2.ext_oneapi_owner_before(WeakObj2)); + + assert((Obj1.ext_oneapi_owner_before(Obj2) && + !Obj2.ext_oneapi_owner_before(Obj1)) || + (Obj2.ext_oneapi_owner_before(Obj1) && + !Obj1.ext_oneapi_owner_before(Obj2))); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + runTestMulti(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_owner_less.cpp b/SYCL/WeakObject/weak_object_owner_less.cpp new file mode 100644 index 0000000000..dff281be5c --- /dev/null +++ b/SYCL/WeakObject/weak_object_owner_less.cpp @@ -0,0 +1,98 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of owner_less semantics for `weak_object`. + +#include "weak_object_utils.hpp" + +#include + +template struct WeakObjectCheckOwnerLess { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + sycl::ext::oneapi::owner_less Comparator; + + assert((Comparator(WeakObj, NullWeakObj) && + !Comparator(NullWeakObj, WeakObj)) || + (Comparator(NullWeakObj, WeakObj) && + !Comparator(WeakObj, NullWeakObj))); + + assert(!Comparator(WeakObj, Obj)); + assert(!Comparator(Obj, WeakObj)); + } +}; + +template struct WeakObjectCheckOwnerLessMulti { + void operator()(SyclObjT Obj1, SyclObjT Obj2) { + sycl::ext::oneapi::weak_object WeakObj1{Obj1}; + sycl::ext::oneapi::weak_object WeakObj2{Obj2}; + sycl::ext::oneapi::owner_less Comparator; + + assert( + (Comparator(WeakObj1, WeakObj2) && !Comparator(WeakObj2, WeakObj1)) || + (Comparator(WeakObj2, WeakObj1) && !Comparator(WeakObj1, WeakObj2))); + + assert(!Comparator(WeakObj1, Obj1)); + assert(!Comparator(Obj1, WeakObj1)); + + assert(!Comparator(WeakObj2, Obj2)); + assert(!Comparator(Obj2, WeakObj2)); + } +}; + +template struct WeakObjectCheckOwnerLessMap { + void operator()(SyclObjT Obj1, SyclObjT Obj2) { + sycl::ext::oneapi::weak_object WeakObj1{Obj1}; + sycl::ext::oneapi::weak_object WeakObj2{Obj2}; + + std::map, int, + sycl::ext::oneapi::owner_less> + Map; + Map[WeakObj1] = 1; + Map[WeakObj2] = 2; + + assert(Map.size() == (size_t)2); + assert(Map[WeakObj1] == 1); + assert(Map[WeakObj2] == 2); + assert(Map[Obj1] == 1); + assert(Map[Obj2] == 2); + + Map[WeakObj1] = 2; + Map[WeakObj2] = 3; + + assert(Map.size() == (size_t)2); + assert(Map[WeakObj1] == 2); + assert(Map[WeakObj2] == 3); + assert(Map[Obj1] == 2); + assert(Map[Obj2] == 3); + + Map[Obj1] = 5; + Map[Obj2] = 6; + + assert(Map.size() == (size_t)2); + assert(Map[WeakObj1] == 5); + assert(Map[WeakObj2] == 6); + assert(Map[Obj1] == 5); + assert(Map[Obj2] == 6); + + Map[sycl::ext::oneapi::weak_object{Obj1}] = 10; + Map[sycl::ext::oneapi::weak_object{Obj2}] = 13; + + assert(Map.size() == (size_t)2); + assert(Map[WeakObj1] == 10); + assert(Map[WeakObj2] == 13); + assert(Map[Obj1] == 10); + assert(Map[Obj2] == 13); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + runTestMulti(Q); + runTestMulti(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_reset.cpp b/SYCL/WeakObject/weak_object_reset.cpp new file mode 100644 index 0000000000..32bb2bb667 --- /dev/null +++ b/SYCL/WeakObject/weak_object_reset.cpp @@ -0,0 +1,37 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of `reset()` for `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckReset { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + + WeakObj.reset(); + assert(WeakObj.expired()); + assert(!WeakObj.owner_before(NullWeakObj)); + assert(!NullWeakObj.owner_before(WeakObj)); + + std::optional TLObj = WeakObj.try_lock(); + assert(!TLObj.has_value()); + + try { + SyclObjT LObj = WeakObj.lock(); + assert(false && "Locking reset weak object did not throw."); + } catch (sycl::exception &E) { + assert(E.code() == sycl::make_error_code(sycl::errc::invalid) && + "Unexpected thrown error code."); + } + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_try_lock.cpp b/SYCL/WeakObject/weak_object_try_lock.cpp new file mode 100644 index 0000000000..a2074ae54c --- /dev/null +++ b/SYCL/WeakObject/weak_object_try_lock.cpp @@ -0,0 +1,29 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +// This test checks the behavior of `try_lock()` for `weak_object`. + +#include "weak_object_utils.hpp" + +template struct WeakObjectCheckTryLock { + void operator()(SyclObjT Obj) { + sycl::ext::oneapi::weak_object WeakObj{Obj}; + sycl::ext::oneapi::weak_object NullWeakObj; + + std::optional TLObj = WeakObj.try_lock(); + std::optional TLNull = NullWeakObj.try_lock(); + + assert(TLObj.has_value()); + assert(!TLNull.has_value()); + + assert(TLObj.value() == Obj); + } +}; + +int main() { + sycl::queue Q; + runTest(Q); + return 0; +} diff --git a/SYCL/WeakObject/weak_object_utils.hpp b/SYCL/WeakObject/weak_object_utils.hpp new file mode 100644 index 0000000000..64192b3624 --- /dev/null +++ b/SYCL/WeakObject/weak_object_utils.hpp @@ -0,0 +1,160 @@ +// Utilities for weak_object testing + +#include + +class TestKernel1; +class TestKernel2; + +void MaterializeTestKernels(sycl::queue Q) { + if (false) { + Q.single_task([]() {}); + Q.single_task([]() {}); + } +} + +template