Skip to content

Commit 4b7f70f

Browse files
committed
Add bounds checking for enqueue operations to the validation layer.
This is accomplished with the various size queries for buffers, images and USM allocations. Since not all adapters have these queries implemented the bounds checking isn't entirely comprehensive on all platforms just yet.
1 parent 9c6e151 commit 4b7f70f

File tree

16 files changed

+747
-403
lines changed

16 files changed

+747
-403
lines changed

include/ur_api.h

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5972,7 +5972,7 @@ urEnqueueEventsWaitWithBarrier(
59725972
UR_APIEXPORT ur_result_t UR_APICALL
59735973
urEnqueueMemBufferRead(
59745974
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
5975-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
5975+
ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object
59765976
bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false)
59775977
size_t offset, ///< [in] offset in bytes in the buffer object
59785978
size_t size, ///< [in] size in bytes of data being read
@@ -6021,7 +6021,7 @@ urEnqueueMemBufferRead(
60216021
UR_APIEXPORT ur_result_t UR_APICALL
60226022
urEnqueueMemBufferWrite(
60236023
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6024-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
6024+
ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object
60256025
bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false)
60266026
size_t offset, ///< [in] offset in bytes in the buffer object
60276027
size_t size, ///< [in] size in bytes of data being written
@@ -6080,7 +6080,7 @@ urEnqueueMemBufferWrite(
60806080
UR_APIEXPORT ur_result_t UR_APICALL
60816081
urEnqueueMemBufferReadRect(
60826082
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6083-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
6083+
ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object
60846084
bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false)
60856085
ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer
60866086
ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region
@@ -6146,7 +6146,7 @@ urEnqueueMemBufferReadRect(
61466146
UR_APIEXPORT ur_result_t UR_APICALL
61476147
urEnqueueMemBufferWriteRect(
61486148
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6149-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
6149+
ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object
61506150
bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false)
61516151
ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer
61526152
ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region
@@ -6199,8 +6199,8 @@ urEnqueueMemBufferWriteRect(
61996199
UR_APIEXPORT ur_result_t UR_APICALL
62006200
urEnqueueMemBufferCopy(
62016201
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6202-
ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object
6203-
ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object
6202+
ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object
6203+
ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object
62046204
size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from
62056205
size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into
62066206
size_t size, ///< [in] size in bytes of data being copied
@@ -6252,8 +6252,8 @@ urEnqueueMemBufferCopy(
62526252
UR_APIEXPORT ur_result_t UR_APICALL
62536253
urEnqueueMemBufferCopyRect(
62546254
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6255-
ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object
6256-
ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object
6255+
ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object
6256+
ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object
62576257
ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer
62586258
ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer
62596259
ur_rect_region_t region, ///< [in] source 3D rectangular region descriptor: width, height, depth
@@ -6307,7 +6307,7 @@ urEnqueueMemBufferCopyRect(
63076307
UR_APIEXPORT ur_result_t UR_APICALL
63086308
urEnqueueMemBufferFill(
63096309
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6310-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
6310+
ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object
63116311
const void *pPattern, ///< [in] pointer to the fill pattern
63126312
size_t patternSize, ///< [in] size in bytes of the pattern
63136313
size_t offset, ///< [in] offset into the buffer
@@ -6357,7 +6357,7 @@ urEnqueueMemBufferFill(
63576357
UR_APIEXPORT ur_result_t UR_APICALL
63586358
urEnqueueMemImageRead(
63596359
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6360-
ur_mem_handle_t hImage, ///< [in] handle of the image object
6360+
ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object
63616361
bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false)
63626362
ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image
63636363
ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D
@@ -6410,7 +6410,7 @@ urEnqueueMemImageRead(
64106410
UR_APIEXPORT ur_result_t UR_APICALL
64116411
urEnqueueMemImageWrite(
64126412
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6413-
ur_mem_handle_t hImage, ///< [in] handle of the image object
6413+
ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object
64146414
bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false)
64156415
ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image
64166416
ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D
@@ -6457,8 +6457,8 @@ urEnqueueMemImageWrite(
64576457
UR_APIEXPORT ur_result_t UR_APICALL
64586458
urEnqueueMemImageCopy(
64596459
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6460-
ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object
6461-
ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object
6460+
ur_mem_handle_t hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object
6461+
ur_mem_handle_t hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object
64626462
ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D
64636463
///< image
64646464
ur_rect_offset_t dstOrigin, ///< [in] defines the (x,y,z) offset in pixels in the destination 1D, 2D,
@@ -6543,7 +6543,7 @@ typedef enum ur_usm_migration_flag_t {
65436543
UR_APIEXPORT ur_result_t UR_APICALL
65446544
urEnqueueMemBufferMap(
65456545
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6546-
ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object
6546+
ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object
65476547
bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false)
65486548
ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping
65496549
size_t offset, ///< [in] offset in bytes of the buffer region being mapped
@@ -6611,7 +6611,7 @@ urEnqueueMemUnmap(
66116611
/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE
66126612
/// + `NULL == hQueue`
66136613
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
6614-
/// + `NULL == ptr`
6614+
/// + `NULL == pMem`
66156615
/// + `NULL == pPattern`
66166616
/// - ::UR_RESULT_ERROR_INVALID_QUEUE
66176617
/// - ::UR_RESULT_ERROR_INVALID_EVENT
@@ -6631,7 +6631,7 @@ urEnqueueMemUnmap(
66316631
UR_APIEXPORT ur_result_t UR_APICALL
66326632
urEnqueueUSMFill(
66336633
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6634-
void *ptr, ///< [in] pointer to USM memory object
6634+
void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object
66356635
size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less
66366636
///< than or equal to width.
66376637
const void *pPattern, ///< [in] pointer with the bytes of the pattern to set.
@@ -6674,8 +6674,8 @@ UR_APIEXPORT ur_result_t UR_APICALL
66746674
urEnqueueUSMMemcpy(
66756675
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
66766676
bool blocking, ///< [in] blocking or non-blocking copy
6677-
void *pDst, ///< [in] pointer to the destination USM memory object
6678-
const void *pSrc, ///< [in] pointer to the source USM memory object
6677+
void *pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object
6678+
const void *pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object
66796679
size_t size, ///< [in] size in bytes to be copied
66806680
uint32_t numEventsInWaitList, ///< [in] size of the event wait list
66816681
const ur_event_handle_t *phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of
@@ -6720,7 +6720,7 @@ urEnqueueUSMMemcpy(
67206720
UR_APIEXPORT ur_result_t UR_APICALL
67216721
urEnqueueUSMPrefetch(
67226722
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6723-
const void *pMem, ///< [in] pointer to the USM memory object
6723+
const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object
67246724
size_t size, ///< [in] size in bytes to be fetched
67256725
ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags
67266726
uint32_t numEventsInWaitList, ///< [in] size of the event wait list
@@ -6762,7 +6762,7 @@ urEnqueueUSMPrefetch(
67626762
UR_APIEXPORT ur_result_t UR_APICALL
67636763
urEnqueueUSMAdvise(
67646764
ur_queue_handle_t hQueue, ///< [in] handle of the queue object
6765-
const void *pMem, ///< [in] pointer to the USM memory object
6765+
const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object
67666766
size_t size, ///< [in] size in bytes to be advised
67676767
ur_usm_advice_flags_t advice, ///< [in] USM memory advice
67686768
ur_event_handle_t *phEvent ///< [out][optional] return an event object that identifies this particular
@@ -6803,7 +6803,7 @@ urEnqueueUSMAdvise(
68036803
UR_APIEXPORT ur_result_t UR_APICALL
68046804
urEnqueueUSMFill2D(
68056805
ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to.
6806-
void *pMem, ///< [in] pointer to memory to be filled.
6806+
void *pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled.
68076807
size_t pitch, ///< [in] the total width of the destination memory including padding.
68086808
size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less
68096809
///< than or equal to width.
@@ -6853,9 +6853,10 @@ UR_APIEXPORT ur_result_t UR_APICALL
68536853
urEnqueueUSMMemcpy2D(
68546854
ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to.
68556855
bool blocking, ///< [in] indicates if this operation should block the host.
6856-
void *pDst, ///< [in] pointer to memory where data will be copied.
6856+
void *pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will
6857+
///< be copied.
68576858
size_t dstPitch, ///< [in] the total width of the source memory including padding.
6858-
const void *pSrc, ///< [in] pointer to memory to be copied.
6859+
const void *pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied.
68596860
size_t srcPitch, ///< [in] the total width of the source memory including padding.
68606861
size_t width, ///< [in] the width in bytes of each row to be copied.
68616862
size_t height, ///< [in] the height of columns to be copied.
@@ -9856,7 +9857,7 @@ typedef struct ur_enqueue_mem_unmap_params_t {
98569857
/// allowing the callback the ability to modify the parameter's value
98579858
typedef struct ur_enqueue_usm_fill_params_t {
98589859
ur_queue_handle_t *phQueue;
9859-
void **pptr;
9860+
void **ppMem;
98609861
size_t *ppatternSize;
98619862
const void **ppPattern;
98629863
size_t *psize;

include/ur_print.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12512,10 +12512,10 @@ inline std::ostream &operator<<(std::ostream &os, [[maybe_unused]] const struct
1251212512
*(params->phQueue));
1251312513

1251412514
os << ", ";
12515-
os << ".ptr = ";
12515+
os << ".pMem = ";
1251612516

1251712517
ur::details::printPtr(os,
12518-
*(params->pptr));
12518+
*(params->ppMem));
1251912519

1252012520
os << ", ";
1252112521
os << ".patternSize = ";

scripts/YaML.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,18 @@ class ur_name_t(Structure):
616616
- `out` is used for params that are write-only; if the param is a pointer, then the memory being pointed to is also write-only
617617
- `in,out` is used for params that are both read and write; typically this is used for pointers to other data structures that contain both read and write params
618618
- `nocheck` is used to specify that no additional validation checks will be generated.
619-
+ `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`}
619+
+ `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`, `"[bounds(offset,size)]"`}
620620
- `optional` is used for params that are handles or pointers where it is legal for the value to be `nullptr`
621621
- `range` is used for params that are array pointers to specify the valid range that the is valid to read
622622
+ `start` and `end` must be an ISO-C standard identifier or literal
623623
+ `start` is inclusive and `end` is exclusive
624624
- `release` is used for params that are handles or pointers to handles where the function will destroy any backing memory associated with the handle(s)
625625
- `typename` is used to denote the type enum for params that are opaque pointers to values of tagged data types.
626+
- `bounds` is used for params that are memory objects or USM allocations. It specifies the range within the memory allocation represented by the param that will be accessed by the operation.
627+
+ `offset` and `size` must be an ISO-C standard identifier or literal
628+
+ The sum of `offset` and `size` will be compared against the size of the memory allocation represented by the param.
629+
+ If `offset` and `size` are not both integers they must be of the types `$x_rect_offset` and `$x_rect_region` respectively.
630+
+ If `bounds` is used the operation must also take a parameter of type `$x_queue_handle_t`
626631
+ `type` must be an ISO-C standard identifier
627632
+ `name` must be a unique ISO-C standard identifier
628633
- A param may take the following optional scalar field: {`init`, `version`}

0 commit comments

Comments
 (0)