@@ -832,17 +832,14 @@ class __SYCL_SPECIAL_CLASS accessor :
832
832
833
833
template <int Dims = Dimensions> size_t getLinearIndex (id<Dims> Id) const {
834
834
835
- #ifdef __SYCL_DEVICE_ONLY__
836
- // Pointer is already adjusted for 1D case.
837
- if (Dimensions == 1 )
838
- return Id[0 ];
839
- #endif // __SYCL_DEVICE_ONLY__
840
-
841
835
size_t Result = 0 ;
842
836
// Unroll the following loop for both host and device code
843
837
__SYCL_UNROLL (3 )
844
838
for (int I = 0 ; I < Dims; ++I) {
845
839
Result = Result * getMemoryRange ()[I] + Id[I];
840
+ // We've already adjusted for the accessor's offset in the __init, so
841
+ // don't include it here in case of device.
842
+ #ifndef __SYCL_DEVICE_ONLY__
846
843
#if __cplusplus >= 201703L
847
844
if constexpr (!(PropertyListT::template has_property<
848
845
sycl::ext::oneapi::property::no_offset>())) {
@@ -851,6 +848,7 @@ class __SYCL_SPECIAL_CLASS accessor :
851
848
#else
852
849
Result += getOffset ()[I];
853
850
#endif
851
+ #endif // __SYCL_DEVICE_ONLY__
854
852
}
855
853
return Result;
856
854
}
@@ -919,17 +917,10 @@ class __SYCL_SPECIAL_CLASS accessor :
919
917
getAccessRange ()[I] = AccessRange[I];
920
918
getMemoryRange ()[I] = MemRange[I];
921
919
}
922
- // In case of 1D buffer, adjust pointer during initialization rather
923
- // then each time in operator[]. Will have to re-adjust in get_pointer
924
- if (1 == AdjustedDim)
925
- #if __cplusplus >= 201703L
926
- if constexpr (!(PropertyListT::template has_property<
927
- sycl::ext::oneapi::property::no_offset>())) {
928
- MData += Offset[0 ];
929
- }
930
- #else
931
- MData += Offset[0 ];
932
- #endif
920
+
921
+ // Adjust for offsets as that part is invariant for all invocations of
922
+ // operator[]. Will have to re-adjust in get_pointer.
923
+ MData += getTotalOffset ();
933
924
}
934
925
935
926
// __init variant used by the device compiler for ESIMD kernels.
@@ -1797,17 +1788,37 @@ class __SYCL_SPECIAL_CLASS accessor :
1797
1788
bool operator !=(const accessor &Rhs) const { return !(*this == Rhs); }
1798
1789
1799
1790
private:
1791
+ #ifdef __SYCL_DEVICE_ONLY__
1792
+ size_t getTotalOffset () const {
1793
+ size_t TotalOffset = 0 ;
1794
+ __SYCL_UNROLL (3 )
1795
+ for (int I = 0 ; I < Dimensions; ++I) {
1796
+ TotalOffset = TotalOffset * impl.MemRange [I];
1797
+ #if __cplusplus >= 201703L
1798
+ if constexpr (!(PropertyListT::template has_property<
1799
+ sycl::ext::oneapi::property::no_offset>())) {
1800
+ TotalOffset += impl.Offset [I];
1801
+ }
1802
+ #else
1803
+ TotalOffset += impl.Offset [I];
1804
+ #endif
1805
+ }
1806
+
1807
+ return TotalOffset;
1808
+ }
1809
+ #endif
1810
+
1800
1811
// supporting function for get_pointer()
1801
- // when dim==1, MData will have been preadjusted for faster access with []
1812
+ // MData has been preadjusted with offset for faster access with []
1802
1813
// but for get_pointer() we must return the original pointer.
1803
1814
// On device, getQualifiedPtr() returns MData, so we need to backjust it.
1804
1815
// On host, getQualifiedPtr() does not return MData, no need to adjust.
1805
1816
PtrType getPointerAdjusted () const {
1806
1817
#ifdef __SYCL_DEVICE_ONLY__
1807
- if (1 == AdjustedDim)
1808
- return getQualifiedPtr () - impl.Offset [0 ];
1809
- #endif
1818
+ return getQualifiedPtr () - getTotalOffset ();
1819
+ #else
1810
1820
return getQualifiedPtr ();
1821
+ #endif
1811
1822
}
1812
1823
1813
1824
void preScreenAccessor (const size_t elemInBuffer,
0 commit comments