diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 4082de198e..3f69582ac6 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -80,6 +80,9 @@ jobs: - name: Generate source from spec, check for uncommitted diff if: matrix.os == 'ubuntu-22.04' run: cmake --build ${{github.workspace}}/build --target check-generated + + - name: Verify that each source file contains a license + run: cmake --build ${{github.workspace}}/build --target verify-licenses - name: Build run: cmake --build ${{github.workspace}}/build -j $(nproc) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbbd88bd7..5561a66dce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR) -project(unified-runtime VERSION 0.6.0) +project(unified-runtime VERSION 0.7.0) include(GNUInstallDirs) include(CheckCXXSourceCompiles) @@ -161,6 +161,7 @@ endif() # Obtain files for clang-format set(format_glob) +set(license_glob) foreach(dir examples include source test tools) list(APPEND format_glob "${dir}/*.h" @@ -171,8 +172,26 @@ foreach(dir examples include source test tools) "${dir}/**/*.hpp" "${dir}/**/*.c" "${dir}/**/*.cpp") + list(APPEND license_glob + "${dir}/*.yml" + "${dir}/**/*.yml" + "${dir}/*.py" + "${dir}/**/*.py" + "${dir}/**/CMakeLists.txt" + "${dir}/CMakeLists.txt" + ) endforeach() file(GLOB_RECURSE format_src ${format_glob}) +file(GLOB_RECURSE license_src ${license_glob}) + +# check for licence +list(FILTER license_src EXCLUDE REGEX "registry.yml") +add_custom_target(verify-licenses + COMMAND ${Python3_EXECUTABLE} + "${PROJECT_SOURCE_DIR}/scripts/verify_license.py" + "--files" ${format_src} ${license_src} + COMMENT "Verify all files contain a license." +) # Add code formatter target add_custom_target(cppformat) diff --git a/README.md b/README.md index 0196869357..dded77262c 100644 --- a/README.md +++ b/README.md @@ -109,17 +109,18 @@ $ make List of options provided by CMake: -| Name | Description | Values | Default | -|-------------------------|--------------------------------------------------------|------------|---------| -| UR_BUILD_TESTS | Build the tests | ON/OFF | ON | -| UR_BUILD_TOOLS | Build tools | ON/OFF | ON | -| UR_FORMAT_CPP_STYLE | Format code style | ON/OFF | OFF | -| UR_DEVELOPER_MODE | Treat warnings as errors and enables additional checks | ON/OFF | OFF | -| UR_USE_ASAN | Enable AddressSanitizer | ON/OFF | OFF | -| UR_USE_TSAN | Enable ThreadSanitizer | ON/OFF | OFF | -| UR_USE_UBSAN | Enable UndefinedBehavior Sanitizer | ON/OFF | OFF | -| UR_USE_MSAN | Enable MemorySanitizer (clang only) | ON/OFF | OFF | -| UR_ENABLE_TRACING | Enable XPTI-based tracing layer | ON/OFF | OFF | +| Name | Description | Values | Default | +| - | - | - | - | +| UR_BUILD_TESTS | Build the tests | ON/OFF | ON | +| UR_BUILD_TOOLS | Build tools | ON/OFF | ON | +| UR_FORMAT_CPP_STYLE | Format code style | ON/OFF | OFF | +| UR_DEVELOPER_MODE | Treat warnings as errors and enables additional checks | ON/OFF | OFF | +| UR_USE_ASAN | Enable AddressSanitizer | ON/OFF | OFF | +| UR_USE_TSAN | Enable ThreadSanitizer | ON/OFF | OFF | +| UR_USE_UBSAN | Enable UndefinedBehavior Sanitizer | ON/OFF | OFF | +| UR_USE_MSAN | Enable MemorySanitizer (clang only) | ON/OFF | OFF | +| UR_ENABLE_TRACING | Enable XPTI-based tracing layer | ON/OFF | OFF | +| UR_CONFORMANCE_TARGET_TRIPLES | SYCL triples to build CTS device binaries for | Comma-separated list | spir64 | | UR_BUILD_ADAPTER_L0 | Fetch and use level-zero adapter from SYCL | ON/OFF | OFF | | UR_BUILD_ADAPTER_OPENCL | Fetch and use opencl adapter from SYCL | ON/OFF | OFF | | UR_BUILD_ADAPTER_CUDA | Fetch and use cuda adapter from SYCL | ON/OFF | OFF | diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index cd3497fc0e..3c90d41236 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -66,7 +66,6 @@ function(add_ur_target_compile_options name) $<$:-fdiagnostics-color=always> $<$:-fcolor-diagnostics> ) - if (CMAKE_BUILD_TYPE STREQUAL "Release") target_compile_definitions(${name} PRIVATE -D_FORTIFY_SOURCE=2) endif() @@ -84,27 +83,46 @@ function(add_ur_target_compile_options name) /MD$<$:d> /GS ) - add_link_options( + + if(UR_DEVELOPER_MODE) + target_compile_options(${name} PRIVATE /WX /GS) + endif() + endif() +endfunction() + +function(add_ur_target_link_options name) + if(NOT MSVC) + if (NOT APPLE) + target_link_options(${name} PRIVATE "LINKER:-z,relro,-z,now") + endif() + elseif(MSVC) + target_link_options(${name} PRIVATE /DYNAMICBASE /HIGHENTROPYVA - /ALLOWISOLATION /NXCOMPAT ) + endif() +endfunction() - if(UR_DEVELOPER_MODE) - target_compile_options(${name} PRIVATE /WX /GS) - endif() +function(add_ur_target_exec_options name) + if(MSVC) + target_link_options(${name} PRIVATE + /ALLOWISOLATION + ) endif() endfunction() function(add_ur_executable name) add_executable(${name} ${ARGN}) add_ur_target_compile_options(${name}) + add_ur_target_exec_options(${name}) + add_ur_target_link_options(${name}) endfunction() function(add_ur_library name) add_library(${name} ${ARGN}) add_ur_target_compile_options(${name}) + add_ur_target_link_options(${name}) endfunction() include(FetchContent) diff --git a/include/ur.py b/include/ur.py index f48acbd21b..5597773501 100644 --- a/include/ur.py +++ b/include/ur.py @@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @file ur.py - @version v0.6-r0 + @version v0.7-r0 """ import platform @@ -569,7 +569,8 @@ def __str__(self): ## ::UR_MAJOR_VERSION and ::UR_MINOR_VERSION class ur_api_version_v(IntEnum): _0_6 = UR_MAKE_VERSION( 0, 6 ) ## version 0.6 - CURRENT = UR_MAKE_VERSION( 0, 6 ) ## latest known version + _0_7 = UR_MAKE_VERSION( 0, 7 ) ## version 0.7 + CURRENT = UR_MAKE_VERSION( 0, 7 ) ## latest known version class ur_api_version_t(c_int): def __str__(self): @@ -2263,53 +2264,6 @@ def __str__(self): ############################################################################### __use_win_types = "Windows" == platform.uname()[0] -############################################################################### -## @brief Function-pointer for urLoaderConfigCreate -if __use_win_types: - _urLoaderConfigCreate_t = WINFUNCTYPE( ur_result_t, POINTER(ur_loader_config_handle_t) ) -else: - _urLoaderConfigCreate_t = CFUNCTYPE( ur_result_t, POINTER(ur_loader_config_handle_t) ) - -############################################################################### -## @brief Function-pointer for urLoaderConfigRetain -if __use_win_types: - _urLoaderConfigRetain_t = WINFUNCTYPE( ur_result_t, ur_loader_config_handle_t ) -else: - _urLoaderConfigRetain_t = CFUNCTYPE( ur_result_t, ur_loader_config_handle_t ) - -############################################################################### -## @brief Function-pointer for urLoaderConfigRelease -if __use_win_types: - _urLoaderConfigRelease_t = WINFUNCTYPE( ur_result_t, ur_loader_config_handle_t ) -else: - _urLoaderConfigRelease_t = CFUNCTYPE( ur_result_t, ur_loader_config_handle_t ) - -############################################################################### -## @brief Function-pointer for urLoaderConfigGetInfo -if __use_win_types: - _urLoaderConfigGetInfo_t = WINFUNCTYPE( ur_result_t, ur_loader_config_handle_t, ur_loader_config_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) -else: - _urLoaderConfigGetInfo_t = CFUNCTYPE( ur_result_t, ur_loader_config_handle_t, ur_loader_config_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) - -############################################################################### -## @brief Function-pointer for urLoaderConfigEnableLayer -if __use_win_types: - _urLoaderConfigEnableLayer_t = WINFUNCTYPE( ur_result_t, ur_loader_config_handle_t, c_char_p ) -else: - _urLoaderConfigEnableLayer_t = CFUNCTYPE( ur_result_t, ur_loader_config_handle_t, c_char_p ) - - -############################################################################### -## @brief Table of LoaderConfig functions pointers -class ur_loader_config_dditable_t(Structure): - _fields_ = [ - ("pfnCreate", c_void_p), ## _urLoaderConfigCreate_t - ("pfnRetain", c_void_p), ## _urLoaderConfigRetain_t - ("pfnRelease", c_void_p), ## _urLoaderConfigRelease_t - ("pfnGetInfo", c_void_p), ## _urLoaderConfigGetInfo_t - ("pfnEnableLayer", c_void_p) ## _urLoaderConfigEnableLayer_t - ] - ############################################################################### ## @brief Function-pointer for urPlatformGet if __use_win_types: @@ -3791,7 +3745,6 @@ class ur_device_dditable_t(Structure): ############################################################################### class ur_dditable_t(Structure): _fields_ = [ - ("LoaderConfig", ur_loader_config_dditable_t), ("Platform", ur_platform_dditable_t), ("Context", ur_context_dditable_t), ("Event", ur_event_dditable_t), diff --git a/include/ur_api.h b/include/ur_api.h index 1ff0ba0905..7df48cb743 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -7,7 +7,7 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * * @file ur_api.h - * @version v0.6-r0 + * @version v0.7-r0 * */ #ifndef UR_API_H_INCLUDED @@ -1021,7 +1021,8 @@ urPlatformGetInfo( /// ::UR_MAJOR_VERSION and ::UR_MINOR_VERSION typedef enum ur_api_version_t { UR_API_VERSION_0_6 = UR_MAKE_VERSION(0, 6), ///< version 0.6 - UR_API_VERSION_CURRENT = UR_MAKE_VERSION(0, 6), ///< latest known version + UR_API_VERSION_0_7 = UR_MAKE_VERSION(0, 7), ///< version 0.7 + UR_API_VERSION_CURRENT = UR_MAKE_VERSION(0, 7), ///< latest known version /// @cond UR_API_VERSION_FORCE_UINT32 = 0x7fffffff /// @endcond diff --git a/include/ur_ddi.h b/include/ur_ddi.h index 958f5ca29b..a0c2a5012d 100644 --- a/include/ur_ddi.h +++ b/include/ur_ddi.h @@ -7,7 +7,7 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * * @file ur_ddi.h - * @version v0.6-r0 + * @version v0.7-r0 * */ #ifndef UR_DDI_H_INCLUDED diff --git a/scripts/Doxyfile b/scripts/Doxyfile index 05b93c5ac5..c038d5276d 100644 --- a/scripts/Doxyfile +++ b/scripts/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Intel One API Unified Runtime API" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = v0.6 +PROJECT_NUMBER = v0.7 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/scripts/YaML.md b/scripts/YaML.md index a735a7f7a4..291e4263c7 100644 --- a/scripts/YaML.md +++ b/scripts/YaML.md @@ -238,12 +238,13 @@ std::function ur_callback_t; * A handle requires the following scalar fields: {`desc`, `name`} - `desc` will be used as the handles's description comment - `name` must be a unique ISO-C standard identifier, start with `$` tag, be snake_case and end with `_handle_t` -* A handle may take the following optional scalar fields: {`class`, `alias`, `condition`, `ordinal`, `version`} +* A handle may take the following optional scalar fields: {`class`, `alias`, `condition`, `ordinal`, `version`, `loader_only`} - `class` will be used to scope the handles declaration within the specified C++ class - `alias` will be used to declare the handle as an alias of another handle; specifically, aliases in another namespace - `condition` will be used as a C/C++ preprocessor `#if` conditional expression - `ordinal` will be used to override the default order (in which they appear) the handles appears within its section; `default="1000"` - `version` will be used to define the minimum API version in which the handles will appear; `default="1.0"` This will also affect the order in which the handles appears within its section. + - `loader_only` will be used to decide whether the handle can be instantiated and managed only by the loader. * A handle may take the following optional field which can be a scalar, a sequence of scalars or scalars to sequences: {`details`} - `details` will be used as the handle's detailed comment @@ -599,12 +600,14 @@ class ur_name_t(Structure): * A function requires the following scalar fields: {`desc`, `name`} - `desc` will be used as the function's description comment - `name` must be a unique ISO-C standard identifier, and be PascalCase -* A function may take the following optional scalar fields: {`class`, `decl`, `condition`, `ordinal`, `version`} +* A function may take the following optional scalar fields: {`class`, `decl`, `condition`, `ordinal`, `version`, `loader_only`} - `class` will be used to scope the function declaration within the specified C++ class - `decl` will be used to specify the function's linkage as one of the following: {`static`} - `condition` will be used as a C/C++ preprocessor `#if` conditional expression - `ordinal` will be used to override the default order (in which they appear) the function appears within its section; `default="1000"` - `version` will be used to define the minimum API version in which the function will appear; `default="1.0"` This will also affect the order in which the function appears within its section and class. + - `loader_only` will be used to decide whether the function will only be implemented by the loader and not appear in the adapters + interface. * A function requires the following sequence of mappings: {`params`} - A param requires the following scalar fields: {`desc`, `type`, `name`} + `desc` will be used as the params's description comment diff --git a/scripts/core/EXP-COMMAND-BUFFER.rst b/scripts/core/EXP-COMMAND-BUFFER.rst index 8a83c8a024..a169117022 100644 --- a/scripts/core/EXP-COMMAND-BUFFER.rst +++ b/scripts/core/EXP-COMMAND-BUFFER.rst @@ -207,6 +207,7 @@ Changelog | Revision | Changes | +===========+=======================================================+ | 1.0 | Initial Draft | ++-----------+-------------------------------------------------------+ | 1.1 | add function definitions for buffer read and write | +-----------+-------------------------------------------------------+ diff --git a/scripts/core/common.yml b/scripts/core/common.yml index 7a522ada35..f96f26a4cf 100644 --- a/scripts/core/common.yml +++ b/scripts/core/common.yml @@ -62,6 +62,7 @@ value: uint8_t type: handle desc: "Handle of a loader config object" class: $xLoaderConfig +loader_only: True name: "$x_loader_config_handle_t" --- #-------------------------------------------------------------------------- type: handle diff --git a/scripts/core/exp-bindless-images.yml b/scripts/core/exp-bindless-images.yml index cbb194849f..846e97ac61 100644 --- a/scripts/core/exp-bindless-images.yml +++ b/scripts/core/exp-bindless-images.yml @@ -1,3 +1,12 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. +# See LICENSE.TXT +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# --- #-------------------------------------------------------------------------- type: header desc: "Bindless Images Extension APIs" diff --git a/scripts/core/exp-usm-import-release.yml b/scripts/core/exp-usm-import-release.yml index 869bff64e8..dc91392af2 100644 --- a/scripts/core/exp-usm-import-release.yml +++ b/scripts/core/exp-usm-import-release.yml @@ -1,3 +1,12 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. +# See LICENSE.TXT +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# --- #-------------------------------------------------------------------------- type: header desc: "Intel $OneApi USM Import/Release Extension APIs" diff --git a/scripts/core/platform.yml b/scripts/core/platform.yml index 6a0d350703..f7020b4138 100644 --- a/scripts/core/platform.yml +++ b/scripts/core/platform.yml @@ -130,6 +130,9 @@ etors: - name: "0_6" value: "$X_MAKE_VERSION( 0, 6 )" desc: "version 0.6" + - name: "0_7" + value: "$X_MAKE_VERSION( 0, 7 )" + desc: "version 0.7" --- #-------------------------------------------------------------------------- type: function desc: "Returns the API version supported by the specified platform" diff --git a/scripts/core/runtime.yml b/scripts/core/runtime.yml index 06010a643c..c14f939cc2 100644 --- a/scripts/core/runtime.yml +++ b/scripts/core/runtime.yml @@ -31,6 +31,7 @@ etors: type: function desc: "Create a loader config object." class: $xLoaderConfig +loader_only: True name: Create decl: static params: @@ -41,6 +42,7 @@ params: type: function desc: "Get a reference to the loader config object." class: $xLoaderConfig +loader_only: True name: Retain decl: static details: @@ -55,6 +57,7 @@ params: type: function desc: "Release config handle." class: $xLoaderConfig +loader_only: True name: Release decl: static details: @@ -80,6 +83,7 @@ etors: type: function desc: "Retrieves various information about the loader." class: $xLoaderConfig +loader_only: True name: GetInfo decl: static details: @@ -122,6 +126,7 @@ returns: type: function desc: "Enable a layer for the specified loader config." class: $xLoaderConfig +loader_only: True name: EnableLayer decl: static params: diff --git a/scripts/json2src.py b/scripts/json2src.py index 10ad00a2fc..0a5c52e38a 100755 --- a/scripts/json2src.py +++ b/scripts/json2src.py @@ -23,33 +23,6 @@ def add_argument(parser, name, help, default=False): group.add_argument("--skip-" + name, dest=name, help="Skip "+help, action="store_false") parser.set_defaults(**{name:default}) -""" - helpers to strip loader only api constructs from the json -""" -def strip_specs_class(specs, strip_class): - for spec in specs: - remove_obj = [] - for obj in spec["objects"]: - if "class" in obj and strip_class in obj["class"]: - remove_obj.append(obj) - for obj in remove_obj: - spec["objects"].remove(obj) - -def strip_meta_entry(meta, entry_name, pattern): - loader_entries = [] - for entry in meta[entry_name]: - if pattern in entry: - loader_entries.append(entry) - - for entry in loader_entries: - del meta[entry_name][entry] - -def strip_loader_meta(meta): - strip_meta_entry(meta, "class", "Loader") - strip_meta_entry(meta, "function", "Loader") - strip_meta_entry(meta, "enum", "loader") - strip_meta_entry(meta, "handle", "loader") - if __name__ == '__main__': parser = argparse.ArgumentParser() add_argument(parser, "lib", "generation of lib files.", True) @@ -75,9 +48,6 @@ def strip_loader_meta(meta): if args.sections == None or config['name'] in args.sections: if args.lib: generate_code.generate_lib(srcpath, config['name'], config['namespace'], config['tags'], args.ver, specs, input['meta']) - # From here only generate code for functions adapters can implement. - strip_specs_class(specs, "Loader") - strip_loader_meta(input['meta']) if args.loader: generate_code.generate_loader(srcpath, config['name'], config['namespace'], config['tags'], args.ver, specs, input['meta']) if args.layers: diff --git a/scripts/parse_specs.py b/scripts/parse_specs.py index d0094f958c..07ae086efd 100644 --- a/scripts/parse_specs.py +++ b/scripts/parse_specs.py @@ -18,8 +18,8 @@ import ctypes import itertools -default_version = "0.5" -all_versions = ["0.5", "1.0", "1.1", "2.0"] +default_version = "0.7" +all_versions = ["0.6", "0.7"] """ preprocess object @@ -915,9 +915,9 @@ def parse(section, version, tags, meta, ref): for c in '_-': name = name.replace(c, ' ') elif header: - # for d in _make_versions(d, float(version)): - objects.append(d) - meta = _generate_meta(d, header['ordinal'], meta) + for d in _make_versions(d, float(version)): + objects.append(d) + meta = _generate_meta(d, header['ordinal'], meta) if header: specs.append({ diff --git a/scripts/templates/__init__.py b/scripts/templates/__init__.py index e69de29bb2..6a50195602 100644 --- a/scripts/templates/__init__.py +++ b/scripts/templates/__init__.py @@ -0,0 +1,8 @@ +""" + Copyright (C) 2023 Intel Corporation + + Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. + See LICENSE.TXT + SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +""" diff --git a/scripts/templates/api.py.mako b/scripts/templates/api.py.mako index 0399bf1ba8..35a2fd6d27 100644 --- a/scripts/templates/api.py.mako +++ b/scripts/templates/api.py.mako @@ -178,9 +178,6 @@ class ${N}_DDI: self.__dll.${x}Init(0, 0) %for tbl in tables: - %if 'Loader' in tbl['name']: -<% continue %> - %endif # call driver to get function pointers ${tbl['name']} = ${tbl['type']}() r = ${x}_result_v(self.__dll.${tbl['export']['name']}(version, byref(${tbl['name']}))) diff --git a/scripts/templates/ddi.h.mako b/scripts/templates/ddi.h.mako index 26d7f3f93d..3a0e0c1af2 100644 --- a/scripts/templates/ddi.h.mako +++ b/scripts/templates/ddi.h.mako @@ -31,9 +31,6 @@ extern "C" { #endif %for tbl in th.get_pfntables(specs, meta, n, tags): -%if 'Loader' in tbl['export']['name']: - <% continue %> -%endif %for obj in tbl['functions']: /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ${th.make_func_name(n, tags, obj)} @@ -97,9 +94,6 @@ typedef ${x}_result_t (${X}_APICALL *${tbl['pfn']})( typedef struct ${n}_dditable_t { %for tbl in th.get_pfntables(specs, meta, n, tags): -%if 'loader' in tbl['type']: - <% continue %> -%endif ${th.append_ws(tbl['type'], 35)} ${tbl['name']}; %endfor } ${n}_dditable_t; diff --git a/scripts/templates/helper.py b/scripts/templates/helper.py index 1e738dbc09..2b283b8119 100644 --- a/scripts/templates/helper.py +++ b/scripts/templates/helper.py @@ -32,6 +32,13 @@ def is_class(obj): except: return False + @staticmethod + def is_handle(obj): + try: + return True if re.match(r"handle", obj['type']) else False + except: + return False + @staticmethod def is_experimental(obj): try: @@ -46,7 +53,12 @@ def class_name(obj): except: return None - + @staticmethod + def is_loader_only(obj): + try: + return obj['loader_only'] + except: + return False """ @@ -440,6 +452,7 @@ def is_global(item, tags): except: return False + """ Public: substitutes each tag['key'] with tag['value'] @@ -547,6 +560,31 @@ def extract_objs(specs, value): objs.append(obj) return objs +""" +Public: + returns a list of all adapter functions +""" +def get_adapter_functions(specs): + objs = [] + for s in specs: + for obj in s['objects']: + if obj_traits.is_function(obj) and not obj_traits.is_loader_only(obj): + objs.append(obj) + return objs + +""" +Public: + returns a list of all adapter handles +""" +def get_adapter_handles(specs): + objs = [] + for s in specs: + for obj in s['objects']: + if obj_traits.is_handle(obj) and not obj_traits.is_loader_only(obj): + objs.append(obj) + + return objs + """ Private: removes 'const' from c++ type @@ -1047,6 +1085,9 @@ def get_pfntables(specs, meta, namespace, tags): tables = [] for cname in sorted(meta['class'], key=lambda x: meta['class'][x]['ordinal']): objs, exp_objs = get_class_function_objs_exp(specs, cname) + objs = list(filter(lambda obj: not obj_traits.is_loader_only(obj), objs)) + exp_objs = list(filter(lambda obj: not obj_traits.is_loader_only(obj), exp_objs)) + if len(objs) > 0: name = get_table_name(namespace, tags, objs[0]) table = "%s_%s_dditable_t"%(namespace, _camel_to_snake(name)) @@ -1111,6 +1152,7 @@ def get_pfntables(specs, meta, namespace, tags): return tables + """ Private: returns the list of parameters, filtering based on desc tags diff --git a/scripts/templates/ldrddi.cpp.mako b/scripts/templates/ldrddi.cpp.mako index bb15dc97c7..0498ba00dc 100644 --- a/scripts/templates/ldrddi.cpp.mako +++ b/scripts/templates/ldrddi.cpp.mako @@ -24,7 +24,7 @@ from templates import helper as th namespace ur_loader { /////////////////////////////////////////////////////////////////////////////// - %for obj in th.extract_objs(specs, r"handle"): + %for obj in th.get_adapter_handles(specs): %if 'class' in obj: <% _handle_t = th.subt(n, tags, obj['name']) @@ -34,7 +34,7 @@ namespace ur_loader %endif %endfor - %for obj in th.extract_objs(specs, r"function"): + %for obj in th.get_adapter_functions(specs): /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for ${th.make_func_name(n, tags, obj)} %if 'condition' in obj: diff --git a/scripts/templates/ldrddi.hpp.mako b/scripts/templates/ldrddi.hpp.mako index 5f7f85b6c9..7618945a55 100644 --- a/scripts/templates/ldrddi.hpp.mako +++ b/scripts/templates/ldrddi.hpp.mako @@ -27,7 +27,7 @@ from templates import helper as th namespace ur_loader { /////////////////////////////////////////////////////////////////////////////// - %for obj in th.extract_objs(specs, r"handle"): + %for obj in th.get_adapter_handles(specs): %if 'class' in obj: <% _handle_t = th.subt(n, tags, obj['name']) diff --git a/scripts/templates/libapi.cpp.mako b/scripts/templates/libapi.cpp.mako index c2fb67808e..d269d62241 100644 --- a/scripts/templates/libapi.cpp.mako +++ b/scripts/templates/libapi.cpp.mako @@ -56,7 +56,7 @@ ${th.make_func_name(n, tags, obj)}( %endfor ) try { -%if 'Loader' in obj['class']: +%if th.obj_traits.is_loader_only(obj): return ur_lib::${th.make_func_name(n, tags, obj)}(${", ".join(th.make_param_lines(n, tags, obj, format=["name"]))} ); %else: %if re.match("Init", obj['name']): diff --git a/scripts/templates/libddi.cpp.mako b/scripts/templates/libddi.cpp.mako index fc04c20ff8..de73cc2fc7 100644 --- a/scripts/templates/libddi.cpp.mako +++ b/scripts/templates/libddi.cpp.mako @@ -33,9 +33,6 @@ namespace ${x}_lib ${x}_result_t result = ${X}_RESULT_SUCCESS; %for tbl in th.get_pfntables(specs, meta, n, tags): - %if 'Loader' in tbl['export']['name']: - <% continue %> - %endif if( ${X}_RESULT_SUCCESS == result ) { result = ${tbl['export']['name']}( ${X}_API_VERSION_CURRENT, &${n}DdiTable.${tbl['name']} ); diff --git a/scripts/templates/nullddi.cpp.mako b/scripts/templates/nullddi.cpp.mako index ac52c654ab..daee79d626 100644 --- a/scripts/templates/nullddi.cpp.mako +++ b/scripts/templates/nullddi.cpp.mako @@ -22,7 +22,7 @@ from templates import helper as th namespace driver { - %for obj in th.extract_objs(specs, r"function"): + %for obj in th.get_adapter_functions(specs): /////////////////////////////////////////////////////////////////////////////// <% fname = th.make_func_name(n, tags, obj) diff --git a/scripts/templates/params.hpp.mako b/scripts/templates/params.hpp.mako index 3fef2e0c72..fd6cbc4c06 100644 --- a/scripts/templates/params.hpp.mako +++ b/scripts/templates/params.hpp.mako @@ -94,6 +94,16 @@ def findMemberType(_item): namespace ${x}_params { +template struct is_handle : std::false_type {}; +%for spec in specs: +%for obj in spec['objects']: +%if re.match(r"handle", obj['type']): +template <> struct is_handle<${th.make_type_name(n, tags, obj)}> : std::true_type {}; +%endif +%endfor +%endfor +template +inline constexpr bool is_handle_v = is_handle::value; template inline void serializePtr(std::ostream &os, T *ptr); template inline void serializeFlag(std::ostream &os, uint32_t flag); template inline void serializeTagged(std::ostream &os, const void *ptr, T value, size_t size); @@ -364,12 +374,6 @@ inline std::ostream &operator<<(std::ostream &os, const struct ${th.make_pfncb_p %endfor namespace ${x}_params { -## This is needed to avoid dereferencing forward declared handles -// https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678 -template -constexpr bool is_type_complete_v = false; -template -constexpr bool is_type_complete_v> = true; template inline void serializePtr(std::ostream &os, T *ptr) { if (ptr == nullptr) { @@ -378,7 +382,7 @@ template inline void serializePtr(std::ostream &os, T *ptr) { os << (void *)(ptr) << " ("; serializePtr(os, *ptr); os << ")"; - } else if constexpr (std::is_void_v || !is_type_complete_v) { + } else if constexpr (std::is_void_v || is_handle_v) { os << (void *)ptr; } else if constexpr (std::is_same_v, char>) { os << (void *)(ptr) << " ("; diff --git a/scripts/templates/trcddi.cpp.mako b/scripts/templates/trcddi.cpp.mako index 6160b0072e..9a2eb3e319 100644 --- a/scripts/templates/trcddi.cpp.mako +++ b/scripts/templates/trcddi.cpp.mako @@ -24,7 +24,7 @@ from templates import helper as th namespace ur_tracing_layer { - %for obj in th.extract_objs(specs, r"function"): + %for obj in th.get_adapter_functions(specs): /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for ${th.make_func_name(n, tags, obj)} %if 'condition' in obj: diff --git a/scripts/templates/valddi.cpp.mako b/scripts/templates/valddi.cpp.mako index ee931f66f9..862c8b81a5 100644 --- a/scripts/templates/valddi.cpp.mako +++ b/scripts/templates/valddi.cpp.mako @@ -24,7 +24,7 @@ from templates import helper as th namespace ur_validation_layer { - %for obj in th.extract_objs(specs, r"function"): + %for obj in th.get_adapter_functions(specs): <% func_name=th.make_func_name(n, tags, obj) object_param=th.make_param_lines(n, tags, obj, format=["name"])[-1] diff --git a/scripts/verify_license.py b/scripts/verify_license.py new file mode 100644 index 0000000000..41b10a0d84 --- /dev/null +++ b/scripts/verify_license.py @@ -0,0 +1,28 @@ +""" + Copyright (C) 2023 Intel Corporation + + Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. + See LICENSE.TXT + SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +""" + +import sys +import argparse + +def verify_file_has_license(file): + with open(file, 'r') as in_file: + contents = in_file.read(300) + if "SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception" not in contents: + raise Exception(f"{file} does not contain a license!") + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--files', nargs='+', default=[]) + args = parser.parse_args() + for file in args.files: + verify_file_has_license(file) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/source/common/umf_pools/disjoint_pool.cpp b/source/common/umf_pools/disjoint_pool.cpp index 7efd243f63..5c6c3a852a 100644 --- a/source/common/umf_pools/disjoint_pool.cpp +++ b/source/common/umf_pools/disjoint_pool.cpp @@ -966,10 +966,10 @@ DisjointPool::~DisjointPool() { size_t HighPeakSlabsInUse; if (impl->getParams().PoolTrace > 1) { auto name = impl->getParams().name; - impl->printStats(TitlePrinted, HighBucketSize, HighPeakSlabsInUse, - name.c_str()); - if (TitlePrinted) { - try { // cannot throw in destructor + try { // cannot throw in destructor + impl->printStats(TitlePrinted, HighBucketSize, HighPeakSlabsInUse, + name.c_str()); + if (TitlePrinted) { std::cout << "Current Pool Size " << impl->getParams().limits->TotalSize.load() << std::endl; @@ -978,8 +978,8 @@ DisjointPool::~DisjointPool() { << std::string(name.c_str() + 1) << ":" << HighBucketSize << "," << HighPeakSlabsInUse << ",64K" << std::endl; - } catch (...) { // ignore exceptions } + } catch (...) { // ignore exceptions } } } diff --git a/source/common/ur_params.hpp b/source/common/ur_params.hpp index b3f9b88fc5..51d11bfdbf 100644 --- a/source/common/ur_params.hpp +++ b/source/common/ur_params.hpp @@ -17,6 +17,29 @@ #include namespace ur_params { +template struct is_handle : std::false_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; +template <> +struct is_handle : std::true_type {}; +template <> +struct is_handle : std::true_type {}; +template inline constexpr bool is_handle_v = is_handle::value; template inline void serializePtr(std::ostream &os, T *ptr); template inline void serializeFlag(std::ostream &os, uint32_t flag); @@ -30,6 +53,10 @@ template <> inline void serializeFlag(std::ostream &os, uint32_t flag); +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_loader_config_info_t value, size_t size); + template <> inline void serializeTagged(std::ostream &os, const void *ptr, ur_adapter_info_t value, size_t size); @@ -283,6 +310,8 @@ inline std::ostream &operator<<(std::ostream &os, const struct ur_rect_region_t params); inline std::ostream &operator<<(std::ostream &os, enum ur_device_init_flag_t value); +inline std::ostream &operator<<(std::ostream &os, + enum ur_loader_config_info_t value); inline std::ostream &operator<<(std::ostream &os, enum ur_adapter_info_t value); inline std::ostream &operator<<(std::ostream &os, enum ur_adapter_backend_t value); @@ -2082,6 +2111,59 @@ inline void serializeFlag(std::ostream &os, } } } // namespace ur_params +inline std::ostream &operator<<(std::ostream &os, + enum ur_loader_config_info_t value) { + switch (value) { + + case UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS: + os << "UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS"; + break; + + case UR_LOADER_CONFIG_INFO_REFERENCE_COUNT: + os << "UR_LOADER_CONFIG_INFO_REFERENCE_COUNT"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} +namespace ur_params { +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_loader_config_info_t value, size_t size) { + if (ptr == NULL) { + serializePtr(os, ptr); + return; + } + + switch (value) { + + case UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS: { + + const char *tptr = (const char *)ptr; + serializePtr(os, tptr); + } break; + + case UR_LOADER_CONFIG_INFO_REFERENCE_COUNT: { + const uint32_t *tptr = (const uint32_t *)ptr; + if (sizeof(uint32_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(uint32_t) << ")"; + return; + } + os << (void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; + default: + os << "unknown enumerator"; + break; + } +} +} // namespace ur_params inline std::ostream &operator<<(std::ostream &os, enum ur_adapter_info_t value) { switch (value) { @@ -13357,6 +13439,86 @@ inline std::ostream &operator<<( return os; } +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_loader_config_create_params_t *params) { + + os << ".phLoaderConfig = "; + + ur_params::serializePtr(os, *(params->pphLoaderConfig)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_loader_config_retain_params_t *params) { + + os << ".hLoaderConfig = "; + + ur_params::serializePtr(os, *(params->phLoaderConfig)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_loader_config_release_params_t *params) { + + os << ".hLoaderConfig = "; + + ur_params::serializePtr(os, *(params->phLoaderConfig)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_loader_config_get_info_params_t *params) { + + os << ".hLoaderConfig = "; + + ur_params::serializePtr(os, *(params->phLoaderConfig)); + + os << ", "; + os << ".propName = "; + + os << *(params->ppropName); + + os << ", "; + os << ".propSize = "; + + os << *(params->ppropSize); + + os << ", "; + os << ".pPropValue = "; + ur_params::serializeTagged(os, *(params->ppPropValue), *(params->ppropName), + *(params->ppropSize)); + + os << ", "; + os << ".pPropSizeRet = "; + + ur_params::serializePtr(os, *(params->ppPropSizeRet)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_loader_config_enable_layer_params_t *params) { + + os << ".hLoaderConfig = "; + + ur_params::serializePtr(os, *(params->phLoaderConfig)); + + os << ", "; + os << ".pLayerName = "; + + ur_params::serializePtr(os, *(params->ppLayerName)); + + return os; +} + inline std::ostream & operator<<(std::ostream &os, const struct ur_mem_image_create_params_t *params) { @@ -15205,10 +15367,6 @@ operator<<(std::ostream &os, } namespace ur_params { -// https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678 -template constexpr bool is_type_complete_v = false; -template -constexpr bool is_type_complete_v> = true; template inline void serializePtr(std::ostream &os, T *ptr) { if (ptr == nullptr) { @@ -15217,7 +15375,7 @@ template inline void serializePtr(std::ostream &os, T *ptr) { os << (void *)(ptr) << " ("; serializePtr(os, *ptr); os << ")"; - } else if constexpr (std::is_void_v || !is_type_complete_v) { + } else if constexpr (std::is_void_v || is_handle_v) { os << (void *)ptr; } else if constexpr (std::is_same_v, char>) { os << (void *)(ptr) << " ("; @@ -15547,6 +15705,21 @@ inline int serializeFunctionParams(std::ostream &os, uint32_t function, os << (const struct ur_kernel_set_specialization_constants_params_t *) params; } break; + case UR_FUNCTION_LOADER_CONFIG_CREATE: { + os << (const struct ur_loader_config_create_params_t *)params; + } break; + case UR_FUNCTION_LOADER_CONFIG_RETAIN: { + os << (const struct ur_loader_config_retain_params_t *)params; + } break; + case UR_FUNCTION_LOADER_CONFIG_RELEASE: { + os << (const struct ur_loader_config_release_params_t *)params; + } break; + case UR_FUNCTION_LOADER_CONFIG_GET_INFO: { + os << (const struct ur_loader_config_get_info_params_t *)params; + } break; + case UR_FUNCTION_LOADER_CONFIG_ENABLE_LAYER: { + os << (const struct ur_loader_config_enable_layer_params_t *)params; + } break; case UR_FUNCTION_MEM_IMAGE_CREATE: { os << (const struct ur_mem_image_create_params_t *)params; } break; diff --git a/source/common/windows/ur_lib_loader.cpp b/source/common/windows/ur_lib_loader.cpp index d22aff68d9..dd4cfd232b 100644 --- a/source/common/windows/ur_lib_loader.cpp +++ b/source/common/windows/ur_lib_loader.cpp @@ -30,7 +30,7 @@ LibLoader::loadAdapterLibrary(const char *name) { } void *LibLoader::getFunctionPtr(HMODULE handle, const char *func_name) { - return GetProcAddress(handle, func_name); + return reinterpret_cast(GetProcAddress(handle, func_name)); } } // namespace ur_loader diff --git a/source/loader/layers/ur_proxy_layer.hpp b/source/loader/layers/ur_proxy_layer.hpp index da45017a5f..782a7e241b 100644 --- a/source/loader/layers/ur_proxy_layer.hpp +++ b/source/loader/layers/ur_proxy_layer.hpp @@ -20,7 +20,7 @@ /////////////////////////////////////////////////////////////////////////////// class __urdlllocal proxy_layer_context_t { public: - ur_api_version_t version = UR_API_VERSION_0_6; + ur_api_version_t version = UR_API_VERSION_CURRENT; virtual std::vector getNames() const = 0; virtual bool isAvailable() const = 0; diff --git a/source/loader/ur_adapter_registry.hpp b/source/loader/ur_adapter_registry.hpp index c97ad224d1..877206c062 100644 --- a/source/loader/ur_adapter_registry.hpp +++ b/source/loader/ur_adapter_registry.hpp @@ -33,7 +33,14 @@ class AdapterRegistry { if (forceLoadedAdaptersOpt.has_value()) { for (const auto &s : forceLoadedAdaptersOpt.value()) { auto path = fs::path(s); - if (fs::exists(path)) { + bool exists = false; + try { + exists = fs::exists(path); + } catch (std::exception &e) { + logger::error(e.what()); + } + + if (exists) { adaptersLoadPaths.emplace_back(std::vector{path}); } else { logger::warning( diff --git a/source/loader/ur_loader.hpp b/source/loader/ur_loader.hpp index ad445d2027..8a0f4a8c23 100644 --- a/source/loader/ur_loader.hpp +++ b/source/loader/ur_loader.hpp @@ -30,7 +30,7 @@ using platform_vector_t = std::vector; class context_t { public: - ur_api_version_t version = UR_API_VERSION_0_6; + ur_api_version_t version = UR_API_VERSION_CURRENT; platform_vector_t platforms; AdapterRegistry adapter_registry; diff --git a/source/ur_api.cpp b/source/ur_api.cpp index c8362e490c..424290d88f 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -7,7 +7,7 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * * @file ur_api.cpp - * @version v0.6-r0 + * @version v0.7-r0 * */ #include "ur_api.h" diff --git a/test/conformance/CMakeLists.txt b/test/conformance/CMakeLists.txt index dadf5d5406..8c74afec43 100644 --- a/test/conformance/CMakeLists.txt +++ b/test/conformance/CMakeLists.txt @@ -91,9 +91,10 @@ if(DEFINED UR_DPCXX) "${CMAKE_CURRENT_BINARY_DIR}/device_binaries" CACHE INTERNAL UR_CONFORMANCE_DEVICE_BINARIES_DIR) file(MAKE_DIRECTORY ${UR_CONFORMANCE_DEVICE_BINARIES_DIR}) - if(DEFINED UR_CONFORMANCE_TARGET_TRIPLES) + if(NOT "${UR_CONFORMANCE_TARGET_TRIPLES}" STREQUAL "") string(REPLACE "," ";" TARGET_TRIPLES ${UR_CONFORMANCE_TARGET_TRIPLES}) else() + message(WARNING "UR_CONFORMANCE_TARGET_TRIPLES wasn't set, defaulting to only generate spir64 device binaries") list(APPEND TARGET_TRIPLES "spir64") endif() diff --git a/test/conformance/enqueue/urEnqueueKernelLaunch.cpp b/test/conformance/enqueue/urEnqueueKernelLaunch.cpp index eea5e68e32..0bca070da9 100644 --- a/test/conformance/enqueue/urEnqueueKernelLaunch.cpp +++ b/test/conformance/enqueue/urEnqueueKernelLaunch.cpp @@ -120,3 +120,93 @@ TEST_P(urEnqueueKernelLaunch3DTest, Success) { ASSERT_SUCCESS(urQueueFinish(queue)); ValidateBuffer(buffer, buffer_size, val); } + +struct urEnqueueKernelLaunchWithVirtualMemory : uur::urKernelExecutionTest { + + void SetUp() override { + program_name = "fill_usm"; + UUR_RETURN_ON_FATAL_FAILURE(uur::urKernelExecutionTest::SetUp()); + + ur_bool_t virtual_memory_support = false; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_VIRTUAL_MEMORY_SUPPORT, sizeof(ur_bool_t), + &virtual_memory_support, nullptr)); + if (!virtual_memory_support) { + GTEST_SKIP() << "Virtual memory is not supported."; + } + + ASSERT_SUCCESS(urVirtualMemGranularityGetInfo( + context, device, UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM, + sizeof(granularity), &granularity, nullptr)); + + alloc_size = 1024; + virtual_page_size = + uur::RoundUpToNearestFactor(alloc_size, granularity); + + ASSERT_SUCCESS(urPhysicalMemCreate(context, device, virtual_page_size, + nullptr, &physical_mem)); + + ASSERT_SUCCESS(urVirtualMemReserve(context, nullptr, virtual_page_size, + &virtual_ptr)); + + ASSERT_SUCCESS(urVirtualMemMap(context, virtual_ptr, virtual_page_size, + physical_mem, 0, + UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE)); + + int pattern = 0; + ASSERT_SUCCESS(urEnqueueUSMFill(queue, virtual_ptr, sizeof(pattern), + &pattern, virtual_page_size, 0, nullptr, + nullptr)); + ASSERT_SUCCESS(urQueueFinish(queue)); + } + + void TearDown() override { + + if (virtual_ptr) { + EXPECT_SUCCESS( + urVirtualMemUnmap(context, virtual_ptr, virtual_page_size)); + EXPECT_SUCCESS( + urVirtualMemFree(context, virtual_ptr, virtual_page_size)); + } + + if (physical_mem) { + EXPECT_SUCCESS(urPhysicalMemRelease(physical_mem)); + } + + UUR_RETURN_ON_FATAL_FAILURE(uur::urKernelExecutionTest::TearDown()); + } + + size_t granularity = 0; + size_t alloc_size = 0; + size_t virtual_page_size = 0; + ur_physical_mem_handle_t physical_mem = nullptr; + void *virtual_ptr = nullptr; +}; +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urEnqueueKernelLaunchWithVirtualMemory); + +TEST_P(urEnqueueKernelLaunchWithVirtualMemory, Success) { + size_t work_dim = 1; + size_t global_offset = 0; + size_t global_size = alloc_size / sizeof(uint32_t); + uint32_t fill_val = 42; + + ASSERT_SUCCESS(urKernelSetArgPointer(kernel, 0, nullptr, virtual_ptr)); + ASSERT_SUCCESS( + urKernelSetArgValue(kernel, 1, sizeof(fill_val), nullptr, &fill_val)); + + ur_event_handle_t kernel_evt; + ASSERT_SUCCESS(urEnqueueKernelLaunch(queue, kernel, work_dim, + &global_offset, &global_size, nullptr, + 0, nullptr, &kernel_evt)); + + std::vector data(global_size); + ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, true, data.data(), virtual_ptr, + alloc_size, 1, &kernel_evt, nullptr)); + + ASSERT_SUCCESS(urQueueFinish(queue)); + + // verify fill worked + for (size_t i = 0; i < data.size(); i++) { + ASSERT_EQ(fill_val, data.at(i)); + } +} diff --git a/test/conformance/enqueue/urEnqueueMemBufferFill.cpp b/test/conformance/enqueue/urEnqueueMemBufferFill.cpp index e9e39b00fd..cbeae5e85c 100644 --- a/test/conformance/enqueue/urEnqueueMemBufferFill.cpp +++ b/test/conformance/enqueue/urEnqueueMemBufferFill.cpp @@ -4,67 +4,149 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -using urEnqueueMemBufferFillTest = uur::urMemBufferQueueTest; -UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urEnqueueMemBufferFillTest); +struct testParametersFill { + size_t size; + size_t pattern_size; +}; + +template +inline std::string +printFillTestString(const testing::TestParamInfo &info) { + const auto device_handle = std::get<0>(info.param); + const auto platform_device_name = + uur::GetPlatformAndDeviceName(device_handle); + std::stringstream test_name; + test_name << platform_device_name << "__size__" + << std::get<1>(info.param).size << "__patternSize__" + << std::get<1>(info.param).pattern_size; + return test_name.str(); +} + +struct urEnqueueMemBufferFillTest + : uur::urQueueTestWithParam { + void SetUp() override { + UUR_RETURN_ON_FATAL_FAILURE( + urQueueTestWithParam::SetUp()); + size = std::get<1>(GetParam()).size; + pattern_size = std::get<1>(GetParam()).pattern_size; + pattern = std::vector(pattern_size); + uur::generateMemFillPattern(pattern); + ASSERT_SUCCESS(urMemBufferCreate(this->context, UR_MEM_FLAG_READ_WRITE, + size, nullptr, &buffer)); + } + + void TearDown() override { + if (buffer) { + EXPECT_SUCCESS(urMemRelease(buffer)); + } + UUR_RETURN_ON_FATAL_FAILURE( + urQueueTestWithParam::TearDown()); + } + + void verifyData(std::vector &output, size_t verify_size) { + size_t pattern_index = 0; + for (size_t i = 0; i < verify_size; ++i) { + ASSERT_EQ(output[i], pattern[pattern_index]) + << "Result mismatch at index: " << i; + + ++pattern_index; + if (pattern_index % pattern_size == 0) { + pattern_index = 0; + } + } + } + + ur_mem_handle_t buffer = nullptr; + std::vector pattern; + size_t size; + size_t pattern_size; +}; + +static std::vector test_cases{ + /* Everything set to 1 */ + {1, 1}, + /* pattern_size == size */ + {256, 256}, + /* pattern_size < size */ + {1024, 256}, + /* pattern sizes corresponding to some common scalar and vector types */ + {256, 4}, + {256, 8}, + {256, 16}, + {256, 32}}; + +UUR_TEST_SUITE_P(urEnqueueMemBufferFillTest, testing::ValuesIn(test_cases), + printFillTestString); TEST_P(urEnqueueMemBufferFillTest, Success) { - const uint32_t pattern = 0xdeadbeef; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), 0, size, 0, nullptr, + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, 0, size, 0, nullptr, nullptr)); - std::vector output(count, 1); + std::vector output(size, 1); ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, output.data(), 0, nullptr, nullptr)); - for (unsigned i = 0; i < count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; - } + verifyData(output, size); } - TEST_P(urEnqueueMemBufferFillTest, SuccessPartialFill) { - const std::vector input(count, 42); + if (size == 1) { + // Can't partially fill one byte + GTEST_SKIP(); + } + const std::vector input(size, 0); ASSERT_SUCCESS(urEnqueueMemBufferWrite(queue, buffer, true, 0, size, input.data(), 0, nullptr, nullptr)); - const uint32_t pattern = 0xdeadbeef; const size_t partial_fill_size = size / 2; - const size_t fill_count = count / 2; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), 0, partial_fill_size, - 0, nullptr, nullptr)); - std::vector output(count, 1); + // Make sure we don't end up with pattern_size > size + pattern_size = pattern_size / 2; + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, 0, partial_fill_size, 0, + nullptr, nullptr)); + std::vector output(size, 1); ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, output.data(), 0, nullptr, nullptr)); - for (size_t i = 0; i < count - fill_count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; - } + // Check the first half matches the pattern and the second half remains untouched. + verifyData(output, partial_fill_size); - for (size_t i = fill_count; i < count; ++i) { - ASSERT_EQ(output[i], 42) << "Result mismatch at index: " << i; + for (size_t i = partial_fill_size; i < size; ++i) { + ASSERT_EQ(output[i], input[i]) << "Result mismatch at index: " << i; } } TEST_P(urEnqueueMemBufferFillTest, SuccessOffset) { - const std::vector input(count, 42); + if (size == 1) { + // No room for an offset + GTEST_SKIP(); + } + const std::vector input(size, 0); ASSERT_SUCCESS(urEnqueueMemBufferWrite(queue, buffer, true, 0, size, input.data(), 0, nullptr, nullptr)); - const uint32_t pattern = 0xdeadbeef; + const size_t offset_size = size / 2; - const size_t offset_count = count / 2; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), offset_size, + // Make sure we don't end up with pattern_size > size + pattern_size = pattern_size / 2; + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, offset_size, offset_size, 0, nullptr, nullptr)); - std::vector output(count, 1); - ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, - output.data(), 0, nullptr, nullptr)); - for (size_t i = 0; i < offset_count; ++i) { - ASSERT_EQ(output[i], 42) << "Result mismatch at index: " << i; - } - for (size_t i = offset_count; i < count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; + // Check the second half matches the pattern and the first half remains untouched. + std::vector output(offset_size); + ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, offset_size, + offset_size, output.data(), 0, + nullptr, nullptr)); + verifyData(output, offset_size); + + ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, offset_size, + output.data(), 0, nullptr, nullptr)); + for (size_t i = 0; i < offset_size; ++i) { + ASSERT_EQ(output[i], input[i]) << "Result mismatch at index: " << i; } } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleQueue) { +using urEnqueueMemBufferFillNegativeTest = uur::urMemBufferQueueTest; + +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urEnqueueMemBufferFillNegativeTest); + +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandleQueue) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, urEnqueueMemBufferFill(nullptr, buffer, &pattern, @@ -72,7 +154,7 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleQueue) { nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleBuffer) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandleBuffer) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, urEnqueueMemBufferFill(queue, nullptr, &pattern, @@ -80,14 +162,14 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleBuffer) { nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandlePointerPattern) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandlePointerPattern) { ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER, urEnqueueMemBufferFill(queue, buffer, nullptr, sizeof(uint32_t), 0, size, 0, nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullPtrEventWaitList) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullPtrEventWaitList) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(urEnqueueMemBufferFill(queue, buffer, &pattern, sizeof(uint32_t), 0, size, 1, @@ -103,7 +185,7 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullPtrEventWaitList) { UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST); } -TEST_P(urEnqueueMemBufferFillTest, InvalidSize) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidSize) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_SIZE, urEnqueueMemBufferFill(queue, buffer, &pattern, diff --git a/test/conformance/enqueue/urEnqueueUSMFill.cpp b/test/conformance/enqueue/urEnqueueUSMFill.cpp index 79c86e6953..e595056035 100644 --- a/test/conformance/enqueue/urEnqueueUSMFill.cpp +++ b/test/conformance/enqueue/urEnqueueUSMFill.cpp @@ -3,7 +3,6 @@ // See LICENSE.TXT // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include struct testParametersFill { @@ -34,7 +33,7 @@ struct urEnqueueUSMFillTestWithParam host_mem = std::vector(size); pattern_size = std::get<1>(GetParam()).pattern_size; pattern = std::vector(pattern_size); - generatePattern(); + uur::generateMemFillPattern(pattern); ur_device_usm_access_capability_flags_t device_usm = 0; ASSERT_SUCCESS(uur::GetDeviceUSMDeviceSupport(device, device_usm)); @@ -54,19 +53,6 @@ struct urEnqueueUSMFillTestWithParam UUR_RETURN_ON_FATAL_FAILURE(urQueueTestWithParam::TearDown()); } - void generatePattern() { - - const size_t seed = 1; - std::mt19937 mersenne_engine{seed}; - std::uniform_int_distribution dist{0, 255}; - - auto gen = [&dist, &mersenne_engine]() { - return static_cast(dist(mersenne_engine)); - }; - - std::generate(begin(pattern), end(pattern), gen); - } - void verifyData() { ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, true, host_mem.data(), ptr, size, 0, nullptr, nullptr)); @@ -98,7 +84,11 @@ static std::vector test_cases{ {256, 256}, /* pattern_size < size */ {1024, 256}, -}; + /* pattern sizes corresponding to some common scalar and vector types */ + {256, 4}, + {256, 8}, + {256, 16}, + {256, 32}}; UUR_TEST_SUITE_P(urEnqueueUSMFillTestWithParam, testing::ValuesIn(test_cases), printFillTestString); diff --git a/test/conformance/enqueue/urEnqueueUSMFill2D.cpp b/test/conformance/enqueue/urEnqueueUSMFill2D.cpp index ed870ee5fd..9cd5bc7591 100644 --- a/test/conformance/enqueue/urEnqueueUSMFill2D.cpp +++ b/test/conformance/enqueue/urEnqueueUSMFill2D.cpp @@ -38,7 +38,7 @@ struct urEnqueueUSMFill2DTestWithParam height = std::get<1>(GetParam()).height; pattern_size = std::get<1>(GetParam()).pattern_size; pattern = std::vector(pattern_size); - generatePattern(); + uur::generateMemFillPattern(pattern); allocation_size = pitch * height; host_mem = std::vector(allocation_size); @@ -60,19 +60,6 @@ struct urEnqueueUSMFill2DTestWithParam UUR_RETURN_ON_FATAL_FAILURE(urQueueTestWithParam::TearDown()); } - void generatePattern() { - - const size_t seed = 1; - std::mt19937 mersenne_engine{seed}; - std::uniform_int_distribution dist{0, 255}; - - auto gen = [&dist, &mersenne_engine]() { - return static_cast(dist(mersenne_engine)); - }; - - std::generate(begin(pattern), end(pattern), gen); - } - void verifyData() { ASSERT_SUCCESS(urEnqueueUSMMemcpy2D(queue, true, host_mem.data(), pitch, ptr, pitch, width, height, 0, diff --git a/test/conformance/testing/CMakeLists.txt b/test/conformance/testing/CMakeLists.txt index 47e90915ed..718b48e36c 100644 --- a/test/conformance/testing/CMakeLists.txt +++ b/test/conformance/testing/CMakeLists.txt @@ -4,7 +4,11 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception add_ur_library(ur_testing STATIC - source/utils.cpp) + source/utils.cpp + source/fixtures.cpp) target_include_directories(ur_testing PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_link_libraries(ur_testing PRIVATE gtest_main unified-runtime::headers) +target_link_libraries(ur_testing PRIVATE + gtest_main + ${PROJECT_NAME}::common + ${PROJECT_NAME}::headers) add_library(${PROJECT_NAME}::testing ALIAS ur_testing) diff --git a/test/conformance/testing/include/uur/fixtures.h b/test/conformance/testing/include/uur/fixtures.h index 7765e00ade..fbb8a48fb1 100644 --- a/test/conformance/testing/include/uur/fixtures.h +++ b/test/conformance/testing/include/uur/fixtures.h @@ -11,6 +11,8 @@ #include #include +#include + #define UUR_RETURN_ON_FATAL_FAILURE(...) \ __VA_ARGS__; \ if (this->HasFatalFailure() || this->IsSkipped()) { \ @@ -634,7 +636,7 @@ struct urUSMPoolTest : urContextTest { void SetUp() override { UUR_RETURN_ON_FATAL_FAILURE(urContextTest::SetUp()); ur_usm_pool_desc_t pool_desc{UR_STRUCTURE_TYPE_USM_POOL_DESC, nullptr, - UR_USM_POOL_FLAG_ZERO_INITIALIZE_BLOCK}; + 0}; ASSERT_SUCCESS(urUSMPoolCreate(this->context, &pool_desc, &pool)); } @@ -645,15 +647,14 @@ struct urUSMPoolTest : urContextTest { UUR_RETURN_ON_FATAL_FAILURE(urContextTest::TearDown()); } - ur_usm_pool_handle_t pool; + ur_usm_pool_handle_t pool = nullptr; }; template struct urUSMPoolTestWithParam : urContextTestWithParam { void SetUp() override { UUR_RETURN_ON_FATAL_FAILURE(urContextTestWithParam::SetUp()); ur_usm_pool_desc_t pool_desc{UR_STRUCTURE_TYPE_USM_POOL_DESC, nullptr, - UR_USM_POOL_FLAG_ZERO_INITIALIZE_BLOCK}; - ur_usm_pool_handle_t pool = nullptr; + 0}; ASSERT_SUCCESS(urUSMPoolCreate(this->context, &pool_desc, &pool)); } @@ -664,12 +665,21 @@ template struct urUSMPoolTestWithParam : urContextTestWithParam { UUR_RETURN_ON_FATAL_FAILURE(urContextTestWithParam::TearDown()); } - ur_usm_pool_handle_t pool; + ur_usm_pool_handle_t pool = nullptr; }; struct urVirtualMemGranularityTest : urContextTest { void SetUp() override { UUR_RETURN_ON_FATAL_FAILURE(urContextTest::SetUp()); + + ur_bool_t virtual_memory_support = false; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_VIRTUAL_MEMORY_SUPPORT, sizeof(ur_bool_t), + &virtual_memory_support, nullptr)); + if (!virtual_memory_support) { + GTEST_SKIP() << "Virtual memory is not supported."; + } + ASSERT_SUCCESS(urVirtualMemGranularityGetInfo( context, device, UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM, sizeof(granularity), &granularity, nullptr)); @@ -681,6 +691,15 @@ template struct urVirtualMemGranularityTestWithParam : urContextTestWithParam { void SetUp() override { UUR_RETURN_ON_FATAL_FAILURE(urContextTestWithParam::SetUp()); + + ur_bool_t virtual_memory_support = false; + ASSERT_SUCCESS(urDeviceGetInfo( + this->device, UR_DEVICE_INFO_VIRTUAL_MEMORY_SUPPORT, + sizeof(ur_bool_t), &virtual_memory_support, nullptr)); + if (!virtual_memory_support) { + GTEST_SKIP() << "Virtual memory is not supported."; + } + ASSERT_SUCCESS(urVirtualMemGranularityGetInfo( this->context, this->device, UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM, sizeof(granularity), @@ -823,8 +842,12 @@ struct urUSMDeviceAllocTestWithParam : urQueueTestWithParam { if (!device_usm) { GTEST_SKIP() << "Device USM in not supported"; } + if (use_pool) { + ur_usm_pool_desc_t pool_desc = {}; + ASSERT_SUCCESS(urUSMPoolCreate(this->context, &pool_desc, &pool)); + } ASSERT_SUCCESS(urUSMDeviceAlloc(this->context, this->device, nullptr, - nullptr, allocation_size, &ptr)); + pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; uint8_t fillPattern = 0; @@ -839,13 +862,32 @@ struct urUSMDeviceAllocTestWithParam : urQueueTestWithParam { void TearDown() override { ASSERT_SUCCESS(urUSMFree(this->context, ptr)); + if (pool) { + ASSERT_TRUE(use_pool); + ASSERT_SUCCESS(urUSMPoolRelease(pool)); + } uur::urQueueTestWithParam::TearDown(); } size_t allocation_size = sizeof(int); void *ptr = nullptr; + bool use_pool = false; + ur_usm_pool_handle_t pool = nullptr; }; +// Generates a random byte pattern for MemFill type entry-points. +inline void generateMemFillPattern(std::vector &pattern) { + const size_t seed = 1; + std::mt19937 mersenne_engine{seed}; + std::uniform_int_distribution dist{0, 255}; + + auto gen = [&dist, &mersenne_engine]() { + return static_cast(dist(mersenne_engine)); + }; + + std::generate(begin(pattern), end(pattern), gen); +} + /// @brief /// @tparam T /// @param info @@ -861,6 +903,22 @@ std::string deviceTestWithParamPrinter( return uur::GetPlatformAndDeviceName(device) + "__" + ss.str(); } +// Helper struct to allow bool param tests with meaningful names. +struct BoolTestParam { + std::string name; + bool value; + + // For use with testing::ValuesIn to generate the param values. + static std::vector makeBoolParam(std::string name) { + return std::vector({{name, true}, {name, false}}); + } +}; + +template <> +std::string deviceTestWithParamPrinter( + const ::testing::TestParamInfo< + std::tuple> &info); + struct urProgramTest : urQueueTest { void SetUp() override { UUR_RETURN_ON_FATAL_FAILURE(urQueueTest::SetUp()); diff --git a/test/conformance/testing/source/fixtures.cpp b/test/conformance/testing/source/fixtures.cpp new file mode 100644 index 0000000000..bd69b0884b --- /dev/null +++ b/test/conformance/testing/source/fixtures.cpp @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Intel Corporation +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. +// See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "uur/fixtures.h" + +namespace uur { +template <> +std::string deviceTestWithParamPrinter( + const ::testing::TestParamInfo< + std::tuple> &info) { + auto device = std::get<0>(info.param); + auto param = std::get<1>(info.param); + + std::stringstream ss; + ss << param.name << (param.value ? "Enabled" : "Disabled"); + return uur::GetPlatformAndDeviceName(device) + "__" + ss.str(); +} +} // namespace uur diff --git a/test/conformance/usm/urUSMDeviceAlloc.cpp b/test/conformance/usm/urUSMDeviceAlloc.cpp index 8fd4742d90..b66f7be727 100644 --- a/test/conformance/usm/urUSMDeviceAlloc.cpp +++ b/test/conformance/usm/urUSMDeviceAlloc.cpp @@ -5,23 +5,43 @@ #include -struct urUSMDeviceAllocTest : uur::urQueueTest { +struct urUSMDeviceAllocTest : uur::urQueueTestWithParam { void SetUp() override { - UUR_RETURN_ON_FATAL_FAILURE(uur::urQueueTest::SetUp()); + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::SetUp()); ur_device_usm_access_capability_flags_t deviceUSMSupport = 0; ASSERT_SUCCESS( uur::GetDeviceUSMDeviceSupport(device, deviceUSMSupport)); if (!deviceUSMSupport) { GTEST_SKIP() << "Device USM is not supported."; } + + if (getParam().value) { + ur_usm_pool_desc_t pool_desc = {}; + ASSERT_SUCCESS(urUSMPoolCreate(context, &pool_desc, &pool)); + } + } + + void TearDown() override { + if (pool) { + ASSERT_SUCCESS(urUSMPoolRelease(pool)); + } + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::TearDown()); } + + ur_usm_pool_handle_t pool = nullptr; }; -UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urUSMDeviceAllocTest); + +UUR_TEST_SUITE_P( + urUSMDeviceAllocTest, + testing::ValuesIn(uur::BoolTestParam::makeBoolParam("UsePool")), + uur::deviceTestWithParamPrinter); TEST_P(urUSMDeviceAllocTest, Success) { void *ptr = nullptr; size_t allocation_size = sizeof(int); - ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr, + ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, pool, allocation_size, &ptr)); ASSERT_NE(ptr, nullptr); @@ -47,7 +67,7 @@ TEST_P(urUSMDeviceAllocTest, SuccessWithDescriptors) { /* alignment */ 0}; void *ptr = nullptr; size_t allocation_size = sizeof(int); - ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, &usm_desc, nullptr, + ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, &usm_desc, pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; @@ -64,27 +84,27 @@ TEST_P(urUSMDeviceAllocTest, InvalidNullHandleContext) { void *ptr = nullptr; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_NULL_HANDLE, - urUSMDeviceAlloc(nullptr, device, nullptr, nullptr, sizeof(int), &ptr)); + urUSMDeviceAlloc(nullptr, device, nullptr, pool, sizeof(int), &ptr)); } TEST_P(urUSMDeviceAllocTest, InvalidNullHandleDevice) { void *ptr = nullptr; - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, - urUSMDeviceAlloc(context, nullptr, nullptr, nullptr, - sizeof(int), &ptr)); + ASSERT_EQ_RESULT( + UR_RESULT_ERROR_INVALID_NULL_HANDLE, + urUSMDeviceAlloc(context, nullptr, nullptr, pool, sizeof(int), &ptr)); } TEST_P(urUSMDeviceAllocTest, InvalidNullPtrResult) { - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER, - urUSMDeviceAlloc(context, device, nullptr, nullptr, - sizeof(int), nullptr)); + ASSERT_EQ_RESULT( + UR_RESULT_ERROR_INVALID_NULL_POINTER, + urUSMDeviceAlloc(context, device, nullptr, pool, sizeof(int), nullptr)); } TEST_P(urUSMDeviceAllocTest, InvalidUSMSize) { void *ptr = nullptr; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_USM_SIZE, - urUSMDeviceAlloc(context, device, nullptr, nullptr, -1, &ptr)); + urUSMDeviceAlloc(context, device, nullptr, pool, -1, &ptr)); } TEST_P(urUSMDeviceAllocTest, InvalidValueAlignPowerOfTwo) { @@ -94,5 +114,5 @@ TEST_P(urUSMDeviceAllocTest, InvalidValueAlignPowerOfTwo) { desc.align = 5; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_VALUE, - urUSMDeviceAlloc(context, device, &desc, nullptr, sizeof(int), &ptr)); + urUSMDeviceAlloc(context, device, &desc, pool, sizeof(int), &ptr)); } diff --git a/test/conformance/usm/urUSMGetMemAllocInfo.cpp b/test/conformance/usm/urUSMGetMemAllocInfo.cpp index 72042e38d6..5ccbf37a70 100644 --- a/test/conformance/usm/urUSMGetMemAllocInfo.cpp +++ b/test/conformance/usm/urUSMGetMemAllocInfo.cpp @@ -6,8 +6,14 @@ #include #include -using urUSMAllocInfoTest = - uur::urUSMDeviceAllocTestWithParam; +struct urUSMAllocInfoTest + : uur::urUSMDeviceAllocTestWithParam { + void SetUp() override { + use_pool = getParam() == UR_USM_ALLOC_INFO_POOL; + UUR_RETURN_ON_FATAL_FAILURE( + uur::urUSMDeviceAllocTestWithParam::SetUp()); + } +}; UUR_TEST_SUITE_P(urUSMAllocInfoTest, ::testing::Values(UR_USM_ALLOC_INFO_TYPE, @@ -71,7 +77,7 @@ TEST_P(urUSMGetMemAllocInfoTest, InvalidEnumeration) { TEST_P(urUSMGetMemAllocInfoTest, InvalidValuePropSize) { ur_usm_type_t USMType; - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_VALUE, + ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_SIZE, urUSMGetMemAllocInfo(context, ptr, UR_USM_ALLOC_INFO_TYPE, sizeof(ur_usm_type_t) - 1, &USMType, nullptr)); diff --git a/test/conformance/usm/urUSMHostAlloc.cpp b/test/conformance/usm/urUSMHostAlloc.cpp index 48d1e098d0..3cf8833783 100644 --- a/test/conformance/usm/urUSMHostAlloc.cpp +++ b/test/conformance/usm/urUSMHostAlloc.cpp @@ -6,17 +6,36 @@ #include #include -struct urUSMHostAllocTest : uur::urQueueTest { +struct urUSMHostAllocTest : uur::urQueueTestWithParam { void SetUp() override { - UUR_RETURN_ON_FATAL_FAILURE(uur::urQueueTest::SetUp()); + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::SetUp()); ur_device_usm_access_capability_flags_t hostUSMSupport = 0; ASSERT_SUCCESS(uur::GetDeviceUSMHostSupport(device, hostUSMSupport)); if (!hostUSMSupport) { GTEST_SKIP() << "Device USM is not supported."; } + if (getParam().value) { + ur_usm_pool_desc_t pool_desc = {}; + ASSERT_SUCCESS(urUSMPoolCreate(context, &pool_desc, &pool)); + } + } + + void TearDown() override { + if (pool) { + ASSERT_SUCCESS(urUSMPoolRelease(pool)); + } + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::TearDown()); } + + ur_usm_pool_handle_t pool = nullptr; }; -UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urUSMHostAllocTest); + +UUR_TEST_SUITE_P( + urUSMHostAllocTest, + testing::ValuesIn(uur::BoolTestParam::makeBoolParam("UsePool")), + uur::deviceTestWithParamPrinter); TEST_P(urUSMHostAllocTest, Success) { ur_device_usm_access_capability_flags_t hostUSMSupport = 0; @@ -27,7 +46,7 @@ TEST_P(urUSMHostAllocTest, Success) { size_t allocation_size = sizeof(int); int *ptr = nullptr; - ASSERT_SUCCESS(urUSMHostAlloc(context, nullptr, nullptr, sizeof(int), + ASSERT_SUCCESS(urUSMHostAlloc(context, nullptr, pool, sizeof(int), reinterpret_cast(&ptr))); ASSERT_NE(ptr, nullptr); @@ -68,7 +87,7 @@ TEST_P(urUSMHostAllocTest, SuccessWithDescriptors) { void *ptr = nullptr; size_t allocation_size = sizeof(int); ASSERT_SUCCESS( - urUSMHostAlloc(context, &usm_desc, nullptr, allocation_size, &ptr)); + urUSMHostAlloc(context, &usm_desc, pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; uint8_t pattern = 0; @@ -82,21 +101,20 @@ TEST_P(urUSMHostAllocTest, SuccessWithDescriptors) { TEST_P(urUSMHostAllocTest, InvalidNullHandleContext) { void *ptr = nullptr; - ASSERT_EQ_RESULT( - UR_RESULT_ERROR_INVALID_NULL_HANDLE, - urUSMHostAlloc(nullptr, nullptr, nullptr, sizeof(int), &ptr)); + ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, + urUSMHostAlloc(nullptr, nullptr, pool, sizeof(int), &ptr)); } TEST_P(urUSMHostAllocTest, InvalidNullPtrMem) { ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_NULL_POINTER, - urUSMHostAlloc(context, nullptr, nullptr, sizeof(int), nullptr)); + urUSMHostAlloc(context, nullptr, pool, sizeof(int), nullptr)); } TEST_P(urUSMHostAllocTest, InvalidUSMSize) { void *ptr = nullptr; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_USM_SIZE, - urUSMHostAlloc(context, nullptr, nullptr, -1, &ptr)); + urUSMHostAlloc(context, nullptr, pool, -1, &ptr)); } TEST_P(urUSMHostAllocTest, InvalidValueAlignPowerOfTwo) { @@ -104,7 +122,6 @@ TEST_P(urUSMHostAllocTest, InvalidValueAlignPowerOfTwo) { ur_usm_desc_t desc = {}; desc.stype = UR_STRUCTURE_TYPE_USM_DESC; desc.align = 5; - ASSERT_EQ_RESULT( - UR_RESULT_ERROR_INVALID_VALUE, - urUSMHostAlloc(context, &desc, nullptr, sizeof(int), &ptr)); + ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_VALUE, + urUSMHostAlloc(context, &desc, pool, sizeof(int), &ptr)); } diff --git a/test/conformance/usm/urUSMPoolCreate.cpp b/test/conformance/usm/urUSMPoolCreate.cpp index af717b1612..a723542026 100644 --- a/test/conformance/usm/urUSMPoolCreate.cpp +++ b/test/conformance/usm/urUSMPoolCreate.cpp @@ -9,6 +9,14 @@ using urUSMPoolCreateTest = uur::urContextTest; UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urUSMPoolCreateTest); TEST_P(urUSMPoolCreateTest, Success) { + ur_usm_pool_desc_t pool_desc{UR_STRUCTURE_TYPE_USM_POOL_DESC, nullptr, 0}; + ur_usm_pool_handle_t pool = nullptr; + ASSERT_SUCCESS(urUSMPoolCreate(context, &pool_desc, &pool)); + ASSERT_NE(pool, nullptr); + EXPECT_SUCCESS(urUSMPoolRelease(pool)); +} + +TEST_P(urUSMPoolCreateTest, SuccessWithFlag) { ur_usm_pool_desc_t pool_desc{UR_STRUCTURE_TYPE_USM_POOL_DESC, nullptr, UR_USM_POOL_FLAG_ZERO_INITIALIZE_BLOCK}; ur_usm_pool_handle_t pool = nullptr; diff --git a/test/conformance/usm/urUSMSharedAlloc.cpp b/test/conformance/usm/urUSMSharedAlloc.cpp index 5e92183500..e400cdc7d8 100644 --- a/test/conformance/usm/urUSMSharedAlloc.cpp +++ b/test/conformance/usm/urUSMSharedAlloc.cpp @@ -5,9 +5,10 @@ #include -struct urUSMSharedAllocTest : uur::urQueueTest { +struct urUSMSharedAllocTest : uur::urQueueTestWithParam { void SetUp() override { - UUR_RETURN_ON_FATAL_FAILURE(uur::urQueueTest::SetUp()); + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::SetUp()); ur_device_usm_access_capability_flags_t shared_usm_cross = 0; ur_device_usm_access_capability_flags_t shared_usm_single = 0; @@ -19,14 +20,33 @@ struct urUSMSharedAllocTest : uur::urQueueTest { if (!(shared_usm_cross || shared_usm_single)) { GTEST_SKIP() << "Shared USM is not supported by the device."; } + + if (getParam().value) { + ur_usm_pool_desc_t pool_desc = {}; + ASSERT_SUCCESS(urUSMPoolCreate(context, &pool_desc, &pool)); + } + } + + void TearDown() override { + if (pool) { + ASSERT_SUCCESS(urUSMPoolRelease(pool)); + } + UUR_RETURN_ON_FATAL_FAILURE( + uur::urQueueTestWithParam::TearDown()); } + + ur_usm_pool_handle_t pool = nullptr; }; -UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urUSMSharedAllocTest); + +UUR_TEST_SUITE_P( + urUSMSharedAllocTest, + testing::ValuesIn(uur::BoolTestParam::makeBoolParam("UsePool")), + uur::deviceTestWithParamPrinter); TEST_P(urUSMSharedAllocTest, Success) { void *ptr = nullptr; size_t allocation_size = sizeof(int); - ASSERT_SUCCESS(urUSMSharedAlloc(context, device, nullptr, nullptr, + ASSERT_SUCCESS(urUSMSharedAlloc(context, device, nullptr, pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; @@ -54,7 +74,7 @@ TEST_P(urUSMSharedAllocTest, SuccessWithDescriptors) { /* alignment */ 0}; void *ptr = nullptr; size_t allocation_size = sizeof(int); - ASSERT_SUCCESS(urUSMSharedAlloc(context, device, &usm_desc, nullptr, + ASSERT_SUCCESS(urUSMSharedAlloc(context, device, &usm_desc, pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; @@ -75,7 +95,7 @@ TEST_P(urUSMSharedAllocTest, SuccessWithMultipleAdvices) { /* alignment */ 0}; void *ptr = nullptr; size_t allocation_size = sizeof(int); - ASSERT_SUCCESS(urUSMSharedAlloc(context, device, &usm_desc, nullptr, + ASSERT_SUCCESS(urUSMSharedAlloc(context, device, &usm_desc, pool, allocation_size, &ptr)); ur_event_handle_t event = nullptr; @@ -92,27 +112,27 @@ TEST_P(urUSMSharedAllocTest, InvalidNullHandleContext) { void *ptr = nullptr; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_NULL_HANDLE, - urUSMSharedAlloc(nullptr, device, nullptr, nullptr, sizeof(int), &ptr)); + urUSMSharedAlloc(nullptr, device, nullptr, pool, sizeof(int), &ptr)); } TEST_P(urUSMSharedAllocTest, InvalidNullHandleDevice) { void *ptr = nullptr; - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, - urUSMSharedAlloc(context, nullptr, nullptr, nullptr, - sizeof(int), &ptr)); + ASSERT_EQ_RESULT( + UR_RESULT_ERROR_INVALID_NULL_HANDLE, + urUSMSharedAlloc(context, nullptr, nullptr, pool, sizeof(int), &ptr)); } TEST_P(urUSMSharedAllocTest, InvalidNullPtrMem) { - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER, - urUSMSharedAlloc(context, device, nullptr, nullptr, - sizeof(int), nullptr)); + ASSERT_EQ_RESULT( + UR_RESULT_ERROR_INVALID_NULL_POINTER, + urUSMSharedAlloc(context, device, nullptr, pool, sizeof(int), nullptr)); } TEST_P(urUSMSharedAllocTest, InvalidUSMSize) { void *ptr = nullptr; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_USM_SIZE, - urUSMSharedAlloc(context, device, nullptr, nullptr, -1, &ptr)); + urUSMSharedAlloc(context, device, nullptr, pool, -1, &ptr)); } TEST_P(urUSMSharedAllocTest, InvalidValueAlignPowerOfTwo) { @@ -122,5 +142,5 @@ TEST_P(urUSMSharedAllocTest, InvalidValueAlignPowerOfTwo) { desc.align = 5; ASSERT_EQ_RESULT( UR_RESULT_ERROR_INVALID_VALUE, - urUSMSharedAlloc(context, device, &desc, nullptr, sizeof(int), &ptr)); + urUSMSharedAlloc(context, device, &desc, pool, sizeof(int), &ptr)); } diff --git a/test/tools/urtrace/CMakeLists.txt b/test/tools/urtrace/CMakeLists.txt index 5c4e7f34d2..938fcf46f8 100644 --- a/test/tools/urtrace/CMakeLists.txt +++ b/test/tools/urtrace/CMakeLists.txt @@ -7,12 +7,17 @@ set(TEST_NAME trace-hello-world) function(add_trace_test name CLI_ARGS) set(TEST_NAME trace_test_${name}) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/${name}.match + ${CMAKE_CURRENT_BINARY_DIR}/${name}.match + @ONLY + ) add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_COMMAND} -D TEST_FILE=${Python3_EXECUTABLE} -D TEST_ARGS="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/urtrace --stdout ${CLI_ARGS} --flush info $" -D MODE=stdout - -D MATCH_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}.match + -D MATCH_FILE=${CMAKE_CURRENT_BINARY_DIR}/${name}.match -P ${PROJECT_SOURCE_DIR}/cmake/match.cmake DEPENDS ur_trace_cli hello_world ) diff --git a/test/tools/urtrace/null_hello_begin.match b/test/tools/urtrace/null_hello_begin.match index 571b01bb89..81c15da60f 100644 --- a/test/tools/urtrace/null_hello_begin.match +++ b/test/tools/urtrace/null_hello_begin.match @@ -10,7 +10,7 @@ end(4) - urPlatformGet(.phAdapters = {{{.*}}}, .NumAdapters = 1, .NumEntries = 1 begin(5) - urPlatformGet(.phAdapters = {{{.*}}}, .NumAdapters = 1, .NumEntries = 1, .phPlatforms = {nullptr}, .pNumPlatforms = nullptr); end(5) - urPlatformGet(.phAdapters = {{{.*}}}, .NumAdapters = 1, .NumEntries = 1, .phPlatforms = {{{.*}}}, .pNumPlatforms = nullptr) -> UR_RESULT_SUCCESS; begin(6) - urPlatformGetApiVersion(.hPlatform = {{.*}}, .pVersion = {{.*}} (0.0)); -end(6) - urPlatformGetApiVersion(.hPlatform = {{.*}}, .pVersion = {{.*}} (0.6)) -> UR_RESULT_SUCCESS; +end(6) - urPlatformGetApiVersion(.hPlatform = {{.*}}, .pVersion = {{.*}} (@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@)) -> UR_RESULT_SUCCESS; API version: {{.*}} begin(7) - urDeviceGet(.hPlatform = {{.*}}, .DeviceType = UR_DEVICE_TYPE_GPU, .NumEntries = 0, .phDevices = {}, .pNumDevices = {{.*}} (0)); end(7) - urDeviceGet(.hPlatform = {{.*}}, .DeviceType = UR_DEVICE_TYPE_GPU, .NumEntries = 0, .phDevices = {}, .pNumDevices = {{.*}} (1)) -> UR_RESULT_SUCCESS; diff --git a/test/tools/urtrace/null_hello_json.match b/test/tools/urtrace/null_hello_json.match index 9ba4d93f62..18c5fbac78 100644 --- a/test/tools/urtrace/null_hello_json.match +++ b/test/tools/urtrace/null_hello_json.match @@ -6,8 +6,8 @@ Platform initialized. { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urAdapterGet", "args": "(.NumEntries = 1, .phAdapters = {{{.*}}}, .pNumAdapters = nullptr)" }, { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urPlatformGet", "args": "(.phAdapters = {{{.*}}}, .NumAdapters = 1, .NumEntries = 1, .phPlatforms = {}, .pNumPlatforms = {{.*}} (1))" }, { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urPlatformGet", "args": "(.phAdapters = {{{.*}}}, .NumAdapters = 1, .NumEntries = 1, .phPlatforms = {{{.*}}}, .pNumPlatforms = nullptr)" }, -{ "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urPlatformGetApiVersion", "args": "(.hPlatform = {{.*}}, .pVersion = {{.*}} (0.6))" }, -API version: 0.6 +{ "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urPlatformGetApiVersion", "args": "(.hPlatform = {{.*}}, .pVersion = {{.*}} (@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@))" }, +API version: @PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@ { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urDeviceGet", "args": "(.hPlatform = {{.*}}, .DeviceType = UR_DEVICE_TYPE_GPU, .NumEntries = 0, .phDevices = {}, .pNumDevices = {{.*}} (1))" }, { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urDeviceGet", "args": "(.hPlatform = {{.*}}, .DeviceType = UR_DEVICE_TYPE_GPU, .NumEntries = 1, .phDevices = {{{.*}}}, .pNumDevices = nullptr)" }, { "cat": "UR", "ph": "X", "pid": {{.*}}, "tid": {{.*}}, "ts": {{.*}}, "dur": {{.*}}, "name": "urDeviceGetInfo", "args": "(.hDevice = {{.*}}, .propName = UR_DEVICE_INFO_TYPE, .propSize = 4, .pPropValue = {{.*}} (UR_DEVICE_TYPE_GPU), .pPropSizeRet = nullptr)" },