-
Notifications
You must be signed in to change notification settings - Fork 766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SYCL][Bindless][UR][E2E] Add image memory and handle support queries #17865
base: sycl
Are you sure you want to change the base?
[SYCL][Bindless][UR][E2E] Add image memory and handle support queries #17865
Conversation
This patch introduces two new SYCL queries for Bindless Images. `get_image_memory_support` returns a vector of supported image backing memory types for a device given an `image_descriptor. `get_image_handle_supported` returns a boolean indicating whether the device supports creation of either a `sampled_image_handle` or `unsampled_image_handle`, given an `image_descriptor` and image backing memory type. Some tests are updated to use these queries to filter out unsupported image properties, e.g. allocating `unorm` channel types on the LevelZero backend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NativeCPU part looks fine.
|
||
template <typename ImageHandleType> | ||
bool | ||
get_image_handle_supported(const image_descriptor &imageDescriptor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming is a little inconsistent here, or is that purposeful to highlight that one returns a vector of support and the other is a bool
? get_image_memory_support
VS get_image_handle_supported
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or is that purposeful to highlight that one returns a vector of support and the other is a
bool
?
That's correct.
enum class image_memory_handle_type : /* unspecified */ { | ||
usm_pointer, | ||
opaque_handle | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there ever going to be more than two options here?
It feels odd that this first query returns a vector for only two elements that are queried whereas the next query also only has two options to query yet that chooses to return a bool based on the templated handle type. Why aren't both sets of queries consistent in this regard? It feels awfully fiddly for users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's plausible to consider that in future the extension might provide support for more than two types of memory backing, e.g. non-usm pointer for host-task only. It's less plausible that we will have more than two types of image handles (sampled & unsampled).
We may also consider splitting usm_pointer
into distinct host_
, device_
, and shared_
variants, which would allow backends to provide finer grained allocation support queries that depend on all the information in an image_descriptor
, as opposed to the current true/false device aspects.
These decisions are not set in stone yet, and the API can change in the future, as this is still an experimental extension.
bool supportsPointerAllocation = false; | ||
Adapter->call< | ||
sycl::errc::runtime, | ||
sycl::detail::UrApiKind::urBindlessImagesGetImageMemoryPointerSupportExp>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does there really need to be two distinct funcs for this query? Why can't you have one func and pass in an enum for what you're specifically querying for as is done in other UR query funcs?
Looking further into this PR, it appears you end up calling into one massive function anyway. Why not do this at a higher level and reduce the number of UR funcs you have defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I weighed this against the addition of two new UR enum types that would not be used outside of passing values to these two queries and thought it simpler to just provide two functions. We could also use a boolean to indicate the memory/image handle types, however, I thought that would make these UR functions less clear.
Additionally, merging these UR functions might also make them less maintainable, as you already mentioned below, these queries tend to grow quite large in order for each backend to verify the properties in a given image descriptor are valid for every image type, while taking into account the type of backing memory.
The current was the most direct and simple solution to the problem as it currently stands. But I can see how passing an enum to the UR function is also valid and might be desirable in some circumstances.
bool supportsUnsampledHandle = false; | ||
Adapter->call<sycl::errc::runtime, | ||
sycl::detail::UrApiKind:: | ||
urBindlessImagesGetImageUnsampledHandleSupportExp>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here for the two different funcs which appear to be identical in signature other than the name.
@@ -248,94 +248,46 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, | |||
return ReturnValue(128u); | |||
} | |||
case UR_DEVICE_INFO_IMAGE2D_MAX_HEIGHT: { | |||
// Take the smaller of maximum surface and maximum texture height. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've made changes to the existing queries in the HIP adapter but there's no mention of this in your PR description. Shouldn't these changes come in as a separate commit specific to the fixes made here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these changes just remove redundant calls to hipDeviceGetAttribute
that I've fixed, alongside the queries for MAX_IMAGE_LINEAR_<DIM>
which are currently required for the HIP UR backend image verification to work.
It could be done as a separate commit, but I don't think fixing the HIP device queries that pertain to supported image properties strays too far away from the spirit of this PR.
@@ -1006,6 +1006,347 @@ UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImageGetInfoExp( | |||
} | |||
} | |||
|
|||
bool verifyCommonImagePropertiesSupport(const ur_device_handle_t hDevice, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function looks awfully unmaintainable. Is there a better way to do this?
I'll need to come back later to go over this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be split into several functions that verify a single image type each, however that could be up to 5 extra helper functions.
@@ -44,6 +44,10 @@ | |||
??$get_backend_info@Uversion@platform@info@_V1@sycl@@@kernel@_V1@sycl@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ | |||
??$get_backend_info@Uversion@platform@info@_V1@sycl@@@platform@_V1@sycl@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ | |||
??$get_backend_info@Uversion@platform@info@_V1@sycl@@@queue@_V1@sycl@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ | |||
??$get_image_handle_supported@Usampled_image_handle@experimental@oneapi@ext@_V1@sycl@@@experimental@oneapi@ext@_V1@sycl@@YA_NAEBUimage_descriptor@01234@W4image_memory_handle_type@01234@AEBVdevice@34@AEBVcontext@34@@Z | |||
??$get_image_handle_supported@Usampled_image_handle@experimental@oneapi@ext@_V1@sycl@@@experimental@oneapi@ext@_V1@sycl@@YA_NAEBUimage_descriptor@01234@W4image_memory_handle_type@01234@AEBVqueue@34@@Z |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, unrelated to the line here: How does these changes mix with the existing image_descriptor::verify()
method. Would it not be a good idea to incorporate the two somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it not be a good idea to incorporate the two somehow?
I think we need to have another look at the verify
function. I'm not sure whether it's still completely applicable, at least in its current state, as it cannot take into account the backend used or the type of image backing memory the descriptor is going to be used to allocate.
The queries I've introduced in this PR do far more than the verify
function can without taking sycl::device/context/queue
parameters, and an indication of the backing memory type.
The queries introduced here also cover creation of sampled/unsampled image handles, should those be incorporated into the verify
function?
As it stands the verify
function acts as a very simple sanity check, and there is specific wording in the documentation as to what it checks.
Going forward, I think the best option may be to get rid of the verify
function in favor of the new queries introduced in this PR, as they are far more rigorous, by taking into the backend used (each backend has some differences in what it provides support for) and the image backing memory type. A general verify
function seems too broad to accommodate verification of an image_descriptor
, as the allocation of the descriptor depends on the properties I mention above.
sycl::device dev; | ||
sycl::queue q(dev); | ||
auto ctxt = q.get_context(); | ||
auto dev = syclQueue.get_device(); | ||
auto ctxt = syclQueue.get_context(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: To make this PR easier to review what changes are necessary vs what are not necessary, any NFC changes should be left to a different PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is not purely NFC.
In order to query the device for image support in run_test
I needed access to the sycl::device
and sycl::context
, which I did by creating a sycl::queue
.
Then, in order to ensure I'm operating on the same queue/device here in run_sycl
, I passed that queue as a parameter here, instead of creating a whole new queue object.
- type: bool | ||
name: isOpaqueAllocation | ||
desc: "[in] indicates whether the image memory would be backed by an opaque handle allocation" | ||
- type: bool* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you change these to use the $x_bool_t typedef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, now using $x_bool_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UR + CL adapter lgtm
This patch introduces two new SYCL queries for Bindless Images.
get_image_memory_support
returns a vector of supported image backing memory types for a device given an `image_descriptor.get_image_handle_supported
returns a boolean indicating whether the device supports creation of either asampled_image_handle
orunsampled_image_handle
, given animage_descriptor
and image backing memory type.Some tests are updated to use these queries to filter out unsupported image properties, e.g. allocating
unorm
channel types on the LevelZero backend.