Skip to content

Commit ae45333

Browse files
authored
[SYCL] Add implementation of kernel_bundle. Part 3 (#3375)
The patch adds - Implementation of more kernel_bundle APIs. - Support of kernel_bundles in handler The patch duplicates some code in program manager in order to support compilation for multiple devices. The refactoring of program manager will be done in a separate patch. Error handling will be added in a separate patch.
1 parent 56b3ec1 commit ae45333

18 files changed

+1354
-216
lines changed

sycl/include/CL/sycl/detail/cg.hpp

Lines changed: 134 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,119 @@ namespace sycl {
3636

3737
// Forward declarations
3838
class queue;
39-
namespace detail {
40-
class queue_impl;
41-
} // namespace detail
4239

4340
namespace detail {
4441

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+
45113
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+
46138
/// Base class for all types of command groups.
47139
class CG {
48140
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+
49150
/// Type of the command group.
50-
enum CGTYPE {
151+
enum CGTYPE : unsigned int {
51152
NONE = 0,
52153
KERNEL = 1,
53154
COPY_ACC_TO_PTR = 2,
@@ -62,7 +163,9 @@ class CG {
62163
FILL_USM = 11,
63164
PREFETCH_USM = 12,
64165
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)),
66169
};
67170

68171
CG(CGTYPE Type, vector_class<vector_class<char>> ArgsStorage,
@@ -87,7 +190,17 @@ class CG {
87190

88191
CG(CG &&CommandGroup) = default;
89192

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+
}
91204

92205
virtual ~CG() = default;
93206

@@ -146,7 +259,8 @@ class CGExecKernel : public CG {
146259
MSyclKernel(std::move(SyclKernel)), MArgs(std::move(Args)),
147260
MKernelName(std::move(KernelName)), MOSModuleHandle(OSModuleHandle),
148261
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) &&
150264
"Wrong type of exec kernel CG.");
151265
}
152266

@@ -155,6 +269,19 @@ class CGExecKernel : public CG {
155269
vector_class<shared_ptr_class<detail::stream_impl>> getStreams() const {
156270
return MStreams;
157271
}
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+
158285
void clearStreams() { MStreams.clear(); }
159286
};
160287

0 commit comments

Comments
 (0)