diff --git a/sycl/include/CL/sycl/accessor.hpp b/sycl/include/CL/sycl/accessor.hpp index 48ee02d661c05..6e22fd8323379 100644 --- a/sycl/include/CL/sycl/accessor.hpp +++ b/sycl/include/CL/sycl/accessor.hpp @@ -196,9 +196,6 @@ class accessor_common { template class AccessorSubscript { static constexpr int Dims = Dimensions; - template - using enable_if_t = typename std::enable_if::type; - mutable id MIDs; AccType MAccessor; @@ -212,21 +209,22 @@ class accessor_common { MIDs[0] = Index; } - template 1)>> + template 1)>> AccessorSubscript operator[](size_t Index) { MIDs[Dims - CurDims] = Index; return AccessorSubscript(MAccessor, MIDs); } template > + typename = detail::enable_if_t> RefType operator[](size_t Index) const { MIDs[Dims - CurDims] = Index; return MAccessor[MIDs]; } template > + typename = detail::enable_if_t> DataT operator[](size_t Index) const { MIDs[Dims - SubDims] = Index; return MAccessor[MIDs]; @@ -250,9 +248,6 @@ class accessor : AccessTarget == access::target::host_buffer), "Expected buffer type"); - template - using enable_if_t = typename std::enable_if::type; - using AccessorCommonT = detail::accessor_common; @@ -336,7 +331,7 @@ class accessor : using const_reference = const DataT &; template - accessor(enable_if_t<((!IsPlaceH && IsHostBuf) || + accessor(detail::enable_if_t<((!IsPlaceH && IsHostBuf) || (IsPlaceH && (IsGlobalBuf || IsConstantBuf))) && Dims == 0, buffer > &BufferRef) #ifdef __SYCL_DEVICE_ONLY__ @@ -358,7 +353,7 @@ class accessor : template accessor( buffer &BufferRef, - enable_if_t<(!IsPlaceH && (IsGlobalBuf || IsConstantBuf)) && Dims == 0, + detail::enable_if_t<(!IsPlaceH && (IsGlobalBuf || IsConstantBuf)) && Dims == 0, handler> &CommandGroupHandler) #ifdef __SYCL_DEVICE_ONLY__ : impl(id(), BufferRef.get_range(), BufferRef.MemRange) { @@ -374,11 +369,11 @@ class accessor : } #endif - template < - int Dims = Dimensions, - typename = enable_if_t<((!IsPlaceH && IsHostBuf) || - (IsPlaceH && (IsGlobalBuf || IsConstantBuf))) && - (Dims > 0)>> + template 0)>> accessor(buffer &BufferRef) #ifdef __SYCL_DEVICE_ONLY__ : impl(id(), BufferRef.get_range(), BufferRef.MemRange) { @@ -398,7 +393,7 @@ class accessor : #endif template 0)>> accessor(buffer &BufferRef, handler &CommandGroupHandler) #ifdef __SYCL_DEVICE_ONLY__ @@ -415,11 +410,11 @@ class accessor : } #endif - template < - int Dims = Dimensions, - typename = enable_if_t<((!IsPlaceH && IsHostBuf) || - (IsPlaceH && (IsGlobalBuf || IsConstantBuf))) && - (Dims > 0)>> + template 0)>> accessor(buffer &BufferRef, range AccessRange, id AccessOffset = {}) #ifdef __SYCL_DEVICE_ONLY__ @@ -427,10 +422,10 @@ class accessor : } #else : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset), - detail::convertToArrayOfN<3, 1>(AccessRange), - detail::convertToArrayOfN<3, 1>(BufferRef.MemRange), - AccessMode, detail::getSyclObjImpl(BufferRef).get(), - Dimensions, sizeof(DataT)) { + detail::convertToArrayOfN<3, 1>(AccessRange), + detail::convertToArrayOfN<3, 1>(BufferRef.MemRange), + AccessMode, detail::getSyclObjImpl(BufferRef).get(), + Dimensions, sizeof(DataT)) { detail::EventImplPtr Event = detail::Scheduler::getInstance().addHostAccessor( AccessorBaseHost::impl.get()); @@ -439,7 +434,7 @@ class accessor : #endif template 0)>> accessor(buffer &BufferRef, handler &CommandGroupHandler, range AccessRange, id AccessOffset = {}) @@ -448,10 +443,10 @@ class accessor : } #else : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset), - detail::convertToArrayOfN<3, 1>(AccessRange), - detail::convertToArrayOfN<3, 1>(BufferRef.MemRange), - AccessMode, detail::getSyclObjImpl(BufferRef).get(), - Dimensions, sizeof(DataT)) { + detail::convertToArrayOfN<3, 1>(AccessRange), + detail::convertToArrayOfN<3, 1>(BufferRef.MemRange), + AccessMode, detail::getSyclObjImpl(BufferRef).get(), + Dimensions, sizeof(DataT)) { CommandGroupHandler.associateWithHandler(*this); } #endif @@ -462,53 +457,53 @@ class accessor : size_t get_count() const { return getMemoryRange().size(); } - template 0)>> + template 0)>> range get_range() const { return detail::convertToArrayOfN(getAccessRange()); } - template 0)>> + template 0)>> id get_offset() const { return detail::convertToArrayOfN(getOffset()); } template > + typename = detail::enable_if_t> operator RefType() const { const size_t LinearIndex = getLinearIndex(id()); return *(getQualifiedPtr() + LinearIndex); } template 0)>> + typename = detail::enable_if_t 0)>> RefType operator[](id Index) const { const size_t LinearIndex = getLinearIndex(Index); return getQualifiedPtr()[LinearIndex]; } template > + typename = detail::enable_if_t> RefType operator[](size_t Index) const { const size_t LinearIndex = getLinearIndex(id(Index)); return getQualifiedPtr()[LinearIndex]; } template > + typename = detail::enable_if_t> operator DataT() const { const size_t LinearIndex = getLinearIndex(id()); return *(getQualifiedPtr() + LinearIndex); } template 0)>> + typename = detail::enable_if_t 0)>> DataT operator[](id Index) const { const size_t LinearIndex = getLinearIndex(Index); return getQualifiedPtr()[LinearIndex]; } template > + typename = detail::enable_if_t> DataT operator[](size_t Index) const { const size_t LinearIndex = getLinearIndex(id(Index)); return getQualifiedPtr()[LinearIndex]; @@ -533,39 +528,39 @@ class accessor : } template - typename enable_if_t>::type + typename detail::enable_if_t>::type operator[](size_t Index) const { const size_t LinearIndex = getLinearIndex(id(Index)); return atomic( multi_ptr(getQualifiedPtr() + LinearIndex)); } - template 1)>> + template 1)>> typename AccessorCommonT::template AccessorSubscript operator[](size_t Index) const { return AccessorSubscript(*this, Index); } - template < - access::target AccessTarget_ = AccessTarget, - typename = enable_if_t> + template > DataT *get_pointer() const { const size_t LinearIndex = getLinearIndex(id()); return getQualifiedPtr() + LinearIndex; } - template < - access::target AccessTarget_ = AccessTarget, - typename = enable_if_t> + template > global_ptr get_pointer() const { const size_t LinearIndex = getLinearIndex(id()); return global_ptr(getQualifiedPtr() + LinearIndex); } - template < - access::target AccessTarget_ = AccessTarget, - typename = enable_if_t> + template > constant_ptr get_pointer() const { const size_t LinearIndex = getLinearIndex(id()); return constant_ptr(getQualifiedPtr() + LinearIndex); @@ -601,9 +596,6 @@ class accessor::type &; using PtrType = typename detail::PtrValueType::type *; - template - using enable_if_t = typename std::enable_if::type; - #ifdef __SYCL_DEVICE_ONLY__ detail::LocalAccessorBaseDevice impl; @@ -646,7 +638,7 @@ class accessor> + template > accessor(handler &CommandGroupHandler) #ifdef __SYCL_DEVICE_ONLY__ : impl(range{1}) { @@ -656,7 +648,7 @@ class accessor 0)>> + template 0)>> accessor(range AllocationSize, handler &CommandGroupHandler) #ifdef __SYCL_DEVICE_ONLY__ : impl(AllocationSize) { @@ -672,48 +664,48 @@ class accessor> + typename = detail::enable_if_t> operator RefType() const { return *getQualifiedPtr(); } template 0)>> + typename = detail::enable_if_t 0)>> RefType operator[](id Index) const { const size_t LinearIndex = getLinearIndex(Index); return getQualifiedPtr()[LinearIndex]; } template > + typename = detail::enable_if_t> RefType operator[](size_t Index) const { return getQualifiedPtr()[Index]; } - template < - int Dims = Dimensions, - typename = enable_if_t> + template > operator atomic() const { return atomic(multi_ptr(getQualifiedPtr())); } - template < - int Dims = Dimensions, - typename = enable_if_t 0)>> + template 0)>> atomic operator[](id Index) const { const size_t LinearIndex = getLinearIndex(Index); return atomic( multi_ptr(getQualifiedPtr() + LinearIndex)); } - template < - int Dims = Dimensions, - typename = enable_if_t> + template > atomic operator[](size_t Index) const { return atomic(multi_ptr(getQualifiedPtr() + Index)); } - template 1)>> + template 1)>> typename AccessorCommonT::template AccessorSubscript operator[](size_t Index) const { return AccessorSubscript(*this, Index); diff --git a/sycl/include/CL/sycl/detail/cg.hpp b/sycl/include/CL/sycl/detail/cg.hpp index 1a8eb3b98e336..73c0619e4e206 100644 --- a/sycl/include/CL/sycl/detail/cg.hpp +++ b/sycl/include/CL/sycl/detail/cg.hpp @@ -9,8 +9,10 @@ #pragma once #include +#include #include #include +#include #include #include #include @@ -45,11 +47,12 @@ class ArgDesc { class NDRDescT { // The method initializes all sizes for dimensions greater than the passed one // to the default values, so they will not affect execution. - template void setNDRangeLeftover() { + void setNDRangeLeftover(int Dims_) { for (int I = Dims_; I < 3; ++I) { GlobalSize[I] = 1; LocalSize[I] = LocalSize[0] ? 1 : 0; GlobalOffset[I] = 0; + NumWorkGroups[I] = 0; } } @@ -61,9 +64,21 @@ class NDRDescT { GlobalSize[I] = NumWorkItems[I]; LocalSize[I] = 0; GlobalOffset[I] = 0; + NumWorkGroups[I] = 0; } + setNDRangeLeftover(Dims_); + Dims = Dims_; + } - setNDRangeLeftover(); + template + void set(sycl::range NumWorkItems, sycl::id Offset) { + for (int I = 0; I < Dims_; ++I) { + GlobalSize[I] = NumWorkItems[I]; + LocalSize[I] = 0; + GlobalOffset[I] = Offset[I]; + NumWorkGroups[I] = 0; + } + setNDRangeLeftover(Dims_); Dims = Dims_; } @@ -72,14 +87,42 @@ class NDRDescT { GlobalSize[I] = ExecutionRange.get_global_range()[I]; LocalSize[I] = ExecutionRange.get_local_range()[I]; GlobalOffset[I] = ExecutionRange.get_offset()[I]; + NumWorkGroups[I] = 0; } - setNDRangeLeftover(); + setNDRangeLeftover(Dims_); + Dims = Dims_; + } + + void set(int Dims_, sycl::nd_range<3> ExecutionRange) { + for (int I = 0; I < Dims_; ++I) { + GlobalSize[I] = ExecutionRange.get_global_range()[I]; + LocalSize[I] = ExecutionRange.get_local_range()[I]; + GlobalOffset[I] = ExecutionRange.get_offset()[I]; + NumWorkGroups[I] = 0; + } + setNDRangeLeftover(Dims_); + Dims = Dims_; + } + + template void setNumWorkGroups(sycl::range N) { + for (int I = 0; I < Dims_; ++I) { + GlobalSize[I] = 0; + // '0' is a mark to adjust before kernel launch when there is enough info: + LocalSize[I] = 0; + GlobalOffset[I] = 0; + NumWorkGroups[I] = N[I]; + } + setNDRangeLeftover(Dims_); Dims = Dims_; } sycl::range<3> GlobalSize; sycl::range<3> LocalSize; sycl::id<3> GlobalOffset; + /// Number of workgroups, used to record the number of workgroups from the + /// simplest form of parallel_for_work_group. If set, all other fields must be + /// zero + sycl::range<3> NumWorkGroups; size_t Dims; }; @@ -102,7 +145,20 @@ class HostKernel : public HostKernelBase { public: HostKernel(KernelType Kernel) : MKernel(Kernel) {} - void call(const NDRDescT &NDRDesc) override { runOnHost(NDRDesc); } + void call(const NDRDescT &NDRDesc) override { + // adjust ND range for serial host: + NDRDescT R1; + bool Adjust = false; + + if (NDRDesc.GlobalSize[0] == 0 && NDRDesc.NumWorkGroups[0] != 0) { + // LocalSize - which is the workgroup size - is not set; need to adjust + range<3> WGsize = {1, 1, 1}; // no better alternative for serial host? + R1.set(NDRDesc.Dims, nd_range<3>(NDRDesc.NumWorkGroups * WGsize, WGsize)); + Adjust = true; + } + const NDRDescT &R = Adjust ? R1 : NDRDesc; + runOnHost(R); + } char *getPtr() override { return reinterpret_cast(&MKernel); } @@ -165,6 +221,7 @@ class HostKernel : public HostKernelBase { sycl::id<3> GroupSize; for (int I = 0; I < 3; ++I) { GroupSize[I] = NDRDesc.GlobalSize[I] / NDRDesc.LocalSize[I]; + // TODO supoport case NDRDesc.GlobalSize[I] % NDRDesc.LocalSize[I] != 0 } sycl::range GlobalSize; @@ -217,6 +274,30 @@ class HostKernel : public HostKernelBase { } } } + + template + enable_if_t>::value> + runOnHost(const NDRDescT &NDRDesc) { + sycl::id NGroups; + + for (int I = 0; I < Dims; ++I) { + NGroups[I] = NDRDesc.GlobalSize[I] / NDRDesc.LocalSize[I]; + assert(NDRDesc.GlobalSize[I] % NDRDesc.LocalSize[I] == 0); + } + sycl::range GlobalSize; + sycl::range LocalSize; + + for (int I = 0; I < Dims; ++I) { + LocalSize[I] = NDRDesc.LocalSize[I]; + GlobalSize[I] = NDRDesc.GlobalSize[I]; + } + detail::NDLoop::iterate(NGroups, [&](const id &GroupID) { + sycl::group Group = + IDBuilder::createGroup(GlobalSize, LocalSize, GroupID); + MKernel(Group); + }); + } + ~HostKernel() = default; }; diff --git a/sycl/include/CL/sycl/detail/cnri.h b/sycl/include/CL/sycl/detail/cnri.h index 5dc0d79e4d121..1a4ba5dd321bf 100644 --- a/sycl/include/CL/sycl/detail/cnri.h +++ b/sycl/include/CL/sycl/detail/cnri.h @@ -93,6 +93,7 @@ typedef cl_context cnri_context; typedef cl_event cnri_event; typedef cl_program cnri_program; typedef cl_kernel cnri_kernel; +typedef cl_device_id cnri_device; enum { CNRI_SUCCESS = CL_SUCCESS }; diff --git a/sycl/include/CL/sycl/detail/common.hpp b/sycl/include/CL/sycl/detail/common.hpp index 4031e138f8d47..1dd2994198cee 100644 --- a/sycl/include/CL/sycl/detail/common.hpp +++ b/sycl/include/CL/sycl/detail/common.hpp @@ -103,6 +103,105 @@ template T createSyclObjFromImpl(decltype(T::impl) ImplObj) { return T(ImplObj); } +// Produces N-dimensional object of type T whose all components are initialized +// to given integer value. +template class T> struct InitializedVal { + template static T &&get(); +}; + +// Specialization for a one-dimensional type. +template