User/xianz/ortthrow (#2596)

* thrown and handle onnxruntime exceptions

* handle exception thrown from ort in winmladapter

* undo changes in error.h

* add message to HRESULT
This commit is contained in:
Xiang Zhang 2019-12-09 16:44:55 -08:00 committed by GitHub
parent b248f2979a
commit 36e557ec12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 133 additions and 74 deletions

View file

@ -101,6 +101,10 @@ void LogRuntimeError(uint32_t session_id, const common::Status& status, const ch
#define ORT_THROW(...) \
throw ::onnxruntime::OnnxRuntimeException(ORT_WHERE_WITH_STACK, ::onnxruntime::MakeString(__VA_ARGS__))
// Throw an exception with optional message and status code.
#define ORT_THROW_WITH_STATUS(status) \
throw ::onnxruntime::OnnxRuntimeException(ORT_WHERE_WITH_STACK, status)
// Just in order to mark things as not implemented. Do not use in final code.
#define ORT_NOT_IMPLEMENTED(...) \
throw ::onnxruntime::NotImplementedException(::onnxruntime::MakeString(__VA_ARGS__))
@ -161,7 +165,7 @@ void LogRuntimeError(uint32_t session_id, const common::Status& status, const ch
auto _status = (expr); \
if ((!_status.IsOK())) { \
::onnxruntime::LogRuntimeError(0, _status, __FILE__, __FUNCTION__, __LINE__); \
ORT_THROW(_status); \
ORT_THROW_WITH_STATUS(_status); \
} \
} while (0)

View file

@ -11,10 +11,12 @@
#include <vector>
#include "core/common/common.h"
#include "core/common/status.h"
#include "core/common/code_location.h"
namespace onnxruntime {
using common::Status;
using common::StatusCode;
class NotImplementedException : public std::logic_error {
public:
explicit NotImplementedException(const char* _Message = "Function not yet implemented") noexcept : std::logic_error(_Message){};
@ -32,6 +34,11 @@ class OnnxRuntimeException : public std::exception {
: OnnxRuntimeException(location, nullptr, msg) {
}
OnnxRuntimeException(const CodeLocation& location, const Status& status) noexcept
: OnnxRuntimeException(location, nullptr, status.ToString()) {
status_ = status;
}
/**
Create a new exception that captures the location it was thrown from.
@param location Location in the source code the exception is being thrown from
@ -58,6 +65,9 @@ class OnnxRuntimeException : public std::exception {
what_ = ss.str();
}
const Status GetStatus() const noexcept {
return status_;
}
const char* what() const noexcept override {
return what_.c_str();
}
@ -66,6 +76,7 @@ class OnnxRuntimeException : public std::exception {
const CodeLocation location_;
const std::vector<std::string> stacktrace_;
std::string what_;
Status status_;
};
} // namespace onnxruntime

View file

@ -13,6 +13,7 @@
#include "CpuOrtSessionBuilder.h"
#include "WinMLAdapter.h"
#include "WinMLAdapterErrors.h"
// winml includes
#include "core/providers/dml/GraphTransformers/GraphTransformerHelpers.h"
@ -52,7 +53,7 @@ CpuOrtSessionBuilder::CreateSessionOptions(
session_options.release();
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT
CpuOrtSessionBuilder::CreateSession(
@ -85,7 +86,7 @@ CpuOrtSessionBuilder::CreateSession(
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT
CpuOrtSessionBuilder::Initialize(
@ -95,6 +96,6 @@ CpuOrtSessionBuilder::Initialize(
ORT_THROW_IF_ERROR(p_session->get()->Initialize());
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
} // Windows::AI::MachineLearning::Adapter

View file

@ -14,6 +14,7 @@
#define ERROR 0
#include "DmlOrtSessionBuilder.h"
#include "WinMLAdapterErrors.h"
// winml includes
#include "core/providers/dml/GraphTransformers/GraphTransformerHelpers.h"
@ -34,8 +35,8 @@ using namespace Windows::AI::MachineLearning;
namespace Windows::AI::MachineLearning::Adapter {
DmlOrtSessionBuilder::DmlOrtSessionBuilder(
ID3D12Device* device,
ID3D12CommandQueue* queue){
ID3D12Device* device,
ID3D12CommandQueue* queue) {
device_.copy_from(device);
queue_.copy_from(queue);
}
@ -58,7 +59,7 @@ DmlOrtSessionBuilder::CreateSessionOptions(
session_options.release();
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
static HRESULT
RegisterCustomRegistry(
@ -71,7 +72,7 @@ RegisterCustomRegistry(
// Register
for (auto& custom_registry : custom_registries) {
ORT_THROW_IF_ERROR(p_session->RegisterCustomRegistry(custom_registry));
ORT_THROW_IF_ERROR(p_session->RegisterCustomRegistry(custom_registry));
}
}
@ -134,7 +135,7 @@ HRESULT DmlOrtSessionBuilder::CreateSession(
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT DmlOrtSessionBuilder::Initialize(
winmla::IInferenceSession* p_session,
@ -156,8 +157,8 @@ HRESULT DmlOrtSessionBuilder::Initialize(
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
} // Windows::AI::MachineLearning::Adapter
} // namespace Windows::AI::MachineLearning::Adapter
#endif USE_DML

View file

@ -3,6 +3,7 @@
#include "pch.h"
#include "WinMLAdapter.h"
#include "WinMLAdapterErrors.h"
#include "CustomRegistryHelper.h"
#include "PheonixSingleton.h"
#include "LotusEnvironment.h"
@ -128,7 +129,7 @@ class ModelInfo : public Microsoft::WRL::RuntimeClass<
winrt::copy_to_abi(out.GetView(), *(void**)metadata);
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetInputFeatures(
ABI::Windows::Foundation::Collections::IVectorView<winml::ILearningModelFeatureDescriptor>** features) override try {
@ -136,7 +137,7 @@ class ModelInfo : public Microsoft::WRL::RuntimeClass<
winrt::copy_to_abi(input_features_.GetView(), *(void**)features);
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetOutputFeatures(
ABI::Windows::Foundation::Collections::IVectorView<winml::ILearningModelFeatureDescriptor>** features) override try {
@ -144,7 +145,7 @@ class ModelInfo : public Microsoft::WRL::RuntimeClass<
winrt::copy_to_abi(output_features_.GetView(), *(void**)features);
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
static std::vector<const char*>
GetAllNodeOutputs(const onnx::ModelProto& model_proto) {
@ -309,7 +310,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
auto model_proto_outer = wil::MakeOrThrow<ModelProto>(model_proto_inner);
return model_proto_outer.CopyTo(__uuidof(IModelProto), reinterpret_cast<void**>(model_proto));
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
// factory methods for creating an ort model from a stream
HRESULT STDMETHODCALLTYPE CreateModelProto(
@ -326,7 +327,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
auto model_proto_outer = wil::MakeOrThrow<ModelProto>(model_proto_inner);
return model_proto_outer.CopyTo(__uuidof(IModelProto), reinterpret_cast<void**>(model_proto));
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
// factory methods for creating an ort model from a model_proto
HRESULT STDMETHODCALLTYPE CreateModelProto(IModelProto* model_proto_in, IModelProto** model_proto) override try {
@ -334,18 +335,18 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
auto model_proto_outer = wil::MakeOrThrow<ModelProto>(model_proto_inner);
return model_proto_outer.CopyTo(__uuidof(IModelProto), reinterpret_cast<void**>(model_proto));
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE CreateModelInfo(IModelProto* model_proto, IModelInfo** model_info) override try {
auto model_info_outer = wil::MakeOrThrow<ModelInfo>(model_proto->get());
return model_info_outer.CopyTo(__uuidof(IModelInfo), reinterpret_cast<void**>(model_info));
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
void STDMETHODCALLTYPE EnableDebugOutput() override try {
WinML::CWinMLLogSink::EnableDebugOutput();
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
static bool IsFeatureDescriptorFp16(
winml::ILearningModelFeatureDescriptor descriptor) {
@ -422,7 +423,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
}
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
ID3D12Resource* STDMETHODCALLTYPE GetD3D12ResourceFromAllocation(onnxruntime::IExecutionProvider* provider, void* allocation) override try {
#ifdef USE_DML
@ -466,7 +467,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return E_NOTIMPL;
#endif USE_DML
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetMapType(const OrtValue* ort_value, ONNXTensorElementDataType* key_type, ONNXTensorElementDataType* value_type) override try {
*key_type = *value_type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED;
@ -498,7 +499,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
}
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetVectorMapType(const OrtValue* ort_value, ONNXTensorElementDataType* key_type, ONNXTensorElementDataType* value_type) override try {
*key_type = *value_type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED;
@ -512,7 +513,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
}
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetCustomRegistry(IMLOperatorRegistry** registry) override try {
#ifdef USE_DML
@ -523,7 +524,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return E_NOTIMPL;
#endif USE_DML
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetOperatorRegistry(ILearningModelOperatorProviderNative* operator_provider_native, IMLOperatorRegistry** registry) override try {
#ifdef USE_DML
@ -536,7 +537,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return E_NOTIMPL;
#endif USE_DML
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
void* STDMETHODCALLTYPE CreateGPUAllocationFromD3DResource(ID3D12Resource* pResource) override try {
#ifdef USE_DML
@ -553,7 +554,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
Dml::FreeGPUAllocation(ptr);
#endif USE_DML
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
HRESULT STDMETHODCALLTYPE CopyTensor(
onnxruntime::IExecutionProvider* provider,
@ -566,7 +567,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return E_NOTIMPL;
#endif USE_DML
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
// Override select shape inference functions which are incomplete in ONNX with versions that are complete,
// and are also used in DML kernel registrations. Doing this avoids kernel and shader creation being
@ -584,7 +585,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return S_OK; // needs to return S_OK otherwise everything breaks because this gets called from the learningmodel constructor
#endif USE_DML
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetProviderMemoryInfo(
onnxruntime::IExecutionProvider* provider,
@ -598,7 +599,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
}
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE GetValueMemoryInfo(const OrtValue* ort_value, OrtMemoryInfo** memory_info) override try {
const auto& tensor = ort_value->Get<onnxruntime::Tensor>();
@ -609,7 +610,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
}
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
struct AllocatorWrapper : public OrtAllocator {
public:
@ -645,7 +646,7 @@ class WinMLAdapter : public Microsoft::WRL::RuntimeClass<
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
}; // namespace Windows::AI::MachineLearning::Adapter
std::shared_ptr<WinML::LotusEnvironment> WinMLAdapter::lotus_environment_ = nullptr;
@ -654,7 +655,7 @@ extern "C" HRESULT STDMETHODCALLTYPE OrtGetWinMLAdapter(IWinMLAdapter** adapter)
Microsoft::WRL::ComPtr<WinMLAdapter> adapterptr = wil::MakeOrThrow<WinMLAdapter>();
return adapterptr.CopyTo(__uuidof(IWinMLAdapter), reinterpret_cast<void**>(adapter));
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
// InferenceSession
// ================
@ -668,19 +669,19 @@ void STDMETHODCALLTYPE InferenceSession::RegisterGraphTransformers() try {
GraphTransformerHelpers::RegisterGraphTransformers(session_.get());
#endif USE_DML
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
HRESULT STDMETHODCALLTYPE InferenceSession::StartProfiling() try {
this->session_->StartProfiling(PheonixSingleton<WinML::LotusEnvironment>()->GetDefaultLogger());
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE InferenceSession::EndProfiling() try {
this->session_->EndProfiling();
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE
InferenceSession::LoadModel(
@ -692,7 +693,7 @@ InferenceSession::LoadModel(
ORT_THROW_IF_ERROR(session_protected_load_accessor->Load(std::move(model_proto_ptr)));
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
HRESULT STDMETHODCALLTYPE
InferenceSession::RegisterCustomRegistry(
@ -710,28 +711,28 @@ InferenceSession::RegisterCustomRegistry(
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
void STDMETHODCALLTYPE InferenceSession::FlushContext(onnxruntime::IExecutionProvider* dml_provider) try {
#ifdef USE_DML
Dml::FlushContext(dml_provider);
#endif USE_DML
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
void STDMETHODCALLTYPE InferenceSession::TrimUploadHeap(onnxruntime::IExecutionProvider* dml_provider) try {
#ifdef USE_DML
Dml::TrimUploadHeap(dml_provider);
#endif USE_DML
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
void STDMETHODCALLTYPE InferenceSession::ReleaseCompletedReferences(onnxruntime::IExecutionProvider* dml_provider) try {
#ifdef USE_DML
Dml::ReleaseCompletedReferences(dml_provider);
#endif USE_DML
}
WINML_CATCH_ALL_DONOTHING
WINMLA_CATCH_ALL_DONOTHING
HRESULT STDMETHODCALLTYPE InferenceSession::CopyOneInputAcrossDevices(
const char* input_name,
@ -745,6 +746,6 @@ HRESULT STDMETHODCALLTYPE InferenceSession::CopyOneInputAcrossDevices(
*new_mlvalue = temp_mlvalue.release();
return S_OK;
}
WINML_CATCH_ALL_COM
WINMLA_CATCH_ALL_COM
} // namespace Windows::AI::MachineLearning::Adapter

View file

@ -0,0 +1,41 @@
#pragma once
#include "core/common/status.h"
inline __declspec(noinline) winrt::hresult_error _winmla_to_hresult() noexcept {
try {
throw;
} catch (winrt::hresult_error const& e) {
return e;
} catch (wil::ResultException const& e) {
return winrt::hresult_error(e.GetErrorCode(), winrt::to_hstring(e.what()));
} catch (std::bad_alloc const&) {
return winrt::hresult_error(E_OUTOFMEMORY);
} catch (std::out_of_range const& e) {
return winrt::hresult_out_of_bounds(winrt::to_hstring(e.what()));
} catch (std::invalid_argument const& e) {
return winrt::hresult_invalid_argument(winrt::to_hstring(e.what()));
} catch (onnxruntime::OnnxRuntimeException const& e) {
StatusCode eStatusCode = static_cast<StatusCode>(e.GetStatus().Code());
return winrt::hresult_error(StatusCodeToHRESULT(eStatusCode), winrt::to_hstring(e.what()));
} catch (std::exception const& e) {
return winrt::hresult_error(E_FAIL, winrt::to_hstring(e.what()));
} catch (...) {
return winrt::hresult_error(E_FAIL);
}
}
#define WINMLA_CATCH_ALL \
catch (...) { \
throw _winmla_to_hresult(); \
}
#define WINMLA_CATCH_ALL_COM \
catch (...) { \
return _winmla_to_hresult().to_abi(); \
}
#define WINMLA_CATCH_ALL_DONOTHING \
catch (...) { \
return; \
}

View file

@ -5,32 +5,32 @@
#include "core/common/status.h"
#define WINML_THROW_IF_NOT_OK(status) \
do { \
auto _status = status; \
if (!_status.IsOK()) { \
HRESULT hresult = StatusCodeToHRESULT(static_cast<StatusCode>(_status.Code())); \
#define WINML_THROW_IF_NOT_OK(status) \
do { \
auto _status = status; \
if (!_status.IsOK()) { \
HRESULT hresult = StatusCodeToHRESULT(static_cast<StatusCode>(_status.Code())); \
telemetry_helper.LogRuntimeError(hresult, _status.ErrorMessage(), __FILE__, __FUNCTION__, __LINE__); \
winrt::hstring errorMessage(WinML::Strings::HStringFromUTF8(_status.ErrorMessage())); \
throw winrt::hresult_error(hresult, errorMessage); \
} \
winrt::hstring errorMessage(WinML::Strings::HStringFromUTF8(_status.ErrorMessage())); \
throw winrt::hresult_error(hresult, errorMessage); \
} \
} while (0)
//
// WINML_THROW_IF_*_MSG Variants
//
#define WINML_THROW_HR_IF_FALSE_MSG(hr, value, message, ...) \
do { \
auto _value = value; \
if (_value == false) { \
auto _hr = hr; \
char msg[1024]; \
sprintf_s(msg, message, __VA_ARGS__); \
#define WINML_THROW_HR_IF_FALSE_MSG(hr, value, message, ...) \
do { \
auto _value = value; \
if (_value == false) { \
auto _hr = hr; \
char msg[1024]; \
sprintf_s(msg, message, __VA_ARGS__); \
telemetry_helper.LogRuntimeError(_hr, msg, __FILE__, __FUNCTION__, __LINE__); \
winrt::hstring errorMessage(WinML::Strings::HStringFromUTF8(msg)); \
throw winrt::hresult_error(_hr, errorMessage); \
} \
winrt::hstring errorMessage(WinML::Strings::HStringFromUTF8(msg)); \
throw winrt::hresult_error(_hr, errorMessage); \
} \
} while (0)
#define WINML_THROW_HR_IF_TRUE_MSG(hr, value, message, ...) WINML_THROW_HR_IF_FALSE_MSG(hr, !(value), message, __VA_ARGS__)
@ -40,20 +40,20 @@
// WINML_THROW_IF_FAILED* Variants
//
#define WINML_THROW_HR(hr) \
{ \
auto _result = hr; \
#define WINML_THROW_HR(hr) \
{ \
auto _result = hr; \
telemetry_helper.LogRuntimeError(_result, "", __FILE__, __FUNCTION__, __LINE__); \
throw winrt::hresult_error(_result); \
throw winrt::hresult_error(_result); \
}
#define WINML_THROW_IF_FAILED(hr) \
do { \
HRESULT _hr = hr; \
if (FAILED(_hr)) { \
#define WINML_THROW_IF_FAILED(hr) \
do { \
HRESULT _hr = hr; \
if (FAILED(_hr)) { \
telemetry_helper.LogRuntimeError(_hr, "", __FILE__, __FUNCTION__, __LINE__); \
throw winrt::hresult_error(_hr); \
} \
throw winrt::hresult_error(_hr); \
} \
} while (0)
#define WINML_THROW_IF_FAILED_MSG(hr, message, ...) \
@ -110,7 +110,7 @@ inline __declspec(noinline) winrt::hresult_error _to_hresult() noexcept {
return _to_hresult().to_abi(); \
}
#define WINML_CATCH_ALL_DONOTHING \
catch (...) { \
return; \
}
#define WINML_CATCH_ALL_DONOTHING \
catch (...) { \
return; \
}