mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Initial changes for layering
This commit is contained in:
parent
b94ae8e965
commit
444bfcc26e
14 changed files with 323 additions and 182 deletions
|
|
@ -425,9 +425,11 @@ if (WIN32)
|
|||
|
||||
# set linker flags to minimize the binary size.
|
||||
if (MSVC)
|
||||
foreach(type EXE SHARED)
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /OPT:REF,ICF,LBR")
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
|
||||
foreach(type EXE STATIC SHARED)
|
||||
if (NOT type MATCHES STATIC)
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /OPT:REF,ICF,LBR")
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
|
||||
endif()
|
||||
if (NOT onnxruntime_USE_CUDA)
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELEASE "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
|
||||
|
|
@ -694,6 +696,15 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Android")
|
|||
list(APPEND onnxruntime_EXTERNAL_LIBRARIES log)
|
||||
endif()
|
||||
|
||||
if (onnxruntime_USE_WINML)
|
||||
if (NOT onnxruntime_USE_DML)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Option onnxruntime_USE_WINML can only be used when onnxruntime_USE_DML is also enabled")
|
||||
endif()
|
||||
include(wil.cmake)
|
||||
include(winml.cmake)
|
||||
endif() # if(onnxruntime_USE_WINML)
|
||||
#The following files may use the 'onnxruntime_libs' and 'onnxruntime_EXTERNAL_LIBRARIES' vars
|
||||
|
||||
if (onnxruntime_BUILD_SHARED_LIB)
|
||||
|
|
@ -733,17 +744,4 @@ if (onnxruntime_BUILD_CSHARP)
|
|||
message(STATUS "CSharp Build is enabled")
|
||||
# set_property(GLOBAL PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "netstandard2.0")
|
||||
include(onnxruntime_csharp.cmake)
|
||||
endif()
|
||||
|
||||
if (onnxruntime_USE_WINML)
|
||||
|
||||
if (NOT onnxruntime_USE_DML)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Option onnxruntime_USE_WINML can only be used when onnxruntime_USE_DML is also enabled")
|
||||
endif()
|
||||
|
||||
include(wil.cmake)
|
||||
include(winml.cmake)
|
||||
|
||||
endif() # if(onnxruntime_USE_WINML)
|
||||
endif()
|
||||
|
|
@ -11,6 +11,7 @@ set(winml_api_root ${REPO_ROOT}/winml/api)
|
|||
get_sdk(sdk_folder sdk_version)
|
||||
set(target_folder ONNXRuntime/winml)
|
||||
set(winml_dll_dir ${REPO_ROOT}/winml/dll)
|
||||
set(winml_lib_dir ${REPO_ROOT}/winml/lib)
|
||||
set(winml_lib_api_dir ${REPO_ROOT}/winml/lib/api)
|
||||
set(winml_lib_api_core_dir ${REPO_ROOT}/winml/lib/api.core)
|
||||
set(winml_lib_api_image_dir ${REPO_ROOT}/winml/lib/api.image)
|
||||
|
|
@ -126,6 +127,7 @@ add_library(winml_lib_core STATIC
|
|||
${winml_lib_api_core_dir}/inc/MLValueHelpers.h
|
||||
${winml_lib_api_core_dir}/inc/ModelInfo.h
|
||||
${winml_lib_api_core_dir}/inc/TensorBaseHelpers.h
|
||||
${winml_lib_api_core_dir}/inc/WinMLAdapter.h
|
||||
${winml_lib_api_core_dir}/CpuOrtSessionBuilder.h
|
||||
${winml_lib_api_core_dir}/DmlOrtSessionBuilder.h
|
||||
${winml_lib_api_core_dir}/FeatureDescriptorFactory.h
|
||||
|
|
@ -138,6 +140,7 @@ add_library(winml_lib_core STATIC
|
|||
${winml_lib_api_core_dir}/LotusEnvironment.cpp
|
||||
${winml_lib_api_core_dir}/ModelInfo.cpp
|
||||
${winml_lib_api_core_dir}/OrtSessionBuilder.cpp
|
||||
${winml_lib_api_core_dir}/WinMLAdapter.cpp
|
||||
${winml_lib_api_core_dir}/ZeroCopyInputStreamWrapper.cpp
|
||||
)
|
||||
|
||||
|
|
@ -167,6 +170,7 @@ target_include_directories(winml_lib_core PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/ex
|
|||
target_include_directories(winml_lib_core PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/onnx)
|
||||
|
||||
target_include_directories(winml_lib_core PRIVATE ${winml_lib_api_dir}) # needed for generated headers
|
||||
target_include_directories(winml_lib_core PRIVATE ${winml_lib_dir})
|
||||
target_include_directories(winml_lib_core PRIVATE ${winml_lib_api_core_dir})
|
||||
target_include_directories(winml_lib_core PRIVATE ${winml_lib_common_dir}/inc)
|
||||
target_include_directories(winml_lib_core PRIVATE ${ONNXRUNTIME_INCLUDE_DIR})
|
||||
|
|
@ -196,6 +200,10 @@ add_dependencies(winml_lib_core winml_api_native_internal)
|
|||
target_link_libraries(winml_lib_core PRIVATE wil)
|
||||
target_link_libraries(winml_lib_core PRIVATE onnxruntime_providers_dml)
|
||||
|
||||
# add it to the onnxruntime shared library
|
||||
list(APPEND onnxruntime_EXTERNAL_LIBRARIES winml_lib_core)
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES winml_lib_core)
|
||||
|
||||
###########################
|
||||
# Add winml_lib_image
|
||||
###########################
|
||||
|
|
@ -430,6 +438,7 @@ target_include_directories(winml_dll PRIVATE ${ONNXRUNTIME_ROOT}/core/graph)
|
|||
target_include_directories(winml_dll PRIVATE ${REPO_ROOT}/cmake/external/onnx)
|
||||
target_include_directories(winml_dll PRIVATE ${REPO_ROOT}/cmake/external/protobuf/src)
|
||||
target_include_directories(winml_dll PRIVATE ${REPO_ROOT}/cmake/external/gsl/include)
|
||||
target_include_directories(winml_dll PRIVATE ${REPO_ROOT}/cmake/external/eigen)
|
||||
|
||||
# Properties
|
||||
set_target_properties(winml_dll
|
||||
|
|
@ -463,22 +472,22 @@ endif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
|||
|
||||
# Link libraries
|
||||
target_link_libraries(winml_dll PRIVATE windowsapp.lib)
|
||||
target_link_libraries(winml_dll PRIVATE libprotobuf)
|
||||
target_link_libraries(winml_dll PRIVATE onnx)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_common)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_graph)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_framework)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_mlas)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_optimizer)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_providers)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_providers_dml)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_session)
|
||||
target_link_libraries(winml_dll PRIVATE onnxruntime_util)
|
||||
target_link_libraries(winml_dll PRIVATE onnx_proto)
|
||||
# target_link_libraries(winml_dll PRIVATE libprotobuf)
|
||||
# target_link_libraries(winml_dll PRIVATE onnx)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_common)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_graph)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_framework)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_mlas)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_optimizer)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_providers)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_providers_dml)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_session)
|
||||
# target_link_libraries(winml_dll PRIVATE onnxruntime_util)
|
||||
# target_link_libraries(winml_dll PRIVATE onnx_proto)
|
||||
target_link_libraries(winml_dll PRIVATE re2)
|
||||
target_link_libraries(winml_dll PRIVATE wil)
|
||||
target_link_libraries(winml_dll PRIVATE winml_lib_api)
|
||||
target_link_libraries(winml_dll PRIVATE winml_lib_core)
|
||||
# target_link_libraries(winml_dll PRIVATE winml_lib_core)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void ModelInfo::Initialize(
|
|||
}
|
||||
|
||||
// factory methods for creating an ort model from a path
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
onnx::ModelProto*
|
||||
WinML::CreateModelProto(
|
||||
const char* path) {
|
||||
int file_descriptor;
|
||||
|
|
@ -152,7 +152,7 @@ WinML::CreateModelProto(
|
|||
auto stream = google::protobuf::io::FileInputStream(file_descriptor);
|
||||
stream.SetCloseOnDelete(true);
|
||||
|
||||
auto model_proto = std::make_unique<onnx::ModelProto>();
|
||||
auto model_proto = new onnx::ModelProto();
|
||||
WINML_THROW_HR_IF_FALSE_MSG(
|
||||
E_INVALIDARG,
|
||||
model_proto->ParseFromZeroCopyStream(&stream),
|
||||
|
|
@ -162,12 +162,12 @@ WinML::CreateModelProto(
|
|||
}
|
||||
|
||||
// factory methods for creating an ort model from a stream
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
onnx::ModelProto*
|
||||
WinML::CreateModelProto(
|
||||
const wss::IRandomAccessStreamReference& stream_reference) {
|
||||
const wss::IRandomAccessStreamReference& stream_reference) {
|
||||
ZeroCopyInputStreamWrapper wrapper(stream_reference);
|
||||
|
||||
auto model_proto = std::make_unique<onnx::ModelProto>();
|
||||
auto model_proto = new onnx::ModelProto();
|
||||
WINML_THROW_HR_IF_FALSE_MSG(
|
||||
E_INVALIDARG,
|
||||
model_proto->ParseFromZeroCopyStream(&wrapper),
|
||||
|
|
|
|||
180
winml/lib/Api.Core/WinMLAdapter.cpp
Normal file
180
winml/lib/Api.Core/WinMLAdapter.cpp
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
#include "inc/WinMLAdapter.h"
|
||||
#include "inc/CustomRegistryHelper.h"
|
||||
#include "inc/LotusEnvironment.h"
|
||||
#include "core/providers/dml/DmlExecutionProvider/inc/DmlExecutionProvider.h"
|
||||
|
||||
#include "LearningModelDevice.h"
|
||||
#include "TensorFeatureDescriptor.h"
|
||||
#include "ImageFeatureDescriptor.h"
|
||||
#include "api.image/inc/D3DDeviceCache.h"
|
||||
|
||||
using namespace winrt::Windows::AI::MachineLearning;
|
||||
|
||||
namespace Windows::AI::MachineLearning::Adapter {
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
RegisterCustomRegistry(
|
||||
onnxruntime::InferenceSession* p_session,
|
||||
IMLOperatorRegistry* registry) {
|
||||
RETURN_HR_IF(S_OK, registry == nullptr);
|
||||
RETURN_HR_IF_NULL(E_POINTER, p_session);
|
||||
|
||||
auto custom_registries = WinML::GetLotusCustomRegistries(registry);
|
||||
|
||||
// Register
|
||||
for (auto& custom_registry : custom_registries) {
|
||||
WINML_THROW_IF_NOT_OK(p_session->RegisterCustomRegistry(custom_registry));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE EnableDebugOutput() {
|
||||
WinML::CWinMLLogSink::EnableDebugOutput();
|
||||
}
|
||||
|
||||
// ORT intentionally requires callers derive from their session class to access
|
||||
// the protected Load method used below.
|
||||
class InferenceSessionProtectedLoadAccessor : public onnxruntime::InferenceSession {
|
||||
public:
|
||||
onnxruntime::common::Status
|
||||
Load(std::unique_ptr<ONNX_NAMESPACE::ModelProto> p_model_proto) {
|
||||
return onnxruntime::InferenceSession::Load(std::move(p_model_proto));
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
LoadModel(
|
||||
onnxruntime::InferenceSession* session,
|
||||
onnx::ModelProto* model_proto) {
|
||||
auto session_protected_load_accessor =
|
||||
static_cast<InferenceSessionProtectedLoadAccessor*>(session);
|
||||
std::unique_ptr<ONNX_NAMESPACE::ModelProto> model_proto_ptr(model_proto);
|
||||
WINML_THROW_IF_NOT_OK(session_protected_load_accessor->Load(std::move(model_proto_ptr)));
|
||||
}
|
||||
|
||||
static bool
|
||||
IsFeatureDescriptorFp16(
|
||||
winml::ILearningModelFeatureDescriptor descriptor) {
|
||||
if (auto imageFeatureDescriptor = descriptor.try_as<winmlp::ImageFeatureDescriptor>()) {
|
||||
return TensorKind::Float16 == imageFeatureDescriptor->TensorKind();
|
||||
}
|
||||
|
||||
if (auto tensorFeatureDescriptor = descriptor.try_as<winmlp::TensorFeatureDescriptor>()) {
|
||||
return TensorKind::Float16 == tensorFeatureDescriptor->TensorKind();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
EnsureModelDeviceCompatibility(
|
||||
winml::LearningModel const& model,
|
||||
onnx::ModelProto* p_model_proto,
|
||||
winml::LearningModelDevice const& device) {
|
||||
auto isFloat16Supported = device.as<winmlp::LearningModelDevice>()->GetD3DDeviceCache()->IsFloat16Supported();
|
||||
if (!isFloat16Supported) {
|
||||
auto& graph = p_model_proto->graph();
|
||||
|
||||
// The model will not contain fp16 operations if:
|
||||
// 1. The model has no fp16 inputs
|
||||
// 2. The model has no fp16 initializers
|
||||
// 3. The model does not create any fp16 intermediary tensors via the Cast (to float16) operator
|
||||
// 4. The model does not have any fp16 outputs
|
||||
|
||||
// 1. Ensure that The model has no fp16 inputs
|
||||
for (auto descriptor : model.InputFeatures()) {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
IsFeatureDescriptorFp16(descriptor),
|
||||
"The model contains a 16-bit input (%ls), but the current device does not support 16-bit float.",
|
||||
descriptor.Name().c_str());
|
||||
}
|
||||
|
||||
// 2. Ensure that the model has no fp16 initializers
|
||||
for (int i = 0; i < graph.node_size(); i++) {
|
||||
auto node = graph.node(i);
|
||||
if (node.op_type() == "Cast" && node.domain().empty()) {
|
||||
for (int attribIndex = 0; attribIndex < node.attribute_size(); attribIndex++) {
|
||||
auto attribute = node.attribute(attribIndex);
|
||||
if (attribute.name() == "to") {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
attribute.i() == onnx::TensorProto::DataType::TensorProto_DataType_FLOAT16,
|
||||
"The model contains a 16-bit float Cast Op (%s), but the current device does not support 16-bit float.",
|
||||
node.name().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Ensure that the model does not create any fp16 intermediary
|
||||
// tensors via the Cast (to float16) operator
|
||||
for (int i = 0; i < graph.initializer_size(); i++) {
|
||||
auto initializer = graph.initializer(i);
|
||||
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
initializer.data_type() == onnx::TensorProto::DataType::TensorProto_DataType_FLOAT16,
|
||||
"The model contains a 16-bit float initializer (%s), but the current device does not support 16-bit float.",
|
||||
initializer.name().c_str());
|
||||
}
|
||||
|
||||
// 4. Ensure that the model does not have any fp16 outputs
|
||||
for (auto descriptor : model.OutputFeatures()) {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
IsFeatureDescriptorFp16(descriptor),
|
||||
"The model contains a 16-bit output (%ls), but the current device does not support 16-bit float.",
|
||||
descriptor.Name().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ReleaseOrtObject(onnx::ModelProto* model_proto) {
|
||||
std::unique_ptr<ONNX_NAMESPACE::ModelProto> ptr(model_proto);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ReleaseOrtObject(onnxruntime::IOBinding* io_binding) {
|
||||
std::unique_ptr<onnxruntime::IOBinding> ptr(io_binding);
|
||||
}
|
||||
|
||||
ID3D12Resource* STDMETHODCALLTYPE
|
||||
GetD3D12ResourceFromAllocation(
|
||||
onnxruntime::IExecutionProvider* provider,
|
||||
void* allocation) {
|
||||
auto d3dResource =
|
||||
Dml::GetD3D12ResourceFromAllocation(
|
||||
provider->GetAllocator(0, ::OrtMemType::OrtMemTypeDefault).get(),
|
||||
allocation);
|
||||
return d3dResource;
|
||||
}
|
||||
|
||||
onnxruntime::MLDataType GetType(winml::TensorKind kind) {
|
||||
switch (kind) {
|
||||
case winml::TensorKind::Float:
|
||||
return onnxruntime::DataTypeImpl::GetType<float>();
|
||||
case winml::TensorKind::Float16:
|
||||
return onnxruntime::DataTypeImpl::GetType<onnxruntime::MLFloat16>();
|
||||
};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
onnxruntime::Tensor* STDMETHODCALLTYPE CreateTensor(
|
||||
winml::TensorKind kind,
|
||||
const int64_t* shape,
|
||||
uint32_t shape_count,
|
||||
onnxruntime::IExecutionProvider* provider) {
|
||||
onnxruntime::TensorShape tensor_shape(shape, shape_count);
|
||||
auto pTensor = new onnxruntime::Tensor(
|
||||
GetType(kind),
|
||||
tensor_shape,
|
||||
provider->GetAllocator(0, ::OrtMemType::OrtMemTypeDefault));
|
||||
return pTensor;
|
||||
}
|
||||
|
||||
} // namespace Windows::AI::MachineLearning::Adapter
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "WinMLAdapter.h"
|
||||
|
||||
namespace Windows::AI::MachineLearning {
|
||||
|
||||
class ModelInfo {
|
||||
|
|
@ -25,9 +27,9 @@ class ModelInfo {
|
|||
};
|
||||
|
||||
// factory methods for creating an ort model from a path
|
||||
std::unique_ptr<onnx::ModelProto> CreateModelProto(const char* path);
|
||||
onnx::ModelProto* CreateModelProto(const char* path);
|
||||
|
||||
// factory methods for creating an ort model from a stream
|
||||
std::unique_ptr<onnx::ModelProto> CreateModelProto(const wss::IRandomAccessStreamReference& stream_reference);
|
||||
onnx::ModelProto* CreateModelProto(const wss::IRandomAccessStreamReference& stream_reference);
|
||||
|
||||
} // namespace Windows::AI::MachineLearning
|
||||
55
winml/lib/Api.Core/inc/WinMLAdapter.h
Normal file
55
winml/lib/Api.Core/inc/WinMLAdapter.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Windows::AI::MachineLearning::Adapter {
|
||||
|
||||
__declspec(dllexport) HRESULT STDMETHODCALLTYPE ReleaseOrtObject(onnx::ModelProto* model_proto);
|
||||
__declspec(dllexport) HRESULT STDMETHODCALLTYPE ReleaseOrtObject(onnxruntime::IOBinding* io_binding);
|
||||
|
||||
__declspec(dllexport) HRESULT STDMETHODCALLTYPE RegisterCustomRegistry(
|
||||
onnxruntime::InferenceSession* p_session,
|
||||
IMLOperatorRegistry* registry);
|
||||
|
||||
__declspec(dllexport) void STDMETHODCALLTYPE EnableDebugOutput();
|
||||
|
||||
__declspec(dllexport) HRESULT STDMETHODCALLTYPE LoadModel(onnxruntime::InferenceSession* session, onnx::ModelProto* model);
|
||||
|
||||
__declspec(dllexport) HRESULT STDMETHODCALLTYPE EnsureModelDeviceCompatibility(
|
||||
winml::LearningModel const& model,
|
||||
onnx::ModelProto* p_model_proto,
|
||||
winml::LearningModelDevice const& device);
|
||||
|
||||
__declspec(dllexport) ID3D12Resource* STDMETHODCALLTYPE GetD3D12ResourceFromAllocation(onnxruntime::IExecutionProvider* provider, void* allocation);
|
||||
|
||||
__declspec(dllexport) onnxruntime::Tensor* STDMETHODCALLTYPE CreateTensor(
|
||||
winml::TensorKind kind,
|
||||
const int64_t * shape,
|
||||
uint32_t shape_count,
|
||||
onnxruntime::IExecutionProvider* provider);
|
||||
|
||||
// header only code to enable smart pointers on abstract ort objects
|
||||
template <typename T>
|
||||
class OrtObject {
|
||||
public:
|
||||
OrtObject() {
|
||||
p_ = nullptr;
|
||||
}
|
||||
|
||||
OrtObject(T* m) {
|
||||
p_ = m;
|
||||
}
|
||||
|
||||
virtual ~OrtObject() {
|
||||
if (p_ != nullptr) {
|
||||
ReleaseOrtObject(p_);
|
||||
}
|
||||
}
|
||||
|
||||
T* p_;
|
||||
};
|
||||
using ModelProto = OrtObject<onnx::ModelProto>;
|
||||
using IOBinding = OrtObject<onnxruntime::IOBinding>;
|
||||
|
||||
} // namespace Windows::AI::MachineLearning::Adapter
|
||||
|
|
@ -3,4 +3,5 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "cppwinrt_onnx.h"
|
||||
#include "cppwinrt_onnx.h"
|
||||
#include "dx.h"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ enum ImageTensorChannelType {
|
|||
struct ImageTensorDescription {
|
||||
ImageTensorDataType dataType;
|
||||
ImageTensorChannelType channelType;
|
||||
UINT sizes[kImageTensorDimensionCountMax];
|
||||
int64_t sizes[kImageTensorDimensionCountMax];
|
||||
};
|
||||
} // namespace Windows::AI::MachineLearning::Internal
|
||||
|
|
@ -347,8 +347,8 @@ static void GPUTensorize(
|
|||
void* pAllocatedResource,
|
||||
WinML::BindingContext& context) {
|
||||
auto d3dResource =
|
||||
Dml::GetD3D12ResourceFromAllocation(
|
||||
spSession->GetExecutionProvider()->GetAllocator(0, ::OrtMemType::OrtMemTypeDefault).get(),
|
||||
_winmla::GetD3D12ResourceFromAllocation(
|
||||
spSession->GetExecutionProvider(),
|
||||
pAllocatedResource);
|
||||
auto spDevice = spSession->Device().as<LearningModelDevice>();
|
||||
|
||||
|
|
@ -391,14 +391,11 @@ static void GPUTensorize(
|
|||
static OrtValue CreateMLValue(
|
||||
com_ptr<LearningModelSession> spSession,
|
||||
const ImageTensorDescription& tensorDescriptor) {
|
||||
auto shape =
|
||||
std::vector<int64_t>(
|
||||
std::begin(tensorDescriptor.sizes),
|
||||
std::end(tensorDescriptor.sizes));
|
||||
auto pTensor = new onnxruntime::Tensor(
|
||||
tensorDescriptor.dataType == kImageTensorDataTypeFloat32 ? onnxruntime::DataTypeImpl::GetType<float>() : onnxruntime::DataTypeImpl::GetType<onnxruntime::MLFloat16>(),
|
||||
onnxruntime::TensorShape(shape),
|
||||
spSession->GetExecutionProvider()->GetAllocator(0, ::OrtMemType::OrtMemTypeDefault));
|
||||
auto pTensor = _winmla::CreateTensor(
|
||||
tensorDescriptor.dataType == kImageTensorDataTypeFloat32 ? TensorKind::Float : TensorKind::Float16,
|
||||
&(tensorDescriptor.sizes[0]),
|
||||
sizeof(tensorDescriptor.sizes) / sizeof(tensorDescriptor.sizes[0]),
|
||||
spSession->GetExecutionProvider());
|
||||
|
||||
OrtValue ort_value;
|
||||
ort_value.Init(pTensor,
|
||||
|
|
@ -591,7 +588,7 @@ HRESULT ImageFeatureValue::UpdateSourceResourceData(BindingContext& context, Ort
|
|||
auto pooledConverter = PoolObjectWrapper::Create(spDevice->DetensorizerStore()->Fetch(descriptor));
|
||||
|
||||
auto pProvider = spSession->GetExecutionProvider();
|
||||
auto d3dResource = Dml::GetD3D12ResourceFromAllocation(pProvider->GetAllocator(0, ::OrtMemType::OrtMemTypeDefault).get(), pAllocatedResource);
|
||||
auto d3dResource = _winmla::GetD3D12ResourceFromAllocation(pProvider, pAllocatedResource);
|
||||
|
||||
for (uint32_t batchIdx = 0; batchIdx < m_batchSize; ++batchIdx) {
|
||||
auto videoFrame = m_videoFrames.GetAt(batchIdx);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
#include "SequenceFeatureDescriptor.h"
|
||||
#include "TensorFeatureDescriptor.h"
|
||||
|
||||
using namespace OperatorHelper;
|
||||
|
||||
namespace winrt::Windows::AI::MachineLearning::implementation {
|
||||
LearningModel::LearningModel(
|
||||
const hstring& path,
|
||||
|
|
@ -35,7 +33,7 @@ LearningModel::LearningModel(
|
|||
|
||||
OverrideShapeInferenceMethods();
|
||||
|
||||
model_proto_ = WinML::CreateModelProto(path.c_str());
|
||||
model_proto_ = std::make_unique<_winmla::ModelProto>(WinML::CreateModelProto(path.c_str()));
|
||||
|
||||
Initialize();
|
||||
|
||||
|
|
@ -52,7 +50,7 @@ LearningModel::LearningModel(
|
|||
|
||||
OverrideShapeInferenceMethods();
|
||||
|
||||
model_proto_ = WinML::CreateModelProto(stream);
|
||||
model_proto_ = std::make_unique<_winmla::ModelProto>(WinML::CreateModelProto(stream));
|
||||
|
||||
Initialize();
|
||||
|
||||
|
|
@ -62,7 +60,7 @@ WINML_CATCH_ALL
|
|||
|
||||
void LearningModel::Initialize() {
|
||||
model_info_ = std::make_unique<WinML::ModelInfo>(
|
||||
model_proto_.get());
|
||||
model_proto_.get()->p_);
|
||||
}
|
||||
|
||||
void LearningModel::LogCreationEvent(bool fromStream) {
|
||||
|
|
@ -257,9 +255,9 @@ LearningModel::LoadFromStream(
|
|||
}
|
||||
WINML_CATCH_ALL
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
LearningModel::DetachModelProto() {
|
||||
std::unique_ptr<onnx::ModelProto> detached_model_proto;
|
||||
std::unique_ptr<_winmla::ModelProto> detached_model_proto;
|
||||
if (model_proto_ != nullptr) {
|
||||
detached_model_proto = std::move(model_proto_);
|
||||
|
||||
|
|
@ -269,13 +267,13 @@ LearningModel::DetachModelProto() {
|
|||
return detached_model_proto;
|
||||
}
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
LearningModel::CopyModelProto() {
|
||||
if (model_proto_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<onnx::ModelProto>(*model_proto_);
|
||||
return std::make_unique<_winmla::ModelProto>(*model_proto_);
|
||||
}
|
||||
|
||||
static std::once_flag g_schema_override_once_flag;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "LearningModel.g.h"
|
||||
#include "WinMLAdapter.h"
|
||||
|
||||
namespace Windows::AI::MachineLearning {
|
||||
class LotusEnvironment;
|
||||
class ModelInfo;
|
||||
namespace Windows::AI::MachineLearning {
|
||||
class LotusEnvironment;
|
||||
class ModelInfo;
|
||||
} // namespace Windows::AI::MachineLearning
|
||||
|
||||
namespace winrt::Windows::AI::MachineLearning::implementation {
|
||||
|
|
@ -101,10 +102,10 @@ struct LearningModel : LearningModelT<LearningModel> {
|
|||
IMLOperatorRegistry*
|
||||
GetOperatorRegistry();
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
DetachModelProto();
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
CopyModelProto();
|
||||
|
||||
private:
|
||||
|
|
@ -125,7 +126,7 @@ struct LearningModel : LearningModelT<LearningModel> {
|
|||
|
||||
private:
|
||||
std::shared_ptr<WinML::LotusEnvironment> lotus_environment_;
|
||||
std::unique_ptr<onnx::ModelProto> model_proto_;
|
||||
std::unique_ptr<WinML::Adapter::ModelProto> model_proto_;
|
||||
std::unique_ptr<WinML::ModelInfo> model_info_;
|
||||
ILearningModelOperatorProvider operator_provider_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#include "LearningModelSession.h"
|
||||
|
||||
#include "CustomRegistryHelper.h"
|
||||
#include "ImageFeatureDescriptor.h"
|
||||
#include "IOrtSessionBuilder.h"
|
||||
#include "WinMLAdapter.h"
|
||||
#include "LearningModel.h"
|
||||
#include "LearningModelBinding.h"
|
||||
#include "LearningModelEvaluationResult.h"
|
||||
|
|
@ -39,110 +39,6 @@ struct __declspec(uuid("D113B493-BBA2-4993-8608-D706A73B91CE")) __declspec(novta
|
|||
static const GUID WINML_PIX_EVAL_CAPTURABLE_WORK_GUID = __uuidof(guid_details::WINML_PIX_EVAL_CAPTURABLE_WORK_GUID);
|
||||
|
||||
namespace winrt::Windows::AI::MachineLearning::implementation {
|
||||
// ORT intentionally requires callers derive from their session class to access
|
||||
// the protected Load method used below.
|
||||
class InferenceSessionProtectedLoadAccessor : public onnxruntime::InferenceSession {
|
||||
public:
|
||||
onnxruntime::common::Status
|
||||
Load(std::unique_ptr<ONNX_NAMESPACE::ModelProto> p_model_proto) {
|
||||
return onnxruntime::InferenceSession::Load(std::move(p_model_proto));
|
||||
}
|
||||
};
|
||||
|
||||
static bool
|
||||
IsFeatureDescriptorFp16(
|
||||
winml::ILearningModelFeatureDescriptor descriptor) {
|
||||
if (auto imageFeatureDescriptor = descriptor.try_as<ImageFeatureDescriptor>()) {
|
||||
return TensorKind::Float16 == imageFeatureDescriptor->TensorKind();
|
||||
}
|
||||
|
||||
if (auto tensorFeatureDescriptor = descriptor.try_as<TensorFeatureDescriptor>()) {
|
||||
return TensorKind::Float16 == tensorFeatureDescriptor->TensorKind();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
EnsureModelDeviceCompatibility(
|
||||
winml::LearningModel const& model,
|
||||
onnx::ModelProto* p_model_proto,
|
||||
winml::LearningModelDevice const& device) {
|
||||
auto isFloat16Supported = device.as<LearningModelDevice>()->GetD3DDeviceCache()->IsFloat16Supported();
|
||||
if (!isFloat16Supported) {
|
||||
auto& graph = p_model_proto->graph();
|
||||
|
||||
// The model will not contain fp16 operations if:
|
||||
// 1. The model has no fp16 inputs
|
||||
// 2. The model has no fp16 initializers
|
||||
// 3. The model does not create any fp16 intermediary tensors via the Cast (to float16) operator
|
||||
// 4. The model does not have any fp16 outputs
|
||||
|
||||
// 1. Ensure that The model has no fp16 inputs
|
||||
for (auto descriptor : model.InputFeatures()) {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
IsFeatureDescriptorFp16(descriptor),
|
||||
"The model contains a 16-bit input (%ls), but the current device does not support 16-bit float.",
|
||||
descriptor.Name().c_str());
|
||||
}
|
||||
|
||||
// 2. Ensure that the model has no fp16 initializers
|
||||
for (int i = 0; i < graph.node_size(); i++) {
|
||||
auto node = graph.node(i);
|
||||
if (node.op_type() == "Cast" && node.domain().empty()) {
|
||||
for (int attribIndex = 0; attribIndex < node.attribute_size(); attribIndex++) {
|
||||
auto attribute = node.attribute(attribIndex);
|
||||
if (attribute.name() == "to") {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
attribute.i() == onnx::TensorProto::DataType::TensorProto_DataType_FLOAT16,
|
||||
"The model contains a 16-bit float Cast Op (%s), but the current device does not support 16-bit float.",
|
||||
node.name().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Ensure that the model does not create any fp16 intermediary
|
||||
// tensors via the Cast (to float16) operator
|
||||
for (int i = 0; i < graph.initializer_size(); i++) {
|
||||
auto initializer = graph.initializer(i);
|
||||
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
initializer.data_type() == onnx::TensorProto::DataType::TensorProto_DataType_FLOAT16,
|
||||
"The model contains a 16-bit float initializer (%s), but the current device does not support 16-bit float.",
|
||||
initializer.name().c_str());
|
||||
}
|
||||
|
||||
// 4. Ensure that the model does not have any fp16 outputs
|
||||
for (auto descriptor : model.OutputFeatures()) {
|
||||
WINML_THROW_HR_IF_TRUE_MSG(
|
||||
DXGI_ERROR_UNSUPPORTED,
|
||||
IsFeatureDescriptorFp16(descriptor),
|
||||
"The model contains a 16-bit output (%ls), but the current device does not support 16-bit float.",
|
||||
descriptor.Name().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
RegisterCustomRegistry(
|
||||
onnxruntime::InferenceSession* p_session,
|
||||
IMLOperatorRegistry* registry) {
|
||||
RETURN_HR_IF(S_OK, registry == nullptr);
|
||||
RETURN_HR_IF_NULL(E_POINTER, p_session);
|
||||
|
||||
auto custom_registries = WinML::GetLotusCustomRegistries(registry);
|
||||
|
||||
// Register
|
||||
for (auto& custom_registry : custom_registries) {
|
||||
WINML_THROW_IF_NOT_OK(p_session->RegisterCustomRegistry(custom_registry));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LearningModelSession::LearningModelSession(
|
||||
winml::LearningModel const& model) try : LearningModelSession(model,
|
||||
|
|
@ -166,7 +62,7 @@ LearningModelSession::LearningModelSession(
|
|||
}
|
||||
WINML_CATCH_ALL
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
LearningModelSession::GetOptimizedModel() {
|
||||
// Get the model proto
|
||||
auto should_close_model =
|
||||
|
|
@ -176,9 +72,9 @@ LearningModelSession::GetOptimizedModel() {
|
|||
return GetOptimizedModel(should_close_model);
|
||||
}
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
LearningModelSession::GetOptimizedModel(bool should_close_model) {
|
||||
std::unique_ptr<onnx::ModelProto> model_proto;
|
||||
std::unique_ptr<_winmla::ModelProto> model_proto;
|
||||
|
||||
{
|
||||
// Lock the model detach/copy since multiple threads can access concurrently
|
||||
|
|
@ -196,7 +92,7 @@ LearningModelSession::GetOptimizedModel(bool should_close_model) {
|
|||
}
|
||||
|
||||
// Ensure that the model is runnable on the device
|
||||
EnsureModelDeviceCompatibility(model_, model_proto.get(), device_);
|
||||
WINML_THROW_IF_FAILED(_winmla::EnsureModelDeviceCompatibility(model_, model_proto.get()->p_, device_));
|
||||
|
||||
return model_proto;
|
||||
}
|
||||
|
|
@ -230,16 +126,16 @@ void LearningModelSession::Initialize() {
|
|||
|
||||
// Register the custom operator registry
|
||||
auto model = model_.as<winmlp::LearningModel>();
|
||||
RegisterCustomRegistry(session.get(), model->GetOperatorRegistry());
|
||||
WINML_THROW_IF_FAILED(_winmla::RegisterCustomRegistry(session.get(), model->GetOperatorRegistry()));
|
||||
|
||||
// Register only the transformers not already in ORT
|
||||
const bool registerLotusTransformers = false;
|
||||
GraphTransformerHelpers::RegisterGraphTransformers(session.get(), registerLotusTransformers);
|
||||
|
||||
// Load the model into the session
|
||||
auto session_protected_load_accessor =
|
||||
static_cast<InferenceSessionProtectedLoadAccessor*>(session.get());
|
||||
WINML_THROW_IF_NOT_OK(session_protected_load_accessor->Load(std::move(model_proto)));
|
||||
WINML_THROW_IF_FAILED(_winmla::LoadModel(session.get(), model_proto.get()->p_));
|
||||
// the session owns the model_proto now
|
||||
model_proto.release();
|
||||
|
||||
// Initialize the session
|
||||
session_builder->Initialize(session.get(), p_cached_execution_provider);
|
||||
|
|
@ -525,7 +421,7 @@ void LearningModelSession::ApplyEvaluationProperties() try {
|
|||
if (evaluation_properties_) {
|
||||
auto is_debug_output_enabled = evaluation_properties_.HasKey(c_enable_debug_output);
|
||||
if (is_debug_output_enabled) {
|
||||
WinML::CWinMLLogSink::EnableDebugOutput();
|
||||
_winmla::EnableDebugOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "LearningModelBinding.h"
|
||||
#include "WinML_Lock.h"
|
||||
#include "WinMLAdapter.h"
|
||||
|
||||
namespace winrt::Windows::AI::MachineLearning::implementation {
|
||||
|
||||
|
|
@ -74,10 +75,10 @@ struct LearningModelSession : LearningModelSessionT<LearningModelSession> {
|
|||
void
|
||||
Initialize();
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
GetOptimizedModel();
|
||||
|
||||
std::unique_ptr<onnx::ModelProto>
|
||||
std::unique_ptr<_winmla::ModelProto>
|
||||
GetOptimizedModel(bool should_close_model);
|
||||
|
||||
uint64_t
|
||||
|
|
|
|||
|
|
@ -34,4 +34,7 @@ namespace Windows::AI::MachineLearning {}
|
|||
namespace WinML = ::Windows::AI::MachineLearning;
|
||||
|
||||
namespace Windows::AI::MachineLearning::Telemetry {}
|
||||
namespace _winmlt = ::Windows::AI::MachineLearning::Telemetry;
|
||||
namespace _winmlt = ::Windows::AI::MachineLearning::Telemetry;
|
||||
|
||||
namespace Windows::AI::MachineLearning::Adapter {}
|
||||
namespace _winmla = ::Windows::AI::MachineLearning::Adapter;
|
||||
Loading…
Reference in a new issue