Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions sycl/source/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,14 @@ verify_sub_copy(const ext::oneapi::experimental::image_descriptor &SrcImgDesc,
static_cast<bool>(result[2]));
};

sycl::range<3> SrcImageSize = {SrcImgDesc.width, SrcImgDesc.height,
SrcImgDesc.depth};
sycl::range<3> DestImageSize = {DestImgDesc.width, DestImgDesc.height,
DestImgDesc.depth};
// If this is a multi-layer array image, use the layer count; otherwise, use
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that L0 does not support arrays of 3d images, but briefly looking at the extension specification I couldn't find any restriction about that on the SYCL level.

Did I just missed it, or is it indeed missing from the spec?

If it is missing, I'm not asking to add it in this PR, but creating an issue to remind us about this would be helpful

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SYCL also does not support arrays of 3D images. The specification is not written clearly, but sentences like "... the 3rd dimension of the ranges represent the arrays' layer(s) being copied, regardless of whether the copy is performed on a 1D or 2D image array." indicate this. You can also see it in the code:

// Image arrays must only be 1D or 2D.

// the depth dimension (following the logic in fill_image_type() ).
sycl::range<3> SrcImageSize = {
SrcImgDesc.width, SrcImgDesc.height,
SrcImgDesc.array_size > 1 ? SrcImgDesc.array_size : SrcImgDesc.depth};
sycl::range<3> DestImageSize = {
DestImgDesc.width, DestImgDesc.height,
DestImgDesc.array_size > 1 ? DestImgDesc.array_size : DestImgDesc.depth};

if (isOutOfRange(SrcImageSize, SrcOffset, CopyExtent) ||
isOutOfRange(DestImageSize, DestOffset, CopyExtent)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// REQUIRES: aspect-ext_oneapi_bindless_images
// REQUIRES: aspect-ext_oneapi_image_array

// UNSUPPORTED: level_zero
// UNSUPPORTED-INTENDED: Undetermined issue causing enqueue process to fail.

// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// REQUIRES: aspect-ext_oneapi_bindless_images
// REQUIRES: aspect-ext_oneapi_image_array

// UNSUPPORTED: level_zero
// UNSUPPORTED-INTENDED: Undetermined issue causing data and invalid pointer
// errors.

// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

Expand Down
54 changes: 29 additions & 25 deletions unified-runtime/source/adapters/level_zero/image_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,47 +731,51 @@ ur_result_t getImageRegionHelper(ze_image_desc_t ZeImageDesc,
UR_ASSERT(Origin, UR_RESULT_ERROR_INVALID_VALUE);
UR_ASSERT(Region, UR_RESULT_ERROR_INVALID_VALUE);

if (ZeImageDesc.type == ZE_IMAGE_TYPE_1D ||
ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY) {
Region->height = 1;
Region->depth = 1;
} else if (ZeImageDesc.type == ZE_IMAGE_TYPE_2D ||
ZeImageDesc.type == ZE_IMAGE_TYPE_2DARRAY) {
Region->depth = 1;
}

#ifndef NDEBUG
// Validate Origin constraints based on image type
UR_ASSERT((ZeImageDesc.type == ZE_IMAGE_TYPE_1D && Origin->y == 0 &&
Origin->z == 0) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY && Origin->z == 0) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY && Origin->y == 0) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_2D && Origin->z == 0) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_2DARRAY) ||
Comment on lines +738 to 740
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also need to assert y == 0 for 1D array and z == 0 for 2D array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the current code is correct as-is. The assertions properly validate that:

  • Unused dimensions are zero (y and z for 1D, z for 2D)
  • Array layer dimensions (z for both 1D and 2D arrays) are allowed to be non-zero

(ZeImageDesc.type == ZE_IMAGE_TYPE_3D),
UR_RESULT_ERROR_INVALID_VALUE);

UR_ASSERT(Region->width && Region->height && Region->depth,
// Validate Region width is non-zero
UR_ASSERT(Region->width != 0, UR_RESULT_ERROR_INVALID_VALUE);

// Validate Region depth for 1D arrays contains layer count
UR_ASSERT(ZeImageDesc.type != ZE_IMAGE_TYPE_1DARRAY || Region->depth != 0,
UR_RESULT_ERROR_INVALID_VALUE);

// Validate Region depth for 2D arrays contains layer count
UR_ASSERT(ZeImageDesc.type != ZE_IMAGE_TYPE_2DARRAY || Region->depth != 0,
UR_RESULT_ERROR_INVALID_VALUE);
UR_ASSERT(
(ZeImageDesc.type == ZE_IMAGE_TYPE_1D && Region->height == 1 &&
Region->depth == 1) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY && Region->depth == 1) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_2D && Region->depth == 1) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_2DARRAY) ||
(ZeImageDesc.type == ZE_IMAGE_TYPE_3D),
UR_RESULT_ERROR_INVALID_VALUE);
#endif // !NDEBUG

uint32_t OriginX = ur_cast<uint32_t>(Origin->x);
uint32_t OriginY = ur_cast<uint32_t>(Origin->y);
uint32_t OriginZ = ur_cast<uint32_t>(Origin->z);

uint32_t Width = ur_cast<uint32_t>(Region->width);
uint32_t Height = (ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY)
? ZeImageDesc.arraylevels
: ur_cast<uint32_t>(Region->height);
uint32_t Depth = (ZeImageDesc.type == ZE_IMAGE_TYPE_2DARRAY)
? ZeImageDesc.arraylevels
: ur_cast<uint32_t>(Region->depth);
uint32_t Height = ur_cast<uint32_t>(Region->height);
uint32_t Depth = ur_cast<uint32_t>(Region->depth);

// Normalize Region dimensions based on image type
if (ZeImageDesc.type == ZE_IMAGE_TYPE_1D) {
// 1D images: height and depth must be 1
Height = 1;
Depth = 1;
} else if (ZeImageDesc.type == ZE_IMAGE_TYPE_1DARRAY) {
// UR uses depth for 1D array layers, but Level Zero uses height
OriginY = OriginZ;
OriginZ = 0;
Height = Depth;
Depth = 1;
} else if (ZeImageDesc.type == ZE_IMAGE_TYPE_2D) {
// 2D images: depth must be 1
Depth = 1;
}

ZeRegion = {OriginX, OriginY, OriginZ, Width, Height, Depth};

Expand Down