DPC++ Runtime
Runtime libraries for oneAPI DPC++
test_proxy.hpp
Go to the documentation of this file.
1 //==-------------- test_proxy.hpp - DPC++ Explicit SIMD API ----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // Test proxy to differentiate move and copy constructor calls
9 //===----------------------------------------------------------------------===//
10 
11 #pragma once
12 
14 
15 // The test proxy if solely for the test purposes, so it's off by default, with
16 // no any code generated. It is enabled only if the __ESIMD_ENABLE_TEST_PROXY
17 // macro is defined.
18 // It's expected for the proxy class to be available in device code, so that it
19 // could be incorporated into the ESIMD API classes. Though there is no reason
20 // to limit it to the __SYCL_DEVICE_ONLY__.
21 #ifndef __ESIMD_ENABLE_TEST_PROXY
22 
23 // No code generation by default
24 #define __ESIMD_DECLARE_TEST_PROXY
25 #define __ESIMD_DECLARE_TEST_PROXY_ACCESS
26 #define __esimd_move_test_proxy(other)
27 
28 #else
29 
30 // Declare the class attribute
31 //
32 // We are using non static data member initialization approach to force
33 // the value required. Initialization will take place even if no
34 // default/copy/move constructor of the test_proxy class was explcitly
35 // called by any of the user-defined constructors of the proxy target
36 #define __ESIMD_DECLARE_TEST_PROXY \
37  esimd::detail::test::test_proxy M_testProxy = \
38  esimd::detail::test::test_proxy();
39 
40 // Declare the getter to access the proxy from the tests
41 #define __ESIMD_DECLARE_TEST_PROXY_ACCESS \
42  const auto &get_test_proxy() const { return M_testProxy; }
43 
44 // Test proxy will be handled in a proper way by default/implicit move
45 // constructors and move operators.
46 // Still the user-defined constructors or move operators should explicitly state
47 // what to do with each of class atributes, so a proper wrapper required
48 //
49 // We are using a simple do-while trick to make sure no code breakage could
50 // possibly occur in case macro becomes multistatement (PRE10-C in SEI CERT C)
51 #define __esimd_move_test_proxy(other) \
52  do { \
53  M_testProxy = std::move(other.M_testProxy); \
54  } while (false)
55 
57 namespace sycl::ext::intel::esimd::detail::test {
58 
59 // The test_proxy class.
60 // Being intended solely for the test purposes, it is enabled only if the
61 // __ESIMD_ENABLE_TEST_PROXY macro is defined, which is off by default.
62 //
63 // This is a helper class for tests to differentiate between the copy
64 // constructor/assignment and the move constructor/assignment calls,
65 // as the copy constructor works as the default fallback for every case with
66 // move constructor disabled or not provided
67 //
68 // It is expected for the class with the test proxy (the class under test) to:
69 // - provide the get_test_proxy() method
70 // - properly handle moving the test_proxy member in user-defined move
71 // constructors and user-defined assignment operators
72 //
73 // Therefore the following expression is expected to return `true` only if the
74 // move constructor or move operator was called for the instance of the class
75 // under test:
76 // instance.get_test_proxy().was_move_destination()
77 //
78 class test_proxy {
79  // Define the default value to use for every constructor
80  bool M_move_destination = false;
81 
82 public:
83  test_proxy() { __esimd_dbg_print(test_proxy()); }
84 
85  test_proxy(const test_proxy &) {
86  __esimd_dbg_print(test_proxy(const test_proxy &other));
87  }
88  test_proxy(test_proxy &&) {
89  __esimd_dbg_print(test_proxy(test_proxy && other));
90  M_move_destination = true;
91  }
92  test_proxy &operator=(const test_proxy &) {
93  __esimd_dbg_print(test_proxy::operator=(const test_proxy &other));
94  return *this;
95  }
96  test_proxy &operator=(test_proxy &&) {
97  __esimd_dbg_print(test_proxy::operator=(test_proxy &&other));
98  M_move_destination = true;
99  return *this;
100  }
101  bool was_move_destination() const { return M_move_destination; }
102 };
103 
104 } // namespace sycl::ext::intel::esimd::detail::test
105 } // __SYCL_INLINE_NAMESPACE(cl)
106 
107 #endif // __ESIMD_ENABLE_TEST_PROXY
108 
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
__esimd_dbg_print
#define __esimd_dbg_print(a)
Definition: types.hpp:22
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12