mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-09 17:28:58 +00:00
Merge branch 'windowsai' into jeffbloo/MergeMasterToWindowsAI
This commit is contained in:
commit
0b1b40077f
22 changed files with 878 additions and 608 deletions
8
cmake/external/dml.cmake
vendored
8
cmake/external/dml.cmake
vendored
|
|
@ -20,19 +20,17 @@ if (NOT onnxruntime_USE_CUSTOM_DIRECTML)
|
|||
set(NUGET_CONFIG ${PROJECT_SOURCE_DIR}/../NuGet.config)
|
||||
set(PACKAGES_CONFIG ${PROJECT_SOURCE_DIR}/../packages.config)
|
||||
set(PACKAGES_DIR ${CMAKE_CURRENT_BINARY_DIR}/packages)
|
||||
set(DML_PACKAGE_DIR ${PACKAGES_DIR}/DirectML.0.0.1)
|
||||
|
||||
# Restore nuget packages, which will pull down the DirectML redist package
|
||||
add_custom_command(
|
||||
OUTPUT restore_packages.stamp
|
||||
OUTPUT ${DML_PACKAGE_DIR}/bin/x64/DirectML.lib ${DML_PACKAGE_DIR}/bin/x86/DirectML.lib
|
||||
DEPENDS ${PACKAGES_CONFIG} ${NUGET_CONFIG}
|
||||
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/nuget/src/nuget restore ${PACKAGES_CONFIG} -PackagesDirectory ${PACKAGES_DIR} -ConfigFile ${NUGET_CONFIG}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch restore_packages.stamp
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(RESTORE_PACKAGES ALL DEPENDS restore_packages.stamp)
|
||||
add_custom_target(RESTORE_PACKAGES ALL DEPENDS ${DML_PACKAGE_DIR}/bin/x64/DirectML.lib ${DML_PACKAGE_DIR}/bin/x86/DirectML.lib)
|
||||
add_dependencies(RESTORE_PACKAGES nuget)
|
||||
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES RESTORE_PACKAGES)
|
||||
else()
|
||||
include_directories(${dml_INCLUDE_DIR})
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -44,6 +44,22 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR_PLATFORM)
|
||||
# Multi-platform generator
|
||||
set(onnxruntime_target_platform ${CMAKE_GENERATOR_PLATFORM})
|
||||
else()
|
||||
set(onnxruntime_target_platform ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
if(onnxruntime_target_platform STREQUAL "ARM64")
|
||||
set(onnxruntime_target_platform "ARM64")
|
||||
elseif(onnxruntime_target_platform STREQUAL "ARM" OR CMAKE_GENERATOR MATCHES "ARM")
|
||||
set(onnxruntime_target_platform "ARM")
|
||||
elseif(onnxruntime_target_platform STREQUAL "x64" OR onnxruntime_target_platform STREQUAL "x86_64" OR onnxruntime_target_platform STREQUAL "AMD64" OR CMAKE_GENERATOR MATCHES "Win64")
|
||||
set(onnxruntime_target_platform "x64")
|
||||
elseif(onnxruntime_target_platform STREQUAL "x86" OR onnxruntime_target_platform STREQUAL "i386" OR onnxruntime_target_platform STREQUAL "i686")
|
||||
set(onnxruntime_target_platform "x86")
|
||||
endif()
|
||||
|
||||
file(GLOB onnxruntime_common_src CONFIGURE_DEPENDS
|
||||
${onnxruntime_common_src_patterns}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ set(mlas_common_srcs
|
|||
)
|
||||
|
||||
if(MSVC)
|
||||
if(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
|
||||
if(onnxruntime_target_platform STREQUAL "ARM64")
|
||||
set(asm_filename ${ONNXRUNTIME_ROOT}/core/mlas/lib/arm64/SgemmKernelNeon.asm)
|
||||
set(pre_filename ${CMAKE_CURRENT_BINARY_DIR}/SgemmKernelNeon.i)
|
||||
set(obj_filename ${CMAKE_CURRENT_BINARY_DIR}/SgemmKernelNeon.obj)
|
||||
|
|
@ -38,11 +38,11 @@ if(MSVC)
|
|||
armasm64.exe ${ARMASM_FLAGS} ${pre_filename} ${obj_filename}
|
||||
)
|
||||
set(mlas_platform_srcs ${obj_filename})
|
||||
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM" OR CMAKE_GENERATOR MATCHES "ARM")
|
||||
elseif(onnxruntime_target_platform STREQUAL "ARM")
|
||||
set(mlas_platform_srcs
|
||||
${ONNXRUNTIME_ROOT}/core/mlas/lib/arm/sgemmc.cpp
|
||||
)
|
||||
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64" OR CMAKE_GENERATOR MATCHES "Win64")
|
||||
elseif(onnxruntime_target_platform STREQUAL "x64")
|
||||
enable_language(ASM_MASM)
|
||||
|
||||
set(mlas_platform_srcs
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ if (onnxruntime_USE_TENSORRT)
|
|||
if ( CMAKE_COMPILER_IS_GNUCC )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers")
|
||||
endif()
|
||||
set(CXX_VERSION_DEFINED TRUE)
|
||||
set(CXX_VERSION_DEFINED TRUE)
|
||||
add_subdirectory(${ONNXRUNTIME_ROOT}/../cmake/external/onnx-tensorrt)
|
||||
set(CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS})
|
||||
if (WIN32)
|
||||
|
|
@ -303,7 +303,7 @@ if (onnxruntime_USE_OPENVINO)
|
|||
if(WIN32)
|
||||
set(OPENVINO_LIB_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/Release)
|
||||
set(OPENVINO_TBB_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/Release)
|
||||
set(OPENVINO_MKL_TINY_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/bin/intel64/Release)
|
||||
set(OPENVINO_MKL_TINY_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/bin/intel64/Release)
|
||||
else()
|
||||
set(OPENVINO_LIB_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64/)
|
||||
set(OPENVINO_TBB_DIR $ENV{INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/tbb/lib)
|
||||
|
|
@ -327,9 +327,9 @@ if (onnxruntime_USE_OPENVINO)
|
|||
else()
|
||||
target_include_directories(onnxruntime_providers_openvino SYSTEM PUBLIC ${ONNXRUNTIME_ROOT} ${eigen_INCLUDE_DIRS} ${OPENVINO_INCLUDE_DIR} ${OPENVINO_EXTENSIONS_DIR} ${OPENVINO_LIB_DIR} ${OPENVINO_TBB_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
string(REPLACE "include" "libs" PYTHON_LIB ${PYTHON_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
string(REPLACE "include" "libs" PYTHON_LIB ${PYTHON_INCLUDE_DIRS})
|
||||
find_package(InferenceEngine 2.1 REQUIRED)
|
||||
set(PYTHON_LIBRARIES ${PYTHON_LIB})
|
||||
set(OPENVINO_CPU_EXTENSION_DIR ${onnxruntime_BINARY_DIR}/ie_cpu_extension/${CMAKE_BUILD_TYPE})
|
||||
|
|
@ -430,22 +430,37 @@ if (onnxruntime_USE_DML)
|
|||
onnxruntime_add_include_to_target(onnxruntime_providers_dml onnxruntime_common onnxruntime_framework onnx onnx_proto protobuf::libprotobuf)
|
||||
add_dependencies(onnxruntime_providers_dml ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
||||
target_include_directories(onnxruntime_providers_dml PRIVATE ${ONNXRUNTIME_ROOT} ${ONNXRUNTIME_ROOT}/../cmake/external/wil/include)
|
||||
|
||||
target_link_libraries(onnxruntime_providers_dml ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_link_libraries(onnxruntime_providers_dml d3d12.lib dxgi.lib)
|
||||
|
||||
if(NOT onnxruntime_target_platform STREQUAL "x86" AND NOT onnxruntime_target_platform STREQUAL "x64")
|
||||
message(FATAL_ERROR "Target platform ${onnxruntime_target_platform} is not supported by DML")
|
||||
endif()
|
||||
foreach(file "DirectML.dll" "DirectML.pdb" "DirectML.Debug.dll" "DirectML.Debug.pdb")
|
||||
add_custom_command(TARGET onnxruntime_providers_dml
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${DML_PACKAGE_DIR}/bin/${onnxruntime_target_platform}/${file}" $<TARGET_FILE_DIR:onnxruntime_providers_dml>)
|
||||
endforeach()
|
||||
|
||||
function(target_add_dml target)
|
||||
target_link_libraries(${target} PRIVATE "${DML_PACKAGE_DIR}/bin/${onnxruntime_target_platform}/DirectML.lib")
|
||||
target_include_directories(${target} PRIVATE "${DML_PACKAGE_DIR}/include")
|
||||
endfunction()
|
||||
|
||||
target_add_dml(onnxruntime_providers_dml)
|
||||
target_link_libraries(onnxruntime_providers_dml PRIVATE d3d12.lib dxgi.lib delayimp.lib)
|
||||
list(APPEND ONNXRUNTIME_LINKER_FLAGS "/DELAYLOAD:DirectML.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:dxgi.dll")
|
||||
|
||||
# The DML EP requires C++17
|
||||
set_target_properties(onnxruntime_providers_dml PROPERTIES CXX_STANDARD 17)
|
||||
set_target_properties(onnxruntime_providers_dml PROPERTIES CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
target_compile_definitions(onnxruntime_providers_dml PRIVATE ONNX_NAMESPACE=onnx ONNX_ML LOTUS_LOG_THRESHOLD=2 LOTUS_ENABLE_STDERR_LOGGING PLATFORM_WINDOWS)
|
||||
target_compile_definitions(onnxruntime_providers_dml PRIVATE UNICODE _UNICODE NOMINMAX)
|
||||
if (MSVC)
|
||||
target_compile_definitions(onnxruntime_providers_dml PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
|
||||
target_compile_options(onnxruntime_providers_dml PRIVATE "/W3")
|
||||
endif()
|
||||
|
||||
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/providers/dml DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/core/providers)
|
||||
|
||||
set_target_properties(onnxruntime_providers_dml PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ function(AddTest)
|
|||
endif()
|
||||
if (onnxruntime_ENABLE_LANGUAGE_INTEROP_OPS AND onnxruntime_ENABLE_PYTHON)
|
||||
target_compile_definitions(${_UT_TARGET} PRIVATE ENABLE_LANGUAGE_INTEROP_OPS)
|
||||
endif()
|
||||
endif()
|
||||
if (WIN32)
|
||||
if (onnxruntime_USE_CUDA)
|
||||
# disable a warning from the CUDA headers about unreferenced local functions
|
||||
|
|
@ -318,7 +318,7 @@ if (onnxruntime_USE_DNNL)
|
|||
target_compile_definitions(onnxruntime_test_utils_for_framework PUBLIC USE_DNNL=1)
|
||||
endif()
|
||||
if (onnxruntime_USE_DML)
|
||||
target_link_libraries(onnxruntime_test_utils_for_framework PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_add_dml(onnxruntime_test_utils_for_framework)
|
||||
endif()
|
||||
add_dependencies(onnxruntime_test_utils_for_framework ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
||||
target_include_directories(onnxruntime_test_utils_for_framework PUBLIC "${TEST_SRC_DIR}/util/include" PRIVATE ${eigen_INCLUDE_DIRS} ${ONNXRUNTIME_ROOT})
|
||||
|
|
@ -336,7 +336,7 @@ if (onnxruntime_USE_DNNL)
|
|||
target_compile_definitions(onnxruntime_test_utils PUBLIC USE_DNNL=1)
|
||||
endif()
|
||||
if (onnxruntime_USE_DML)
|
||||
target_link_libraries(onnxruntime_test_utils PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_add_dml(onnxruntime_test_utils)
|
||||
endif()
|
||||
add_dependencies(onnxruntime_test_utils ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
||||
target_include_directories(onnxruntime_test_utils PUBLIC "${TEST_SRC_DIR}/util/include" PRIVATE ${eigen_INCLUDE_DIRS} ${ONNXRUNTIME_ROOT})
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
# header name as input. The function will generate a .cpp file that includes the header and is used
|
||||
# to generate the precompiled header; this source file is added to the target's sources.
|
||||
function(target_precompiled_header target_name header_name)
|
||||
if (MSVC)
|
||||
|
||||
if (MSVC AND CMAKE_VS_PLATFORM_TOOLSET)
|
||||
# The input precompiled header source (i.e. the '.h' file used for the precompiled header).
|
||||
set(pch_header_path ${header_name})
|
||||
get_filename_component(header_base_name ${header_name} NAME_WE)
|
||||
|
|
@ -14,14 +13,14 @@ function(target_precompiled_header target_name header_name)
|
|||
set(pch_source_content "// THIS FILE IS GENERATED BY CMAKE\n#include \"${pch_header_path}\"")
|
||||
file(WRITE ${pch_source_path} ${pch_source_content})
|
||||
set_source_files_properties(${pch_source_path} PROPERTIES COMPILE_FLAGS "/Yc${pch_header_path}")
|
||||
|
||||
|
||||
# The target's C++ sources use the precompiled header (/Yu). Source-level properties will
|
||||
# take precedence over target-level properties, so this will not change the generated source
|
||||
# take precedence over target-level properties, so this will not change the generated source
|
||||
# file's property to create the precompiled header (/Yc).
|
||||
target_compile_options(${target_name} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/Yu${header_name}>)
|
||||
|
||||
|
||||
# Append generated precompiled source to target's sources.
|
||||
target_sources(${target_name} PRIVATE ${pch_source_path})
|
||||
|
||||
endif(MSVC)
|
||||
endfunction()
|
||||
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ list(APPEND winml_adapter_files
|
|||
${winml_adapter_dir}/WinMLAdapter.cpp
|
||||
${winml_adapter_dir}/WinMLAdapter.h
|
||||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.cpp
|
||||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.h
|
||||
${winml_adapter_dir}/ZeroCopyInputStreamWrapper.h
|
||||
)
|
||||
|
||||
if (onnxruntime_USE_DML)
|
||||
|
|
@ -159,6 +159,7 @@ add_dependencies(winml_adapter ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
|||
target_precompiled_header(winml_adapter pch.h)
|
||||
|
||||
# Includes
|
||||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # windows machine learning generated component headers
|
||||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers
|
||||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers
|
||||
target_include_directories(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers
|
||||
|
|
@ -181,11 +182,11 @@ add_dependencies(winml_adapter winml_api_native_internal)
|
|||
# Link libraries
|
||||
target_link_libraries(winml_adapter PRIVATE wil)
|
||||
if (onnxruntime_USE_DML)
|
||||
target_link_libraries(winml_adapter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_add_dml(winml_adapter)
|
||||
endif(onnxruntime_USE_DML)
|
||||
|
||||
# add it to the onnxruntime shared library
|
||||
set(onnxruntime_winml windowsapp.lib winml_adapter)
|
||||
set(onnxruntime_winml winml_adapter)
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES winml_adapter)
|
||||
|
||||
###########################
|
||||
|
|
@ -230,6 +231,7 @@ target_compile_definitions(winml_lib_image PRIVATE _SCL_SECURE_NO_WARNINGS)
|
|||
target_precompiled_header(winml_lib_image pch.h)
|
||||
|
||||
# Includes
|
||||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # windows machine learning generated component headers
|
||||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers
|
||||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers
|
||||
target_include_directories(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers
|
||||
|
|
@ -258,7 +260,7 @@ add_dependencies(winml_lib_image winml_api_native_internal)
|
|||
# Link libraries
|
||||
target_link_libraries(winml_lib_image PRIVATE wil)
|
||||
if (onnxruntime_USE_DML)
|
||||
target_link_libraries(winml_lib_image PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_add_dml(winml_lib_image)
|
||||
endif(onnxruntime_USE_DML)
|
||||
|
||||
|
||||
|
|
@ -360,7 +362,7 @@ add_dependencies(winml_lib_api winml_api_native_internal)
|
|||
# Link libraries
|
||||
target_link_libraries(winml_lib_api PRIVATE wil)
|
||||
if (onnxruntime_USE_DML)
|
||||
target_link_libraries(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/packages/DirectML.0.0.1/build/DirectML.targets)
|
||||
target_add_dml(winml_lib_api)
|
||||
endif(onnxruntime_USE_DML)
|
||||
|
||||
|
||||
|
|
@ -438,10 +440,17 @@ if (onnxruntime_USE_DML)
|
|||
set(delayload_dml "/DELAYLOAD:directml.dll")
|
||||
endif(onnxruntime_USE_DML)
|
||||
|
||||
# The default libraries to link with in Windows are kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib
|
||||
# Remove them and use the onecore umbrella library instead
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "onecoreuap_apiset.lib")
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "onecoreuap_apiset.lib")
|
||||
foreach(default_lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdgl32.lib advapi32.lib)
|
||||
set(removed_libs "${removed_libs} /NODEFAULTLIB:${default_lib}")
|
||||
endforeach()
|
||||
set_target_properties(winml_dll
|
||||
PROPERTIES
|
||||
LINK_FLAGS
|
||||
"/DEF:${WINML_DIR}/windows.ai.machinelearning.def ${os_component_link_flags} /DELAYLOAD:d3d12.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:dxgi.dll ${delayload_dml}")
|
||||
"/DEF:${WINML_DIR}/windows.ai.machinelearning.def ${os_component_link_flags} /DELAYLOAD:d3d12.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:dxgi.dll ${delayload_dml} ${removed_libs}")
|
||||
|
||||
|
||||
set_target_properties(winml_dll
|
||||
|
|
@ -467,11 +476,10 @@ endif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
|||
target_link_libraries(winml_dll PRIVATE onnxruntime)
|
||||
target_link_libraries(winml_dll PRIVATE re2)
|
||||
target_link_libraries(winml_dll PRIVATE wil)
|
||||
#target_link_libraries(winml_dll PRIVATE windowsapp.lib)
|
||||
target_link_libraries(winml_dll PRIVATE winml_lib_api)
|
||||
target_link_libraries(winml_dll PRIVATE winml_lib_image)
|
||||
target_link_libraries(winml_dll PRIVATE winml_lib_telemetry)
|
||||
target_link_libraries(winml_dll PRIVATE onecoreuap_apiset.lib)
|
||||
target_link_libraries(winml_dll PRIVATE delayimp.lib)
|
||||
target_link_libraries(winml_dll PRIVATE ${DBGHELP})
|
||||
|
||||
# 1 of 3 projects that fail in link with 'failed to do memory mapped file I/O' (Only release)
|
||||
|
|
@ -483,6 +491,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
|||
set_target_properties(winml_dll PROPERTIES VS_GLOBAL_PreferredToolArchitecture "x64")
|
||||
endif("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
|
||||
option(onnxruntime_BUILD_WINML_TESTS "Build WinML tests" ON)
|
||||
if (onnxruntime_BUILD_WINML_TESTS)
|
||||
include(winml_unittests.cmake)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ function(target_cppwinrt
|
|||
# Get directory
|
||||
get_filename_component(idl_source_directory ${file} DIRECTORY)
|
||||
|
||||
set(target_outputs ${CMAKE_CURRENT_BINARY_DIR}/${target_name})
|
||||
set(target_outputs ${CMAKE_CURRENT_BINARY_DIR}/${target_name})
|
||||
convert_forward_slashes_to_back(${target_outputs}/comp output_dir_back_slash)
|
||||
convert_forward_slashes_to_back(${target_outputs}/temp temp_dir_back_slash)
|
||||
convert_forward_slashes_to_back(${target_outputs}/comp_generated generated_dir_back_slash)
|
||||
|
|
@ -126,50 +126,53 @@ function(target_cppwinrt
|
|||
/tlb ${tlb_filename}
|
||||
${idl_file_forward_slash}
|
||||
COMMAND
|
||||
${cppwinrt_exe} -in \"${winmd_filename}\" -comp \"${output_dir_back_slash}\" -ref \"${sdk_metadata_directory}\" -out \"${generated_dir_back_slash}\" -verbose
|
||||
${cppwinrt_exe} -in ${winmd_filename} -comp ${output_dir_back_slash} -ref ${sdk_metadata_directory} -out ${generated_dir_back_slash} -verbose
|
||||
COMMAND
|
||||
# copy the generated component files into a temporary directory where headers exclusions will be applied
|
||||
xcopy \"${output_dir_back_slash}\" \"${temp_dir_back_slash}\\\" /Y /D
|
||||
xcopy ${output_dir_back_slash} ${temp_dir_back_slash}\\ /Y /D
|
||||
COMMAND
|
||||
# for each file in the temp directory, ensure it is not in the exclusions list.
|
||||
# if it is, then we need to delete it.
|
||||
for /f %%I in ('dir /b \"${temp_dir_back_slash}\"')
|
||||
do
|
||||
(
|
||||
for /f %%E in (${CPPWINRT_COMPONENT_EXCLUSION_LIST})
|
||||
do
|
||||
(
|
||||
if %%E == %%I
|
||||
(
|
||||
del \"${temp_dir_back_slash}\\%%I\"
|
||||
)
|
||||
)
|
||||
)
|
||||
cmd /C "@echo off \
|
||||
for /f %I in ('dir /b ${temp_dir_back_slash}') \
|
||||
do \
|
||||
( \
|
||||
for /f %E in (${CPPWINRT_COMPONENT_EXCLUSION_LIST}) \
|
||||
do \
|
||||
( \
|
||||
if %E == %I \
|
||||
( \
|
||||
del ${temp_dir_back_slash}\\%I \
|
||||
) \
|
||||
) \
|
||||
)"
|
||||
COMMAND
|
||||
# for each file in the temp directory, copy the file back into the source tree
|
||||
# unless the file already exists
|
||||
for /f %%I in ('dir /b \"${temp_dir_back_slash}\"')
|
||||
do
|
||||
(
|
||||
if not exist \"${out_sources_folder}\\%%I\"
|
||||
(
|
||||
xcopy \"${temp_dir_back_slash}\\%%I\" \"${out_sources_folder}\\%%I\"
|
||||
)
|
||||
)
|
||||
cmd /C "@echo off \
|
||||
for /f %I in ('dir /b ${temp_dir_back_slash}') \
|
||||
do \
|
||||
( \
|
||||
if not exist ${out_sources_folder}\\%I \
|
||||
( \
|
||||
copy ${temp_dir_back_slash}\\%I ${out_sources_folder}\\%I \
|
||||
) \
|
||||
)"
|
||||
COMMAND
|
||||
# open the generated module.g.cpp and strip all the includes (lines) containing excluded headers
|
||||
# write the new file out to module.g.excl.cpp.
|
||||
powershell -Command \"& {
|
||||
$exclusions = get-content '${CPPWINRT_COMPONENT_EXCLUSION_LIST}'\;
|
||||
(get-content '${module_g_cpp_back_slash}')
|
||||
| where {
|
||||
$str = $_\;
|
||||
$matches = ($exclusions | where { $str -match $_ }) \;
|
||||
$matches.Length -eq 0 }
|
||||
| Out-File '${module_g_ecxl_cpp_back_slash}'
|
||||
}\"
|
||||
powershell -Command "& { \
|
||||
$exclusions = get-content '${CPPWINRT_COMPONENT_EXCLUSION_LIST}'; \
|
||||
(get-content '${module_g_cpp_back_slash}') \
|
||||
| where { \
|
||||
$str = $_; \
|
||||
$matches = ($exclusions | where { $str -match $_ }); \
|
||||
$matches.Length -eq 0 } \
|
||||
| Out-File '${module_g_ecxl_cpp_back_slash}' \
|
||||
}"
|
||||
BYPRODUCTS
|
||||
${generated_dir_back_slash}/module.g.excl.cpp
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
|
|
@ -214,4 +217,4 @@ function(add_generate_cppwinrt_sdk_headers_target
|
|||
|
||||
set_target_properties(${target_name} PROPERTIES FOLDER ${folder_name})
|
||||
endif()
|
||||
endfunction()
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# utility
|
||||
# utility
|
||||
function(convert_forward_slashes_to_back input output)
|
||||
string(REGEX REPLACE "/" "\\\\" backwards ${input})
|
||||
set(${output} ${backwards} PARENT_SCOPE)
|
||||
|
|
@ -16,7 +16,23 @@ function(get_installed_sdk
|
|||
set(${sdk_folder} ${win10_sdk_root} PARENT_SCOPE)
|
||||
|
||||
# return the sdk version
|
||||
set(${output_sdk_version} ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION} PARENT_SCOPE)
|
||||
if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
|
||||
set(${output_sdk_version} ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION} PARENT_SCOPE)
|
||||
else()
|
||||
# choose the SDK matching the system version, or fallback to the latest
|
||||
file(GLOB win10_sdks RELATIVE "${win10_sdk_root}/UnionMetadata" "${win10_sdk_root}/UnionMetadata/*.*.*.*")
|
||||
list(GET win10_sdks 0 latest_sdk)
|
||||
foreach(sdk IN LISTS win10_sdks)
|
||||
string(FIND ${sdk} ${CMAKE_SYSTEM_VERSION} is_system_version)
|
||||
if(NOT ${is_system_version} EQUAL -1)
|
||||
set(${output_sdk_version} ${sdk} PARENT_SCOPE)
|
||||
return()
|
||||
elseif(sdk VERSION_GREATER latest_sdk)
|
||||
set(latest_sdk ${sdk})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${output_sdk_version} ${latest_sdk} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# current sdk binary directory
|
||||
|
|
@ -95,7 +111,7 @@ function(get_sdk
|
|||
set(${output_sdk_version} ${winml_WINDOWS_SDK_VERSION_OVERRIDE} PARENT_SCOPE)
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
FATAL_ERROR
|
||||
"Options winml_WINDOWS_SDK_DIR_OVERRIDE and winml_WINDOWS_SDK_VERSION_OVERRIDE must be defined together, or not at all.")
|
||||
endif()
|
||||
endfunction()
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ function(add_winml_test)
|
|||
if (_UT_DEPENDS)
|
||||
add_dependencies(${_UT_TARGET} ${_UT_DEPENDS})
|
||||
endif()
|
||||
target_link_libraries(${_UT_TARGET} PRIVATE ${_UT_LIBS} gtest windowsapp winml_lib_image ${onnxruntime_EXTERNAL_LIBRARIES} winml_lib_telemetry)
|
||||
target_link_libraries(${_UT_TARGET} PRIVATE ${_UT_LIBS} gtest windowsapp winml_lib_image ${onnxruntime_EXTERNAL_LIBRARIES} winml_lib_telemetry winml_lib_api onnxruntime)
|
||||
|
||||
add_test(NAME ${_UT_TARGET}
|
||||
COMMAND ${_UT_TARGET}
|
||||
|
|
@ -69,6 +69,7 @@ add_winml_test(
|
|||
SOURCES ${winml_test_api_src}
|
||||
LIBS winml_test_common
|
||||
)
|
||||
target_compile_definitions(winml_test_api PRIVATE BUILD_GOOGLE_TEST)
|
||||
target_precompiled_header(winml_test_api testPch.h)
|
||||
|
||||
if (onnxruntime_USE_DML)
|
||||
|
|
|
|||
|
|
@ -232,12 +232,8 @@ Memory_LeakCheck::~Memory_LeakCheck() {
|
|||
_snprintf_s(buffer, _TRUNCATE, "%d bytes of memory leaked in %d allocations", leaked_bytes, leak_count);
|
||||
string.append(buffer);
|
||||
|
||||
// If we're being actively debugged, show a message box to get the dev's attention
|
||||
if (IsDebuggerPresent())
|
||||
MessageBoxA(nullptr, string.c_str(), "Warning", MB_OK | MB_ICONWARNING);
|
||||
else {
|
||||
// If we're on the command line (like on a build machine), output to the console and exit(-1)
|
||||
std::cout << "\n----- MEMORY LEAKS: " << string.c_str() << "\n";
|
||||
std::cout << "\n----- MEMORY LEAKS: " << string.c_str() << "\n";
|
||||
if (!IsDebuggerPresent()) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <d3d11on12.h>
|
||||
#include <wil/winrt.h>
|
||||
#include "inc/DeviceHelpers.h"
|
||||
#include "LearningModelDevice.h"
|
||||
|
||||
namespace DeviceHelpers {
|
||||
constexpr uint32_t c_intelVendorId = 0x8086;
|
||||
|
|
@ -133,6 +134,10 @@ static HRESULT IsFloat16Blocked(ID3D12Device& device, bool* isBlocked) {
|
|||
}
|
||||
|
||||
bool IsFloat16Supported(const winrt::Windows::AI::MachineLearning::LearningModelDevice& device) {
|
||||
auto modelImpl = device.as<winmlp::LearningModelDevice>();
|
||||
if (modelImpl->IsCpuDevice()) {
|
||||
return true;
|
||||
}
|
||||
winrt::com_ptr<ID3D12Device> d3d12Device;
|
||||
if (FAILED(GetD3D12Device(device, d3d12Device.put()))) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -5,37 +5,25 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class APITest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void LoadModel(const std::wstring& modelPath)
|
||||
{
|
||||
std::wstring fullPath = FileHelpers::GetModulePath() + modelPath;
|
||||
m_model = winrt::Windows::AI::MachineLearning::LearningModel::LoadFromFilePath(fullPath);
|
||||
}
|
||||
|
||||
winrt::Windows::AI::MachineLearning::LearningModel m_model = nullptr;
|
||||
winrt::Windows::AI::MachineLearning::LearningModelDevice m_device = nullptr;
|
||||
winrt::Windows::AI::MachineLearning::LearningModelSession m_session = nullptr;
|
||||
|
||||
uint64_t GetAdapterIdQuadPart()
|
||||
{
|
||||
LARGE_INTEGER id;
|
||||
id.LowPart = m_device.AdapterId().LowPart;
|
||||
id.HighPart = m_device.AdapterId().HighPart;
|
||||
return id.QuadPart;
|
||||
};
|
||||
|
||||
_LUID GetAdapterIdAsLUID()
|
||||
{
|
||||
_LUID id;
|
||||
id.LowPart = m_device.AdapterId().LowPart;
|
||||
id.HighPart = m_device.AdapterId().HighPart;
|
||||
return id;
|
||||
}
|
||||
|
||||
bool m_runGPUTests = true;
|
||||
#include "fileHelpers.h"
|
||||
namespace APITest {
|
||||
static void LoadModel(const std::wstring& modelPath,
|
||||
winrt::Windows::AI::MachineLearning::LearningModel& learningModel) {
|
||||
std::wstring fullPath = FileHelpers::GetModulePath() + modelPath;
|
||||
learningModel = winrt::Windows::AI::MachineLearning::LearningModel::LoadFromFilePath(fullPath);
|
||||
};
|
||||
|
||||
static uint64_t GetAdapterIdQuadPart(winrt::Windows::AI::MachineLearning::LearningModelDevice& device) {
|
||||
LARGE_INTEGER id;
|
||||
id.LowPart = device.AdapterId().LowPart;
|
||||
id.HighPart = device.AdapterId().HighPart;
|
||||
return id.QuadPart;
|
||||
};
|
||||
|
||||
static _LUID GetAdapterIdAsLUID(winrt::Windows::AI::MachineLearning::LearningModelDevice& device) {
|
||||
_LUID id;
|
||||
id.LowPart = device.AdapterId().LowPart;
|
||||
id.HighPart = device.AdapterId().HighPart;
|
||||
return id;
|
||||
}
|
||||
}; // namespace APITest
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "testPch.h"
|
||||
|
||||
#include "LearningModelAPITest.h"
|
||||
#include "APITest.h"
|
||||
|
||||
#include <winrt/Windows.Graphics.Imaging.h>
|
||||
#include <winrt/Windows.Media.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
|
@ -15,107 +14,96 @@ using namespace winrt::Windows::Media;
|
|||
using namespace winrt::Windows::Storage;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
|
||||
class LearningModelAPITest : public APITest
|
||||
{
|
||||
protected:
|
||||
LearningModelAPITest() {
|
||||
init_apartment();
|
||||
m_model = nullptr;
|
||||
m_device = nullptr;
|
||||
m_session = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class LearningModelAPITestGpu : public LearningModelAPITest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
GPUTEST
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LearningModelAPITest, CreateModelFromFilePath)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
static void LearningModelAPITestSetup() {
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, CreateModelFromIStorage)
|
||||
{
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromStorageFileAsync(storageFile).get());
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(L"onnx-caffe2", author);
|
||||
static void LearningModelAPITestGpuSetup() {
|
||||
GPUTEST;
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, CreateModelFromIStorageOutsideCwd)
|
||||
{
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"ModelSubdirectory\\ModelInSubdirectory.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromStorageFileAsync(storageFile).get());
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(L"onnx-caffe2", author);
|
||||
static void CreateModelFromFilePath() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, CreateModelFromIStream)
|
||||
{
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
winrt::Windows::Storage::Streams::IRandomAccessStreamReference streamref;
|
||||
storageFile.as(streamref);
|
||||
static void CreateModelFromIStorage() {
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStorageFileAsync(storageFile).get());
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromStreamAsync(streamref).get());
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(L"onnx-caffe2", author);
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(L"onnx-caffe2", author);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, GetAuthor)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(L"onnx-caffe2", author);
|
||||
static void CreateModelFromIStorageOutsideCwd() {
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"ModelSubdirectory\\ModelInSubdirectory.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStorageFileAsync(storageFile).get());
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(L"onnx-caffe2", author);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, GetName)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
std::wstring name(m_model.Name());
|
||||
EXPECT_EQ(L"squeezenet_old", name);
|
||||
static void CreateModelFromIStream() {
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
winrt::Windows::Storage::Streams::IRandomAccessStreamReference streamref;
|
||||
storageFile.as(streamref);
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStreamAsync(streamref).get());
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
|
||||
// check the author so we know the model was populated correctly.
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(L"onnx-caffe2", author);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, GetDomain)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
std::wstring domain(m_model.Domain());
|
||||
EXPECT_EQ(L"test-domain", domain);
|
||||
static void ModelGetAuthor() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(L"onnx-caffe2", author);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, GetDescription)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
std::wstring description(m_model.Description());
|
||||
EXPECT_EQ(L"test-doc_string", description);
|
||||
static void ModelGetName() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
std::wstring name(learningModel.Name());
|
||||
WINML_EXPECT_EQUAL(L"squeezenet_old", name);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, GetVersion)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
int64_t version(m_model.Version());
|
||||
(void)(version);
|
||||
static void ModelGetDomain() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
std::wstring domain(learningModel.Domain());
|
||||
WINML_EXPECT_EQUAL(L"test-domain", domain);
|
||||
}
|
||||
|
||||
static void ModelGetDescription() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
std::wstring description(learningModel.Description());
|
||||
WINML_EXPECT_EQUAL(L"test-doc_string", description);
|
||||
}
|
||||
|
||||
static void ModelGetVersion() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
int64_t version(learningModel.Version());
|
||||
(void)(version);
|
||||
}
|
||||
|
||||
typedef std::vector<std::pair<std::wstring, std::wstring>> Metadata;
|
||||
|
||||
/*
|
||||
class MetadataTest : public LearningModelAPITest, public testing::WithParamInterface<std::pair<std::wstring, Metadata>>
|
||||
{};
|
||||
|
||||
|
|
@ -125,16 +113,16 @@ TEST_P(MetadataTest, GetMetaData)
|
|||
std::vector<std::pair<std::wstring, std::wstring>> keyValuePairs;
|
||||
|
||||
tie(fileName, keyValuePairs) = GetParam();
|
||||
EXPECT_NO_THROW(LoadModel(fileName.c_str()));
|
||||
EXPECT_TRUE(m_model.Metadata() != nullptr);
|
||||
EXPECT_EQ(keyValuePairs.size(), m_model.Metadata().Size());
|
||||
WINML_EXPECT_NO_THROW(LoadModel(fileName.c_str()));
|
||||
WINML_EXPECT_TRUE(m_model.Metadata() != nullptr);
|
||||
WINML_EXPECT_EQUAL(keyValuePairs.size(), m_model.Metadata().Size());
|
||||
|
||||
auto iter = m_model.Metadata().First();
|
||||
for (auto& keyValue : keyValuePairs)
|
||||
{
|
||||
EXPECT_TRUE(iter.HasCurrent());
|
||||
EXPECT_EQ(keyValue.first, std::wstring(iter.Current().Key()));
|
||||
EXPECT_EQ(keyValue.second, std::wstring(iter.Current().Value()));
|
||||
WINML_EXPECT_TRUE(iter.HasCurrent());
|
||||
WINML_EXPECT_EQUAL(keyValue.first, std::wstring(iter.Current().Key()));
|
||||
WINML_EXPECT_EQUAL(keyValue.second, std::wstring(iter.Current().Value()));
|
||||
iter.MoveNext();
|
||||
}
|
||||
}
|
||||
|
|
@ -147,122 +135,141 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
std::pair(L"modelWithMetaData.onnx", Metadata{{L"thisisalongkey", L"thisisalongvalue"}}),
|
||||
std::pair(L"modelWith2MetaData.onnx", Metadata{{L"thisisalongkey", L"thisisalongvalue"}, {L"key2", L"val2"}})
|
||||
));
|
||||
*/
|
||||
|
||||
TEST_F(LearningModelAPITest, EnumerateInputs)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
static void EnumerateInputs() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
|
||||
// purposely don't cache "InputFeatures" in order to exercise calling it multiple times
|
||||
EXPECT_TRUE(m_model.InputFeatures().First().HasCurrent());
|
||||
// purposely don't cache "InputFeatures" in order to exercise calling it multiple times
|
||||
WINML_EXPECT_TRUE(learningModel.InputFeatures().First().HasCurrent());
|
||||
|
||||
std::wstring name(m_model.InputFeatures().First().Current().Name());
|
||||
EXPECT_EQ(L"data_0", name);
|
||||
std::wstring name(learningModel.InputFeatures().First().Current().Name());
|
||||
WINML_EXPECT_EQUAL(L"data_0", name);
|
||||
|
||||
// make sure it's either tensor or image
|
||||
TensorFeatureDescriptor tensorDescriptor = nullptr;
|
||||
m_model.InputFeatures().First().Current().try_as(tensorDescriptor);
|
||||
if (tensorDescriptor == nullptr)
|
||||
{
|
||||
ImageFeatureDescriptor imageDescriptor = nullptr;
|
||||
EXPECT_NO_THROW(m_model.InputFeatures().First().Current().as(imageDescriptor));
|
||||
}
|
||||
// make sure it's either tensor or image
|
||||
TensorFeatureDescriptor tensorDescriptor = nullptr;
|
||||
learningModel.InputFeatures().First().Current().try_as(tensorDescriptor);
|
||||
if (tensorDescriptor == nullptr) {
|
||||
ImageFeatureDescriptor imageDescriptor = nullptr;
|
||||
WINML_EXPECT_NO_THROW(learningModel.InputFeatures().First().Current().as(imageDescriptor));
|
||||
}
|
||||
|
||||
auto modelDataKind = tensorDescriptor.TensorKind();
|
||||
EXPECT_EQ(TensorKind::Float, modelDataKind);
|
||||
auto modelDataKind = tensorDescriptor.TensorKind();
|
||||
WINML_EXPECT_EQUAL(TensorKind::Float, modelDataKind);
|
||||
|
||||
EXPECT_TRUE(tensorDescriptor.IsRequired());
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.IsRequired());
|
||||
|
||||
std::vector<int64_t> expectedShapes = { 1,3,224,224 };
|
||||
EXPECT_EQ(expectedShapes.size(), tensorDescriptor.Shape().Size());
|
||||
for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++)
|
||||
{
|
||||
EXPECT_EQ(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j));
|
||||
}
|
||||
std::vector<int64_t> expectedShapes = {1, 3, 224, 224};
|
||||
WINML_EXPECT_EQUAL(expectedShapes.size(), tensorDescriptor.Shape().Size());
|
||||
for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) {
|
||||
WINML_EXPECT_EQUAL(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j));
|
||||
}
|
||||
|
||||
auto first = m_model.InputFeatures().First();
|
||||
first.MoveNext();
|
||||
EXPECT_FALSE(first.HasCurrent());
|
||||
auto first = learningModel.InputFeatures().First();
|
||||
first.MoveNext();
|
||||
WINML_EXPECT_FALSE(first.HasCurrent());
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, EnumerateOutputs)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
static void EnumerateOutputs() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
|
||||
// purposely don't cache "OutputFeatures" in order to exercise calling it multiple times
|
||||
std::wstring name(m_model.OutputFeatures().First().Current().Name());
|
||||
EXPECT_EQ(L"softmaxout_1", name);
|
||||
// purposely don't cache "OutputFeatures" in order to exercise calling it multiple times
|
||||
std::wstring name(learningModel.OutputFeatures().First().Current().Name());
|
||||
WINML_EXPECT_EQUAL(L"softmaxout_1", name);
|
||||
|
||||
TensorFeatureDescriptor tensorDescriptor = nullptr;
|
||||
EXPECT_NO_THROW(m_model.OutputFeatures().First().Current().as(tensorDescriptor));
|
||||
EXPECT_TRUE(tensorDescriptor != nullptr);
|
||||
TensorFeatureDescriptor tensorDescriptor = nullptr;
|
||||
WINML_EXPECT_NO_THROW(learningModel.OutputFeatures().First().Current().as(tensorDescriptor));
|
||||
WINML_EXPECT_TRUE(tensorDescriptor != nullptr);
|
||||
|
||||
auto tensorName = tensorDescriptor.Name();
|
||||
EXPECT_EQ(L"softmaxout_1", tensorName);
|
||||
auto tensorName = tensorDescriptor.Name();
|
||||
WINML_EXPECT_EQUAL(L"softmaxout_1", tensorName);
|
||||
|
||||
auto modelDataKind = tensorDescriptor.TensorKind();
|
||||
EXPECT_EQ(TensorKind::Float, modelDataKind);
|
||||
auto modelDataKind = tensorDescriptor.TensorKind();
|
||||
WINML_EXPECT_EQUAL(TensorKind::Float, modelDataKind);
|
||||
|
||||
EXPECT_TRUE(tensorDescriptor.IsRequired());
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.IsRequired());
|
||||
|
||||
std::vector<int64_t> expectedShapes = { 1, 1000, 1, 1 };
|
||||
EXPECT_EQ(expectedShapes.size(), tensorDescriptor.Shape().Size());
|
||||
for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++)
|
||||
{
|
||||
EXPECT_EQ(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j));
|
||||
}
|
||||
std::vector<int64_t> expectedShapes = {1, 1000, 1, 1};
|
||||
WINML_EXPECT_EQUAL(expectedShapes.size(), tensorDescriptor.Shape().Size());
|
||||
for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) {
|
||||
WINML_EXPECT_EQUAL(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j));
|
||||
}
|
||||
|
||||
auto first = m_model.OutputFeatures().First();
|
||||
first.MoveNext();
|
||||
EXPECT_FALSE(first.HasCurrent());
|
||||
auto first = learningModel.OutputFeatures().First();
|
||||
first.MoveNext();
|
||||
WINML_EXPECT_FALSE(first.HasCurrent());
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, CloseModelCheckMetadata)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx"));
|
||||
EXPECT_NO_THROW(m_model.Close());
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(L"onnx-caffe2", author);
|
||||
std::wstring name(m_model.Name());
|
||||
EXPECT_EQ(L"squeezenet_old", name);
|
||||
std::wstring domain(m_model.Domain());
|
||||
EXPECT_EQ(L"test-domain", domain);
|
||||
std::wstring description(m_model.Description());
|
||||
EXPECT_EQ(L"test-doc_string", description);
|
||||
int64_t version(m_model.Version());
|
||||
EXPECT_EQ(123456, version);
|
||||
static void CloseModelCheckMetadata() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel));
|
||||
WINML_EXPECT_NO_THROW(learningModel.Close());
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(L"onnx-caffe2", author);
|
||||
std::wstring name(learningModel.Name());
|
||||
WINML_EXPECT_EQUAL(L"squeezenet_old", name);
|
||||
std::wstring domain(learningModel.Domain());
|
||||
WINML_EXPECT_EQUAL(L"test-domain", domain);
|
||||
std::wstring description(learningModel.Description());
|
||||
WINML_EXPECT_EQUAL(L"test-doc_string", description);
|
||||
int64_t version(learningModel.Version());
|
||||
WINML_EXPECT_EQUAL(123456, version);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITestGpu, CloseModelCheckEval)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModelSession session = nullptr;
|
||||
EXPECT_NO_THROW(session = LearningModelSession(m_model));
|
||||
EXPECT_NO_THROW(m_model.Close());
|
||||
static void CloseModelCheckEval() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
LearningModelSession session = nullptr;
|
||||
WINML_EXPECT_NO_THROW(session = LearningModelSession(learningModel));
|
||||
WINML_EXPECT_NO_THROW(learningModel.Close());
|
||||
|
||||
std::wstring fullImagePath = FileHelpers::GetModulePath() + L"kitten_224.png";
|
||||
StorageFile imagefile = StorageFile::GetFileFromPathAsync(fullImagePath).get();
|
||||
IRandomAccessStream stream = imagefile.OpenAsync(FileAccessMode::Read).get();
|
||||
SoftwareBitmap softwareBitmap = (BitmapDecoder::CreateAsync(stream).get()).GetSoftwareBitmapAsync().get();
|
||||
VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
|
||||
std::wstring fullImagePath = FileHelpers::GetModulePath() + L"kitten_224.png";
|
||||
StorageFile imagefile = StorageFile::GetFileFromPathAsync(fullImagePath).get();
|
||||
IRandomAccessStream stream = imagefile.OpenAsync(FileAccessMode::Read).get();
|
||||
SoftwareBitmap softwareBitmap = (BitmapDecoder::CreateAsync(stream).get()).GetSoftwareBitmapAsync().get();
|
||||
VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
|
||||
|
||||
LearningModelBinding binding = nullptr;
|
||||
EXPECT_NO_THROW(binding = LearningModelBinding(session));
|
||||
EXPECT_NO_THROW(binding.Bind(m_model.InputFeatures().First().Current().Name(), frame));
|
||||
LearningModelBinding binding = nullptr;
|
||||
WINML_EXPECT_NO_THROW(binding = LearningModelBinding(session));
|
||||
WINML_EXPECT_NO_THROW(binding.Bind(learningModel.InputFeatures().First().Current().Name(), frame));
|
||||
|
||||
EXPECT_NO_THROW(session.Evaluate(binding, L""));
|
||||
WINML_EXPECT_NO_THROW(session.Evaluate(binding, L""));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelAPITest, CloseModelNoNewSessions)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
EXPECT_NO_THROW(m_model.Close());
|
||||
LearningModelSession session = nullptr;
|
||||
EXPECT_THROW(
|
||||
try {
|
||||
session = LearningModelSession(m_model);
|
||||
} catch (const winrt::hresult_error& e) {
|
||||
EXPECT_EQ(E_INVALIDARG, e.code());
|
||||
throw;
|
||||
}
|
||||
, winrt::hresult_error);
|
||||
static void CloseModelNoNewSessions() {
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
WINML_EXPECT_NO_THROW(learningModel.Close());
|
||||
LearningModelSession session = nullptr;
|
||||
WINML_EXPECT_THROW_SPECIFIC(
|
||||
session = LearningModelSession(learningModel);,
|
||||
winrt::hresult_error,
|
||||
[](const winrt::hresult_error& e) -> bool {
|
||||
return e.code() == E_INVALIDARG;
|
||||
});
|
||||
}
|
||||
|
||||
const LearningModelApiTestApi& getapi() {
|
||||
static constexpr LearningModelApiTestApi api =
|
||||
{
|
||||
LearningModelAPITestSetup,
|
||||
LearningModelAPITestGpuSetup,
|
||||
CreateModelFromFilePath,
|
||||
CreateModelFromIStorage,
|
||||
CreateModelFromIStorageOutsideCwd,
|
||||
CreateModelFromIStream,
|
||||
ModelGetAuthor,
|
||||
ModelGetName,
|
||||
ModelGetDomain,
|
||||
ModelGetDescription,
|
||||
ModelGetVersion,
|
||||
EnumerateInputs,
|
||||
EnumerateOutputs,
|
||||
CloseModelCheckMetadata,
|
||||
CloseModelCheckEval,
|
||||
CloseModelNoNewSessions
|
||||
};
|
||||
return api;
|
||||
}
|
||||
41
winml/test/api/LearningModelAPITest.h
Normal file
41
winml/test/api/LearningModelAPITest.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "test.h"
|
||||
struct LearningModelApiTestApi
|
||||
{
|
||||
SetupTest LearningModelAPITestSetup;
|
||||
SetupTest LearningModelAPITestGpuSetup;
|
||||
VoidTest CreateModelFromFilePath;
|
||||
VoidTest CreateModelFromIStorage;
|
||||
VoidTest CreateModelFromIStorageOutsideCwd;
|
||||
VoidTest CreateModelFromIStream;
|
||||
VoidTest ModelGetAuthor;
|
||||
VoidTest ModelGetName;
|
||||
VoidTest ModelGetDomain;
|
||||
VoidTest ModelGetDescription;
|
||||
VoidTest ModelGetVersion;
|
||||
VoidTest EnumerateInputs;
|
||||
VoidTest EnumerateOutputs;
|
||||
VoidTest CloseModelCheckMetadata;
|
||||
VoidTest CloseModelCheckEval;
|
||||
VoidTest CloseModelNoNewSessions;
|
||||
};
|
||||
const LearningModelApiTestApi& getapi();
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelAPITest, LearningModelAPITestSetup)
|
||||
WINML_TEST(LearningModelAPITest, CreateModelFromFilePath)
|
||||
WINML_TEST(LearningModelAPITest, CreateModelFromIStorage)
|
||||
WINML_TEST(LearningModelAPITest, CreateModelFromIStorageOutsideCwd)
|
||||
WINML_TEST(LearningModelAPITest, CreateModelFromIStream)
|
||||
WINML_TEST(LearningModelAPITest, ModelGetAuthor)
|
||||
WINML_TEST(LearningModelAPITest, ModelGetName)
|
||||
WINML_TEST(LearningModelAPITest, ModelGetDomain)
|
||||
WINML_TEST(LearningModelAPITest, ModelGetDescription)
|
||||
WINML_TEST(LearningModelAPITest, ModelGetVersion)
|
||||
WINML_TEST(LearningModelAPITest, EnumerateInputs)
|
||||
WINML_TEST(LearningModelAPITest, EnumerateOutputs)
|
||||
WINML_TEST(LearningModelAPITest, CloseModelCheckMetadata)
|
||||
WINML_TEST(LearningModelAPITest, CloseModelNoNewSessions)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelAPITestGpu, LearningModelAPITestGpuSetup)
|
||||
WINML_TEST(LearningModelAPITestGpu, CloseModelCheckEval)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
#include "testPch.h"
|
||||
|
||||
#include "APITest.h"
|
||||
#include "LearningModelBindingAPITest.h"
|
||||
#include "SqueezeNetValidator.h"
|
||||
|
||||
#include <winrt/Windows.Graphics.Imaging.h>
|
||||
#include <winrt/Windows.Media.h>
|
||||
#include "winrt/Windows.Storage.h"
|
||||
#include "DeviceHelpers.h"
|
||||
|
||||
#include <sstream>
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::AI::MachineLearning;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
|
@ -15,25 +16,22 @@ using namespace winrt::Windows::Graphics::Imaging;
|
|||
using namespace winrt::Windows::Media;
|
||||
using namespace winrt::Windows::Storage;
|
||||
|
||||
class LearningModelBindingAPITest : public APITest
|
||||
{};
|
||||
static void LearningModelBindingAPITestSetup() {
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
class LearningModelBindingAPITestGpu : public LearningModelBindingAPITest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
GPUTEST
|
||||
}
|
||||
};
|
||||
static void LearningModelBindingAPITestGpuSetup() {
|
||||
GPUTEST;
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, CpuSqueezeNet)
|
||||
static void CpuSqueezeNet()
|
||||
{
|
||||
std::string cpuInstance("CPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(cpuInstance, LearningModelDeviceKind::Cpu, /*dataTolerance*/ 0.00001f, false);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs)
|
||||
static void CpuSqueezeNetEmptyOutputs()
|
||||
{
|
||||
std::string cpuInstance("CPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -44,7 +42,7 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs)
|
|||
OutputBindingStrategy::Empty);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs)
|
||||
static void CpuSqueezeNetUnboundOutputs()
|
||||
{
|
||||
std::string cpuInstance("CPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -55,7 +53,7 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs)
|
|||
OutputBindingStrategy::Unbound);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable)
|
||||
static void CpuSqueezeNetBindInputTensorAsInspectable()
|
||||
{
|
||||
std::string cpuInstance("CPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -67,27 +65,28 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable)
|
|||
true /* bind inputs as inspectables */);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, CastMapInt64)
|
||||
static void CastMapInt64()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"castmap-int64.onnx"));
|
||||
WINML_EXPECT_NO_THROW(LearningModel::LoadFromFilePath(FileHelpers::GetModulePath() + L"castmap-int64.onnx"));
|
||||
// TODO: Check Descriptor
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapInt64)
|
||||
static void DictionaryVectorizerMapInt64()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"dictvectorizer-int64.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-int64.onnx", learningModel));
|
||||
|
||||
auto inputDescriptor = m_model.InputFeatures().First().Current();
|
||||
EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map);
|
||||
auto inputDescriptor = learningModel.InputFeatures().First().Current();
|
||||
WINML_EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map);
|
||||
auto mapDescriptor = inputDescriptor.as<MapFeatureDescriptor>();
|
||||
EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64);
|
||||
EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
auto tensorDescriptor = mapDescriptor.ValueDescriptor().as<TensorFeatureDescriptor>();
|
||||
// empty size means tensor of scalar value
|
||||
EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0);
|
||||
EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
|
||||
LearningModelSession modelSession(m_model);
|
||||
LearningModelSession modelSession(learningModel);
|
||||
LearningModelBinding binding(modelSession);
|
||||
std::unordered_map<int64_t, float> map;
|
||||
map[1] = 1.f;
|
||||
|
|
@ -102,38 +101,39 @@ TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapInt64)
|
|||
binding.Bind(mapInputName, abiMap);
|
||||
auto mapInputInspectable = abiMap.as<winrt::Windows::Foundation::IInspectable>();
|
||||
auto first = binding.First();
|
||||
EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
EXPECT_TRUE(first.Current().Value() == mapInputInspectable);
|
||||
EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable);
|
||||
WINML_EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
WINML_EXPECT_TRUE(first.Current().Value() == mapInputInspectable);
|
||||
WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable);
|
||||
|
||||
// Bind as IMapView
|
||||
auto mapView = abiMap.GetView();
|
||||
binding.Bind(mapInputName, mapView);
|
||||
mapInputInspectable = mapView.as<winrt::Windows::Foundation::IInspectable>();
|
||||
first = binding.First();
|
||||
EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
EXPECT_TRUE(first.Current().Value() == mapView);
|
||||
EXPECT_TRUE(binding.Lookup(mapInputName) == mapView);
|
||||
WINML_EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
WINML_EXPECT_TRUE(first.Current().Value() == mapView);
|
||||
WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapView);
|
||||
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapString)
|
||||
static void DictionaryVectorizerMapString()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"dictvectorizer-string.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-string.onnx", learningModel));
|
||||
|
||||
auto inputDescriptor = m_model.InputFeatures().First().Current();
|
||||
EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map);
|
||||
auto inputDescriptor = learningModel.InputFeatures().First().Current();
|
||||
WINML_EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map);
|
||||
|
||||
auto mapDescriptor = inputDescriptor.as<MapFeatureDescriptor>();
|
||||
EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String);
|
||||
EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
|
||||
auto tensorDescriptor = mapDescriptor.ValueDescriptor().as<TensorFeatureDescriptor>();
|
||||
// empty size means tensor of scalar value
|
||||
EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0);
|
||||
EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
|
||||
LearningModelSession modelSession(m_model);
|
||||
LearningModelSession modelSession(learningModel);
|
||||
LearningModelBinding binding(modelSession);
|
||||
std::unordered_map<winrt::hstring, float> map;
|
||||
map[L"1"] = 1.f;
|
||||
|
|
@ -146,9 +146,9 @@ TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapString)
|
|||
|
||||
auto mapInputInspectable = abiMap.as<winrt::Windows::Foundation::IInspectable>();
|
||||
auto first = binding.First();
|
||||
EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
EXPECT_TRUE(first.Current().Value() == mapInputInspectable);
|
||||
EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable);
|
||||
WINML_EXPECT_TRUE(first.Current().Key() == mapInputName);
|
||||
WINML_EXPECT_TRUE(first.Current().Value() == mapInputInspectable);
|
||||
WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable);
|
||||
}
|
||||
|
||||
static void RunZipMapInt64(
|
||||
|
|
@ -157,15 +157,15 @@ static void RunZipMapInt64(
|
|||
{
|
||||
auto outputFeatures = model.OutputFeatures();
|
||||
auto outputDescriptor = outputFeatures.First().Current();
|
||||
EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence);
|
||||
WINML_EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence);
|
||||
|
||||
auto seqDescriptor = outputDescriptor.as<SequenceFeatureDescriptor>();
|
||||
auto mapDescriptor = seqDescriptor.ElementDescriptor().as<MapFeatureDescriptor>();
|
||||
EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64);
|
||||
|
||||
EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
auto tensorDescriptor = mapDescriptor.ValueDescriptor().as<TensorFeatureDescriptor>();
|
||||
EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
|
||||
LearningModelSession session(model);
|
||||
LearningModelBinding binding(session);
|
||||
|
|
@ -199,63 +199,66 @@ static void RunZipMapInt64(
|
|||
// from output binding
|
||||
const auto &out1 = abiOutput.GetAt(0);
|
||||
const auto &out2 = result.Lookup(L"Y").as<IVectorView<ABIMap>>().GetAt(0);
|
||||
SCOPED_TRACE((std::ostringstream() << "size: " << out1.Size()).str());
|
||||
WINML_LOG_COMMENT((std::ostringstream() << "size: " << out1.Size()).str());
|
||||
// check outputs
|
||||
auto iter1 = out1.First();
|
||||
auto iter2 = out2.First();
|
||||
for (uint32_t i = 0, size = (uint32_t)inputs.size(); i < size; ++i)
|
||||
{
|
||||
EXPECT_TRUE(iter1.HasCurrent());
|
||||
EXPECT_TRUE(iter2.HasCurrent());
|
||||
WINML_EXPECT_TRUE(iter1.HasCurrent());
|
||||
WINML_EXPECT_TRUE(iter2.HasCurrent());
|
||||
const auto &pair1 = iter1.Current();
|
||||
const auto &pair2 = iter2.Current();
|
||||
SCOPED_TRACE((std::ostringstream() << "key: " << pair1.Key() << ", value: " << pair2.Value()).str());
|
||||
EXPECT_TRUE(pair1.Key() == i && pair2.Key() == i);
|
||||
EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]);
|
||||
WINML_LOG_COMMENT((std::ostringstream() << "key: " << pair1.Key() << ", value: " << pair2.Value()).str());
|
||||
WINML_EXPECT_TRUE(pair1.Key() == i && pair2.Key() == i);
|
||||
WINML_EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]);
|
||||
iter1.MoveNext();
|
||||
iter2.MoveNext();
|
||||
}
|
||||
EXPECT_TRUE(!iter1.HasCurrent());
|
||||
EXPECT_TRUE(!iter2.HasCurrent());
|
||||
WINML_EXPECT_TRUE(!iter1.HasCurrent());
|
||||
WINML_EXPECT_TRUE(!iter2.HasCurrent());
|
||||
}
|
||||
else
|
||||
{
|
||||
abiOutput = result.Lookup(L"Y").as<ABISequeneceOfMap>();
|
||||
EXPECT_TRUE(abiOutput.Size() == 1);
|
||||
WINML_EXPECT_TRUE(abiOutput.Size() == 1);
|
||||
ABIMap map = abiOutput.GetAt(0);
|
||||
EXPECT_TRUE(map.Size() == 3);
|
||||
EXPECT_TRUE(map.Lookup(0) == 0.5);
|
||||
EXPECT_TRUE(map.Lookup(1) == .25);
|
||||
EXPECT_TRUE(map.Lookup(2) == .125);
|
||||
WINML_EXPECT_TRUE(map.Size() == 3);
|
||||
WINML_EXPECT_TRUE(map.Lookup(0) == 0.5);
|
||||
WINML_EXPECT_TRUE(map.Lookup(1) == .25);
|
||||
WINML_EXPECT_TRUE(map.Lookup(2) == .125);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, ZipMapInt64)
|
||||
static void ZipMapInt64()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx"));
|
||||
RunZipMapInt64(m_model, OutputBindingStrategy::Bound);
|
||||
LearningModel learningModel= nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel));
|
||||
RunZipMapInt64(learningModel, OutputBindingStrategy::Bound);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, ZipMapInt64Unbound)
|
||||
static void ZipMapInt64Unbound()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx"));
|
||||
RunZipMapInt64(m_model, OutputBindingStrategy::Unbound);
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel));
|
||||
RunZipMapInt64(learningModel, OutputBindingStrategy::Unbound);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, ZipMapString)
|
||||
static void ZipMapString()
|
||||
{
|
||||
// output constraint: "seq(map(string, float))" or "seq(map(int64, float))"
|
||||
EXPECT_NO_THROW(LoadModel(L"zipmap-string.onnx"));
|
||||
auto outputs = m_model.OutputFeatures();
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-string.onnx", learningModel));
|
||||
auto outputs = learningModel.OutputFeatures();
|
||||
auto outputDescriptor = outputs.First().Current();
|
||||
EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence);
|
||||
WINML_EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence);
|
||||
auto mapDescriptor = outputDescriptor.as<SequenceFeatureDescriptor>().ElementDescriptor().as<MapFeatureDescriptor>();
|
||||
EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String);
|
||||
EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String);
|
||||
WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor);
|
||||
auto tensorDescriptor = mapDescriptor.ValueDescriptor().as<TensorFeatureDescriptor>();
|
||||
EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float);
|
||||
|
||||
LearningModelSession session(m_model);
|
||||
LearningModelSession session(learningModel);
|
||||
LearningModelBinding binding(session);
|
||||
|
||||
std::vector<float> inputs = { 0.5f, 0.25f, 0.125f };
|
||||
|
|
@ -274,27 +277,27 @@ TEST_F(LearningModelBindingAPITest, ZipMapString)
|
|||
// from output binding
|
||||
const auto &out1 = ABIOutput.GetAt(0);
|
||||
const auto &out2 = result.Lookup(L"Y").as<IVectorView<ABIMap>>().GetAt(0);
|
||||
SCOPED_TRACE((std::ostringstream() << "size: " << out1.Size()).str());
|
||||
WINML_LOG_COMMENT((std::ostringstream() << "size: " << out1.Size()).str());
|
||||
// single key,value pair for each map
|
||||
auto iter1 = out1.First();
|
||||
auto iter2 = out2.First();
|
||||
for (uint32_t i = 0, size = (uint32_t)inputs.size(); i < size; ++i)
|
||||
{
|
||||
EXPECT_TRUE(iter2.HasCurrent());
|
||||
WINML_EXPECT_TRUE(iter2.HasCurrent());
|
||||
const auto &pair1 = iter1.Current();
|
||||
const auto &pair2 = iter2.Current();
|
||||
SCOPED_TRACE((std::ostringstream() << "key: " << pair1.Key().c_str() << ", value " << pair2.Value()).str());
|
||||
EXPECT_TRUE(std::wstring(pair1.Key().c_str()).compare(labels[i]) == 0);
|
||||
EXPECT_TRUE(std::wstring(pair2.Key().c_str()).compare(labels[i]) == 0);
|
||||
EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]);
|
||||
WINML_LOG_COMMENT((std::ostringstream() << "key: " << pair1.Key().c_str() << ", value " << pair2.Value()).str());
|
||||
WINML_EXPECT_TRUE(std::wstring(pair1.Key().c_str()).compare(labels[i]) == 0);
|
||||
WINML_EXPECT_TRUE(std::wstring(pair2.Key().c_str()).compare(labels[i]) == 0);
|
||||
WINML_EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]);
|
||||
iter1.MoveNext();
|
||||
iter2.MoveNext();
|
||||
}
|
||||
EXPECT_TRUE(!iter1.HasCurrent());
|
||||
EXPECT_TRUE(!iter2.HasCurrent());
|
||||
WINML_EXPECT_TRUE(!iter1.HasCurrent());
|
||||
WINML_EXPECT_TRUE(!iter2.HasCurrent());
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNet)
|
||||
static void GpuSqueezeNet()
|
||||
{
|
||||
std::string gpuInstance("GPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -303,7 +306,7 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNet)
|
|||
/*dataTolerance*/ 0.00001f);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs)
|
||||
static void GpuSqueezeNetEmptyOutputs()
|
||||
{
|
||||
std::string gpuInstance("GPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -314,7 +317,7 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs)
|
|||
OutputBindingStrategy::Empty);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs)
|
||||
static void GpuSqueezeNetUnboundOutputs()
|
||||
{
|
||||
std::string gpuInstance("GPU");
|
||||
WinML::Engine::Test::ModelValidator::SqueezeNet(
|
||||
|
|
@ -326,44 +329,48 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs)
|
|||
}
|
||||
|
||||
// Validates that when the input image is the same as the model expects, the binding step is executed correctly.
|
||||
TEST_F(LearningModelBindingAPITestGpu, ImageBindingDimensions)
|
||||
static void ImageBindingDimensions()
|
||||
{
|
||||
LearningModelBinding m_binding = nullptr;
|
||||
LearningModelBinding learningModelBinding = nullptr;
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelSession learningModelSession = nullptr;
|
||||
LearningModelDevice leraningModelDevice = nullptr;
|
||||
std::wstring filePath = FileHelpers::GetModulePath() + L"model.onnx";
|
||||
// load a model with expected input size: 224 x 224
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(filePath));
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session));
|
||||
WINML_EXPECT_NO_THROW(leraningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(filePath));
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, leraningModelDevice));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession));
|
||||
|
||||
// Create input images and execute bind
|
||||
// Test Case 1: both width and height are larger than model expects
|
||||
VideoFrame inputImage1(BitmapPixelFormat::Rgba8, 1000, 1000);
|
||||
ImageFeatureValue inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage1);
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor));
|
||||
|
||||
// Test Case 2: only height is larger, while width is smaller
|
||||
VideoFrame inputImage2(BitmapPixelFormat::Rgba8, 20, 1000);
|
||||
inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage2);
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor));
|
||||
|
||||
// Test Case 3: only width is larger, while height is smaller
|
||||
VideoFrame inputImage3(BitmapPixelFormat::Rgba8, 1000, 20);
|
||||
inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage3);
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor));
|
||||
|
||||
// Test Case 4: both width and height are smaller than model expects
|
||||
VideoFrame inputImage4(BitmapPixelFormat::Rgba8, 20, 20);
|
||||
inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage4);
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions)
|
||||
static void VerifyInvalidBindExceptions()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel));
|
||||
|
||||
LearningModelSession session(m_model);
|
||||
LearningModelSession session(learningModel);
|
||||
LearningModelBinding binding(session);
|
||||
|
||||
std::vector<float> inputs = { 0.5f, 0.25f, 0.125f };
|
||||
|
|
@ -384,47 +391,47 @@ TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions)
|
|||
|
||||
// Bind invalid image as tensorfloat input
|
||||
auto image = FileHelpers::LoadImageFeatureValue(L"227x227.png");
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"X", image), winrt::hresult_error, ensureWinmlSizeMismatch);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", image), winrt::hresult_error, ensureWinmlSizeMismatch);
|
||||
|
||||
// Bind invalid map as tensorfloat input
|
||||
std::unordered_map<float, float> map;
|
||||
auto abiMap = winrt::single_threaded_map(std::move(map));
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid sequence as tensorfloat input
|
||||
std::vector<uint32_t> sequence;
|
||||
auto abiSequence = winrt::single_threaded_vector(std::move(sequence));
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid tensor size as tensorfloat input
|
||||
auto tensorBoolean = TensorBoolean::Create();
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid tensor shape as tensorfloat input
|
||||
auto tensorInvalidShape = TensorFloat::Create(std::vector<int64_t> { 2, 3, 4 });
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
/*
|
||||
Verify sequence bindings throw correct bind exceptions
|
||||
*/
|
||||
|
||||
// Bind invalid image as sequence<map<int, float> output
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", image), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", image), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid map as sequence<map<int, float> output
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid sequence<int> as sequence<map<int, float> output
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid tensor as sequence<map<int, float> output
|
||||
EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
/*
|
||||
Verify image bindings throw correct bind exceptions
|
||||
*/
|
||||
|
||||
// EXPECT_NO_THROW(LoadModel(L"fns-candy.onnx"));
|
||||
// WINML_EXPECT_NO_THROW(LoadModel(L"fns-candy.onnx"));
|
||||
|
||||
// LearningModelSession imageSession(m_model);
|
||||
// LearningModelBinding imageBinding(imageSession);
|
||||
|
|
@ -432,74 +439,77 @@ TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions)
|
|||
// auto inputName = m_model.InputFeatures().First().Current().Name();
|
||||
|
||||
// // Bind invalid map as image input
|
||||
// EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
// WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// // Bind invalid sequence as image input
|
||||
// EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
// WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// // Bind invalid tensor type as image input
|
||||
// EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
// WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// // Bind invalid tensor size as image input
|
||||
// auto tensorFloat = TensorFloat::Create(std::vector<int64_t> { 1, 1, 100, 100 });
|
||||
// EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorFloat), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
// WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorFloat), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// // Bind invalid tensor shape as image input
|
||||
// EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
// WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
/*
|
||||
Verify map bindings throw correct bind exceptions
|
||||
*/
|
||||
EXPECT_NO_THROW(LoadModel(L"dictvectorizer-int64.onnx"));
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-int64.onnx", learningModel));
|
||||
|
||||
LearningModelSession mapSession(m_model);
|
||||
LearningModelSession mapSession(learningModel);
|
||||
LearningModelBinding mapBinding(mapSession);
|
||||
|
||||
auto inputName = m_model.InputFeatures().First().Current().Name();
|
||||
auto inputName = learningModel.InputFeatures().First().Current().Name();
|
||||
|
||||
// Bind invalid image as image input
|
||||
auto smallImage = FileHelpers::LoadImageFeatureValue(L"100x100.png");
|
||||
EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, smallImage), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, smallImage), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid map as image input
|
||||
EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid sequence as image input
|
||||
EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
|
||||
// Bind invalid tensor type as image input
|
||||
EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding);
|
||||
}
|
||||
|
||||
// Verify that it throws an error when binding an invalid name.
|
||||
TEST_F(LearningModelBindingAPITestGpu, BindInvalidInputName)
|
||||
static void BindInvalidInputName()
|
||||
{
|
||||
LearningModelBinding m_binding = nullptr;
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelBinding learningModelBinding = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
LearningModelSession learningModelSession = nullptr;
|
||||
std::wstring modelPath = FileHelpers::GetModulePath() + L"Add_ImageNet1920.onnx";
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(modelPath));
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session));
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(modelPath));
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession));
|
||||
|
||||
VideoFrame iuputImage(BitmapPixelFormat::Rgba8, 1920, 1080);
|
||||
ImageFeatureValue inputTensor = ImageFeatureValue::CreateFromVideoFrame(iuputImage);
|
||||
|
||||
auto first = m_model.InputFeatures().First();
|
||||
auto first = learningModel.InputFeatures().First();
|
||||
std::wstring testInvalidName = L"0";
|
||||
|
||||
// Verify that testInvalidName is not in model's InputFeatures
|
||||
while (first.HasCurrent())
|
||||
{
|
||||
EXPECT_NE(testInvalidName, first.Current().Name());
|
||||
WINML_EXPECT_NOT_EQUAL(testInvalidName, first.Current().Name());
|
||||
first.MoveNext();
|
||||
}
|
||||
|
||||
// Bind inputTensor to a valid input name
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"input_39:0", inputTensor));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"input_39:0", inputTensor));
|
||||
|
||||
// Bind inputTensor to an invalid input name
|
||||
EXPECT_THROW_SPECIFIC(m_binding.Bind(testInvalidName, inputTensor),
|
||||
WINML_EXPECT_THROW_SPECIFIC(learningModelBinding.Bind(testInvalidName, inputTensor),
|
||||
winrt::hresult_error,
|
||||
[](const winrt::hresult_error& e) -> bool
|
||||
{
|
||||
|
|
@ -507,15 +517,18 @@ TEST_F(LearningModelBindingAPITestGpu, BindInvalidInputName)
|
|||
});
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice)
|
||||
static void VerifyOutputAfterEvaluateAsyncCalledTwice()
|
||||
{
|
||||
LearningModelBinding m_binding = nullptr;
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelBinding learningModelBinding = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
LearningModelSession learningModelSession = nullptr;
|
||||
std::wstring filePath = FileHelpers::GetModulePath() + L"relu.onnx";
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(filePath));
|
||||
EXPECT_TRUE(m_model != nullptr);
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session));
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(filePath));
|
||||
WINML_EXPECT_TRUE(learningModel != nullptr);
|
||||
WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession));
|
||||
|
||||
auto inputShape = std::vector<int64_t>{ 5 };
|
||||
auto inputData1 = std::vector<float>{ -50.f, -25.f, 0.f, 25.f, 50.f };
|
||||
|
|
@ -530,22 +543,22 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice)
|
|||
inputShape,
|
||||
single_threaded_vector<float>(std::move(inputData2)).GetView());
|
||||
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"X", inputValue1));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"X", inputValue1));
|
||||
|
||||
auto outputValue = TensorFloat::Create();
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"Y", outputValue));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"Y", outputValue));
|
||||
|
||||
EXPECT_NO_THROW(m_session.Evaluate(m_binding, L""));
|
||||
WINML_EXPECT_NO_THROW(learningModelSession.Evaluate(learningModelBinding, L""));
|
||||
|
||||
auto buffer1 = outputValue.GetAsVectorView();
|
||||
EXPECT_TRUE(buffer1 != nullptr);
|
||||
WINML_EXPECT_TRUE(buffer1 != nullptr);
|
||||
|
||||
// The second evaluation
|
||||
// If we don't bind output again, the output value will not change
|
||||
EXPECT_NO_THROW(m_binding.Bind(L"X", inputValue2));
|
||||
EXPECT_NO_THROW(m_session.Evaluate(m_binding, L""));
|
||||
WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"X", inputValue2));
|
||||
WINML_EXPECT_NO_THROW(learningModelSession.Evaluate(learningModelBinding, L""));
|
||||
auto buffer2 = outputValue.GetAsVectorView();
|
||||
EXPECT_EQ(buffer1.Size(), buffer2.Size());
|
||||
WINML_EXPECT_EQUAL(buffer1.Size(), buffer2.Size());
|
||||
bool isSame = true;
|
||||
for (uint32_t i = 0; i < buffer1.Size(); ++i)
|
||||
{
|
||||
|
|
@ -555,7 +568,7 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice)
|
|||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_FALSE(isSame);
|
||||
WINML_EXPECT_FALSE(isSame);
|
||||
}
|
||||
|
||||
static VideoFrame CreateVideoFrame(const wchar_t* path)
|
||||
|
|
@ -567,7 +580,7 @@ static VideoFrame CreateVideoFrame(const wchar_t* path)
|
|||
return VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
||||
static void VerifyOutputAfterImageBindCalledTwice()
|
||||
{
|
||||
std::wstring fullModelPath = FileHelpers::GetModulePath() + L"model.onnx";
|
||||
std::wstring fullImagePath1 = FileHelpers::GetModulePath() + L"kitten_224.png";
|
||||
|
|
@ -575,9 +588,9 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
|||
|
||||
// winml model creation
|
||||
LearningModel model = nullptr;
|
||||
EXPECT_NO_THROW(model = LearningModel::LoadFromFilePath(fullModelPath));
|
||||
WINML_EXPECT_NO_THROW(model = LearningModel::LoadFromFilePath(fullModelPath));
|
||||
LearningModelSession modelSession = nullptr;
|
||||
EXPECT_NO_THROW(modelSession = LearningModelSession(model, LearningModelDevice(LearningModelDeviceKind::Default)));
|
||||
WINML_EXPECT_NO_THROW(modelSession = LearningModelSession(model, LearningModelDevice(LearningModelDeviceKind::Default)));
|
||||
LearningModelBinding modelBinding(modelSession);
|
||||
|
||||
// create the tensor for the actual output
|
||||
|
|
@ -587,8 +600,8 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
|||
// Bind image 1 and evaluate
|
||||
auto frame = CreateVideoFrame(fullImagePath1.c_str());
|
||||
auto imageTensor = ImageFeatureValue::CreateFromVideoFrame(frame);
|
||||
EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor));
|
||||
EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L""));
|
||||
WINML_EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor));
|
||||
WINML_EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L""));
|
||||
|
||||
// Store 1st result
|
||||
auto outputVectorView1 = output.GetAsVectorView();
|
||||
|
|
@ -598,13 +611,13 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
|||
// The expected result is that the videoframe will be re-tensorized at bind
|
||||
auto frame2 = CreateVideoFrame(fullImagePath2.c_str());
|
||||
frame2.CopyToAsync(frame).get();
|
||||
EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor));
|
||||
EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L""));
|
||||
WINML_EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor));
|
||||
WINML_EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L""));
|
||||
|
||||
// Store 2nd result
|
||||
auto outputVectorView2 = output.GetAsVectorView();
|
||||
|
||||
EXPECT_EQ(outputVectorView1.Size(), outputVectorView2.Size());
|
||||
WINML_EXPECT_EQUAL(outputVectorView1.Size(), outputVectorView2.Size());
|
||||
bool isSame = true;
|
||||
for (uint32_t i = 0; i < outputVectorView1.Size(); ++i)
|
||||
{
|
||||
|
|
@ -614,5 +627,32 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
|||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_FALSE(isSame);
|
||||
WINML_EXPECT_FALSE(isSame);
|
||||
}
|
||||
|
||||
const LearningModelBindingAPITestApi& getapi() {
|
||||
static constexpr LearningModelBindingAPITestApi api =
|
||||
{
|
||||
LearningModelBindingAPITestSetup,
|
||||
LearningModelBindingAPITestGpuSetup,
|
||||
CpuSqueezeNet,
|
||||
CpuSqueezeNetEmptyOutputs,
|
||||
CpuSqueezeNetUnboundOutputs,
|
||||
CpuSqueezeNetBindInputTensorAsInspectable,
|
||||
CastMapInt64,
|
||||
DictionaryVectorizerMapInt64,
|
||||
DictionaryVectorizerMapString,
|
||||
ZipMapInt64,
|
||||
ZipMapInt64Unbound,
|
||||
ZipMapString,
|
||||
GpuSqueezeNet,
|
||||
GpuSqueezeNetEmptyOutputs,
|
||||
GpuSqueezeNetUnboundOutputs,
|
||||
ImageBindingDimensions,
|
||||
VerifyInvalidBindExceptions,
|
||||
BindInvalidInputName,
|
||||
VerifyOutputAfterEvaluateAsyncCalledTwice,
|
||||
VerifyOutputAfterImageBindCalledTwice
|
||||
};
|
||||
return api;
|
||||
}
|
||||
49
winml/test/api/LearningModelBindingAPITest.h
Normal file
49
winml/test/api/LearningModelBindingAPITest.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include "test.h"
|
||||
|
||||
struct LearningModelBindingAPITestApi {
|
||||
SetupTest LearningModelBindingAPITestSetup;
|
||||
SetupTest LearningModelBindingAPITestGpuSetup;
|
||||
VoidTest CpuSqueezeNet;
|
||||
VoidTest CpuSqueezeNetEmptyOutputs;
|
||||
VoidTest CpuSqueezeNetUnboundOutputs;
|
||||
VoidTest CpuSqueezeNetBindInputTensorAsInspectable;
|
||||
VoidTest CastMapInt64;
|
||||
VoidTest DictionaryVectorizerMapInt64;
|
||||
VoidTest DictionaryVectorizerMapString;
|
||||
VoidTest ZipMapInt64;
|
||||
VoidTest ZipMapInt64Unbound;
|
||||
VoidTest ZipMapString;
|
||||
VoidTest GpuSqueezeNet;
|
||||
VoidTest GpuSqueezeNetEmptyOutputs;
|
||||
VoidTest GpuSqueezeNetUnboundOutputs;
|
||||
VoidTest ImageBindingDimensions;
|
||||
VoidTest VerifyInvalidBindExceptions;
|
||||
VoidTest BindInvalidInputName;
|
||||
VoidTest VerifyOutputAfterEvaluateAsyncCalledTwice;
|
||||
VoidTest VerifyOutputAfterImageBindCalledTwice;
|
||||
};
|
||||
const LearningModelBindingAPITestApi& getapi();
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelBindingAPITest, LearningModelBindingAPITestSetup)
|
||||
WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNet)
|
||||
WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs)
|
||||
WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs)
|
||||
WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable)
|
||||
WINML_TEST(LearningModelBindingAPITest, CastMapInt64)
|
||||
WINML_TEST(LearningModelBindingAPITest, DictionaryVectorizerMapInt64)
|
||||
WINML_TEST(LearningModelBindingAPITest, DictionaryVectorizerMapString)
|
||||
WINML_TEST(LearningModelBindingAPITest, ZipMapInt64)
|
||||
WINML_TEST(LearningModelBindingAPITest, ZipMapInt64Unbound)
|
||||
WINML_TEST(LearningModelBindingAPITest, ZipMapString)
|
||||
WINML_TEST(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice)
|
||||
WINML_TEST(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelBindingAPITestGpu, LearningModelBindingAPITestGpuSetup)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNet)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, ImageBindingDimensions)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions)
|
||||
WINML_TEST(LearningModelBindingAPITestGpu, BindInvalidInputName)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "testPch.h"
|
||||
#include "APITest.h"
|
||||
|
||||
#include "LearningModelSessionAPITest.h"
|
||||
#include "winrt/Windows.Storage.h"
|
||||
|
||||
#include "DeviceHelpers.h"
|
||||
|
|
@ -16,144 +16,151 @@ using namespace winrt::Windows::Foundation::Collections;
|
|||
|
||||
using winrt::Windows::Foundation::IPropertyValue;
|
||||
|
||||
class LearningModelSessionAPITests : public APITest
|
||||
{};
|
||||
|
||||
class LearningModelSessionAPITestsGpu : public APITest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
GPUTEST
|
||||
}
|
||||
};
|
||||
|
||||
class LearningModelSessionAPITestsSkipEdgeCore : public LearningModelSessionAPITestsGpu
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
LearningModelSessionAPITestsGpu::SetUp();
|
||||
SKIP_EDGECORE
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, CreateSessionDeviceDefault)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
static void LearningModelSessionAPITestSetup() {
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, CreateSessionDeviceCpu)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
static void LearningModelSessionAPITestGpuSetup() {
|
||||
GPUTEST;
|
||||
init_apartment();
|
||||
}
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Cpu));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
static void LearningModelSessionAPITestsSkipEdgeCoreSetup() {
|
||||
LearningModelSessionAPITestGpuSetup();
|
||||
SKIP_EDGECORE
|
||||
}
|
||||
|
||||
static void CreateSessionDeviceDefault()
|
||||
{
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
}
|
||||
|
||||
static void CreateSessionDeviceCpu()
|
||||
{
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Cpu));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
// for the CPU device, make sure that we get back NULL and 0 for any device properties
|
||||
EXPECT_FALSE(m_device.Direct3D11Device());
|
||||
WINML_EXPECT_EQUAL(learningModelDevice.Direct3D11Device(), nullptr);
|
||||
LARGE_INTEGER id;
|
||||
id.QuadPart = GetAdapterIdQuadPart();
|
||||
EXPECT_EQ(id.LowPart, static_cast<DWORD>(0));
|
||||
EXPECT_EQ(id.HighPart, 0);
|
||||
id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice);
|
||||
WINML_EXPECT_EQUAL(id.LowPart, static_cast<DWORD>(0));
|
||||
WINML_EXPECT_EQUAL(id.HighPart, 0);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, CreateSessionWithModelLoadedFromStream)
|
||||
static void CreateSessionWithModelLoadedFromStream()
|
||||
{
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
std::wstring path = FileHelpers::GetModulePath() + L"model.onnx";
|
||||
auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get();
|
||||
|
||||
EXPECT_NO_THROW(m_model = LearningModel::LoadFromStream(storageFile));
|
||||
WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStream(storageFile));
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectX)
|
||||
static void CreateSessionDeviceDirectX()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectX));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectX));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectXHighPerformance)
|
||||
static void CreateSessionDeviceDirectXHighPerformance()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectXMinimumPower)
|
||||
static void CreateSessionDeviceDirectXMinimumPower()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower));
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsSkipEdgeCore, AdapterIdAndDevice)
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
static void AdapterIdAndDevice() {
|
||||
LearningModel learningModel = nullptr;
|
||||
LearningModelDevice learningModelDevice = nullptr;
|
||||
LearningModelSession learningModelSession = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
|
||||
com_ptr<IDXGIFactory6> factory;
|
||||
EXPECT_HRESULT_SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory6), factory.put_void()));
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory6), factory.put_void()));
|
||||
com_ptr<IDXGIAdapter> adapter;
|
||||
|
||||
m_device = LearningModelDevice(LearningModelDeviceKind::DirectX);
|
||||
EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapters(0, adapter.put()));
|
||||
learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectX);
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapters(0, adapter.put()));
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
LARGE_INTEGER id;
|
||||
id.QuadPart = GetAdapterIdQuadPart();
|
||||
EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
EXPECT_TRUE(m_device.Direct3D11Device() != nullptr);
|
||||
id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr);
|
||||
|
||||
m_device = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance);
|
||||
learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance);
|
||||
adapter = nullptr;
|
||||
EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof(IDXGIAdapter), adapter.put_void()));
|
||||
EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
id.QuadPart = GetAdapterIdQuadPart();
|
||||
EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
EXPECT_TRUE(m_device.Direct3D11Device() != nullptr);
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof(IDXGIAdapter), adapter.put_void()));
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr);
|
||||
|
||||
adapter = nullptr;
|
||||
m_device = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower);
|
||||
EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_MINIMUM_POWER, __uuidof(IDXGIAdapter), adapter.put_void()));
|
||||
EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
id.QuadPart = GetAdapterIdQuadPart();
|
||||
EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
EXPECT_TRUE(m_device.Direct3D11Device() != nullptr);
|
||||
learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower);
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_MINIMUM_POWER, __uuidof(IDXGIAdapter), adapter.put_void()));
|
||||
WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc));
|
||||
id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart);
|
||||
WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart);
|
||||
WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr);
|
||||
|
||||
EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device));
|
||||
EXPECT_EQ(m_session.Device().AdapterId(), m_device.AdapterId());
|
||||
WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice));
|
||||
WINML_EXPECT_EQUAL(learningModelSession.Device().AdapterId(), learningModelDevice.AdapterId());
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, EvaluateFeatures)
|
||||
static void EvaluateFeatures()
|
||||
{
|
||||
std::vector<int64_t> shape = { 4 };
|
||||
std::vector<winrt::hstring> data = { L"one", L"two", L"three", L"four" };
|
||||
|
||||
// create from buffer
|
||||
auto tensor = TensorString::CreateFromArray(shape, data);
|
||||
EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
|
||||
// create from vector view
|
||||
auto dataCopy = data;
|
||||
tensor = TensorString::CreateFromIterable(
|
||||
shape, winrt::single_threaded_vector<winrt::hstring>(std::move(dataCopy)).GetView());
|
||||
EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
|
||||
EXPECT_NO_THROW(LoadModel(L"id-tensor-string.onnx"));
|
||||
LearningModelSession session(m_model);
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"id-tensor-string.onnx", learningModel));
|
||||
LearningModelSession session(learningModel);
|
||||
|
||||
auto outputTensor = TensorString::Create();
|
||||
|
||||
|
|
@ -164,29 +171,30 @@ TEST_F(LearningModelSessionAPITests, EvaluateFeatures)
|
|||
session.EvaluateFeatures(featureswinrtmap, L"0");
|
||||
|
||||
// verify identity model round-trip works
|
||||
EXPECT_EQ(outputTensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(outputTensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView())));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, EvaluateFeaturesAsync)
|
||||
static void EvaluateFeaturesAsync()
|
||||
{
|
||||
std::vector<int64_t> shape = { 4 };
|
||||
std::vector<winrt::hstring> data = { L"one", L"two", L"three", L"four" };
|
||||
|
||||
// create from buffer
|
||||
auto tensor = TensorString::CreateFromArray(shape, data);
|
||||
EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
|
||||
// create from vector view
|
||||
auto dataCopy = data;
|
||||
tensor = TensorString::CreateFromIterable(
|
||||
shape, winrt::single_threaded_vector<winrt::hstring>(std::move(dataCopy)).GetView());
|
||||
EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView())));
|
||||
|
||||
EXPECT_NO_THROW(LoadModel(L"id-tensor-string.onnx"));
|
||||
LearningModelSession session(m_model);
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"id-tensor-string.onnx", learningModel));
|
||||
LearningModelSession session(learningModel);
|
||||
|
||||
auto outputTensor = TensorString::Create(shape);
|
||||
|
||||
|
|
@ -197,37 +205,39 @@ TEST_F(LearningModelSessionAPITests, EvaluateFeaturesAsync)
|
|||
session.EvaluateFeaturesAsync(featureswinrtmap, L"0").get();
|
||||
|
||||
// verify identity model round-trip works
|
||||
EXPECT_EQ(outputTensor.GetAsVectorView().Size(), data.size());
|
||||
EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView())));
|
||||
WINML_EXPECT_EQUAL(outputTensor.GetAsVectorView().Size(), data.size());
|
||||
WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView())));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, EvaluationProperties)
|
||||
static void EvaluationProperties()
|
||||
{
|
||||
// load a model
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
// create a session
|
||||
m_session = LearningModelSession(m_model);
|
||||
LearningModelSession learningModelSession = nullptr;
|
||||
learningModelSession = LearningModelSession(learningModel);
|
||||
// set a property
|
||||
auto value = winrt::Windows::Foundation::PropertyValue::CreateBoolean(true);
|
||||
m_session.EvaluationProperties().Insert(L"propName1", value);
|
||||
learningModelSession.EvaluationProperties().Insert(L"propName1", value);
|
||||
// get the property and make sure it's there with the right value
|
||||
auto value2 = m_session.EvaluationProperties().Lookup(L"propName1");
|
||||
EXPECT_EQ(value2.as<IPropertyValue>().GetBoolean(), true);
|
||||
auto value2 = learningModelSession.EvaluationProperties().Lookup(L"propName1");
|
||||
WINML_EXPECT_EQUAL(value2.as<IPropertyValue>().GetBoolean(), true);
|
||||
}
|
||||
|
||||
static LearningModelSession CreateSession(LearningModel model)
|
||||
{
|
||||
LearningModelDevice device(nullptr);
|
||||
EXPECT_NO_THROW(device = LearningModelDevice(LearningModelDeviceKind::DirectX));
|
||||
WINML_EXPECT_NO_THROW(device = LearningModelDevice(LearningModelDeviceKind::DirectX));
|
||||
|
||||
LearningModelSession session(nullptr);
|
||||
if (DeviceHelpers::IsFloat16Supported(device))
|
||||
{
|
||||
EXPECT_NO_THROW(session = LearningModelSession(model, device));
|
||||
WINML_EXPECT_NO_THROW(session = LearningModelSession(model, device));
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_THROW_SPECIFIC(
|
||||
WINML_EXPECT_THROW_SPECIFIC(
|
||||
session = LearningModelSession(model, device),
|
||||
winrt::hresult_error,
|
||||
[](const winrt::hresult_error& e) -> bool
|
||||
|
|
@ -239,26 +249,28 @@ static LearningModelSession CreateSession(LearningModel model)
|
|||
return session;
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsGpu, CreateSessionWithCastToFloat16InModel)
|
||||
static void CreateSessionWithCastToFloat16InModel()
|
||||
{
|
||||
// load a model
|
||||
EXPECT_NO_THROW(LoadModel(L"fp16-truncate-with-cast.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"fp16-truncate-with-cast.onnx", learningModel));
|
||||
|
||||
CreateSession(m_model);
|
||||
CreateSession(learningModel);
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITestsGpu, DISABLED_CreateSessionWithFloat16InitializersInModel)
|
||||
static void DISABLED_CreateSessionWithFloat16InitializersInModel()
|
||||
{
|
||||
// Disabled due to https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/21624720:
|
||||
// Model fails to resolve due to ORT using incorrect IR version within partition
|
||||
|
||||
// load a model
|
||||
EXPECT_NO_THROW(LoadModel(L"fp16-initializer.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"fp16-initializer.onnx", learningModel));
|
||||
|
||||
CreateSession(m_model);
|
||||
CreateSession(learningModel);
|
||||
}
|
||||
|
||||
static void EvaluateSessionAndCloseModel(
|
||||
static void EvaluateSessionAndCloseModelHelper(
|
||||
LearningModelDeviceKind kind,
|
||||
bool close_model_on_session_creation)
|
||||
{
|
||||
|
|
@ -275,7 +287,7 @@ static void EvaluateSessionAndCloseModel(
|
|||
// ensure you can create a session from the model
|
||||
LearningModelSession session(nullptr);
|
||||
|
||||
EXPECT_NO_THROW(session = LearningModelSession(model, device, options));
|
||||
WINML_EXPECT_NO_THROW(session = LearningModelSession(model, device, options));
|
||||
|
||||
std::vector<float> input(1000);
|
||||
std::iota(std::begin(input), std::end(input), 0.0f);
|
||||
|
|
@ -284,12 +296,12 @@ static void EvaluateSessionAndCloseModel(
|
|||
binding.Bind(L"input", tensor_input);
|
||||
|
||||
LearningModelEvaluationResult result(nullptr);
|
||||
EXPECT_NO_THROW(result = session.Evaluate(binding, L""));
|
||||
WINML_EXPECT_NO_THROW(result = session.Evaluate(binding, L""));
|
||||
|
||||
if (close_model_on_session_creation)
|
||||
{
|
||||
// ensure that the model has been closed
|
||||
EXPECT_THROW_SPECIFIC(
|
||||
WINML_EXPECT_THROW_SPECIFIC(
|
||||
LearningModelSession(model, device, options),
|
||||
winrt::hresult_error,
|
||||
[](const winrt::hresult_error& e) -> bool
|
||||
|
|
@ -299,19 +311,20 @@ static void EvaluateSessionAndCloseModel(
|
|||
}
|
||||
else
|
||||
{
|
||||
EXPECT_NO_THROW(LearningModelSession(model, device, options));
|
||||
WINML_EXPECT_NO_THROW(LearningModelSession(model, device, options));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, EvaluateSessionAndCloseModel)
|
||||
static void EvaluateSessionAndCloseModel()
|
||||
{
|
||||
EXPECT_NO_THROW(::EvaluateSessionAndCloseModel(LearningModelDeviceKind::Cpu, true));
|
||||
EXPECT_NO_THROW(::EvaluateSessionAndCloseModel(LearningModelDeviceKind::Cpu, false));
|
||||
WINML_EXPECT_NO_THROW(::EvaluateSessionAndCloseModelHelper(LearningModelDeviceKind::Cpu, true));
|
||||
WINML_EXPECT_NO_THROW(::EvaluateSessionAndCloseModelHelper(LearningModelDeviceKind::Cpu, false));
|
||||
}
|
||||
|
||||
TEST_F(LearningModelSessionAPITests, CloseSession)
|
||||
static void CloseSession()
|
||||
{
|
||||
EXPECT_NO_THROW(LoadModel(L"model.onnx"));
|
||||
LearningModel learningModel = nullptr;
|
||||
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel));
|
||||
LearningModelSession session = nullptr;
|
||||
|
||||
/*
|
||||
|
|
@ -329,7 +342,7 @@ TEST_F(LearningModelSessionAPITests, CloseSession)
|
|||
SIZE_T afterSessionCloseWorkingSetSize = 0;
|
||||
bool getProcessMemoryInfoSuccess = false;
|
||||
*/
|
||||
EXPECT_NO_THROW(session = LearningModelSession(m_model));
|
||||
WINML_EXPECT_NO_THROW(session = LearningModelSession(learningModel));
|
||||
|
||||
/*
|
||||
// Get the current process memory info after session creation.
|
||||
|
|
@ -341,7 +354,7 @@ TEST_F(LearningModelSessionAPITests, CloseSession)
|
|||
beforeSessionCloseWorkingSetSize = pmc.WorkingSetSize;
|
||||
pmc = { 0 };
|
||||
*/
|
||||
EXPECT_NO_THROW(session.Close());
|
||||
WINML_EXPECT_NO_THROW(session.Close());
|
||||
|
||||
/*
|
||||
Bug 23659026: Working set difference tolerance is too tight for LearningModelSessionAPITests::CloseSession
|
||||
|
|
@ -367,17 +380,41 @@ TEST_F(LearningModelSessionAPITests, CloseSession)
|
|||
*/
|
||||
|
||||
// verify that model still has metadata info after session close
|
||||
std::wstring author(m_model.Author());
|
||||
EXPECT_EQ(author, L"onnx-caffe2");
|
||||
std::wstring author(learningModel.Author());
|
||||
WINML_EXPECT_EQUAL(author, L"onnx-caffe2");
|
||||
|
||||
// verify that session throws RO_E_CLOSED error
|
||||
std::vector<float> input(1 * 3 * 224 * 224, 0);
|
||||
std::vector<int64_t> shape = { 1, 3, 224, 224 };
|
||||
auto tensor_input = TensorFloat::CreateFromShapeArrayAndDataArray(shape, input);
|
||||
EXPECT_THROW_SPECIFIC(LearningModelBinding binding(session),
|
||||
WINML_EXPECT_THROW_SPECIFIC(LearningModelBinding binding(session),
|
||||
winrt::hresult_error,
|
||||
[](const winrt::hresult_error &e) -> bool
|
||||
{
|
||||
return e.code() == RO_E_CLOSED;
|
||||
});
|
||||
}
|
||||
|
||||
const LearningModelSesssionAPITestApi& getapi() {
|
||||
static constexpr LearningModelSesssionAPITestApi api =
|
||||
{
|
||||
LearningModelSessionAPITestSetup,
|
||||
LearningModelSessionAPITestGpuSetup,
|
||||
LearningModelSessionAPITestsSkipEdgeCoreSetup,
|
||||
CreateSessionDeviceDefault,
|
||||
CreateSessionDeviceCpu,
|
||||
CreateSessionWithModelLoadedFromStream,
|
||||
CreateSessionDeviceDirectX,
|
||||
CreateSessionDeviceDirectXHighPerformance,
|
||||
CreateSessionDeviceDirectXMinimumPower,
|
||||
AdapterIdAndDevice,
|
||||
EvaluateFeatures,
|
||||
EvaluateFeaturesAsync,
|
||||
EvaluationProperties,
|
||||
CreateSessionWithCastToFloat16InModel,
|
||||
DISABLED_CreateSessionWithFloat16InitializersInModel,
|
||||
EvaluateSessionAndCloseModel,
|
||||
CloseSession,
|
||||
};
|
||||
return api;
|
||||
}
|
||||
44
winml/test/api/LearningModelSessionAPITest.h
Normal file
44
winml/test/api/LearningModelSessionAPITest.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "test.h"
|
||||
|
||||
struct LearningModelSesssionAPITestApi {
|
||||
SetupTest LearningModelSessionAPITestSetup;
|
||||
SetupTest LearningModelSessionAPITestGpuSetup;
|
||||
SetupTest LearningModelSessionAPITestsSkipEdgeCoreSetup;
|
||||
VoidTest CreateSessionDeviceDefault;
|
||||
VoidTest CreateSessionDeviceCpu;
|
||||
VoidTest CreateSessionWithModelLoadedFromStream;
|
||||
VoidTest CreateSessionDeviceDirectX;
|
||||
VoidTest CreateSessionDeviceDirectXHighPerformance;
|
||||
VoidTest CreateSessionDeviceDirectXMinimumPower;
|
||||
VoidTest AdapterIdAndDevice;
|
||||
VoidTest EvaluateFeatures;
|
||||
VoidTest EvaluateFeaturesAsync;
|
||||
VoidTest EvaluationProperties;
|
||||
VoidTest CreateSessionWithCastToFloat16InModel;
|
||||
VoidTest DISABLED_CreateSessionWithFloat16InitializersInModel;
|
||||
VoidTest EvaluateSessionAndCloseModel;
|
||||
VoidTest CloseSession;
|
||||
};
|
||||
const LearningModelSesssionAPITestApi& getapi();
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITest, LearningModelSessionAPITestSetup)
|
||||
WINML_TEST(LearningModelSessionAPITest, CreateSessionDeviceDefault)
|
||||
WINML_TEST(LearningModelSessionAPITest,CreateSessionDeviceCpu)
|
||||
WINML_TEST(LearningModelSessionAPITest,CreateSessionWithModelLoadedFromStream)
|
||||
WINML_TEST(LearningModelSessionAPITest,EvaluateFeatures)
|
||||
WINML_TEST(LearningModelSessionAPITest,EvaluateFeaturesAsync)
|
||||
WINML_TEST(LearningModelSessionAPITest,EvaluationProperties)
|
||||
WINML_TEST(LearningModelSessionAPITest,EvaluateSessionAndCloseModel)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITestGpu, LearningModelSessionAPITestGpuSetup)
|
||||
WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectX)
|
||||
WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectXHighPerformance)
|
||||
WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectXMinimumPower)
|
||||
WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionWithCastToFloat16InModel)
|
||||
WINML_TEST(LearningModelSessionAPITestGpu, DISABLED_CreateSessionWithFloat16InitializersInModel)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
||||
WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITestsSkipEdgeCore, LearningModelSessionAPITestsSkipEdgeCoreSetup)
|
||||
WINML_TEST(LearningModelSessionAPITestsSkipEdgeCore, AdapterIdAndDevice)
|
||||
WINML_TEST_CLASS_END()
|
||||
|
|
@ -10,18 +10,20 @@
|
|||
}
|
||||
|
||||
#define WINML_TEST_CLASS_BEGIN_NO_SETUP(test_class_name) \
|
||||
class test_class_name : public ::testing::Test { \
|
||||
};
|
||||
namespace { \
|
||||
class test_class_name : public ::testing::Test { \
|
||||
};
|
||||
|
||||
#define WINML_TEST_CLASS_BEGIN_WITH_SETUP(test_class_name, setup_method) \
|
||||
class test_class_name : public ::testing::Test { \
|
||||
protected: \
|
||||
void SetUp() override { \
|
||||
getapi().setup_method(); \
|
||||
} \
|
||||
};
|
||||
namespace { \
|
||||
class test_class_name : public ::testing::Test { \
|
||||
protected: \
|
||||
void SetUp() override { \
|
||||
getapi().setup_method(); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define WINML_TEST_CLASS_END()
|
||||
#define WINML_TEST_CLASS_END() }
|
||||
|
||||
// For old versions of gtest without GTEST_SKIP, stream the message and return success instead
|
||||
#ifndef GTEST_SKIP
|
||||
|
|
@ -30,17 +32,34 @@
|
|||
#define GTEST_SKIP GTEST_SKIP_("")
|
||||
#endif
|
||||
|
||||
#define EXPECT_THROW_SPECIFIC(statement, exception, condition) \
|
||||
EXPECT_THROW( \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const exception& e) { \
|
||||
EXPECT_TRUE(condition(e)); \
|
||||
throw; \
|
||||
} \
|
||||
, exception);
|
||||
|
||||
#ifndef INSTANTIATE_TEST_SUITE_P
|
||||
// Use the old name, removed in newer versions of googletest
|
||||
#define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P
|
||||
#endif
|
||||
|
||||
#define WINML_SKIP_TEST(message) \
|
||||
GTEST_SKIP() << message;
|
||||
|
||||
#define WINML_EXPECT_NO_THROW(statement) EXPECT_NO_THROW(statement)
|
||||
#define WINML_EXPECT_TRUE(statement) EXPECT_TRUE(statement)
|
||||
#define WINML_EXPECT_FALSE(statement) EXPECT_FALSE(statement)
|
||||
#define WINML_EXPECT_EQUAL(val1, val2) EXPECT_EQ(val1, val2)
|
||||
#define WINML_EXPECT_NOT_EQUAL(val1, val2) EXPECT_NE(val1, val2)
|
||||
|
||||
#define WINML_LOG_ERROR(message) \
|
||||
ADD_FAILURE() << message
|
||||
|
||||
#define WINML_LOG_COMMENT(message)\
|
||||
SCOPED_TRACE(message)
|
||||
#define WINML_EXPECT_HRESULT_SUCCEEDED(hresult_expression) EXPECT_HRESULT_SUCCEEDED(hresult_expression)
|
||||
#define WINML_EXPECT_HRESULT_FAILED(hresult_expression) EXPECT_HRESULT_FAILED(hresult_expression)
|
||||
#define WINML_EXPECT_THROW_SPECIFIC(statement, exception, condition) EXPECT_THROW_SPECIFIC(statement, exception, condition)
|
||||
|
|
@ -60,4 +79,4 @@
|
|||
if (auto isEdgeCore = RuntimeParameters::Parameters.find("EdgeCore"); \
|
||||
isEdgeCore != RuntimeParameters::Parameters.end() && isEdgeCore->second != "0") { \
|
||||
WINML_SKIP_TEST("Test can't be run in EdgeCore"); \
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,19 +29,4 @@
|
|||
#include "comp_generated/winrt/windows.ai.machinelearning.h"
|
||||
|
||||
// WinML
|
||||
#include "Windows.AI.MachineLearning.Native.h"
|
||||
|
||||
#define EXPECT_THROW_SPECIFIC(statement, exception, condition) \
|
||||
EXPECT_THROW( \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const exception& e) { \
|
||||
EXPECT_TRUE(condition(e)); \
|
||||
throw; \
|
||||
} \
|
||||
, exception);
|
||||
|
||||
#ifndef INSTANTIATE_TEST_SUITE_P
|
||||
// Use the old name, removed in newer versions of googletest
|
||||
#define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P
|
||||
#endif
|
||||
#include "Windows.AI.MachineLearning.Native.h"
|
||||
|
|
@ -30,11 +30,13 @@ using namespace WEX::TestExecution;
|
|||
|
||||
#define WINML_EXPECT_NO_THROW(statement) VERIFY_NO_THROW(statement)
|
||||
#define WINML_EXPECT_TRUE(statement) VERIFY_IS_TRUE(statement)
|
||||
#define WINML_EXPECT_FALSE(statement) VERIFY_IS_FALSE(statement)
|
||||
#define WINML_EXPECT_EQUAL(val1, val2) VERIFY_ARE_EQUAL(val1, val2)
|
||||
#define WINML_EXPECT_NOT_EQUAL(val1, val2) VERIFY_ARE_NOT_EQUAL(val1, val2)
|
||||
#define WINML_LOG_ERROR(message) \
|
||||
VERIFY_FAIL(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(message).c_str())
|
||||
|
||||
#define WINML_LOG_COMMENT(message)\
|
||||
WEX::Logging::Log::Comment(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(message).c_str())
|
||||
#define WINML_EXPECT_HRESULT_SUCCEEDED(hresult_expression) VERIFY_SUCCEEDED(hresult_expression)
|
||||
#define WINML_EXPECT_THROW_SPECIFIC(statement, exception, condition) VERIFY_THROWS_SPECIFIC(statement, exception, condition)
|
||||
#define WINML_EXPECT_HRESULT_FAILED(hresult_expression) VERIFY_FAILED(hresult_expression)
|
||||
|
|
|
|||
Loading…
Reference in a new issue