From 4b7f70f264ad093b45c40aed21f0c887128a691a Mon Sep 17 00:00:00 2001 From: Aaron Greig Date: Thu, 16 Nov 2023 17:19:20 +0000 Subject: [PATCH] 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. --- include/ur_api.h | 49 ++--- include/ur_print.hpp | 4 +- scripts/YaML.md | 7 +- scripts/core/enqueue.yml | 46 ++-- scripts/parse_specs.py | 9 + scripts/templates/helper.py | 61 +++++- source/adapters/hip/usm.cpp | 6 +- source/adapters/null/ur_nullddi.cpp | 90 +++++--- source/adapters/opencl/enqueue.cpp | 176 +++------------ source/loader/layers/tracing/ur_trcddi.cpp | 92 +++++--- source/loader/layers/validation/ur_valddi.cpp | 202 +++++++++++++++--- .../layers/validation/ur_validation_layer.cpp | 125 +++++++++++ .../layers/validation/ur_validation_layer.hpp | 11 + source/loader/ur_ldrddi.cpp | 90 +++++--- source/loader/ur_libapi.cpp | 92 +++++--- source/ur_api.cpp | 90 +++++--- 16 files changed, 747 insertions(+), 403 deletions(-) diff --git a/include/ur_api.h b/include/ur_api.h index 09f6d77a6b..63f5fc8083 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -5972,7 +5972,7 @@ urEnqueueEventsWaitWithBarrier( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -6021,7 +6021,7 @@ urEnqueueMemBufferRead( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being written @@ -6080,7 +6080,7 @@ urEnqueueMemBufferWrite( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -6146,7 +6146,7 @@ urEnqueueMemBufferReadRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -6199,8 +6199,8 @@ urEnqueueMemBufferWriteRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -6252,8 +6252,8 @@ urEnqueueMemBufferCopy( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t region, ///< [in] source 3D rectangular region descriptor: width, height, depth @@ -6307,7 +6307,7 @@ urEnqueueMemBufferCopyRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object const void *pPattern, ///< [in] pointer to the fill pattern size_t patternSize, ///< [in] size in bytes of the pattern size_t offset, ///< [in] offset into the buffer @@ -6357,7 +6357,7 @@ urEnqueueMemBufferFill( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D @@ -6410,7 +6410,7 @@ urEnqueueMemImageRead( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D @@ -6457,8 +6457,8 @@ urEnqueueMemImageWrite( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_mem_handle_t hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image 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 { UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -6611,7 +6611,7 @@ urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -6631,7 +6631,7 @@ urEnqueueMemUnmap( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. const void *pPattern, ///< [in] pointer with the bytes of the pattern to set. @@ -6674,8 +6674,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object + void *pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void *pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t *phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -6720,7 +6720,7 @@ urEnqueueUSMMemcpy( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMPrefetch( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object + const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list @@ -6762,7 +6762,7 @@ urEnqueueUSMPrefetch( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMAdvise( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object + const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t *phEvent ///< [out][optional] return an event object that identifies this particular @@ -6803,7 +6803,7 @@ urEnqueueUSMAdvise( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void *pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -6853,9 +6853,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void *pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void *pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. size_t height, ///< [in] the height of columns to be copied. @@ -9856,7 +9857,7 @@ typedef struct ur_enqueue_mem_unmap_params_t { /// allowing the callback the ability to modify the parameter's value typedef struct ur_enqueue_usm_fill_params_t { ur_queue_handle_t *phQueue; - void **pptr; + void **ppMem; size_t *ppatternSize; const void **ppPattern; size_t *psize; diff --git a/include/ur_print.hpp b/include/ur_print.hpp index dc7442068c..9a0ce9e657 100644 --- a/include/ur_print.hpp +++ b/include/ur_print.hpp @@ -12512,10 +12512,10 @@ inline std::ostream &operator<<(std::ostream &os, [[maybe_unused]] const struct *(params->phQueue)); os << ", "; - os << ".ptr = "; + os << ".pMem = "; ur::details::printPtr(os, - *(params->pptr)); + *(params->ppMem)); os << ", "; os << ".patternSize = "; diff --git a/scripts/YaML.md b/scripts/YaML.md index 291e4263c7..ee22cd39d6 100644 --- a/scripts/YaML.md +++ b/scripts/YaML.md @@ -616,13 +616,18 @@ class ur_name_t(Structure): - `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 - `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 - `nocheck` is used to specify that no additional validation checks will be generated. - + `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`} + + `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`, `"[bounds(offset,size)]"`} - `optional` is used for params that are handles or pointers where it is legal for the value to be `nullptr` - `range` is used for params that are array pointers to specify the valid range that the is valid to read + `start` and `end` must be an ISO-C standard identifier or literal + `start` is inclusive and `end` is exclusive - `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) - `typename` is used to denote the type enum for params that are opaque pointers to values of tagged data types. + - `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. + + `offset` and `size` must be an ISO-C standard identifier or literal + + The sum of `offset` and `size` will be compared against the size of the memory allocation represented by the param. + + If `offset` and `size` are not both integers they must be of the types `$x_rect_offset` and `$x_rect_region` respectively. + + If `bounds` is used the operation must also take a parameter of type `$x_queue_handle_t` + `type` must be an ISO-C standard identifier + `name` must be a unique ISO-C standard identifier - A param may take the following optional scalar field: {`init`, `version`} diff --git a/scripts/core/enqueue.yml b/scripts/core/enqueue.yml index 7da1c8f680..7af03074c9 100644 --- a/scripts/core/enqueue.yml +++ b/scripts/core/enqueue.yml @@ -158,7 +158,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -211,7 +211,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -265,7 +265,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(bufferOrigin, region)] handle of the buffer object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -341,7 +341,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(bufferOrigin, region)] handle of the buffer object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -414,10 +414,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBufferSrc - desc: "[in] handle of the src buffer object" + desc: "[in][bounds(srcOffset, size)] handle of the src buffer object" - type: $x_mem_handle_t name: hBufferDst - desc: "[in] handle of the dest buffer object" + desc: "[in][bounds(dstOffset, size)] handle of the dest buffer object" - type: size_t name: srcOffset desc: "[in] offset into hBufferSrc to begin copying from" @@ -466,10 +466,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBufferSrc - desc: "[in] handle of the source buffer object" + desc: "[in][bounds(srcOrigin, region)] handle of the source buffer object" - type: $x_mem_handle_t name: hBufferDst - desc: "[in] handle of the dest buffer object" + desc: "[in][bounds(dstOrigin, region)] handle of the dest buffer object" - type: $x_rect_offset_t name: srcOrigin desc: "[in] 3D offset in the source buffer" @@ -537,7 +537,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: "const void*" name: pPattern desc: "[in] pointer to the fill pattern" @@ -595,7 +595,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImage - desc: "[in] handle of the image object" + desc: "[in][bounds(origin, region)] handle of the image object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -654,7 +654,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImage - desc: "[in] handle of the image object" + desc: "[in][bounds(origin, region)] handle of the image object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -711,10 +711,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImageSrc - desc: "[in] handle of the src image object" + desc: "[in][bounds(srcOrigin, region)] handle of the src image object" - type: $x_mem_handle_t name: hImageDst - desc: "[in] handle of the dest image object" + desc: "[in][bounds(dstOrigin, region)] handle of the dest image object" - type: $x_rect_offset_t name: srcOrigin desc: "[in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D image" @@ -842,7 +842,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingMap desc: "[in] indicates blocking (true), non-blocking (false)" @@ -996,8 +996,8 @@ params: name: hQueue desc: "[in] handle of the queue object" - type: void* - name: ptr - desc: "[in] pointer to USM memory object" + name: pMem + desc: "[in][bounds(0, size)] pointer to USM memory object" - type: size_t name: patternSize desc: "[in] the size in bytes of the pattern. Must be a power of 2 and less than or equal to width." @@ -1050,10 +1050,10 @@ params: desc: "[in] blocking or non-blocking copy" - type: void* name: pDst - desc: "[in] pointer to the destination USM memory object" + desc: "[in][bounds(0, size)] pointer to the destination USM memory object" - type: "const void*" name: pSrc - desc: "[in] pointer to the source USM memory object" + desc: "[in][bounds(0, size)] pointer to the source USM memory object" - type: size_t name: size desc: "[in] size in bytes to be copied" @@ -1097,7 +1097,7 @@ params: desc: "[in] handle of the queue object" - type: "const void*" name: pMem - desc: "[in] pointer to the USM memory object" + desc: "[in][bounds(0, size)] pointer to the USM memory object" - type: size_t name: size desc: "[in] size in bytes to be fetched" @@ -1144,7 +1144,7 @@ params: desc: "[in] handle of the queue object" - type: "const void*" name: pMem - desc: "[in] pointer to the USM memory object" + desc: "[in][bounds(0, size)] pointer to the USM memory object" - type: size_t name: size desc: "[in] size in bytes to be advised" @@ -1176,7 +1176,7 @@ params: desc: "[in] handle of the queue to submit to." - type: void* name: pMem - desc: "[in] pointer to memory to be filled." + desc: "[in][bounds(0, pitch * height)] pointer to memory to be filled." - type: size_t name: pitch desc: "[in] the total width of the destination memory including padding." @@ -1238,13 +1238,13 @@ params: desc: "[in] indicates if this operation should block the host." - type: void* name: pDst - desc: "[in] pointer to memory where data will be copied." + desc: "[in][bounds(0, dstPitch * height)] pointer to memory where data will be copied." - type: size_t name: dstPitch desc: "[in] the total width of the source memory including padding." - type: "const void*" name: pSrc - desc: "[in] pointer to memory to be copied." + desc: "[in][bounds(0, srcPitch * height)] pointer to memory to be copied." - type: size_t name: srcPitch desc: "[in] the total width of the source memory including padding." diff --git a/scripts/parse_specs.py b/scripts/parse_specs.py index a1477ce534..332af88cc7 100644 --- a/scripts/parse_specs.py +++ b/scripts/parse_specs.py @@ -338,6 +338,15 @@ def __validate_params(d, tags): if not param_traits.is_range(item): raise Exception(prefix+"handle type must include a range(start, end) as part of 'desc'") + if param_traits.is_bounds(item): + has_queue = False + for p in d['params']: + if re.match(r"hQueue$", p['name']): + has_queue = True + + if not has_queue: + raise Exception(prefix+"bounds must only be used on entry points which take a `hQueue` parameter") + ver = __validate_version(item, prefix=prefix, base_version=d_ver) if ver < max_ver: raise Exception(prefix+"'version' must be increasing: %s"%item['version']) diff --git a/scripts/templates/helper.py b/scripts/templates/helper.py index 4fbb2ca47b..928db1675c 100644 --- a/scripts/templates/helper.py +++ b/scripts/templates/helper.py @@ -356,6 +356,7 @@ class param_traits: RE_RELEASE = r".*\[release\].*" RE_TYPENAME = r".*\[typename\((.+),\s(.+)\)\].*" RE_TAGGED = r".*\[tagged_by\((.+)\)].*" + RE_BOUNDS = r".*\[bounds\((.+),\s*(.+)\)].*" @classmethod def is_mbz(cls, item): @@ -412,6 +413,13 @@ def is_tagged(cls, item): return True if re.match(cls.RE_TAGGED, item['desc']) else False except: return False + + @classmethod + def is_bounds(cls, item): + try: + return True if re.match(cls.RE_BOUNDS, item['desc']) else False + except: + return False @classmethod def tagged_member(cls, item): @@ -457,6 +465,22 @@ def typename_size(cls, item): else: return None + @classmethod + def bounds_offset(cls, item): + match = re.match(cls.RE_BOUNDS, item['desc']) + if match: + return match.group(1) + else: + return None + + @classmethod + def bounds_size(cls, item): + match = re.match(cls.RE_BOUNDS, item['desc']) + if match: + return match.group(2) + else: + return None + """ Extracts traits from a function object """ @@ -1041,7 +1065,35 @@ def make_pfncb_param_type(namespace, tags, obj): """ Public: - returns a dict of auto-generated c++ parameter validation checks + returns an appropriate bounds helper function call for an entry point + parameter with the [bounds] tag +""" +def get_bounds_check(param, bounds_error): + # Images need their own helper, since function signature wise they would be + # identical to buffer rect + bounds_function = 'boundsImage' if 'image' in param['name'].lower() else 'bounds' + bounds_check = "auto {0} = {1}({2}, {3}, {4})".format( + bounds_error, + bounds_function, + param["name"], + param_traits.bounds_offset(param), + param_traits.bounds_size(param), + ) + bounds_check += '; {0} != UR_RESULT_SUCCESS'.format(bounds_error) + + # USM bounds checks need the queue handle parameter to be able to use the + # GetMemAllocInfo entry point + if type_traits.is_pointer(param['type']): + # If no `hQueue` parameter exists that should have been caught at spec + # generation. + return re.sub(r'bounds\(', 'bounds(hQueue, ', bounds_check) + + return bounds_check + +""" +Public: + returns a dict of auto-generated c++ parameter validation checks for the + given function (specified by `obj`) """ def make_param_checks(namespace, tags, obj, cpp=False, meta=None): checks = {} @@ -1054,6 +1106,13 @@ def make_param_checks(namespace, tags, obj, cpp=False, meta=None): if key not in checks: checks[key] = [] checks[key].append(subt(namespace, tags, code.group(1), False, cpp)) + + for p in obj.get('params', []): + if param_traits.is_bounds(p): + if 'boundsError' not in checks: + checks['boundsError'] = [] + checks['boundsError'].append(get_bounds_check(p, 'boundsError')) + return checks """ diff --git a/source/adapters/hip/usm.cpp b/source/adapters/hip/usm.cpp index 7af7401f87..0aaf6de53e 100644 --- a/source/adapters/hip/usm.cpp +++ b/source/adapters/hip/usm.cpp @@ -190,9 +190,6 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem, #endif return ReturnValue(UR_USM_TYPE_UNKNOWN); } - case UR_USM_ALLOC_INFO_BASE_PTR: - case UR_USM_ALLOC_INFO_SIZE: - return UR_RESULT_ERROR_INVALID_VALUE; case UR_USM_ALLOC_INFO_DEVICE: { // get device index associated with this pointer UR_CHECK_ERROR(hipPointerGetAttributes(&hipPointerAttributeType, pMem)); @@ -222,6 +219,9 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem, } return ReturnValue(Pool); } + case UR_USM_ALLOC_INFO_BASE_PTR: + case UR_USM_ALLOC_INFO_SIZE: + return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION; default: return UR_RESULT_ERROR_INVALID_ENUMERATION; } diff --git a/source/adapters/null/ur_nullddi.cpp b/source/adapters/null/ur_nullddi.cpp index a4e91e3dc0..f016830d11 100644 --- a/source/adapters/null/ur_nullddi.cpp +++ b/source/adapters/null/ur_nullddi.cpp @@ -2917,7 +2917,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -2956,7 +2957,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -2997,7 +2999,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -3050,7 +3053,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -3105,9 +3109,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -3144,9 +3150,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -3195,10 +3203,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3234,7 +3243,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -3278,7 +3288,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -3322,9 +3333,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -3368,7 +3381,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -3445,7 +3459,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -3468,7 +3482,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( // if the driver has created a custom function, then call it instead of using the generic path auto pfnUSMFill = d_context.urDdiTable.Enqueue.pfnUSMFill; if (nullptr != pfnUSMFill) { - result = pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + result = pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); } else { // generic implementation @@ -3487,9 +3501,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -3522,9 +3538,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3558,9 +3575,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -3588,7 +3606,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -3635,10 +3654,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/adapters/opencl/enqueue.cpp b/source/adapters/opencl/enqueue.cpp index 24d60e62f5..6830a28eec 100644 --- a/source/adapters/opencl/enqueue.cpp +++ b/source/adapters/opencl/enqueue.cpp @@ -25,77 +25,6 @@ cl_map_flags convertURMapFlagsToCL(ur_map_flags_t URFlags) { return CLFlags; } -ur_result_t ValidateBufferSize(ur_mem_handle_t Buffer, size_t Size, - size_t Origin) { - size_t BufferSize = 0; - CL_RETURN_ON_FAILURE(clGetMemObjectInfo(cl_adapter::cast(Buffer), - CL_MEM_SIZE, sizeof(BufferSize), - &BufferSize, nullptr)); - if (Size + Origin > BufferSize) - return UR_RESULT_ERROR_INVALID_SIZE; - return UR_RESULT_SUCCESS; -} - -ur_result_t ValidateBufferRectSize(ur_mem_handle_t Buffer, - ur_rect_region_t Region, - ur_rect_offset_t Offset) { - size_t BufferSize = 0; - CL_RETURN_ON_FAILURE(clGetMemObjectInfo(cl_adapter::cast(Buffer), - CL_MEM_SIZE, sizeof(BufferSize), - &BufferSize, nullptr)); - if (Offset.x >= BufferSize || Offset.y >= BufferSize || - Offset.z >= BufferSize) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - if ((Region.width + Offset.x) * (Region.height + Offset.y) * - (Region.depth + Offset.z) > - BufferSize) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - return UR_RESULT_SUCCESS; -} - -ur_result_t ValidateImageSize(ur_mem_handle_t Image, ur_rect_region_t Region, - ur_rect_offset_t Origin) { - size_t Width = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_WIDTH, sizeof(Width), &Width, - nullptr)); - if (Region.width + Origin.x > Width) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - size_t Height = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_HEIGHT, sizeof(Height), &Height, - nullptr)); - - // CL returns a height and depth of 0 for images that don't have those - // dimensions, but regions for enqueue operations must set these to 1, so we - // need to make this adjustment to validate. - if (Height == 0) - Height = 1; - - if (Region.height + Origin.y > Height) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - size_t Depth = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_DEPTH, sizeof(Depth), &Depth, - nullptr)); - if (Depth == 0) - Depth = 1; - - if (Region.depth + Origin.z > Depth) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - return UR_RESULT_SUCCESS; -} - UR_APIEXPORT ur_result_t UR_APICALL urEnqueueKernelLaunch( ur_queue_handle_t hQueue, ur_kernel_handle_t hKernel, uint32_t workDim, const size_t *pGlobalWorkOffset, const size_t *pGlobalWorkSize, @@ -141,16 +70,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead( size_t offset, size_t size, void *pDst, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueReadBuffer( + CL_RETURN_ON_FAILURE(clEnqueueReadBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingRead, offset, size, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( @@ -158,16 +84,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( size_t offset, size_t size, const void *pSrc, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueWriteBuffer( + CL_RETURN_ON_FAILURE(clEnqueueWriteBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingWrite, offset, size, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( @@ -182,18 +105,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( const size_t HostOrigin[3] = {hostOrigin.x, hostOrigin.y, hostOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueReadBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueReadBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingRead, BufferOrigin, HostOrigin, Region, bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBuffer, region, bufferOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( @@ -208,18 +128,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( const size_t HostOrigin[3] = {hostOrigin.x, hostOrigin.y, hostOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueWriteBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueWriteBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingWrite, BufferOrigin, HostOrigin, Region, bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBuffer, region, bufferOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( @@ -228,18 +145,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueCopyBuffer( + CL_RETURN_ON_FAILURE(clEnqueueCopyBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBufferSrc), cl_adapter::cast(hBufferDst), srcOffset, dstOffset, size, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBufferSrc, size, srcOffset)); - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBufferDst, size, dstOffset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( @@ -253,19 +166,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( const size_t DstOrigin[3] = {dstOrigin.x, dstOrigin.y, dstOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueCopyBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueCopyBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBufferSrc), cl_adapter::cast(hBufferDst), SrcOrigin, DstOrigin, Region, srcRowPitch, srcSlicePitch, dstRowPitch, dstSlicePitch, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBufferSrc, region, srcOrigin)); - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBufferDst, region, dstOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( @@ -276,16 +185,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( // CL FillBuffer only allows pattern sizes up to the largest CL type: // long16/double16 if (patternSize <= 128) { - auto ClErr = (clEnqueueFillBuffer( - cl_adapter::cast(hQueue), - cl_adapter::cast(hBuffer), pPattern, patternSize, offset, size, - numEventsInWaitList, - cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent))); - if (ClErr != CL_SUCCESS) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + CL_RETURN_ON_FAILURE( + clEnqueueFillBuffer(cl_adapter::cast(hQueue), + cl_adapter::cast(hBuffer), pPattern, + patternSize, offset, size, numEventsInWaitList, + cl_adapter::cast(phEventWaitList), + cl_adapter::cast(phEvent))); + return UR_RESULT_SUCCESS; } auto NumValues = size / sizeof(uint64_t); @@ -303,7 +209,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( &WriteEvent); if (ClErr != CL_SUCCESS) { delete[] HostBuffer; - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, offset, size)); CL_RETURN_ON_FAILURE(ClErr); } @@ -338,17 +243,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead( const size_t Origin[3] = {origin.x, origin.y, origin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueReadImage( + CL_RETURN_ON_FAILURE(clEnqueueReadImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImage), blockingRead, Origin, Region, rowPitch, slicePitch, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImage, region, origin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( @@ -359,17 +261,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( const size_t Origin[3] = {origin.x, origin.y, origin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueWriteImage( + CL_RETURN_ON_FAILURE(clEnqueueWriteImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImage), blockingWrite, Origin, Region, rowPitch, slicePitch, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImage, region, origin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( @@ -382,18 +281,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( const size_t DstOrigin[3] = {dstOrigin.x, dstOrigin.y, dstOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueCopyImage( + CL_RETURN_ON_FAILURE(clEnqueueCopyImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImageSrc), cl_adapter::cast(hImageDst), SrcOrigin, DstOrigin, Region, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImageSrc, region, srcOrigin)); - UR_RETURN_ON_FAILURE(ValidateImageSize(hImageDst, region, dstOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( @@ -410,9 +305,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( cl_adapter::cast(phEventWaitList), cl_adapter::cast(phEvent), &Err); - if (Err == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } return mapCLErrorToUR(Err); } diff --git a/source/loader/layers/tracing/ur_trcddi.cpp b/source/loader/layers/tracing/ur_trcddi.cpp index d33a3aaf51..402b64d638 100644 --- a/source/loader/layers/tracing/ur_trcddi.cpp +++ b/source/loader/layers/tracing/ur_trcddi.cpp @@ -3325,7 +3325,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -3367,7 +3368,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -3412,7 +3414,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -3479,7 +3482,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -3549,9 +3553,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -3590,9 +3596,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -3646,10 +3654,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3693,7 +3702,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -3741,7 +3751,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -3789,9 +3800,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -3837,7 +3850,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -3920,7 +3934,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -3945,14 +3959,14 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( } ur_enqueue_usm_fill_params_t params = { - &hQueue, &ptr, &patternSize, + &hQueue, &pMem, &patternSize, &pPattern, &size, &numEventsInWaitList, &phEventWaitList, &phEvent}; uint64_t instance = context.notify_begin(UR_FUNCTION_ENQUEUE_USM_FILL, "urEnqueueUSMFill", ¶ms); ur_result_t result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); context.notify_end(UR_FUNCTION_ENQUEUE_USM_FILL, "urEnqueueUSMFill", @@ -3966,9 +3980,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4004,9 +4020,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4043,9 +4060,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4074,7 +4092,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -4124,10 +4143,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/loader/layers/validation/ur_valddi.cpp b/source/loader/layers/validation/ur_valddi.cpp index ec0df692cf..72e225028c 100644 --- a/source/loader/layers/validation/ur_valddi.cpp +++ b/source/loader/layers/validation/ur_valddi.cpp @@ -4084,7 +4084,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4126,6 +4127,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4146,7 +4152,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4190,6 +4197,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4210,7 +4222,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4304,6 +4317,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, bufferOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4325,7 +4343,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4423,6 +4442,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, bufferOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4443,9 +4467,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4486,6 +4512,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBufferSrc, srcOffset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hBufferDst, dstOffset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4505,9 +4541,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4593,6 +4631,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBufferSrc, srcOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hBufferDst, dstOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4614,10 +4662,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4676,6 +4725,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4696,7 +4750,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4747,6 +4802,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImage, origin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4767,7 +4827,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4819,6 +4880,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImage, origin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4838,9 +4904,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4891,6 +4959,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImageSrc, srcOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = boundsImage(hImageDst, dstOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4911,7 +4989,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4959,6 +5038,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5039,7 +5123,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -5068,7 +5152,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } - if (NULL == ptr) { + if (NULL == pMem) { return UR_RESULT_ERROR_INVALID_NULL_POINTER; } @@ -5100,6 +5184,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5110,7 +5199,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( } ur_result_t result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); return result; @@ -5121,9 +5210,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -5165,6 +5256,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pDst, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hQueue, pSrc, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5184,9 +5285,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5229,6 +5331,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5248,9 +5355,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -5278,6 +5386,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( if (size == 0) { return UR_RESULT_ERROR_INVALID_SIZE; } + + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } } ur_result_t result = pfnUSMAdvise(hQueue, pMem, size, advice, phEvent); @@ -5289,7 +5402,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5370,6 +5484,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, pitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5391,10 +5510,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. @@ -5456,6 +5578,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pDst, 0, dstPitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hQueue, pSrc, 0, srcPitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { diff --git a/source/loader/layers/validation/ur_validation_layer.cpp b/source/loader/layers/validation/ur_validation_layer.cpp index 5cd3f8c13a..3e040fcc50 100644 --- a/source/loader/layers/validation/ur_validation_layer.cpp +++ b/source/loader/layers/validation/ur_validation_layer.cpp @@ -11,6 +11,8 @@ */ #include "ur_validation_layer.hpp" +#include + namespace ur_validation_layer { context_t context; @@ -20,4 +22,127 @@ context_t::context_t() : logger(logger::create_logger("validation")) {} /////////////////////////////////////////////////////////////////////////////// context_t::~context_t() {} +// Some adapters don't support all the queries yet, we should be lenient and +// just not attempt to validate in those cases to preserve functionality. +#define RETURN_ON_FAILURE(result) \ + if (result == UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION || \ + result == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) \ + return UR_RESULT_SUCCESS; \ + if (result != UR_RESULT_SUCCESS) { \ + context.logger.error("Unexpected non-success result code from {}", \ + #result); \ + assert(0); \ + return result; \ + } + +ur_result_t bounds(ur_mem_handle_t buffer, size_t offset, size_t size) { + auto pfnMemGetInfo = context.urDdiTable.Mem.pfnGetInfo; + + size_t bufferSize = 0; + RETURN_ON_FAILURE(pfnMemGetInfo(buffer, UR_MEM_INFO_SIZE, + sizeof(bufferSize), &bufferSize, nullptr)); + + if (size + offset > bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t bounds(ur_mem_handle_t buffer, ur_rect_offset_t offset, + ur_rect_region_t region) { + auto pfnMemGetInfo = context.urDdiTable.Mem.pfnGetInfo; + + size_t bufferSize = 0; + RETURN_ON_FAILURE(pfnMemGetInfo(buffer, UR_MEM_INFO_SIZE, + sizeof(bufferSize), &bufferSize, nullptr)); + + if (offset.x >= bufferSize || offset.y >= bufferSize || + offset.z >= bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + if ((region.width + offset.x) * (region.height + offset.y) * + (region.depth + offset.z) > + bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t bounds(ur_queue_handle_t queue, const void *ptr, size_t offset, + size_t size) { + auto pfnQueueGetInfo = context.urDdiTable.Queue.pfnGetInfo; + auto pfnUSMGetMemAllocInfo = context.urDdiTable.USM.pfnGetMemAllocInfo; + + ur_context_handle_t urContext = nullptr; + RETURN_ON_FAILURE(pfnQueueGetInfo(queue, UR_QUEUE_INFO_CONTEXT, + sizeof(ur_context_handle_t), &urContext, + nullptr)); + ur_usm_type_t usmType = UR_USM_TYPE_UNKNOWN; + RETURN_ON_FAILURE( + pfnUSMGetMemAllocInfo(urContext, ptr, UR_USM_ALLOC_INFO_TYPE, + sizeof(usmType), &usmType, nullptr)); + + // We can't reliably get size info about pointers that didn't come from the + // USM alloc entry points. + if (usmType == UR_USM_TYPE_UNKNOWN) { + return UR_RESULT_SUCCESS; + } + + size_t allocSize = 0; + RETURN_ON_FAILURE( + pfnUSMGetMemAllocInfo(urContext, ptr, UR_USM_ALLOC_INFO_SIZE, + sizeof(allocSize), &allocSize, nullptr)); + + if (size + offset > allocSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t boundsImage(ur_mem_handle_t image, ur_rect_offset_t origin, + ur_rect_region_t region) { + auto pfnMemImageGetInfo = context.urDdiTable.Mem.pfnImageGetInfo; + + size_t width = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_WIDTH, + sizeof(width), &width, nullptr)); + if (region.width + origin.x > width) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + size_t height = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_HEIGHT, + sizeof(height), &height, nullptr)); + + // Some adapters return a height and depth of 0 for images that don't have + // those dimensions, but regions for enqueue operations must set these to + // 1, so we need to make this adjustment to properly validate. + if (height == 0) { + height = 1; + } + + if (region.height + origin.y > height) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + size_t depth = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_DEPTH, + sizeof(depth), &depth, nullptr)); + if (depth == 0) { + depth = 1; + } + + if (region.depth + origin.z > depth) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +#undef RETURN_ON_FAILURE + } // namespace ur_validation_layer diff --git a/source/loader/layers/validation/ur_validation_layer.hpp b/source/loader/layers/validation/ur_validation_layer.hpp index e41c621dc8..d29b64230e 100644 --- a/source/loader/layers/validation/ur_validation_layer.hpp +++ b/source/loader/layers/validation/ur_validation_layer.hpp @@ -44,6 +44,17 @@ class __urdlllocal context_t : public proxy_layer_context_t { const std::string nameLeakChecking = "UR_LAYER_LEAK_CHECKING"; }; +ur_result_t bounds(ur_mem_handle_t buffer, size_t offset, size_t size); + +ur_result_t bounds(ur_mem_handle_t buffer, ur_rect_offset_t offset, + ur_rect_region_t region); + +ur_result_t bounds(ur_queue_handle_t queue, const void *ptr, size_t offset, + size_t size); + +ur_result_t boundsImage(ur_mem_handle_t image, ur_rect_offset_t origin, + ur_rect_region_t region); + extern context_t context; } // namespace ur_validation_layer diff --git a/source/loader/ur_ldrddi.cpp b/source/loader/ur_ldrddi.cpp index 27d8011cf7..5d7df7e672 100644 --- a/source/loader/ur_ldrddi.cpp +++ b/source/loader/ur_ldrddi.cpp @@ -3852,7 +3852,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -3916,7 +3917,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -3982,7 +3984,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4059,7 +4062,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4138,9 +4142,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4205,9 +4211,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4283,10 +4291,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4347,7 +4356,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4416,7 +4426,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4485,9 +4496,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4559,7 +4572,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4686,7 +4700,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -4726,7 +4740,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( // forward to device-platform result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitListLocal.data(), phEvent); if (UR_RESULT_SUCCESS != result) { @@ -4751,9 +4765,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4809,9 +4825,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4867,9 +4884,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4911,7 +4929,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -4980,10 +4999,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index de9e029536..80d1bc3fb6 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -4833,7 +4833,8 @@ ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4894,7 +4895,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4967,7 +4969,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -5052,7 +5055,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -5125,9 +5129,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -5191,9 +5197,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -5266,10 +5274,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5329,7 +5338,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferFill( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -5396,7 +5406,8 @@ ur_result_t UR_APICALL urEnqueueMemImageRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -5458,9 +5469,11 @@ ur_result_t UR_APICALL urEnqueueMemImageWrite( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -5532,7 +5545,8 @@ ur_result_t UR_APICALL urEnqueueMemImageCopy( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -5625,7 +5639,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -5644,7 +5658,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -5667,7 +5681,7 @@ ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_UNINITIALIZED; } - return pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + return pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); } catch (...) { return exceptionToResult(std::current_exception()); @@ -5701,9 +5715,11 @@ ur_result_t UR_APICALL urEnqueueUSMFill( ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -5757,9 +5773,10 @@ ur_result_t UR_APICALL urEnqueueUSMMemcpy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5810,9 +5827,10 @@ ur_result_t UR_APICALL urEnqueueUSMPrefetch( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -5861,7 +5879,8 @@ ur_result_t UR_APICALL urEnqueueUSMAdvise( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5926,10 +5945,13 @@ ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/ur_api.cpp b/source/ur_api.cpp index ca1f82019c..3a7cebca8c 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -4094,7 +4094,8 @@ ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4147,7 +4148,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4212,7 +4214,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4287,7 +4290,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4350,9 +4354,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4407,9 +4413,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4472,10 +4480,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4526,7 +4535,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferFill( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4585,7 +4595,8 @@ ur_result_t UR_APICALL urEnqueueMemImageRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4638,9 +4649,11 @@ ur_result_t UR_APICALL urEnqueueMemImageWrite( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4704,7 +4717,8 @@ ur_result_t UR_APICALL urEnqueueMemImageCopy( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4782,7 +4796,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -4801,7 +4815,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -4851,9 +4865,11 @@ ur_result_t UR_APICALL urEnqueueUSMFill( ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4900,9 +4916,10 @@ ur_result_t UR_APICALL urEnqueueUSMMemcpy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4946,9 +4963,10 @@ ur_result_t UR_APICALL urEnqueueUSMPrefetch( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4991,7 +5009,8 @@ ur_result_t UR_APICALL urEnqueueUSMAdvise( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5049,10 +5068,13 @@ ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied.