fixed some lifetime management.

fixed the debug build.
squeezenet passes using winmlrunner for CPU and GPU
This commit is contained in:
Paul McDaniel 2019-11-18 09:50:25 -08:00
parent 7f9a7f5abe
commit b4047a0aad
14 changed files with 75 additions and 99 deletions

View file

@ -122,10 +122,8 @@ target_link_libraries(winml_lib_telemetry PRIVATE wil)
add_library(winml_lib_core STATIC
${winml_lib_api_core_dir}/inc/AbiCustomRegistryImpl.h
${winml_lib_api_core_dir}/inc/CustomRegistryHelper.h
${winml_lib_api_core_dir}/inc/IOrtSessionBuilder.h
${winml_lib_api_core_dir}/inc/LotusEnvironment.h
${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
@ -138,8 +136,6 @@ add_library(winml_lib_core STATIC
${winml_lib_api_core_dir}/CpuOrtSessionBuilder.cpp
${winml_lib_api_core_dir}/DmlOrtSessionBuilder.cpp
${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
)

View file

@ -1,10 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "precomp.h"
namespace Dml
{
}

View file

@ -32,24 +32,26 @@ CpuOrtSessionBuilder::CpuOrtSessionBuilder() {
HRESULT
CpuOrtSessionBuilder::CreateSessionOptions(
onnxruntime::SessionOptions* p_options) {
ISessionOptions** p_options) {
RETURN_HR_IF_NULL(E_POINTER, p_options);
*p_options = onnxruntime::SessionOptions();
p_options->graph_optimization_level = onnxruntime::TransformerLevel::Level3;
auto options = wil::MakeOrThrow<AbiSafeSessionOptions>();
options.CopyTo(__uuidof(ISessionOptions), (void**)p_options);
(*p_options)->get().graph_optimization_level = onnxruntime::TransformerLevel::Level3;
// Onnxruntime will use half the number of concurrent threads supported on the system
// by default. This causes MLAS to not exercise every logical core.
// We force the thread pool size to be maxxed out to ensure that WinML always
// runs the fastest.
p_options->intra_op_num_threads = std::thread::hardware_concurrency();
(*p_options)->get().intra_op_num_threads = std::thread::hardware_concurrency();
return S_OK;
}
HRESULT
CpuOrtSessionBuilder::CreateSession(
const onnxruntime::SessionOptions& options,
ISessionOptions* options,
_winmla::IInferenceSession** p_session,
onnxruntime::IExecutionProvider** pp_provider) {
RETURN_HR_IF_NULL(E_POINTER, p_session);
@ -57,7 +59,7 @@ CpuOrtSessionBuilder::CreateSession(
RETURN_HR_IF(E_POINTER, *pp_provider != nullptr);
// Create the inference session
auto session = std::make_unique<onnxruntime::InferenceSession>(options);
auto session = std::make_unique<onnxruntime::InferenceSession>(options->get());
// Create the cpu execution provider
onnxruntime::CPUExecutionProviderInfo xpInfo;

View file

@ -15,10 +15,10 @@ class CpuOrtSessionBuilder : public Microsoft::WRL::RuntimeClass <
CpuOrtSessionBuilder();
HRESULT STDMETHODCALLTYPE CreateSessionOptions(
onnxruntime::SessionOptions* p_options) override;
ISessionOptions** p_options) override;
HRESULT STDMETHODCALLTYPE CreateSession(
const onnxruntime::SessionOptions& options,
ISessionOptions* options,
_winmla::IInferenceSession** p_session,
onnxruntime::IExecutionProvider** pp_provider) override;

View file

@ -39,15 +39,16 @@ DmlOrtSessionBuilder::DmlOrtSessionBuilder(
HRESULT
DmlOrtSessionBuilder::CreateSessionOptions(
onnxruntime::SessionOptions* p_options) {
ISessionOptions** p_options) {
RETURN_HR_IF_NULL(E_POINTER, p_options);
*p_options = onnxruntime::SessionOptions();
p_options->graph_optimization_level = onnxruntime::TransformerLevel::Level3;
auto options = wil::MakeOrThrow<AbiSafeSessionOptions>();
options.CopyTo(__uuidof(ISessionOptions), (void**)p_options);
(*p_options)->get().graph_optimization_level = onnxruntime::TransformerLevel::Level3;
// Disable the mem pattern session option for DML. It will cause problems with how memory is allocated.
p_options->enable_mem_pattern = false;
(*p_options)->get().enable_mem_pattern = false;
return S_OK;
}
@ -100,7 +101,7 @@ Microsoft::WRL::ComPtr<IDMLDevice> CreateDmlDevice(ID3D12Device* d3d12Device) {
}
HRESULT DmlOrtSessionBuilder::CreateSession(
const onnxruntime::SessionOptions& options,
ISessionOptions* options,
_winmla::IInferenceSession** p_session,
onnxruntime::IExecutionProvider** pp_provider) {
RETURN_HR_IF_NULL(E_POINTER, p_session);
@ -113,7 +114,7 @@ HRESULT DmlOrtSessionBuilder::CreateSession(
Microsoft::WRL::ComPtr<IDMLDevice> dmlDevice = CreateDmlDevice(p_d3d_device);
std::unique_ptr<onnxruntime::IExecutionProvider> gpu_provider = Dml::CreateExecutionProvider(dmlDevice.Get(), p_queue);
auto session = std::make_unique<onnxruntime::InferenceSession>(options);
auto session = std::make_unique<onnxruntime::InferenceSession>(options->get());
// Cache the provider's raw pointer
*pp_provider = gpu_provider.get();

View file

@ -15,10 +15,10 @@ class DmlOrtSessionBuilder : public Microsoft::WRL::RuntimeClass <
DmlOrtSessionBuilder(ID3D12Device* device, ID3D12CommandQueue* queue);
HRESULT STDMETHODCALLTYPE CreateSessionOptions(
onnxruntime::SessionOptions* p_options) override;
ISessionOptions** p_options) override;
HRESULT STDMETHODCALLTYPE CreateSession(
const onnxruntime::SessionOptions& options,
ISessionOptions* options,
_winmla::IInferenceSession** p_session,
onnxruntime::IExecutionProvider** pp_provider) override;

View file

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "inc/ModelInfo.h"
#include "FeatureDescriptorFactory.h"
using namespace Windows::AI::MachineLearning;

View file

@ -1,5 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"

View file

@ -44,8 +44,6 @@ class InferenceSessionProtectedLoadAccessor : public onnxruntime::InferenceSessi
}
};
// class AbiSafeTensor
//
class AbiSafeTensor : public Microsoft::WRL::RuntimeClass <
@ -112,8 +110,7 @@ public:
HRESULT STDMETHODCALLTYPE GetTensor(ITensor ** tensor) override {
auto tensor_inner = ort_value_.GetMutable<onnxruntime::Tensor>();
auto tensor_outer = wil::MakeOrThrow<AbiSafeTensor>(tensor_inner, this);
*tensor = tensor_outer.Detach();
return S_OK;
return tensor_outer.CopyTo(__uuidof(ITensor), (void**)tensor);
}
}; // class AbiSafeOrtValue
@ -130,8 +127,12 @@ public:
return model_proto_.get();
}
onnx::ModelProto* STDMETHODCALLTYPE detach() override {
return model_proto_.release();
}
private:
std::shared_ptr<onnx::ModelProto> model_proto_;
std::unique_ptr<onnx::ModelProto> model_proto_;
}; // class ModelProto
@ -155,28 +156,28 @@ public:
Initialize(model_proto);
}
std::string STDMETHODCALLTYPE author() override {
std::string& STDMETHODCALLTYPE author() override {
return author_;
}
std::string STDMETHODCALLTYPE name() override {
std::string& STDMETHODCALLTYPE name() override {
return name_;
}
std::string STDMETHODCALLTYPE domain() override {
std::string& STDMETHODCALLTYPE domain() override {
return domain_;
}
std::string STDMETHODCALLTYPE description() override {
std::string& STDMETHODCALLTYPE description() override {
return description_;
}
int64_t STDMETHODCALLTYPE version() override {
return version_;
}
std::unordered_map<std::string, std::string> STDMETHODCALLTYPE model_metadata() override {
std::unordered_map<std::string, std::string>& STDMETHODCALLTYPE model_metadata() override {
return model_metadata_;
}
wfc::IVector<winml::ILearningModelFeatureDescriptor> STDMETHODCALLTYPE input_features() override {
wfc::IVector<winml::ILearningModelFeatureDescriptor>& STDMETHODCALLTYPE input_features() override {
return input_features_;
}
wfc::IVector<winml::ILearningModelFeatureDescriptor> STDMETHODCALLTYPE output_features() override {
wfc::IVector<winml::ILearningModelFeatureDescriptor>& STDMETHODCALLTYPE output_features() override {
return output_features_;
}
@ -804,7 +805,8 @@ InferenceSession::LoadModel(
IModelProto* model_proto) {
auto session_protected_load_accessor =
static_cast<InferenceSessionProtectedLoadAccessor*>(session_.get());
std::unique_ptr<ONNX_NAMESPACE::ModelProto> model_proto_ptr(model_proto->get());
// session's like to have their very own copy of the model_proto, use detach()
std::unique_ptr<ONNX_NAMESPACE::ModelProto> model_proto_ptr(model_proto->detach());
ORT_THROW_IF_ERROR(session_protected_load_accessor->Load(std::move(model_proto_ptr)));
return S_OK;
}

View file

@ -1,5 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once

View file

@ -1,9 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
namespace Windows::AI::MachineLearning {
} // namespace Windows::AI::MachineLearning

View file

@ -3,21 +3,18 @@
#pragma once
#include "IOrtSessionBuilder.h"
#include "ModelInfo.h"
namespace Windows::AI::MachineLearning::Adapter {
MIDL_INTERFACE("eaae30b5-7381-432d-9730-322136b02371") IModelInfo : IUnknown{
// model metadata
virtual std::string STDMETHODCALLTYPE author() = 0;
virtual std::string STDMETHODCALLTYPE name() = 0;
virtual std::string STDMETHODCALLTYPE domain() = 0;
virtual std::string STDMETHODCALLTYPE description() = 0;
virtual std::string& STDMETHODCALLTYPE author() = 0;
virtual std::string& STDMETHODCALLTYPE name() = 0;
virtual std::string& STDMETHODCALLTYPE domain() = 0;
virtual std::string& STDMETHODCALLTYPE description() = 0;
virtual int64_t STDMETHODCALLTYPE version() = 0;
virtual std::unordered_map<std::string, std::string> STDMETHODCALLTYPE model_metadata() = 0;
virtual wfc::IVector<winml::ILearningModelFeatureDescriptor> STDMETHODCALLTYPE input_features() = 0;
virtual wfc::IVector<winml::ILearningModelFeatureDescriptor> STDMETHODCALLTYPE output_features() = 0;
virtual std::unordered_map<std::string, std::string>& STDMETHODCALLTYPE model_metadata() = 0;
virtual wfc::IVector<winml::ILearningModelFeatureDescriptor>& STDMETHODCALLTYPE input_features() = 0;
virtual wfc::IVector<winml::ILearningModelFeatureDescriptor>& STDMETHODCALLTYPE output_features() = 0;
};
MIDL_INTERFACE("eaae30b5-7381-432d-9730-322136b02371") ITensor : IUnknown{
@ -53,7 +50,10 @@ MIDL_INTERFACE("438e7719-554a-4058-84d9-eb6226c34887") IIOBinding : IUnknown{
};
MIDL_INTERFACE("a848faf6-5a2e-4a7f-b622-cc036f71e28a") IModelProto : IUnknown{
// this returns a weak ref
virtual onnx::ModelProto* STDMETHODCALLTYPE get() = 0;
// this returns the ownership without touching the reference and forgets about the object
virtual onnx::ModelProto* STDMETHODCALLTYPE detach() = 0;
};
MIDL_INTERFACE("6ec766ef-6365-42bf-b64f-ae85c015adb8") IInferenceSession : IUnknown {
@ -70,15 +70,22 @@ MIDL_INTERFACE("6ec766ef-6365-42bf-b64f-ae85c015adb8") IInferenceSession : IUnkn
virtual void STDMETHODCALLTYPE ReleaseCompletedReferences(onnxruntime::IExecutionProvider* dml_provider) = 0;
};
MIDL_INTERFACE("55a956a7-c20e-440d-b2d2-a77acf35de10") ISessionOptions : IUnknown{
// this returns a weak ref
virtual onnxruntime::SessionOptions& STDMETHODCALLTYPE get() = 0;
// end
virtual void STDMETHODCALLTYPE SetBatchOverride(uint32_t batch_size) = 0;
};
// The IOrtSessionBuilder offers an abstraction over the creation of
// InferenceSession, that enables the creation of the session based on a device (CPU/DML).
MIDL_INTERFACE("2746f03a-7e08-4564-b5d0-c670fef116ee") IOrtSessionBuilder : IUnknown {
virtual HRESULT STDMETHODCALLTYPE CreateSessionOptions(
onnxruntime::SessionOptions* options) = 0;
ISessionOptions** options) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateSession(
const onnxruntime::SessionOptions& options,
ISessionOptions* options,
IInferenceSession** session,
onnxruntime::IExecutionProvider** provider) = 0;
@ -184,6 +191,22 @@ private:
std::shared_ptr<onnxruntime::InferenceSession> session_;
};
class AbiSafeSessionOptions : public Microsoft::WRL::RuntimeClass <
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
ISessionOptions> {
private:
onnxruntime::SessionOptions options_;
public:
virtual onnxruntime::SessionOptions& STDMETHODCALLTYPE get() override {
return options_;
}
virtual void STDMETHODCALLTYPE SetBatchOverride(uint32_t batch_size) override {
onnxruntime::FreeDimensionOverride overrideOption = {};
overrideOption.dimension_denotation = onnx::DATA_BATCH;
overrideOption.dimension_override = batch_size;
options_.free_dimension_overrides.emplace_back(overrideOption);
}
};
// header only code to enable smart pointers on abstract ort objects
template <typename T>

View file

@ -6,7 +6,6 @@
#include "LearningModel.h"
#include "core/providers/dml/DmlExecutionProvider/src/MLOperatorAuthorImpl.h"
#include "ModelInfo.h"
#include "TelemetryEvent.h"
#include "LotusEnvironment.h"

View file

@ -6,7 +6,6 @@
#include "LearningModelSession.h"
#include "ImageFeatureDescriptor.h"
#include "IOrtSessionBuilder.h"
#include "WinMLAdapter.h"
#include "LearningModel.h"
#include "LearningModelBinding.h"
@ -110,21 +109,18 @@ void LearningModelSession::Initialize() {
device_impl->GetDeviceQueue(),
session_builder.put()));
onnxruntime::SessionOptions options = {};
WINML_THROW_IF_FAILED(session_builder->CreateSessionOptions(&options));
com_ptr<_winmla::ISessionOptions> options;
WINML_THROW_IF_FAILED(session_builder->CreateSessionOptions(options.put()));
// Make onnxruntime apply the batch size override, if any
if (session_options_ && session_options_.BatchSizeOverride() != 0)
{
onnxruntime::FreeDimensionOverride overrideOption = {};
overrideOption.dimension_denotation = onnx::DATA_BATCH;
overrideOption.dimension_override = session_options_.BatchSizeOverride();
options.free_dimension_overrides.emplace_back(overrideOption);
options->SetBatchOverride(session_options_.BatchSizeOverride());
}
com_ptr<_winmla::IInferenceSession> session;
WINML_THROW_IF_FAILED(session_builder->CreateSession(
options, session.put(), &cached_execution_provider_));
options.get(), session.put(), &cached_execution_provider_));
// Register the custom operator registry
auto model = model_.as<winmlp::LearningModel>();
@ -136,7 +132,7 @@ void LearningModelSession::Initialize() {
// Load the model into the session
WINML_THROW_IF_FAILED(session->LoadModel(model_proto.get()));
// the session owns the model_proto now
// the session owns the model_proto now, it used detach()
model_proto = nullptr;
// Initialize the session