@@ -36,18 +36,119 @@ namespace sycl {
36
36
37
37
// Forward declarations
38
38
class queue ;
39
- namespace detail {
40
- class queue_impl ;
41
- } // namespace detail
42
39
43
40
namespace detail {
44
41
42
+ // Periodically there is a need to extend handler and CG classes to hold more
43
+ // data(members) than it has now. But any modification of the layout of those
44
+ // classes is an ABI break. To have an ability to have more data the following
45
+ // approach is implemented:
46
+ //
47
+ // Those classes have a member - MSharedPtrStorage which is an std::vector of
48
+ // std::shared_ptr's and is supposed to hold reference counters of user
49
+ // provided shared_ptr's.
50
+ //
51
+ // The first element of this vector is reused to store a vector of additional
52
+ // members handler and CG need to have.
53
+ //
54
+ // These additional arguments are represented using "ExtendedMemberT" structure
55
+ // which has a pointer to an arbitrary value and an integer which is used to
56
+ // understand how the value the pointer points to should be interpreted.
57
+ //
58
+ // ======== ======== ========
59
+ // | | | | ... | | std::vector<std::shared_ptr<void>>
60
+ // ======== ======== ========
61
+ // || || ||
62
+ // || \/ \/
63
+ // || user user
64
+ // || data data
65
+ // \/
66
+ // ======== ======== ========
67
+ // | Type | | Type | ... | Type | std::vector<ExtendedMemberT>
68
+ // | | | | | |
69
+ // | Ptr | | Ptr | ... | Ptr |
70
+ // ======== ======== ========
71
+ //
72
+ // Prior to this change this vector was supposed to have user's values only, so
73
+ // it is not legal to expect that the first argument is a special one.
74
+ // Versioning is implemented to overcome this problem - if the first element of
75
+ // the MSharedPtrStorage is a pointer to the special vector then CGType value
76
+ // has version "1" encoded.
77
+ //
78
+ // The version of CG type is encoded in the highest byte of the value:
79
+ //
80
+ // 0x00000001 - CG type KERNEL version 0
81
+ // 0x01000001 - CG type KERNEL version 1
82
+ // /\
83
+ // ||
84
+ // The byte specifies the version
85
+ //
86
+ // A user of this vector should not expect that a specific data is stored at a
87
+ // specific position, but iterate over all looking for an ExtendedMemberT value
88
+ // with the desired type.
89
+ // This allows changing/extending the contents of this vector without changing
90
+ // the version.
91
+ //
92
+
93
+ // Used to represent a type of an extended member
94
+ enum class ExtendedMembersType : unsigned int {
95
+ HANDLER_KERNEL_BUNDLE = 0 ,
96
+ };
97
+
98
+ // Holds a pointer to an object of an arbitrary type and an ID value which
99
+ // should be used to understand what type pointer points to.
100
+ // Used as to extend handler class without introducing new class members which
101
+ // would change handler layout.
102
+ struct ExtendedMemberT {
103
+ ExtendedMembersType MType;
104
+ std::shared_ptr<void > MData;
105
+ };
106
+
107
+ static std::shared_ptr<std::vector<ExtendedMemberT>>
108
+ convertToExtendedMembers (const std::shared_ptr<const void > &SPtr) {
109
+ return std::const_pointer_cast<std::vector<ExtendedMemberT>>(
110
+ std::static_pointer_cast<const std::vector<ExtendedMemberT>>(SPtr));
111
+ }
112
+
45
113
class stream_impl ;
114
+ class queue_impl ;
115
+ class kernel_bundle_impl ;
116
+
117
+ // The constant is used to left shift a CG type value to access it's version
118
+ constexpr unsigned int ShiftBitsForVersion = 24 ;
119
+
120
+ // Constructs versioned type
121
+ constexpr unsigned int getVersionedCGType (unsigned int Type,
122
+ unsigned char Version) {
123
+ return Type | (static_cast <unsigned int >(Version) << ShiftBitsForVersion);
124
+ }
125
+
126
+ // Returns the type without version encoded
127
+ constexpr unsigned char getUnversionedCGType (unsigned int Type) {
128
+ unsigned int Mask = -1 ;
129
+ Mask >>= (sizeof (Mask) * 8 - ShiftBitsForVersion);
130
+ return Type & Mask;
131
+ }
132
+
133
+ // Returns the version encoded to the type
134
+ constexpr unsigned char getCGTypeVersion (unsigned int Type) {
135
+ return Type >> ShiftBitsForVersion;
136
+ }
137
+
46
138
// / Base class for all types of command groups.
47
139
class CG {
48
140
public:
141
+ // Used to version CG and handler classes. Using unsigned char as the version
142
+ // is encoded in the highest byte of CGType value. So it is not possible to
143
+ // encode a value > 255 anyway which should be big enough room for version
144
+ // bumping.
145
+ enum class CG_VERSION : unsigned char {
146
+ V0 = 0 ,
147
+ V1 = 1 ,
148
+ };
149
+
49
150
// / Type of the command group.
50
- enum CGTYPE {
151
+ enum CGTYPE : unsigned int {
51
152
NONE = 0 ,
52
153
KERNEL = 1 ,
53
154
COPY_ACC_TO_PTR = 2 ,
@@ -62,7 +163,9 @@ class CG {
62
163
FILL_USM = 11 ,
63
164
PREFETCH_USM = 12 ,
64
165
CODEPLAY_INTEROP_TASK = 13 ,
65
- CODEPLAY_HOST_TASK = 14
166
+ CODEPLAY_HOST_TASK = 14 ,
167
+ KERNEL_V1 =
168
+ getVersionedCGType (KERNEL, static_cast <unsigned int >(CG_VERSION::V1)),
66
169
};
67
170
68
171
CG (CGTYPE Type, vector_class<vector_class<char >> ArgsStorage,
@@ -87,7 +190,17 @@ class CG {
87
190
88
191
CG (CG &&CommandGroup) = default;
89
192
90
- CGTYPE getType () { return MType; }
193
+ CGTYPE getType () { return static_cast <CGTYPE>(getUnversionedCGType (MType)); }
194
+
195
+ std::shared_ptr<std::vector<ExtendedMemberT>> getExtendedMembers () {
196
+ if (getCGTypeVersion (MType) == static_cast <unsigned int >(CG_VERSION::V0) ||
197
+ MSharedPtrStorage.empty ())
198
+ return nullptr ;
199
+
200
+ // The first value in shared_ptr storage is supposed to store a vector of
201
+ // extended members.
202
+ return convertToExtendedMembers (MSharedPtrStorage[0 ]);
203
+ }
91
204
92
205
virtual ~CG () = default ;
93
206
@@ -146,7 +259,8 @@ class CGExecKernel : public CG {
146
259
MSyclKernel(std::move(SyclKernel)), MArgs(std::move(Args)),
147
260
MKernelName(std::move(KernelName)), MOSModuleHandle(OSModuleHandle),
148
261
MStreams(std::move(Streams)) {
149
- assert ((getType () == RUN_ON_HOST_INTEL || getType () == KERNEL) &&
262
+ assert ((getType () == RUN_ON_HOST_INTEL || getType () == KERNEL ||
263
+ getType () == KERNEL_V1) &&
150
264
" Wrong type of exec kernel CG." );
151
265
}
152
266
@@ -155,6 +269,19 @@ class CGExecKernel : public CG {
155
269
vector_class<shared_ptr_class<detail::stream_impl>> getStreams () const {
156
270
return MStreams;
157
271
}
272
+
273
+ std::shared_ptr<detail::kernel_bundle_impl> getKernelBundle () {
274
+ const std::shared_ptr<std::vector<ExtendedMemberT>> &ExtendedMembers =
275
+ getExtendedMembers ();
276
+ if (!ExtendedMembers)
277
+ return nullptr ;
278
+ for (const ExtendedMemberT &EMember : *ExtendedMembers)
279
+ if (ExtendedMembersType::HANDLER_KERNEL_BUNDLE == EMember.MType )
280
+ return std::static_pointer_cast<detail::kernel_bundle_impl>(
281
+ EMember.MData );
282
+ return nullptr ;
283
+ }
284
+
158
285
void clearStreams () { MStreams.clear (); }
159
286
};
160
287
0 commit comments