From 1aa21df149fe7be5ac39b3d23f80234a6f4d7890 Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Thu, 18 Nov 2021 16:58:02 +1000 Subject: [PATCH] Fix issue with debug VS2022 build when python bindings are enabled (#9794) * Add intermediate header between the ORT code and pybind11 to workaround an issue with VS2022 debug builds by making sure corecrt.h is included first. This avoids the _STL_ASSERT macro being defined in an incompatible way for a debug build by pybind including the python headers with _DEBUG temporarily undefined . See #9735 for details. --- onnxruntime/python/onnxruntime_pybind.h | 18 ++++++++++++++++++ .../python/onnxruntime_pybind_exceptions.h | 2 +- .../python/onnxruntime_pybind_mlvalue.h | 2 +- .../python/onnxruntime_pybind_module.cc | 6 +++--- onnxruntime/python/onnxruntime_pybind_state.h | 7 +++---- .../python/onnxruntime_pybind_state_common.h | 9 ++++----- 6 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 onnxruntime/python/onnxruntime_pybind.h diff --git a/onnxruntime/python/onnxruntime_pybind.h b/onnxruntime/python/onnxruntime_pybind.h new file mode 100644 index 0000000000..dda612ecea --- /dev/null +++ b/onnxruntime/python/onnxruntime_pybind.h @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +// If performing a debug build with VS2022 (_MSC_VER == 1930) we need to include corecrt.h before pybind +// so that the _STL_ASSERT macro is defined in a compatible way. +// +// pybind11/pybind11.h includes pybind11/detail/common.h, which undefines _DEBUG whilst including the Python headers +// (which in turn include corecrt.h). This alters how the _STL_ASSERT macro is defined and causes the build to fail. +// +// see https://github.com/microsoft/onnxruntime/issues/9735 +// +#if defined(_MSC_VER) && defined(_DEBUG) && _MSC_VER >= 1930 +#include +#endif + +#include diff --git a/onnxruntime/python/onnxruntime_pybind_exceptions.h b/onnxruntime/python/onnxruntime_pybind_exceptions.h index 3b42a76ed8..bc7d31ff2b 100644 --- a/onnxruntime/python/onnxruntime_pybind_exceptions.h +++ b/onnxruntime/python/onnxruntime_pybind_exceptions.h @@ -3,7 +3,7 @@ #pragma once -#include +#include "onnxruntime_pybind.h" // must use this for the include of #include #include "core/common/status.h" diff --git a/onnxruntime/python/onnxruntime_pybind_mlvalue.h b/onnxruntime/python/onnxruntime_pybind_mlvalue.h index f5631a3c92..eb1b43a55d 100644 --- a/onnxruntime/python/onnxruntime_pybind_mlvalue.h +++ b/onnxruntime/python/onnxruntime_pybind_mlvalue.h @@ -4,8 +4,8 @@ #pragma once #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include "onnxruntime_pybind.h" // must use this for the include of #include -#include #include #include diff --git a/onnxruntime/python/onnxruntime_pybind_module.cc b/onnxruntime/python/onnxruntime_pybind_module.cc index 378117b096..28434e0404 100644 --- a/onnxruntime/python/onnxruntime_pybind_module.cc +++ b/onnxruntime/python/onnxruntime_pybind_module.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include +#include "onnxruntime_pybind.h" // must use this for the include of #include #include "core/providers/get_execution_providers.h" @@ -20,5 +20,5 @@ PYBIND11_MODULE(onnxruntime_pybind11_state, m) { "The order of elements represents the default priority order of Execution Providers " "from highest to lowest."); } -} -} \ No newline at end of file +} // namespace python +} // namespace onnxruntime diff --git a/onnxruntime/python/onnxruntime_pybind_state.h b/onnxruntime/python/onnxruntime_pybind_state.h index aa11a4f2c3..47cde0d4cf 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.h +++ b/onnxruntime/python/onnxruntime_pybind_state.h @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include +#include "onnxruntime_pybind.h" // must use this for the include of namespace onnxruntime { namespace python { @@ -10,6 +10,5 @@ void addGlobalMethods(py::module& m, Environment& env); void addObjectMethods(py::module& m, Environment& env); void addOrtValueMethods(pybind11::module& m); - -} -} \ No newline at end of file +} // namespace python +} // namespace onnxruntime diff --git a/onnxruntime/python/onnxruntime_pybind_state_common.h b/onnxruntime/python/onnxruntime_pybind_state_common.h index 583b2b5d5d..a55c3cb664 100644 --- a/onnxruntime/python/onnxruntime_pybind_state_common.h +++ b/onnxruntime/python/onnxruntime_pybind_state_common.h @@ -15,7 +15,7 @@ #include "core/dlpack/dlpack_converter.h" #endif -#include +#include "onnxruntime_pybind.h" // must use this for the include of // execution provider factory creator headers struct OrtStatus { @@ -207,7 +207,7 @@ class SparseTensor; #endif namespace python { -using ExecutionProviderRegistrationFn = std::function&, const ProviderOptionsMap&)>; @@ -313,7 +313,7 @@ inline AllocatorPtr& GetAllocator() { // so incoming arrays do not disappear. To this end we create an instance of SparseTensor // on top of the user provided numpy arrays and create a duplicate of py::objects for those // numpy array for ref-counting purposes and store it here. -// +// // - to be able to expose SparseTensor returned from run method. We get an OrtValue from run() // and store a copy of it in ort_value_. The OrtValue shared_ptr ref-counting will make sure // the memory stays around. @@ -375,7 +375,6 @@ class PySparseTensor { std::unique_ptr AsOrtValue() const; private: - // instance_ represents data that comes as input. Thus we depend on numpy // arrays that own the underlying memory to stay around. We store copies // of py::objects for those arrays in backing_storage_ as an extra ref-count. @@ -480,5 +479,5 @@ std::shared_ptr CreateExecutionProviderFactory_Nnapi( std::shared_ptr CreateExecutionProviderFactory_Rknpu(); std::shared_ptr CreateExecutionProviderFactory_CoreML(uint32_t flags); -constexpr const char* kDefaultExecutionProviderEntry = "GetProvider"; +constexpr const char* kDefaultExecutionProviderEntry = "GetProvider"; } // namespace onnxruntime