Minimize changes to fix missing symbols used from C# (#8867)

* Revert "Cleanup C# bindings to add EP (#8810)"

This reverts commit b21ea00020.

* Add back in a minimal set of changes.
Provide stubs in for a limited set of things
  - things called from C# using a static lib of ORT built for mac/ios
  - things in OrtApis that are not included in the build by default
  - things in OrtApis that are excluded in a minimal build

* Cleanup order or EPs in test

* Fix unused function in ROCM build
This commit is contained in:
Scott McKay 2021-08-28 07:10:14 +10:00 committed by GitHub
parent f3083f4bf3
commit 0034ad72e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 15347 additions and 186 deletions

4
.gitignore vendored
View file

@ -52,6 +52,4 @@ onnxruntime/python/version_info.py
/tools/perf_util/target/classes
/tools/perf_util/src/main/resources
/orttraining/orttraining/eager/ort_aten.g.cpp
/orttraining/orttraining/eager/ort_customops.g.cpp
/csharp/tools/Microsoft.ML.OnnxRuntime.PerfTool/OnnxMl.cs
/csharp/test/Microsoft.ML.OnnxRuntime.Tests/OnnxMl.cs
/orttraining/orttraining/eager/ort_customops.g.cpp

View file

@ -16,7 +16,7 @@ endif()
# This macro is to get the path of header files for mobile packaging, for iOS and Android
macro(get_mobile_api_headers _HEADERS)
# include both c and cxx api, and stubs to provide graceful error if EP is not included in build
# include both c and cxx api
set(${_HEADERS}
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_c_api.h"
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_api.h"
@ -41,7 +41,6 @@ list(APPEND SYMBOL_FILES "${REPO_ROOT}/tools/ci_build/gen_def.py")
foreach(f ${ONNXRUNTIME_PROVIDER_NAMES})
list(APPEND SYMBOL_FILES "${ONNXRUNTIME_ROOT}/core/providers/${f}/symbols.txt")
endforeach()
list(APPEND SYMBOL_FILES "${ONNXRUNTIME_ROOT}/core/session/symbols.txt")
add_custom_command(OUTPUT ${SYMBOL_FILE} ${CMAKE_CURRENT_BINARY_DIR}/generated_source.c
COMMAND ${Python_EXECUTABLE} "${REPO_ROOT}/tools/ci_build/gen_def.py"

View file

@ -5,7 +5,6 @@ file(GLOB onnxruntime_session_srcs CONFIGURE_DEPENDS
"${ONNXRUNTIME_INCLUDE_DIR}/core/session/*.h"
"${ONNXRUNTIME_ROOT}/core/session/*.h"
"${ONNXRUNTIME_ROOT}/core/session/*.cc"
"${ONNXRUNTIME_ROOT}/core/session/symbols.txt"
)
if (onnxruntime_MINIMAL_BUILD)

View file

@ -92,19 +92,8 @@ namespace Microsoft.ML.OnnxRuntime.Tests
var ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AddSessionConfigEntry("", "invalid key"); });
Assert.Contains("[ErrorCode:InvalidArgument] Config key is empty", ex.Message);
opt.AppendExecutionProvider_CPU(1);
#if USE_CUDA
opt.AppendExecutionProvider_CUDA(0);
#else
try
{
opt.AppendExecutionProvider_CUDA(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("Failed to load shared library", ortEx.Message);
}
#endif
#if USE_DML
@ -118,113 +107,37 @@ namespace Microsoft.ML.OnnxRuntime.Tests
// Restore the default dll search order
SetDllDirectory(null);
#else
try
{
opt.AppendExecutionProvider_DML(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("is not enabled in this build", ortEx.Message);
}
#endif
#if USE_DNNL
opt.AppendExecutionProvider_Dnnl(0);
#else
try
{
opt.AppendExecutionProvider_Dnnl(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("Failed to load shared library", ortEx.Message);
}
#endif
#if USE_MIGRAPHX
opt.AppendExecutionProvider_MIGraphX(0);
#else
try
{
opt.AppendExecutionProvider_MIGraphX(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("is not enabled in this build", ortEx.Message);
}
#endif
#if USE_NNAPI
opt.AppendExecutionProvider_Nnapi(0);
#else
try
{
opt.AppendExecutionProvider_Nnapi(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("is not enabled in this build", ortEx.Message);
}
#endif
#if USE_NUPHAR
opt.AppendExecutionProvider_Nuphar();
#else
try
{
opt.AppendExecutionProvider_Nnapi();
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("is not enabled in this build", ortEx.Message);
}
#endif
#if USE_OPENVINO
opt.AppendExecutionProvider_OpenVINO();
#else
try
{
opt.AppendExecutionProvider_OpenVINO();
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("Failed to load shared library", ortEx.Message);
}
#endif
#if USE_ROCM
opt.AppendExecutionProvider_ROCM(0);
#else
try
{
var gpuMemLimit = new UIntPtr(10*1024);
opt.AppendExecutionProvider_ROCM(0, gpuMemLimit);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("is not enabled in this build", ortEx.Message);
}
#endif
#if USE_TENSORRT
opt.AppendExecutionProvider_Tensorrt(0);
#else
try
{
opt.AppendExecutionProvider_Dnnl(0);
}
catch (OnnxRuntimeException ortEx)
{
Assert.Contains("Failed to load shared library", ortEx.Message);
}
#endif
opt.AppendExecutionProvider_CPU(1);
}
}

View file

@ -73,13 +73,9 @@
</ItemGroup>
<!-- generate OnnxMl.cs from ONNX protobuf definition -->
<Target Name="ProtoGen" BeforeTargets="BeforeBuild">
<Target Name="ProtoGen" BeforeTargets="BeforeBuild" Condition="Exists('$(ProtocExe)')">
<Exec Command="$(ProtocExe) -I=$(ProtoSrc) --csharp_out=. $(ProtoSrc)\onnx-ml.proto3" ContinueOnError="false"></Exec>
</Target>
<ItemGroup>
<!-- manually include if we're going to generate in this build. otherwise it's automatically included. -->
<Compile Include="$(ProjectDir)\OnnxMl.cs" Condition="!Exists('$(ProjectDir)\OnnxMl.cs')"/>
</ItemGroup>
<ItemGroup>
<None Include="$(NativeBuildOutputDir)\*.dll;$(NativeBuildOutputDir)\*.pdb;$(NativeBuildOutputDir)\libcustom*.so;$(NativeBuildOutputDir)\libcustom*.dylib">

File diff suppressed because it is too large Load diff

View file

@ -70,12 +70,8 @@
</ItemGroup>
<!-- create OnnxMl.cs and add to project -->
<Target Name="ProtoGen" BeforeTargets="BeforeBuild">
<Target Name="ProtoGen" BeforeTargets="BeforeBuild" Condition="Exists('$(ProtocExe)')">
<Exec Command="$(ProtocExe) -I=$(ProtoSrc) --csharp_out=. $(ProtoSrc)\onnx-ml.proto3" ContinueOnError="false"></Exec>
</Target>
<ItemGroup>
<!-- manually include if we're going to generate in this build. otherwise it's automatically included. -->
<Compile Include="$(ProjectDir)\OnnxMl.cs" Condition="!Exists('$(ProjectDir)\OnnxMl.cs')"/>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load diff

View file

@ -28,9 +28,7 @@ extern "C" {
* IDXGIFactory::EnumAdapters. A device_id of 0 always corresponds to the default adapter, which is typically the
* primary display GPU installed on the system. A negative device_id is invalid.
*/
// declared in include/onnxruntime/core/session/onnxruntime_c_api.h for convenience and so we can provide a graceful
// error message if not enabled.
// ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_DML, _In_ OrtSessionOptions* options, int device_id);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_DML, _In_ OrtSessionOptions* options, int device_id);
/**
* Creates a DirectML Execution Provider using the given DirectML device, and which executes work on the supplied D3D12

View file

@ -6,9 +6,7 @@
extern "C" {
#endif
// declared in include/onnxruntime/core/session/onnxruntime_c_api.h for convenience and so we can provide a graceful
// error message if not enabled.
// ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id);
#ifdef __cplusplus
}

View file

@ -44,10 +44,8 @@ enum NNAPIFlags {
extern "C" {
#endif
// declared in include/onnxruntime/core/session/onnxruntime_c_api.h for convenience and so we can provide a graceful
// error message if not enabled.
// ORT_EXPORT ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nnapi,
// _In_ OrtSessionOptions* options, uint32_t nnapi_flags);
ORT_EXPORT ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nnapi,
_In_ OrtSessionOptions* options, uint32_t nnapi_flags);
#ifdef __cplusplus
}

View file

@ -10,10 +10,7 @@ extern "C" {
* \param device_id nuphar device id, starts from zero.
* \param settings_str Nuphar settings string.
*/
// declared in include/onnxruntime/core/session/onnxruntime_c_api.h for convenience and so we can provide a graceful
// error message if not enabled.
// ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nuphar, _In_ OrtSessionOptions* options,
// int allow_unaligned_buffers, _In_ const char* settings_str);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nuphar, _In_ OrtSessionOptions* options, int allow_unaligned_buffers, _In_ const char* settings_str);
#ifdef __cplusplus
}

View file

@ -10,9 +10,7 @@ extern "C" {
/**
* \param device_id hip device id, starts from zero.
*/
// declared in include/onnxruntime/core/session/onnxruntime_c_api.h for convenience and so we can provide a graceful
// error message if not enabled.
//ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_ROCM, _In_ OrtSessionOptions* options, int device_id, size_t gpu_mem_limit);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_ROCM, _In_ OrtSessionOptions* options, int device_id, size_t gpu_mem_limit);
#ifdef __cplusplus
}

View file

@ -1798,23 +1798,6 @@ struct OrtCustomOp {
*/
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_CUDA, _In_ OrtSessionOptions* options, int device_id);
// EPs that provider_bridge_ort.cc handles. Function implementation is there.
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Dnnl, _In_ OrtSessionOptions* options, int use_arena);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_OpenVINO, _In_ OrtSessionOptions* options,
_In_ const char* device_type);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Tensorrt, _In_ OrtSessionOptions* options, int device_id);
// EPs conditionally included in the build that are exposed in the C# bindings.
// Function implementation is in the EP code if enabled, or in onnxruntime/core/session/provider_stubs.cc if not.
// If not enabled the function will return an error message saying so.
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_DML, _In_ OrtSessionOptions* options, int device_id);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_ROCM,
_In_ OrtSessionOptions* options, int device_id, size_t gpu_mem_limit);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nnapi, _In_ OrtSessionOptions* options, uint32_t nnapi_flags);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nuphar,
_In_ OrtSessionOptions* options, int allow_unaligned_buffers, _In_ const char* settings);
#ifdef __cplusplus
}
#endif

View file

@ -7,9 +7,16 @@
#include "core/session/onnxruntime_c_api.h"
#include "core/session/ort_apis.h"
#if defined(__APPLE__) || defined(ORT_MINIMAL_BUILD) || !defined(USE_ROCM)
static OrtStatus* CreateNotEnabledStatus(const std::string& ep) {
return OrtApis::CreateStatus(ORT_FAIL, (ep + " execution provider is not enabled in this build. ").c_str());
}
#endif
// we need stubs for functions called from C# when building an iOS app using Xamarin.
// in that case a static ORT library is used and the symbol needs to exist but doesn't need to be publicly exported.
// TODO: Not sure if we need to purely limit to iOS builds, so limit to __APPLE__ for now
#ifdef __APPLE__
#ifdef __cplusplus
extern "C" {
@ -61,18 +68,12 @@ ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Nuphar,
}
#endif
/* see provider_bridge_ort.cc for these:
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_CUDA, _In_ OrtSessionOptions* options, int device_id);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Dnnl, _In_ OrtSessionOptions* options, int use_arena);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_OpenVINO, _In_ OrtSessionOptions* options,
_In_ const char* device_type);
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Tensorrt, _In_ OrtSessionOptions* options, int device_id);
*/
#ifdef __cplusplus
}
#endif
#endif // __APPLE__
/*
OrtApis::SessionOptionsAppendExecutionProvider_<EP> stubs for EPs not included in this build.

View file

@ -1,15 +0,0 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
#
# we provide stubs for these functions for EPs that are enabled via C# so that we can return a graceful error message
# if they are not enabled in the onnxruntime library being used. the C# bindings don't know what will be available
# until runtime so must include the ability to call these functions in all builds.
OrtSessionOptionsAppendExecutionProvider_CUDA
OrtSessionOptionsAppendExecutionProvider_DML
OrtSessionOptionsAppendExecutionProvider_Dnnl
OrtSessionOptionsAppendExecutionProvider_MIGraphX
OrtSessionOptionsAppendExecutionProvider_Nnapi
OrtSessionOptionsAppendExecutionProvider_Nuphar
OrtSessionOptionsAppendExecutionProvider_OpenVINO
OrtSessionOptionsAppendExecutionProvider_ROCM
OrtSessionOptionsAppendExecutionProvider_Tensorrt

View file

@ -14,21 +14,6 @@ def parse_arguments():
return parser.parse_args()
def read_symbols(filename: str, allow_dups: bool = False):
with open(filename, 'r') as file:
for line in file:
line = line.strip()
if len(line) == 0 or line.startswith('#'):
continue
if line in symbols:
if not allow_dups:
print("dup symbol: %s", line)
exit(-1)
else:
symbols.add(line)
args = parse_arguments()
print("Generating symbol file for %s" % str(args.config))
with open(args.version_file, 'r') as f:
@ -40,13 +25,12 @@ symbols = set()
for c in args.config:
file_name = os.path.join(args.src_root, 'core', 'providers', c, 'symbols.txt')
with open(file_name, 'r') as file:
read_symbols(file_name)
# add stubs from session to provide graceful error message if EP isn't included in the build.
# this will have dups for EPs that are enabled in the build which is fine as we #ifdef out the stubs
# in the ORT C API implementation if that is the case
read_symbols(os.path.join(args.src_root, 'core', 'session', 'symbols.txt'), allow_dups=True)
for line in file:
line = line.strip()
if line in symbols:
print("dup symbol: %s", line)
exit(-1)
symbols.add(line)
symbols = sorted(symbols)
symbol_index = 1
@ -75,13 +59,13 @@ with open(args.output, 'w') as file:
file.write("}; \n")
with open(args.output_source, 'w') as file:
file.write('#include "core/session/onnxruntime_c_api.h"\n')
file.write("#include <onnxruntime_c_api.h>\n")
for c in args.config:
# WinML adapter should not be exported in platforms other than Windows.
# Exporting OrtGetWinMLAdapter is exported without issues using .def file when compiling for Windows
# so it isn't necessary to include it in generated_source.c
if c != "winml" and c != "cuda":
file.write('#include "core/providers/%s/%s_provider_factory.h"\n' % (c, c))
file.write("#include <core/providers/%s/%s_provider_factory.h>\n" % (c, c))
file.write("void* GetFunctionEntryByName(const char* name){\n")
for symbol in symbols:
if symbol != "OrtGetWinMLAdapter":