Skip to content

Commit cb221b6

Browse files
committed
[SYCL][ESIMD] RT: remove wrapping buffer objects into images.
BE is now able to accept buffers instead of image1d buffers, so remove the w/a wrapping. This patch also gets rid of majority of __SYCL_EXPLICIT_SIMD__ macro checks in the API code, paving a way for ESIMD/SYCL kernel co-existence. Details: - Use new int header feature KernelInfo<>::isESIMD() to properly set accessor args - Add __init_esimd accessor methods to be used by FE with ESIMD kernels - Some ESIMD-related stuff is now unsed - can't be removed now not to break ABI. TODOs added. Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 69d8d7a commit cb221b6

File tree

13 files changed

+76
-85
lines changed

13 files changed

+76
-85
lines changed

sycl/include/CL/sycl/accessor.hpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,9 @@ class accessor :
859859
detail::AccessorImplDevice<AdjustedDim> impl;
860860

861861
#ifdef __SYCL_EXPLICIT_SIMD__
862+
// TODO all the Image1dBuffer* stuff, including the union with MData field
863+
// below is not used anymore and is left temporarily to avoid ABI breaking
864+
// changes.
862865
using OCLImage1dBufferTy =
863866
typename detail::opencl_image1d_buffer_type<AccessMode>::type;
864867
#endif // __SYCL_EXPLICIT_SIMD__
@@ -870,15 +873,9 @@ class accessor :
870873
#endif // __SYCL_EXPLICIT_SIMD__
871874
};
872875

873-
#ifdef __SYCL_EXPLICIT_SIMD__
874-
// TODO In ESIMD accessors usage is limited for now - access range, mem
875-
// range and offset are not supported. The cl_mem object allocated for
876-
// a global accessor is always wrapped into a 1d image buffer to enable
877-
// surface index-based addressing.
878-
void __init(OCLImage1dBufferTy ImgBuf) { ImageBuffer = ImgBuf; }
876+
// TODO replace usages with getQualifiedPtr
877+
const ConcreteASPtrType getNativeImageObj() const { return MData; }
879878

880-
const OCLImage1dBufferTy getNativeImageObj() const { return ImageBuffer; }
881-
#else
882879
void __init(ConcreteASPtrType Ptr, range<AdjustedDim> AccessRange,
883880
range<AdjustedDim> MemRange, id<AdjustedDim> Offset) {
884881
MData = Ptr;
@@ -893,7 +890,12 @@ class accessor :
893890
if (1 == AdjustedDim)
894891
MData += Offset[0];
895892
}
896-
#endif // __SYCL_EXPLICIT_SIMD__
893+
894+
// __init variant used by the device compiler for ESIMD kernels.
895+
// TODO In ESIMD accessors usage is limited for now - access range, mem
896+
// range and offset are not supported.
897+
void __init_esimd(ConcreteASPtrType Ptr) { MData = Ptr; }
898+
897899
ConcreteASPtrType getQualifiedPtr() const { return MData; }
898900

899901
template <typename, int, access::mode, access::target, access::placeholder,
@@ -1963,6 +1965,9 @@ class accessor<DataT, Dimensions, AccessMode, access::target::image,
19631965
// It does not call the base class's init method.
19641966
void __init(OCLImageTy Image) { this->imageAccessorInit(Image); }
19651967

1968+
// __init variant used by the device compiler for ESIMD kernels.
1969+
void __init_esimd(OCLImageTy Image) { this->imageAccessorInit(Image); }
1970+
19661971
public:
19671972
// Default constructor for objects later initialized with __init member.
19681973
accessor() = default;
@@ -2014,6 +2019,9 @@ class accessor<DataT, Dimensions, AccessMode, access::target::image_array,
20142019
// It does not call the base class's init method.
20152020
void __init(OCLImageTy Image) { this->imageAccessorInit(Image); }
20162021

2022+
// __init variant used by the device compiler for ESIMD kernels.
2023+
void __init_esimd(OCLImageTy Image) { this->imageAccessorInit(Image); }
2024+
20172025
public:
20182026
// Default constructor for objects later initialized with __init member.
20192027
accessor() = default;

sycl/include/CL/sycl/detail/accessor_impl.hpp

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,16 @@ template <int Dims> class LocalAccessorBaseDevice {
7070
}
7171
};
7272

73-
// TODO ESIMD Currently all accessors are treated as ESIMD under corresponding
74-
// compiler option enabling the macro below. Eventually ESIMD kernels and usual
75-
// kernels must co-exist and there must be a mechanism for distinguishing usual
76-
// and ESIMD accessors.
77-
#ifndef __SYCL_EXPLICIT_SIMD__
78-
constexpr bool IsESIMDAccInit = false;
79-
#else
80-
constexpr bool IsESIMDAccInit = true;
81-
#endif // __SYCL_EXPLICIT_SIMD__
82-
8373
class __SYCL_EXPORT AccessorImplHost {
8474
public:
8575
AccessorImplHost(id<3> Offset, range<3> AccessRange, range<3> MemoryRange,
8676
access::mode AccessMode, detail::SYCLMemObjI *SYCLMemObject,
8777
int Dims, int ElemSize, int OffsetInBytes = 0,
88-
bool IsSubBuffer = false, bool IsESIMDAcc = IsESIMDAccInit)
78+
bool IsSubBuffer = false)
8979
: MOffset(Offset), MAccessRange(AccessRange), MMemoryRange(MemoryRange),
9080
MAccessMode(AccessMode), MSYCLMemObj(SYCLMemObject), MDims(Dims),
9181
MElemSize(ElemSize), MOffsetInBytes(OffsetInBytes),
92-
MIsSubBuffer(IsSubBuffer) {
93-
MIsESIMDAcc =
94-
IsESIMDAcc && (SYCLMemObject->getType() == SYCLMemObjI::BUFFER);
95-
}
82+
MIsSubBuffer(IsSubBuffer) {}
9683

9784
~AccessorImplHost();
9885

@@ -101,7 +88,7 @@ class __SYCL_EXPORT AccessorImplHost {
10188
MMemoryRange(Other.MMemoryRange), MAccessMode(Other.MAccessMode),
10289
MSYCLMemObj(Other.MSYCLMemObj), MDims(Other.MDims),
10390
MElemSize(Other.MElemSize), MOffsetInBytes(Other.MOffsetInBytes),
104-
MIsSubBuffer(Other.MIsSubBuffer), MIsESIMDAcc(Other.MIsESIMDAcc) {}
91+
MIsSubBuffer(Other.MIsSubBuffer) {}
10592

10693
// The resize method provides a way to change the size of the
10794
// allocated memory and corresponding properties for the accessor.
@@ -133,9 +120,6 @@ class __SYCL_EXPORT AccessorImplHost {
133120
Command *MBlockedCmd = nullptr;
134121

135122
bool PerWI = false;
136-
137-
// Whether this accessor is ESIMD accessor with special memory allocation.
138-
bool MIsESIMDAcc;
139123
};
140124

141125
using AccessorImplPtr = shared_ptr_class<AccessorImplHost>;
@@ -148,8 +132,7 @@ class AccessorBaseHost {
148132
bool IsSubBuffer = false) {
149133
impl = shared_ptr_class<AccessorImplHost>(new AccessorImplHost(
150134
Offset, AccessRange, MemoryRange, AccessMode, SYCLMemObject, Dims,
151-
ElemSize, OffsetInBytes, IsSubBuffer,
152-
IsESIMDAccInit && (SYCLMemObject->getType() == SYCLMemObjI::BUFFER)));
135+
ElemSize, OffsetInBytes, IsSubBuffer));
153136
}
154137

155138
protected:

sycl/include/CL/sycl/detail/image_ocl_types.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ inline int getSPIRVElementSize(int ImageChannelType, int ImageChannelOrder) {
193193
}
194194

195195
#ifdef __SYCL_EXPLICIT_SIMD__
196+
// TODO all the opencl_image1d_buffer* stuff below is not used anymore and is
197+
// left temporarily to avoid ABI breaking changes - field of this type is
198+
// temporarily present in the accessor class.
196199
template <access::mode AccessMode> struct opencl_image1d_buffer_type;
197200

198201
// OpenCL types used only when compiling DPCPP ESIMD kernels

sycl/include/CL/sycl/detail/kernel_desc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ template <class KernelNameType> struct KernelInfo {
5656
return Dummy;
5757
}
5858
static constexpr const char *getName() { return ""; }
59+
static constexpr bool isESIMD() { return 0; }
5960
};
6061
#else
6162
template <char...> struct KernelInfoData {
@@ -65,6 +66,7 @@ template <char...> struct KernelInfoData {
6566
return Dummy;
6667
}
6768
static constexpr const char *getName() { return ""; }
69+
static constexpr bool isESIMD() { return 0; }
6870
};
6971

7072
// C++14 like index_sequence and make_index_sequence

sycl/include/CL/sycl/detail/memory_manager.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ class __SYCL_EXPORT MemoryManager {
4949
RT::PiEvent &OutEvent);
5050

5151
// Allocates memory buffer wrapped into an image. MemObj must be a buffer,
52-
// not an image. Used in ESIMD extension to enable surface index-based access.
52+
// not an image.
53+
// TODO not used - remove.
5354
static void *wrapIntoImageBuffer(ContextImplPtr TargetContext, void *MemBuf,
5455
SYCLMemObjI *MemObj);
5556

5657
// Releases the image buffer created by wrapIntoImageBuffer.
58+
// TODO not used - remove.
5759
static void releaseImageBuffer(ContextImplPtr TargetContext, void *ImageBuf);
5860

5961
// The following method creates OpenCL sub buffer for specified

sycl/include/CL/sycl/handler.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,17 +318,30 @@ class __SYCL_EXPORT handler {
318318

319319
/// Extracts and prepares kernel arguments from the lambda using integration
320320
/// header.
321+
/// TODO replace with the version below once ABI breaking changes are allowed.
321322
void
322323
extractArgsAndReqsFromLambda(char *LambdaPtr, size_t KernelArgsNum,
323324
const detail::kernel_param_desc_t *KernelArgs);
324325

326+
/// Extracts and prepares kernel arguments from the lambda using integration
327+
/// header.
328+
void
329+
extractArgsAndReqsFromLambda(char *LambdaPtr, size_t KernelArgsNum,
330+
const detail::kernel_param_desc_t *KernelArgs,
331+
bool IsESIMD);
332+
325333
/// Extracts and prepares kernel arguments set via set_arg(s).
326334
void extractArgsAndReqs();
327335

336+
/// TODO replace with the version below once ABI breaking changes are allowed.
328337
void processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
329338
const int Size, const size_t Index, size_t &IndexShift,
330339
bool IsKernelCreatedFromSource);
331340

341+
void processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
342+
const int Size, const size_t Index, size_t &IndexShift,
343+
bool IsKernelCreatedFromSource, bool IsESIMD);
344+
332345
/// \return a string containing name of SYCL kernel.
333346
string_class getKernelName();
334347

@@ -490,9 +503,10 @@ class __SYCL_EXPORT handler {
490503
// Empty name indicates that the compilation happens without integration
491504
// header, so don't perform things that require it.
492505
if (KI::getName() != nullptr && KI::getName()[0] != '\0') {
506+
// TODO support ESIMD in no-integration-header case too.
493507
MArgs.clear();
494508
extractArgsAndReqsFromLambda(MHostKernel->getPtr(), KI::getNumParams(),
495-
&KI::getParamDesc(0));
509+
&KI::getParamDesc(0), KI::isESIMD());
496510
MKernelName = KI::getName();
497511
MOSModuleHandle = detail::OSUtil::getOSModuleHandle(KI::getName());
498512
} else {

sycl/source/detail/memory_manager.cpp

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ void MemoryManager::release(ContextImplPtr TargetContext, SYCLMemObjI *MemObj,
4747

4848
void MemoryManager::releaseImageBuffer(ContextImplPtr TargetContext,
4949
void *ImageBuf) {
50-
auto PIObj = reinterpret_cast<pi_mem>(ImageBuf);
51-
TargetContext->getPlugin().call<PiApiKind::piMemRelease>(PIObj);
50+
// TODO remove when ABI breaking changes are allowed.
51+
throw runtime_error("Deprecated release operation", PI_INVALID_OPERATION);
5252
}
5353

5454
void MemoryManager::releaseMemObj(ContextImplPtr TargetContext,
@@ -81,28 +81,10 @@ void *MemoryManager::allocate(ContextImplPtr TargetContext, SYCLMemObjI *MemObj,
8181
OutEvent);
8282
}
8383

84-
// Creates an image1d buffer wrapper object around given memory object.
8584
void *MemoryManager::wrapIntoImageBuffer(ContextImplPtr TargetContext,
8685
void *MemBuf, SYCLMemObjI *MemObj) {
87-
// Image format: 1 channel per pixel, each pixel 8 bit, Size pixels occupies
88-
// Size bytes.
89-
pi_image_format Format = {PI_IMAGE_CHANNEL_ORDER_R,
90-
PI_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8};
91-
92-
// Image descriptor - request wrapper image1d creation.
93-
pi_image_desc Desc = {};
94-
Desc.image_type = PI_MEM_TYPE_IMAGE1D_BUFFER;
95-
Desc.image_width = MemObj->getSize();
96-
Desc.buffer = reinterpret_cast<pi_mem>(MemBuf);
97-
98-
// Create the image object.
99-
const detail::plugin &Plugin = TargetContext->getPlugin();
100-
pi_mem Res = nullptr;
101-
pi_mem_flags Flags = 0;
102-
// Do not ref count the context handle, as it is not captured by the call.
103-
Plugin.call<PiApiKind::piMemImageCreate>(TargetContext->getHandleRef(), Flags,
104-
&Format, &Desc, nullptr, &Res);
105-
return Res;
86+
// TODO remove when ABI breaking changes are allowed.
87+
throw runtime_error("Deprecated allocation operation", PI_INVALID_OPERATION);
10688
}
10789

10890
void *MemoryManager::allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr,

sycl/source/detail/scheduler/commands.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -761,14 +761,6 @@ cl_int AllocaCommand::enqueueImp() {
761761
detail::getSyclObjImpl(MQueue->get_context()), getSYCLMemObj(),
762762
MInitFromUserData, HostPtr, std::move(EventImpls), Event);
763763

764-
// if this is ESIMD accessor, wrap the allocated device memory buffer into
765-
// an image buffer object.
766-
// TODO Address copying SYCL/ESIMD memory between contexts.
767-
if (getRequirement()->MIsESIMDAcc)
768-
ESIMDExt.MWrapperImage = MemoryManager::wrapIntoImageBuffer(
769-
detail::getSyclObjImpl(MQueue->get_context()), MMemAllocation,
770-
getSYCLMemObj());
771-
772764
return CL_SUCCESS;
773765
}
774766

@@ -960,10 +952,6 @@ cl_int ReleaseCommand::enqueueImp() {
960952
MAllocaCmd->getSYCLMemObj(),
961953
MAllocaCmd->getMemAllocation(),
962954
std::move(EventImpls), Event);
963-
// Release the wrapper object if present.
964-
if (void *WrapperImage = MAllocaCmd->ESIMDExt.MWrapperImage)
965-
MemoryManager::releaseImageBuffer(
966-
detail::getSyclObjImpl(MQueue->get_context()), WrapperImage);
967955
}
968956
return CL_SUCCESS;
969957
}
@@ -1670,9 +1658,7 @@ pi_result ExecCGCommand::SetKernelParamsAndLaunch(
16701658
case kernel_param_kind_t::kind_accessor: {
16711659
Requirement *Req = (Requirement *)(Arg.MPtr);
16721660
AllocaCommandBase *AllocaCmd = getAllocaForReq(Req);
1673-
RT::PiMem MemArg = Req->MIsESIMDAcc
1674-
? (RT::PiMem)AllocaCmd->ESIMDExt.MWrapperImage
1675-
: (RT::PiMem)AllocaCmd->getMemAllocation();
1661+
RT::PiMem MemArg = (RT::PiMem)AllocaCmd->getMemAllocation();
16761662
if (Plugin.getBackend() == backend::opencl) {
16771663
Plugin.call<PiApiKind::piKernelSetArg>(Kernel, NextTrueIndex,
16781664
sizeof(RT::PiMem), &MemArg);

sycl/source/detail/scheduler/commands.hpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,6 @@ class AllocaCommandBase : public Command {
339339

340340
void *MMemAllocation = nullptr;
341341

342-
// ESIMD-extension-specific fields.
343-
struct {
344-
// If this alloca corresponds to an ESIMD accessor, then this field holds
345-
// an image buffer wrapping the memory allocation above.
346-
void *MWrapperImage = nullptr;
347-
} ESIMDExt;
348-
349342
/// Alloca command linked with current command.
350343
/// Device and host alloca commands can be linked, so they may share the same
351344
/// memory. Only one allocation from a pair can be accessed at a time. Alloca

sycl/source/detail/scheduler/graph_builder.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,7 @@ AllocaCommandBase *Scheduler::GraphBuilder::getOrCreateAllocaForReq(
602602
const Requirement FullReq(/*Offset*/ {0, 0, 0}, Req->MMemoryRange,
603603
Req->MMemoryRange, access::mode::read_write,
604604
Req->MSYCLMemObj, Req->MDims, Req->MElemSize,
605-
0 /*ReMOffsetInBytes*/, false /*MIsSubBuffer*/,
606-
Req->MIsESIMDAcc);
605+
0 /*ReMOffsetInBytes*/, false /*MIsSubBuffer*/);
607606
// Can reuse user data for the first allocation
608607
const bool InitFromUserData = Record->MAllocaCommands.empty();
609608

sycl/source/handler.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,17 @@ void handler::associateWithHandler(detail::AccessorBaseHost *AccBase,
130130
/*index*/ 0);
131131
}
132132

133+
// TODO remove this one once ABI breaking changes are allowed.
133134
void handler::processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
134135
const int Size, const size_t Index, size_t &IndexShift,
135136
bool IsKernelCreatedFromSource) {
137+
processArg(Ptr, Kind, Size, Index, IndexShift, IsKernelCreatedFromSource,
138+
false);
139+
}
140+
141+
void handler::processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
142+
const int Size, const size_t Index, size_t &IndexShift,
143+
bool IsKernelCreatedFromSource, bool IsESIMD) {
136144
using detail::kernel_param_kind_t;
137145

138146
switch (Kind) {
@@ -162,7 +170,7 @@ void handler::processArg(void *Ptr, const detail::kernel_param_kind_t &Kind,
162170
// TODO ESIMD currently does not suport offset, memory and access ranges -
163171
// accessor::init for ESIMD-mode accessor has a single field, translated
164172
// to a single kernel argument set above.
165-
if (!AccImpl->MIsESIMDAcc && !IsKernelCreatedFromSource) {
173+
if (!IsKernelCreatedFromSource && !IsESIMD) {
166174
// Dimensionality of the buffer is 1 when dimensionality of the
167175
// accessor is 0.
168176
const size_t SizeAccField =
@@ -253,13 +261,21 @@ void handler::extractArgsAndReqs() {
253261
const detail::kernel_param_kind_t &Kind = UnPreparedArgs[I].MType;
254262
const int &Size = UnPreparedArgs[I].MSize;
255263
const int Index = UnPreparedArgs[I].MIndex;
256-
processArg(Ptr, Kind, Size, Index, IndexShift, IsKernelCreatedFromSource);
264+
processArg(Ptr, Kind, Size, Index, IndexShift, IsKernelCreatedFromSource,
265+
false);
257266
}
258267
}
259268

269+
// TODO remove once ABI breaking changes are allowed
260270
void handler::extractArgsAndReqsFromLambda(
261271
char *LambdaPtr, size_t KernelArgsNum,
262272
const detail::kernel_param_desc_t *KernelArgs) {
273+
extractArgsAndReqsFromLambda(LambdaPtr, KernelArgsNum, KernelArgs, false);
274+
}
275+
276+
void handler::extractArgsAndReqsFromLambda(
277+
char *LambdaPtr, size_t KernelArgsNum,
278+
const detail::kernel_param_desc_t *KernelArgs, bool IsESIMD) {
263279
const bool IsKernelCreatedFromSource = false;
264280
size_t IndexShift = 0;
265281
for (size_t I = 0; I < KernelArgsNum; ++I) {
@@ -284,7 +300,8 @@ void handler::extractArgsAndReqsFromLambda(
284300
Ptr = detail::getSyclObjImpl(*LocalAccBase).get();
285301
}
286302
}
287-
processArg(Ptr, Kind, Size, I, IndexShift, IsKernelCreatedFromSource);
303+
processArg(Ptr, Kind, Size, I, IndexShift, IsKernelCreatedFromSource,
304+
IsESIMD);
288305
}
289306
}
290307

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3830,10 +3830,12 @@ _ZN2cl4sycl7contextC2ERKSt6vectorINS0_6deviceESaIS3_EESt8functionIFvNS0_14except
38303830
_ZN2cl4sycl7contextC2ERKSt8functionIFvNS0_14exception_listEEERKNS0_13property_listE
38313831
_ZN2cl4sycl7contextC2ESt10shared_ptrINS0_6detail12context_implEE
38323832
_ZN2cl4sycl7handler10processArgEPvRKNS0_6detail19kernel_param_kind_tEimRmb
3833+
_ZN2cl4sycl7handler10processArgEPvRKNS0_6detail19kernel_param_kind_tEimRmbb
38333834
_ZN2cl4sycl7handler13getKernelNameB5cxx11Ev
38343835
_ZN2cl4sycl7handler18extractArgsAndReqsEv
38353836
_ZN2cl4sycl7handler20associateWithHandlerEPNS0_6detail16AccessorBaseHostENS0_6access6targetE
38363837
_ZN2cl4sycl7handler28extractArgsAndReqsFromLambdaEPcmPKNS0_6detail19kernel_param_desc_tE
3838+
_ZN2cl4sycl7handler28extractArgsAndReqsFromLambdaEPcmPKNS0_6detail19kernel_param_desc_tEb
38373839
_ZN2cl4sycl7handler6memcpyEPvPKvm
38383840
_ZN2cl4sycl7handler6memsetEPvim
38393841
_ZN2cl4sycl7handler7barrierERKSt6vectorINS0_5eventESaIS3_EE

0 commit comments

Comments
 (0)