2018-11-20 00:48:22 +00:00
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
2020-03-17 23:10:23 +00:00
# include "python/onnxruntime_pybind_exceptions.h"
# include "python/onnxruntime_pybind_mlvalue.h"
2020-03-20 03:59:41 +00:00
# include "python/onnxruntime_pybind_state_common.h"
2018-11-20 00:48:22 +00:00
# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
# define PY_ARRAY_UNIQUE_SYMBOL onnxruntime_python_ARRAY_API
# include <numpy/arrayobject.h>
2020-03-17 23:10:23 +00:00
# include "core/framework/data_transfer_utils.h"
2019-12-05 00:04:17 +00:00
# include "core/framework/data_types_internal.h"
2020-04-28 15:41:37 +00:00
# include "core/framework/tensorprotoutils.h"
2018-12-04 16:41:03 +00:00
# include "core/graph/graph_viewer.h"
2019-08-15 00:12:08 +00:00
# include "core/common/logging/logging.h"
# include "core/common/logging/severity.h"
2019-10-10 22:58:49 +00:00
# include "core/framework/TensorSeq.h"
2020-04-14 18:30:50 +00:00
# include "core/framework/random_seed.h"
2019-10-14 16:48:19 +00:00
# include "core/framework/session_options.h"
2020-03-11 21:25:37 +00:00
# include "core/framework/bfc_arena.h"
2020-03-17 23:10:23 +00:00
# include "core/session/IOBinding.h"
2018-11-20 00:48:22 +00:00
# if USE_CUDA
# define BACKEND_PROC "GPU"
# else
# define BACKEND_PROC "CPU"
# endif
2020-03-30 19:18:40 +00:00
# if _OPENMP
2018-11-20 00:48:22 +00:00
# define BACKEND_OPENMP "-OPENMP"
# else
# define BACKEND_OPENMP ""
# endif
2019-12-03 15:34:23 +00:00
# if USE_DNNL
# define BACKEND_DNNL "-DNNL"
2018-11-20 00:48:22 +00:00
# else
2019-12-03 15:34:23 +00:00
# define BACKEND_DNNL ""
2018-11-20 00:48:22 +00:00
# endif
# if USE_MKLML
# define BACKEND_MKLML "-MKL-ML"
# else
# define BACKEND_MKLML ""
# endif
2019-04-21 00:02:35 +00:00
# if USE_NGRAPH
# define BACKEND_NGRAPH "-NGRAPH"
# include "core/providers/ngraph/ngraph_execution_provider.h"
# else
# define BACKEND_NGRAPH ""
# endif
2020-05-26 20:24:59 +00:00
# if USE_MIGRAPHX
# define BACKEND_MIGRAPHX "-MIGRAPHX"
# else
# define BACKEND_MIGRAPHX ""
# endif
2020-04-24 11:06:02 +00:00
# ifdef USE_OPENVINO
2020-05-06 07:57:09 +00:00
# if OPENVINO_CONFIG_CPU_FP32
# define BACKEND_OPENVINO "-OPENVINO_CPU_FP32"
2019-09-19 19:43:44 +00:00
2020-05-06 07:57:09 +00:00
# elif OPENVINO_CONFIG_GPU_FP32
# define BACKEND_OPENVINO "-OPENVINO_GPU_FP32"
2019-09-19 19:43:44 +00:00
2020-05-06 07:57:09 +00:00
# elif OPENVINO_CONFIG_GPU_FP16
# define BACKEND_OPENVINO "-OPENVINO_GPU_FP16"
2019-09-19 19:43:44 +00:00
2020-05-06 07:57:09 +00:00
# elif OPENVINO_CONFIG_MYRIAD
# define BACKEND_OPENVINO "-OPENVINO_MYRIAD"
2019-09-19 19:43:44 +00:00
2020-05-06 07:57:09 +00:00
# elif OPENVINO_CONFIG_VAD_M
# define BACKEND_OPENVINO "-OPENVINO_VAD_M"
2019-09-19 19:43:44 +00:00
2020-05-06 07:57:09 +00:00
# elif OPENVINO_CONFIG_VAD_F
# define BACKEND_OPENVINO "-OPENVINO_VAD_F"
# endif
2019-06-18 15:58:53 +00:00
# else
2020-05-06 07:57:09 +00:00
# define BACKEND_OPENVINO ""
2019-06-18 15:58:53 +00:00
# endif
2019-09-02 06:01:47 +00:00
# ifdef USE_NUPHAR
# define BACKEND_NUPHAR "-NUPHAR"
# else
# define BACKEND_NUPHAR ""
# endif
2020-05-19 12:32:32 +00:00
# if USE_VITISAI
# define BACKEND_VITISAI "-VITISAI"
# include "core/providers/vitisai/vitisai_execution_provider.h"
# else
# define BACKEND_VITISAI ""
# endif
2018-11-20 00:48:22 +00:00
# if USE_OPENBLAS
# define BACKEND_OPENBLAS "-OPENBLAS"
# else
# define BACKEND_OPENBLAS ""
# endif
2020-06-18 14:54:14 +00:00
# if USE_ACL
# define BACKEND_ACL "-ACL"
# else
# define BACKEND_ACL ""
# endif
# if USE_ARMNN
# define BACKEND_ARMNN "-ARMNN"
# else
# define BACKEND_ARMNN ""
# endif
# define BACKEND_DEVICE BACKEND_PROC BACKEND_DNNL BACKEND_MKLML BACKEND_NGRAPH BACKEND_OPENVINO BACKEND_NUPHAR BACKEND_OPENBLAS BACKEND_MIGRAPHX BACKEND_ACL BACKEND_ARMNN
2018-11-20 00:48:22 +00:00
# include "core/session/onnxruntime_cxx_api.h"
2019-01-26 03:41:10 +00:00
# include "core/providers/providers.h"
2018-11-20 00:48:22 +00:00
# include "core/providers/cpu/cpu_execution_provider.h"
# include "core/providers/cpu/cpu_provider_factory.h"
# ifdef USE_CUDA
# include "core/providers/cuda/cuda_provider_factory.h"
2020-03-17 23:10:23 +00:00
OrtDevice : : DeviceId cuda_device_id = 0 ;
2020-03-11 21:25:37 +00:00
size_t cuda_mem_limit = std : : numeric_limits < size_t > : : max ( ) ;
onnxruntime : : ArenaExtendStrategy arena_extend_strategy = onnxruntime : : ArenaExtendStrategy : : kNextPowerOfTwo ;
2018-11-20 00:48:22 +00:00
# endif
2019-03-14 19:00:39 +00:00
# ifdef USE_TENSORRT
# include "core/providers/tensorrt/tensorrt_provider_factory.h"
# endif
2020-05-26 20:24:59 +00:00
# ifdef USE_MIGRAPHX
# include "core/providers/migraphx/migraphx_provider_factory.h"
# endif
2019-04-21 00:02:35 +00:00
# ifdef USE_NGRAPH
# include "core/providers/ngraph/ngraph_provider_factory.h"
# endif
2019-06-18 15:58:53 +00:00
# ifdef USE_OPENVINO
# include "core/providers/openvino/openvino_provider_factory.h"
2020-04-24 11:06:02 +00:00
std : : string openvino_device ;
2019-06-18 15:58:53 +00:00
# endif
2018-11-20 00:48:22 +00:00
# ifdef USE_NUPHAR
# include "core/providers/nuphar/nuphar_provider_factory.h"
2019-09-02 06:01:47 +00:00
std : : string nuphar_settings ;
2018-11-20 00:48:22 +00:00
# endif
2020-05-19 12:32:32 +00:00
# ifdef USE_VITISAI
# include "core/providers/vitisai/vitisai_provider_factory.h"
# endif
2020-06-18 14:54:14 +00:00
# ifdef USE_ACL
# include "core/providers/acl/acl_provider_factory.h"
# endif
# ifdef USE_ARMNN
# include "core/providers/armnn/armnn_provider_factory.h"
# endif
2019-01-26 03:41:10 +00:00
namespace onnxruntime {
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_CPU ( int use_arena ) ;
2020-03-11 21:25:37 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_CUDA ( OrtDevice : : DeviceId device_id ,
size_t cuda_mem_limit ,
onnxruntime : : ArenaExtendStrategy arena_extend_strategy ) ;
2019-08-09 02:31:39 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_Tensorrt ( int device_id ) ;
2020-05-26 20:24:59 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_MIGraphX ( int device_id ) ;
2019-12-03 15:34:23 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_Dnnl ( int use_arena ) ;
2019-04-21 00:02:35 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_NGraph ( const char * ng_backend_type ) ;
2019-06-18 15:58:53 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_OpenVINO ( const char * device ) ;
2019-09-02 06:01:47 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_Nuphar ( bool , const char * ) ;
2020-05-19 12:32:32 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_VITISAI ( const char * backend_type , int device_id ) ;
2020-06-18 14:54:14 +00:00
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_ACL ( int use_arena ) ;
std : : shared_ptr < IExecutionProviderFactory > CreateExecutionProviderFactory_ArmNN ( int use_arena ) ;
2019-01-26 03:41:10 +00:00
} // namespace onnxruntime
2018-11-20 00:48:22 +00:00
# if defined(_MSC_VER)
# pragma warning(disable : 4267 4996 4503 4003)
# endif // _MSC_VER
# include <iterator>
# if defined(_MSC_VER)
# pragma warning(disable : 4267 4996 4503 4003)
# endif // _MSC_VER
namespace onnxruntime {
namespace python {
namespace py = pybind11 ;
using namespace onnxruntime ;
using namespace onnxruntime : : logging ;
template < typename T >
2019-09-24 18:13:14 +00:00
void AddNonTensor ( OrtValue & val , std : : vector < py : : object > & pyobjs ) {
2018-11-20 00:48:22 +00:00
pyobjs . push_back ( py : : cast ( val . Get < T > ( ) ) ) ;
}
2019-10-07 22:35:09 +00:00
2020-03-11 21:25:37 +00:00
void GetPyObjFromTensor ( const Tensor & rtensor , py : : object & obj , const DataTransferManager * data_transfer_manager = nullptr ) {
2019-10-10 22:58:49 +00:00
std : : vector < npy_intp > npy_dims ;
const TensorShape & shape = rtensor . Shape ( ) ;
for ( size_t n = 0 ; n < shape . NumDimensions ( ) ; + + n ) {
npy_dims . push_back ( shape [ n ] ) ;
}
MLDataType dtype = rtensor . DataType ( ) ;
const int numpy_type = OnnxRuntimeTensorToNumpyType ( dtype ) ;
obj = py : : reinterpret_steal < py : : object > ( PyArray_SimpleNew (
shape . NumDimensions ( ) , npy_dims . data ( ) , numpy_type ) ) ;
void * outPtr = static_cast < void * > (
PyArray_DATA ( reinterpret_cast < PyArrayObject * > ( obj . ptr ( ) ) ) ) ;
if ( numpy_type ! = NPY_OBJECT ) {
2020-03-11 21:25:37 +00:00
//if it is not cpu tensor, need to copy to host
if ( rtensor . Location ( ) . device . Type ( ) ! = OrtDevice : : CPU ) {
if ( ! data_transfer_manager )
2020-04-08 20:54:42 +00:00
throw std : : runtime_error ( " GetPyObjFromTensor: data transfer manager is needed to convert non-CPU tensor to numpy array " ) ;
2020-03-11 21:25:37 +00:00
static const OrtMemoryInfo cpu_alloc_info { onnxruntime : : CPU , OrtDeviceAllocator } ;
std : : vector < char > tensor_data_buffer { } ;
tensor_data_buffer . resize ( rtensor . SizeInBytes ( ) ) ;
ORT_THROW_IF_ERROR ( CopyTensorDataToByteSpan (
* data_transfer_manager , rtensor , cpu_alloc_info , gsl : : make_span ( tensor_data_buffer ) ) ) ;
memcpy ( outPtr , tensor_data_buffer . data ( ) , dtype - > Size ( ) * shape . Size ( ) ) ;
} else
memcpy ( outPtr , rtensor . DataRaw ( dtype ) , dtype - > Size ( ) * shape . Size ( ) ) ;
2019-10-10 22:58:49 +00:00
} else {
// Handle string type.
py : : object * outObj = static_cast < py : : object * > ( outPtr ) ;
const std : : string * src = rtensor . template Data < std : : string > ( ) ;
for ( int i = 0 ; i < rtensor . Shape ( ) . Size ( ) ; i + + , src + + ) {
outObj [ i ] = py : : cast ( * src ) ;
}
}
}
2020-06-12 00:04:06 +00:00
static const char * GetDeviceName ( const OrtDevice & device ) {
2020-03-11 21:25:37 +00:00
switch ( device . Type ( ) ) {
case OrtDevice : : CPU :
return CPU ;
case OrtDevice : : GPU :
return CUDA ;
case OrtDevice : : FPGA :
return " FPGA " ;
default :
2020-06-12 00:04:06 +00:00
ORT_THROW ( " Unknown device type: " , device . Type ( ) ) ;
2020-03-11 21:25:37 +00:00
}
}
2019-10-10 22:58:49 +00:00
template < >
void AddNonTensor < TensorSeq > ( OrtValue & val , std : : vector < py : : object > & pyobjs ) {
const auto & seq_tensors = val . Get < TensorSeq > ( ) ;
py : : list py_list ;
2019-12-05 00:04:17 +00:00
for ( const auto & rtensor : seq_tensors ) {
2019-10-10 22:58:49 +00:00
py : : object obj ;
GetPyObjFromTensor ( rtensor , obj ) ;
py_list . append ( obj ) ;
}
pyobjs . push_back ( py_list ) ;
}
2019-09-24 18:13:14 +00:00
void AddNonTensorAsPyObj ( OrtValue & val , std : : vector < py : : object > & pyobjs ) {
2018-11-20 00:48:22 +00:00
// Should be in sync with core/framework/datatypes.h
2019-12-05 00:04:17 +00:00
auto val_type = val . Type ( ) ;
if ( val_type - > IsTensorSequenceType ( ) ) {
2019-10-10 22:58:49 +00:00
AddNonTensor < TensorSeq > ( val , pyobjs ) ;
2018-11-20 00:48:22 +00:00
} else {
2019-12-05 00:04:17 +00:00
utils : : ContainerChecker c_checker ( val_type ) ;
if ( c_checker . IsMap ( ) ) {
if ( c_checker . IsMapOf < std : : string , std : : string > ( ) ) {
AddNonTensor < MapStringToString > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < std : : string , int64_t > ( ) ) {
AddNonTensor < MapStringToInt64 > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < std : : string , float > ( ) ) {
AddNonTensor < MapStringToFloat > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < std : : string , double > ( ) ) {
AddNonTensor < MapStringToDouble > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < int64_t , std : : string > ( ) ) {
AddNonTensor < MapInt64ToString > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < int64_t , int64_t > ( ) ) {
AddNonTensor < MapInt64ToInt64 > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < int64_t , float > ( ) ) {
AddNonTensor < MapInt64ToFloat > ( val , pyobjs ) ;
} else if ( c_checker . IsMapOf < int64_t , double > ( ) ) {
AddNonTensor < MapInt64ToDouble > ( val , pyobjs ) ;
}
} else {
if ( c_checker . IsSequenceOf < std : : map < std : : string , float > > ( ) ) {
AddNonTensor < VectorMapStringToFloat > ( val , pyobjs ) ;
} else if ( c_checker . IsSequenceOf < std : : map < int64_t , float > > ( ) ) {
AddNonTensor < VectorMapInt64ToFloat > ( val , pyobjs ) ;
} else {
throw std : : runtime_error ( " Output is a non-tensor type which is not supported. " ) ;
}
}
2018-11-20 00:48:22 +00:00
}
}
2019-09-24 18:13:14 +00:00
void AddTensorAsPyObj ( OrtValue & val , std : : vector < py : : object > & pyobjs ) {
2018-11-20 00:48:22 +00:00
const Tensor & rtensor = val . Get < Tensor > ( ) ;
2019-10-10 22:58:49 +00:00
py : : object obj ;
GetPyObjFromTensor ( rtensor , obj ) ;
2018-11-20 00:48:22 +00:00
pyobjs . push_back ( obj ) ;
}
2019-01-26 03:41:10 +00:00
inline void RegisterExecutionProvider ( InferenceSession * sess , onnxruntime : : IExecutionProviderFactory & f ) {
auto p = f . CreateProvider ( ) ;
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( sess - > RegisterExecutionProvider ( std : : move ( p ) ) ) ;
2018-11-20 00:48:22 +00:00
}
2019-09-13 18:25:18 +00:00
// ordered by default priority. highest to lowest.
const std : : vector < std : : string > & GetAllProviders ( ) {
2019-12-03 15:34:23 +00:00
static std : : vector < std : : string > all_providers = { kTensorrtExecutionProvider , kCudaExecutionProvider , kDnnlExecutionProvider ,
2019-09-13 18:25:18 +00:00
kNGraphExecutionProvider , kOpenVINOExecutionProvider , kNupharExecutionProvider ,
2020-06-18 14:54:14 +00:00
kVitisAIExecutionProvider , kCpuExecutionProvider , kMIGraphXExecutionProvider ,
kAclExecutionProvider , kArmNNExecutionProvider } ;
2019-09-13 18:25:18 +00:00
return all_providers ;
}
2019-01-26 03:41:10 +00:00
2019-09-13 18:25:18 +00:00
const std : : vector < std : : string > & GetAvailableProviders ( ) {
auto InitializeProviders = [ ] ( ) {
2020-06-23 06:22:51 +00:00
std : : vector < std : : string > available_providers ( std : : begin ( providers_available ) , std : : end ( providers_available ) ) ;
2019-09-13 18:25:18 +00:00
return available_providers ;
} ;
static std : : vector < std : : string > available_providers = InitializeProviders ( ) ;
return available_providers ;
}
2019-06-18 15:58:53 +00:00
2019-09-13 18:25:18 +00:00
void RegisterExecutionProviders ( InferenceSession * sess , const std : : vector < std : : string > & provider_types ) {
for ( const std : : string & type : provider_types ) {
if ( type = = kCpuExecutionProvider ) {
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_CPU ( sess - > GetSessionOptions ( ) . enable_cpu_mem_arena ) ) ;
} else if ( type = = kTensorrtExecutionProvider ) {
# ifdef USE_TENSORRT
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_Tensorrt ( 0 ) ) ;
2020-05-26 20:24:59 +00:00
# endif
} else if ( type = = kMIGraphXExecutionProvider ) {
# ifdef USE_MIGRAPHX
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_MIGraphX ( 0 ) ) ;
2019-09-13 18:25:18 +00:00
# endif
} else if ( type = = kCudaExecutionProvider ) {
# ifdef USE_CUDA
2020-03-11 21:25:37 +00:00
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_CUDA ( cuda_device_id , cuda_mem_limit , arena_extend_strategy ) ) ;
2019-09-13 18:25:18 +00:00
# endif
2019-12-03 15:34:23 +00:00
} else if ( type = = kDnnlExecutionProvider ) {
# ifdef USE_DNNL
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_Dnnl ( sess - > GetSessionOptions ( ) . enable_cpu_mem_arena ) ) ;
2019-09-13 18:25:18 +00:00
# endif
} else if ( type = = kNGraphExecutionProvider ) {
2019-04-21 00:02:35 +00:00
# if USE_NGRAPH
2019-09-13 18:25:18 +00:00
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_NGraph ( " CPU " ) ) ;
2019-04-21 00:02:35 +00:00
# endif
2019-09-13 18:25:18 +00:00
} else if ( type = = kOpenVINOExecutionProvider ) {
2019-06-18 15:58:53 +00:00
# ifdef USE_OPENVINO
2020-04-24 11:06:02 +00:00
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_OpenVINO ( openvino_device . c_str ( ) ) ) ;
openvino_device . clear ( ) ;
2019-06-18 15:58:53 +00:00
# endif
2019-09-13 18:25:18 +00:00
} else if ( type = = kNupharExecutionProvider ) {
2019-09-02 06:01:47 +00:00
# if USE_NUPHAR
2019-09-13 18:25:18 +00:00
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_Nuphar ( true , nuphar_settings . c_str ( ) ) ) ;
nuphar_settings . clear ( ) ; // clear nuphar_settings after use to avoid it being accidentally passed on to next session
2020-05-19 12:32:32 +00:00
# endif
} else if ( type = = kVitisAIExecutionProvider ) {
# if USE_VITISAI
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_VITISAI ( " dpuv1 " , 0 ) ) ;
2020-06-18 14:54:14 +00:00
# endif
} else if ( type = = kAclExecutionProvider ) {
# ifdef USE_ACL
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_ACL ( sess - > GetSessionOptions ( ) . enable_cpu_mem_arena ) ) ;
# endif
} else if ( type = = kArmNNExecutionProvider ) {
# ifdef USE_ARMNN
RegisterExecutionProvider ( sess , * onnxruntime : : CreateExecutionProviderFactory_ArmNN ( sess - > GetSessionOptions ( ) . enable_cpu_mem_arena ) ) ;
2019-04-10 18:21:06 +00:00
# endif
2019-09-13 18:25:18 +00:00
} else {
// unknown provider
throw std : : runtime_error ( " Unknown Provider Type: " + type ) ;
}
}
}
2019-04-10 18:21:06 +00:00
2019-09-13 18:25:18 +00:00
void InitializeSession ( InferenceSession * sess , const std : : vector < std : : string > & provider_types ) {
if ( provider_types . empty ( ) ) {
// use default registration priority.
RegisterExecutionProviders ( sess , GetAllProviders ( ) ) ;
} else {
RegisterExecutionProviders ( sess , provider_types ) ;
}
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( sess - > Initialize ( ) ) ;
2019-09-13 18:25:18 +00:00
}
2018-11-20 00:48:22 +00:00
2020-03-18 22:42:46 +00:00
void addGlobalMethods ( py : : module & m , const Environment & env ) {
2019-12-04 00:56:07 +00:00
m . def ( " get_default_session_options " , & GetDefaultCPUSessionOptions , " Return a default session_options instance. " ) ;
2018-11-20 00:48:22 +00:00
m . def ( " get_session_initializer " , & SessionObjectInitializer : : Get , " Return a default session object initializer. " ) ;
2018-12-05 22:03:45 +00:00
m . def (
" get_device " , [ ] ( ) - > std : : string { return BACKEND_DEVICE ; } ,
" Return the device used to compute the prediction (CPU, MKL, ...) " ) ;
2020-04-14 18:30:50 +00:00
m . def (
2020-04-14 22:34:12 +00:00
" set_seed " , [ ] ( const int64_t seed ) { utils : : SetRandomSeed ( seed ) ; } ,
2020-04-14 18:30:50 +00:00
" Sets the seed used for random number generation in Onnxruntime. " ) ;
2019-09-26 06:48:23 +00:00
m . def (
2020-03-18 22:42:46 +00:00
" set_default_logger_severity " , [ & env ] ( int severity ) {
2019-09-26 06:48:23 +00:00
ORT_ENFORCE ( severity > = 0 & & severity < = 4 ,
" Invalid logging severity. 0:Verbose, 1:Info, 2:Warning, 3:Error, 4:Fatal " ) ;
2020-03-18 22:42:46 +00:00
logging : : LoggingManager * default_logging_manager = env . GetLoggingManager ( ) ;
2019-09-26 06:48:23 +00:00
default_logging_manager - > SetDefaultLoggerSeverity ( static_cast < logging : : Severity > ( severity ) ) ;
} ,
" Sets the default logging severity. 0:Verbose, 1:Info, 2:Warning, 3:Error, 4:Fatal " ) ;
2019-09-24 18:13:14 +00:00
m . def (
" get_all_providers " , [ ] ( ) - > const std : : vector < std : : string > & { return GetAllProviders ( ) ; } ,
" Return list of Execution Providers that this version of Onnxruntime can support. " ) ;
m . def (
" get_available_providers " , [ ] ( ) - > const std : : vector < std : : string > & { return GetAvailableProviders ( ) ; } ,
" Return list of available Execution Providers available in this installed version of Onnxruntime. " ) ;
2019-03-27 04:58:01 +00:00
2019-09-02 06:01:47 +00:00
# ifdef USE_NUPHAR
m . def ( " set_nuphar_settings " , [ ] ( const std : : string & str ) {
nuphar_settings = str ;
} ) ;
m . def ( " get_nuphar_settings " , [ ] ( ) - > std : : string {
return nuphar_settings ;
} ) ;
# endif
2020-04-24 11:06:02 +00:00
# ifdef USE_OPENVINO
2020-05-06 07:57:09 +00:00
m . def (
" set_openvino_device " , [ ] ( const std : : string & device ) { openvino_device = device ; } ,
" Set the prefered OpenVINO device(s) to be used. If left unset, all available devices will be used. " ) ;
m . def (
" get_openvino_device " , [ ] ( ) - > std : : string {
return openvino_device ;
} ,
" " ) ;
2020-04-24 11:06:02 +00:00
# endif
2019-03-27 04:58:01 +00:00
# ifdef onnxruntime_PYBIND_EXPORT_OPSCHEMA
m . def (
2019-06-11 22:54:03 +00:00
" get_all_operator_schema " , [ ] ( ) - > const std : : vector < ONNX_NAMESPACE : : OpSchema > {
2019-03-27 04:58:01 +00:00
return ONNX_NAMESPACE : : OpSchemaRegistry : : get_all_schemas_with_history ( ) ;
} ,
2019-06-11 22:54:03 +00:00
" Return a vector of OpSchema all registed operators " ) ;
2019-08-15 01:12:24 +00:00
m . def (
" get_all_opkernel_def " , [ ] ( ) - > const std : : vector < onnxruntime : : KernelDef > {
std : : vector < onnxruntime : : KernelDef > result ;
std : : vector < std : : shared_ptr < onnxruntime : : IExecutionProviderFactory > > factories = {
2019-09-13 18:25:18 +00:00
onnxruntime : : CreateExecutionProviderFactory_CPU ( 0 ) ,
2019-08-15 01:12:24 +00:00
# ifdef USE_CUDA
2020-06-13 02:32:57 +00:00
onnxruntime : : CreateExecutionProviderFactory_CUDA ( cuda_device_id , cuda_mem_limit , arena_extend_strategy ) ,
2019-08-15 01:12:24 +00:00
# endif
2019-12-03 15:34:23 +00:00
# ifdef USE_DNNL
onnxruntime : : CreateExecutionProviderFactory_Dnnl ( 1 ) ,
2019-04-23 18:11:35 +00:00
# endif
2019-08-15 01:12:24 +00:00
# ifdef USE_NGRAPH
2019-09-13 18:25:18 +00:00
onnxruntime : : CreateExecutionProviderFactory_NGraph ( " CPU " ) ,
2019-08-15 01:12:24 +00:00
# endif
# ifdef USE_OPENVINO
2020-05-06 07:57:09 +00:00
onnxruntime : : CreateExecutionProviderFactory_OpenVINO ( openvino_device ) ,
2019-09-13 18:25:18 +00:00
# endif
# ifdef USE_TENSORRT
2020-05-26 20:24:59 +00:00
onnxruntime : : CreateExecutionProviderFactory_Tensorrt ( 0 ) ,
# endif
# ifdef USE_MIGRAPHX
onnxruntime : : CreateExecutionProviderFactory_MIGraphX ( 0 )
2020-05-19 12:32:32 +00:00
# endif
# ifdef USE_VITISAI
onnxruntime : : CreateExecutionProviderFactory_VitisAI ( " DPU " , 0 ) ,
2020-06-18 14:54:14 +00:00
# endif
# ifdef USE_ACL
onnxruntime : : CreateExecutionProviderFactory_ACL ( 0 )
# endif
# ifdef USE_ARMNN
onnxruntime : : CreateExecutionProviderFactory_ArmNN ( 0 )
2019-09-13 18:25:18 +00:00
# endif
2019-08-15 01:12:24 +00:00
} ;
2019-09-13 18:25:18 +00:00
for ( const auto & f : factories ) {
for ( const auto & m : f - > CreateProvider ( )
- > GetKernelRegistry ( )
- > GetKernelCreateMap ( ) ) {
result . emplace_back ( * ( m . second . kernel_def ) ) ;
}
2019-08-15 01:12:24 +00:00
}
2019-09-13 18:25:18 +00:00
return result ;
} ,
" Return a vector of KernelDef for all registered OpKernels " ) ;
# endif //onnxruntime_PYBIND_EXPORT_OPSCHEMA
2020-03-11 21:25:37 +00:00
# ifdef USE_CUDA
2020-03-17 23:10:23 +00:00
m . def ( " set_cuda_device_id " , [ ] ( const int id ) { cuda_device_id = static_cast < OrtDevice : : DeviceId > ( id ) ; } ) ;
2020-03-11 21:25:37 +00:00
m . def ( " set_cuda_mem_limit " , [ ] ( const int64_t limit ) {
cuda_mem_limit = static_cast < size_t > ( limit ) ;
} ) ;
m . def ( " set_arena_extend_strategy " , [ ] ( const onnxruntime : : ArenaExtendStrategy strategy ) { arena_extend_strategy = strategy ; } ) ;
# endif
2019-03-27 04:58:01 +00:00
}
# ifdef onnxruntime_PYBIND_EXPORT_OPSCHEMA
2019-09-13 18:25:18 +00:00
void addOpKernelSubmodule ( py : : module & m ) {
2019-08-15 01:12:24 +00:00
auto opkernel = m . def_submodule ( " opkernel " ) ;
opkernel . doc ( ) = " OpKernel submodule " ;
py : : class_ < onnxruntime : : KernelDef > kernel_def ( opkernel , " KernelDef " ) ;
kernel_def . def_property_readonly ( " op_name " , & onnxruntime : : KernelDef : : OpName )
2019-09-13 18:25:18 +00:00
. def_property_readonly ( " domain " , & onnxruntime : : KernelDef : : Domain )
. def_property_readonly ( " provider " , & onnxruntime : : KernelDef : : Provider )
. def_property_readonly ( " version_range " ,
[ ] ( const onnxruntime : : KernelDef & kernelDef ) - > std : : pair < int , int > {
return kernelDef . onnxruntime : : KernelDef : : SinceVersion ( ) ;
} )
. def_property_readonly ( " type_constraints " ,
[ ] ( const onnxruntime : : KernelDef & kernelDef ) - > std : : unordered_map < std : : string , std : : vector < std : : string > > {
std : : unordered_map < std : : string , std : : vector < std : : string > > result ;
const auto & tempResult = kernelDef . TypeConstraints ( ) ;
for ( const auto & tc : tempResult ) {
result [ tc . first ] = std : : vector < std : : string > ( ) ;
for ( const auto & dt : tc . second ) {
result [ tc . first ] . emplace_back ( onnxruntime : : DataTypeImpl : : ToString ( dt ) ) ;
}
}
return result ;
} ) ;
2019-08-15 01:12:24 +00:00
}
2019-06-11 22:54:03 +00:00
void addOpSchemaSubmodule ( py : : module & m ) {
2019-03-27 04:58:01 +00:00
auto schemadef = m . def_submodule ( " schemadef " ) ;
schemadef . doc ( ) = " Schema submodule " ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : class_ < ONNX_NAMESPACE : : OpSchema > op_schema ( schemadef , " OpSchema " , py : : module_local ( ) ) ;
2019-03-27 04:58:01 +00:00
op_schema . def_property_readonly ( " file " , & ONNX_NAMESPACE : : OpSchema : : file )
. def_property_readonly ( " line " , & ONNX_NAMESPACE : : OpSchema : : line )
. def_property_readonly ( " support_level " , & ONNX_NAMESPACE : : OpSchema : : support_level )
. def_property_readonly (
" doc " , & ONNX_NAMESPACE : : OpSchema : : doc , py : : return_value_policy : : reference )
. def_property_readonly ( " since_version " , & ONNX_NAMESPACE : : OpSchema : : since_version )
. def_property_readonly ( " deprecated " , & ONNX_NAMESPACE : : OpSchema : : deprecated )
. def_property_readonly ( " domain " , & ONNX_NAMESPACE : : OpSchema : : domain )
. def_property_readonly ( " name " , & ONNX_NAMESPACE : : OpSchema : : Name )
. def_property_readonly ( " min_input " , & ONNX_NAMESPACE : : OpSchema : : min_input )
. def_property_readonly ( " max_input " , & ONNX_NAMESPACE : : OpSchema : : max_input )
. def_property_readonly ( " min_output " , & ONNX_NAMESPACE : : OpSchema : : min_output )
. def_property_readonly ( " max_output " , & ONNX_NAMESPACE : : OpSchema : : max_output )
. def_property_readonly ( " attributes " , & ONNX_NAMESPACE : : OpSchema : : attributes )
. def_property_readonly ( " inputs " , & ONNX_NAMESPACE : : OpSchema : : inputs )
. def_property_readonly ( " outputs " , & ONNX_NAMESPACE : : OpSchema : : outputs )
. def_property_readonly (
" has_type_and_shape_inference_function " ,
& ONNX_NAMESPACE : : OpSchema : : has_type_and_shape_inference_function )
. def_property_readonly (
" type_constraints " , & ONNX_NAMESPACE : : OpSchema : : typeConstraintParams )
. def_static ( " is_infinite " , [ ] ( int v ) {
return v = = std : : numeric_limits < int > : : max ( ) ;
} ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : class_ < ONNX_NAMESPACE : : OpSchema : : Attribute > ( op_schema , " Attribute " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. def_readonly ( " name " , & ONNX_NAMESPACE : : OpSchema : : Attribute : : name )
. def_readonly ( " description " , & ONNX_NAMESPACE : : OpSchema : : Attribute : : description )
. def_readonly ( " type " , & ONNX_NAMESPACE : : OpSchema : : Attribute : : type )
. def_property_readonly (
" _default_value " ,
[ ] ( ONNX_NAMESPACE : : OpSchema : : Attribute * attr ) - > py : : bytes {
std : : string out ;
attr - > default_value . SerializeToString ( & out ) ;
return out ;
} )
. def_readonly ( " required " , & ONNX_NAMESPACE : : OpSchema : : Attribute : : required ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : class_ < ONNX_NAMESPACE : : OpSchema : : TypeConstraintParam > ( op_schema , " TypeConstraintParam " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. def_readonly (
" type_param_str " , & ONNX_NAMESPACE : : OpSchema : : TypeConstraintParam : : type_param_str )
. def_readonly ( " description " , & ONNX_NAMESPACE : : OpSchema : : TypeConstraintParam : : description )
. def_readonly (
" allowed_type_strs " ,
& ONNX_NAMESPACE : : OpSchema : : TypeConstraintParam : : allowed_type_strs ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : enum_ < ONNX_NAMESPACE : : OpSchema : : FormalParameterOption > ( op_schema , " FormalParameterOption " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. value ( " Single " , ONNX_NAMESPACE : : OpSchema : : Single )
. value ( " Optional " , ONNX_NAMESPACE : : OpSchema : : Optional )
. value ( " Variadic " , ONNX_NAMESPACE : : OpSchema : : Variadic ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : class_ < ONNX_NAMESPACE : : OpSchema : : FormalParameter > ( op_schema , " FormalParameter " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. def_property_readonly ( " name " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetName )
. def_property_readonly ( " types " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetTypes )
. def_property_readonly ( " typeStr " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetTypeStr )
. def_property_readonly (
" description " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetDescription )
. def_property_readonly ( " option " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetOption )
. def_property_readonly (
" isHomogeneous " , & ONNX_NAMESPACE : : OpSchema : : FormalParameter : : GetIsHomogeneous ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : enum_ < ONNX_NAMESPACE : : AttributeProto : : AttributeType > ( op_schema , " AttrType " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. value ( " FLOAT " , ONNX_NAMESPACE : : AttributeProto : : FLOAT )
. value ( " INT " , ONNX_NAMESPACE : : AttributeProto : : INT )
. value ( " STRING " , ONNX_NAMESPACE : : AttributeProto : : STRING )
. value ( " TENSOR " , ONNX_NAMESPACE : : AttributeProto : : TENSOR )
. value ( " GRAPH " , ONNX_NAMESPACE : : AttributeProto : : GRAPH )
. value ( " FLOATS " , ONNX_NAMESPACE : : AttributeProto : : FLOATS )
. value ( " INTS " , ONNX_NAMESPACE : : AttributeProto : : INTS )
. value ( " STRINGS " , ONNX_NAMESPACE : : AttributeProto : : STRINGS )
. value ( " TENSORS " , ONNX_NAMESPACE : : AttributeProto : : TENSORS )
. value ( " GRAPHS " , ONNX_NAMESPACE : : AttributeProto : : GRAPHS ) ;
2020-06-13 02:32:57 +00:00
// Keep this binding local to this module
py : : enum_ < ONNX_NAMESPACE : : OpSchema : : SupportType > ( op_schema , " SupportType " , py : : module_local ( ) )
2019-03-27 04:58:01 +00:00
. value ( " COMMON " , ONNX_NAMESPACE : : OpSchema : : SupportType : : COMMON )
. value ( " EXPERIMENTAL " , ONNX_NAMESPACE : : OpSchema : : SupportType : : EXPERIMENTAL ) ;
2018-11-20 00:48:22 +00:00
}
2019-06-11 22:54:03 +00:00
# endif //onnxruntime_PYBIND_EXPORT_OPSCHEMA
2019-03-27 04:58:01 +00:00
2020-03-18 22:42:46 +00:00
void addObjectMethods ( py : : module & m , Environment & env ) {
2019-08-15 00:12:08 +00:00
py : : enum_ < GraphOptimizationLevel > ( m , " GraphOptimizationLevel " )
. value ( " ORT_DISABLE_ALL " , GraphOptimizationLevel : : ORT_DISABLE_ALL )
. value ( " ORT_ENABLE_BASIC " , GraphOptimizationLevel : : ORT_ENABLE_BASIC )
. value ( " ORT_ENABLE_EXTENDED " , GraphOptimizationLevel : : ORT_ENABLE_EXTENDED )
. value ( " ORT_ENABLE_ALL " , GraphOptimizationLevel : : ORT_ENABLE_ALL ) ;
2019-10-14 16:48:19 +00:00
py : : enum_ < ExecutionMode > ( m , " ExecutionMode " )
. value ( " ORT_SEQUENTIAL " , ExecutionMode : : ORT_SEQUENTIAL )
. value ( " ORT_PARALLEL " , ExecutionMode : : ORT_PARALLEL ) ;
2020-03-11 21:25:37 +00:00
py : : class_ < OrtDevice > device ( m , " OrtDevice " , R " pbdoc(ONNXRuntime device informaion.)pbdoc " ) ;
device . def ( py : : init < OrtDevice : : DeviceType , OrtDevice : : MemoryType , OrtDevice : : DeviceId > ( ) )
. def ( " device_id " , & OrtDevice : : Id , R " pbdoc(Device Id.)pbdoc " )
. def ( " device_type " , & OrtDevice : : Type , R " pbdoc(Device Type.)pbdoc " )
. def_static ( " cpu " , [ ] ( ) { return OrtDevice : : CPU ; } )
. def_static ( " cuda " , [ ] ( ) { return OrtDevice : : GPU ; } )
. def_static ( " default_memory " , [ ] ( ) { return OrtDevice : : MemType : : DEFAULT ; } ) ;
py : : class_ < SessionIOBinding > binding ( m , " SessionIOBinding " ) ;
binding
. def ( py : : init < InferenceSession * > ( ) )
. def ( " bind_input " , [ ] ( SessionIOBinding * io_binding , const std : : string & name , const OrtDevice & device , py : : object element_type , std : : vector < int64_t > shape , int64_t data_ptr ) - > void {
PyArray_Descr * dtype ;
if ( ! PyArray_DescrConverter ( element_type . ptr ( ) , & dtype ) )
throw std : : runtime_error ( " Not a valid numpy type " ) ;
int type_num = dtype - > type_num ;
Py_DECREF ( dtype ) ;
2020-06-12 00:04:06 +00:00
OrtMemoryInfo info ( GetDeviceName ( device ) , OrtDeviceAllocator , device ) ;
2020-03-11 21:25:37 +00:00
std : : unique_ptr < Tensor > p_tensor = onnxruntime : : make_unique < Tensor > ( NumpyTypeToOnnxRuntimeType ( type_num ) , shape , ( void * ) data_ptr , info ) ;
OrtValue mlvalue ;
mlvalue . Init ( p_tensor . release ( ) ,
DataTypeImpl : : GetType < Tensor > ( ) ,
DataTypeImpl : : GetType < Tensor > ( ) - > GetDeleteFunc ( ) ) ;
auto status = io_binding - > Get ( ) - > BindInput ( name , mlvalue ) ;
if ( ! status . IsOK ( ) )
throw std : : runtime_error ( " Error when bind input: " + status . ErrorMessage ( ) ) ;
} )
. def ( " bind_output " , [ ] ( SessionIOBinding * io_binding , const std : : string & name , const OrtDevice & device , py : : object element_type , std : : vector < int64_t > shape , int64_t data_ptr ) - > void {
PyArray_Descr * dtype ;
if ( ! PyArray_DescrConverter ( element_type . ptr ( ) , & dtype ) )
throw std : : runtime_error ( " Not a valid numpy type " ) ;
int type_num = dtype - > type_num ;
Py_DECREF ( dtype ) ;
2020-06-12 00:04:06 +00:00
OrtMemoryInfo info ( GetDeviceName ( device ) , OrtDeviceAllocator , device ) ;
2020-03-11 21:25:37 +00:00
std : : unique_ptr < Tensor > p_tensor = onnxruntime : : make_unique < Tensor > ( NumpyTypeToOnnxRuntimeType ( type_num ) , shape , ( void * ) data_ptr , info ) ;
OrtValue mlvalue ;
mlvalue . Init ( p_tensor . release ( ) ,
DataTypeImpl : : GetType < Tensor > ( ) ,
DataTypeImpl : : GetType < Tensor > ( ) - > GetDeleteFunc ( ) ) ;
auto status = io_binding - > Get ( ) - > BindOutput ( name , mlvalue ) ;
if ( ! status . IsOK ( ) )
throw std : : runtime_error ( " Error when bind input: " + status . ErrorMessage ( ) ) ;
} )
. def ( " clear_binding_inputs " , [ ] ( SessionIOBinding * io_binding ) - > void {
io_binding - > Get ( ) - > ClearInputs ( ) ;
} )
. def ( " clear_binding_outputs " , [ ] ( SessionIOBinding * io_binding ) - > void {
io_binding - > Get ( ) - > ClearOutputs ( ) ;
} ) ;
2019-10-14 16:48:19 +00:00
py : : class_ < SessionOptions >
sess ( m , " SessionOptions " , R " pbdoc(Configuration information for a session.)pbdoc " ) ;
2019-08-15 00:12:08 +00:00
sess
2018-11-20 00:48:22 +00:00
. def ( py : : init ( ) )
2018-11-30 01:03:09 +00:00
. def_readwrite ( " enable_cpu_mem_arena " , & SessionOptions : : enable_cpu_mem_arena ,
R " pbdoc(Enables the memory arena on CPU. Arena may pre-allocate memory for future usage.
Set this option to false if you don ' t want it . Default is True . ) pbdoc " )
2018-11-20 00:48:22 +00:00
. def_readwrite ( " enable_profiling " , & SessionOptions : : enable_profiling ,
2018-11-30 01:03:09 +00:00
R " pbdoc(Enable profiling for this session. Default is false.)pbdoc " )
2019-08-13 01:43:40 +00:00
. def_readwrite ( " optimized_model_filepath " , & SessionOptions : : optimized_model_filepath ,
R " pbdoc(File path to serialize optimized model. By default, optimized model is not serialized if optimized_model_filepath is not provided.)pbdoc " )
2019-06-19 18:17:21 +00:00
. def_readwrite ( " enable_mem_pattern " , & SessionOptions : : enable_mem_pattern ,
R " pbdoc(Enable the memory pattern optimization. Default is true.)pbdoc " )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " logid " , & SessionOptions : : session_logid ,
2018-11-20 00:48:22 +00:00
R " pbdoc(Logger id to use for session output.)pbdoc " )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " log_severity_level " , & SessionOptions : : session_log_severity_level ,
2019-09-19 19:43:44 +00:00
R " pbdoc(Log severity level. Applies to session load, initialization, etc.
2019-06-11 22:54:03 +00:00
0 : Verbose , 1 : Info , 2 : Warning . 3 : Error , 4 : Fatal . Default is 2. ) pbdoc " )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " log_verbosity_level " , & SessionOptions : : session_log_verbosity_level ,
2019-09-19 19:43:44 +00:00
R " pbdoc(VLOG level if DEBUG build and session_log_verbosity_level is 0.
2019-06-11 22:54:03 +00:00
Applies to session load , initialization , etc . Default is 0. ) pbdoc " )
2020-05-06 07:57:09 +00:00
. def_property (
" intra_op_num_threads " , [ ] ( const SessionOptions * options ) - > int { return options - > intra_op_param . thread_pool_size ; } , [ ] ( SessionOptions * options , int value ) - > void { options - > intra_op_param . thread_pool_size = value ; } , R " pbdoc(Sets the number of threads used to parallelize the execution within nodes. Default is 0 to let onnxruntime choose.)pbdoc " )
. def_property (
" inter_op_num_threads " , [ ] ( const SessionOptions * options ) - > int { return options - > inter_op_param . thread_pool_size ; } , [ ] ( SessionOptions * options , int value ) - > void { options - > inter_op_param . thread_pool_size = value ; } , R " pbdoc(Sets the number of threads used to parallelize the execution of the graph (across nodes). Default is 0 to let onnxruntime choose.)pbdoc " )
2019-10-14 16:48:19 +00:00
. def_readwrite ( " execution_mode " , & SessionOptions : : execution_mode ,
R " pbdoc(Sets the execution mode. Default is sequential.)pbdoc " )
2019-08-27 19:48:46 +00:00
. def_property (
2019-06-11 22:54:03 +00:00
" graph_optimization_level " ,
2019-08-15 00:12:08 +00:00
[ ] ( const SessionOptions * options ) - > GraphOptimizationLevel {
2020-01-13 22:05:38 +00:00
GraphOptimizationLevel retval = ORT_ENABLE_ALL ;
2019-08-15 00:12:08 +00:00
switch ( options - > graph_optimization_level ) {
case onnxruntime : : TransformerLevel : : Default :
retval = ORT_DISABLE_ALL ;
break ;
case onnxruntime : : TransformerLevel : : Level1 :
retval = ORT_ENABLE_BASIC ;
break ;
case onnxruntime : : TransformerLevel : : Level2 :
retval = ORT_ENABLE_EXTENDED ;
break ;
case onnxruntime : : TransformerLevel : : Level3 :
retval = ORT_ENABLE_ALL ;
break ;
default :
2020-01-13 22:05:38 +00:00
retval = ORT_ENABLE_ALL ;
LOGS_DEFAULT ( WARNING ) < < " Got invalid graph optimization level; defaulting to ORT_ENABLE_ALL " ;
2019-08-15 00:12:08 +00:00
break ;
}
return retval ;
2019-06-11 22:54:03 +00:00
} ,
2019-09-13 18:25:18 +00:00
2019-08-15 00:12:08 +00:00
[ ] ( SessionOptions * options , GraphOptimizationLevel level ) - > void {
switch ( level ) {
case ORT_DISABLE_ALL :
options - > graph_optimization_level = onnxruntime : : TransformerLevel : : Default ;
break ;
case ORT_ENABLE_BASIC :
options - > graph_optimization_level = onnxruntime : : TransformerLevel : : Level1 ;
break ;
case ORT_ENABLE_EXTENDED :
options - > graph_optimization_level = onnxruntime : : TransformerLevel : : Level2 ;
break ;
case ORT_ENABLE_ALL :
options - > graph_optimization_level = onnxruntime : : TransformerLevel : : Level3 ;
break ;
}
2019-06-11 22:54:03 +00:00
} ,
2019-08-15 00:12:08 +00:00
R " pbdoc(Graph optimization level for this session.)pbdoc " ) ;
2018-11-20 00:48:22 +00:00
py : : class_ < RunOptions > ( m , " RunOptions " , R " pbdoc(Configuration information for a single Run.)pbdoc " )
. def ( py : : init ( ) )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " log_severity_level " , & RunOptions : : run_log_severity_level ,
2019-06-11 22:54:03 +00:00
R " pbdoc(Log severity level for a particular Run() invocation. 0:Verbose, 1:Info, 2:Warning. 3:Error, 4:Fatal. Default is 2.)pbdoc " )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " log_verbosity_level " , & RunOptions : : run_log_verbosity_level ,
2019-09-19 19:43:44 +00:00
R " pbdoc(VLOG level if DEBUG build and run_log_severity_level is 0.
2019-06-11 22:54:03 +00:00
Applies to a particular Run ( ) invocation . Default is 0. ) pbdoc " )
2019-08-27 19:48:46 +00:00
. def_readwrite ( " logid " , & RunOptions : : run_tag ,
2018-11-30 01:03:09 +00:00
" To identify logs generated by a particular Run() invocation. " )
. def_readwrite ( " terminate " , & RunOptions : : terminate ,
R " pbdoc(Set to True to terminate any currently executing calls that are using this
2020-03-11 21:25:37 +00:00
RunOptions instance . The individual calls will exit gracefully and return an error status . ) pbdoc " )
. def_readwrite ( " only_execute_path_to_fetches " , & RunOptions : : only_execute_path_to_fetches ,
2020-04-29 04:03:37 +00:00
R " pbdoc(Only execute the nodes needed by fetch list)pbdoc " )
. def_readwrite ( " training_mode " , & RunOptions : : training_mode ,
R " pbdoc(Choose to run in training or inferencing mode)pbdoc " ) ;
2018-11-20 00:48:22 +00:00
py : : class_ < ModelMetadata > ( m , " ModelMetadata " , R " pbdoc(Pre-defined and custom metadata about the model.
It is usually used to identify the model used to run the prediction and
facilitate the comparison . ) pbdoc " )
. def_readwrite ( " producer_name " , & ModelMetadata : : producer_name , " producer name " )
. def_readwrite ( " graph_name " , & ModelMetadata : : graph_name , " graph name " )
. def_readwrite ( " domain " , & ModelMetadata : : domain , " ONNX domain " )
. def_readwrite ( " description " , & ModelMetadata : : description , " description of the model " )
. def_readwrite ( " version " , & ModelMetadata : : version , " version of the model " )
. def_readwrite ( " custom_metadata_map " , & ModelMetadata : : custom_metadata_map , " additional metadata " ) ;
py : : class_ < onnxruntime : : NodeArg > ( m , " NodeArg " , R " pbdoc(Node argument definition, for both input and output,
including arg name , arg type ( contains both type and shape ) . ) pbdoc " )
. def_property_readonly ( " name " , & onnxruntime : : NodeArg : : Name , " node name " )
2018-12-05 22:03:45 +00:00
. def_property_readonly (
" type " , [ ] ( const onnxruntime : : NodeArg & na ) - > std : : string {
return * ( na . Type ( ) ) ;
} ,
" node type " )
2020-05-06 07:57:09 +00:00
. def (
" __str__ " , [ ] ( const onnxruntime : : NodeArg & na ) - > std : : string {
std : : ostringstream res ;
res < < " NodeArg(name=' " < < na . Name ( ) < < " ', type=' " < < * ( na . Type ( ) ) < < " ', shape= " ;
auto shape = na . Shape ( ) ;
std : : vector < py : : object > arr ;
if ( shape = = nullptr | | shape - > dim_size ( ) = = 0 ) {
res < < " [] " ;
2019-06-11 22:54:03 +00:00
} else {
2020-05-06 07:57:09 +00:00
res < < " [ " ;
for ( int i = 0 ; i < shape - > dim_size ( ) ; + + i ) {
if ( utils : : HasDimValue ( shape - > dim ( i ) ) ) {
res < < shape - > dim ( i ) . dim_value ( ) ;
} else if ( utils : : HasDimParam ( shape - > dim ( i ) ) ) {
res < < " ' " < < shape - > dim ( i ) . dim_param ( ) < < " ' " ;
} else {
res < < " None " ;
}
if ( i < shape - > dim_size ( ) - 1 ) {
res < < " , " ;
}
}
res < < " ] " ;
2019-06-11 22:54:03 +00:00
}
2020-05-06 07:57:09 +00:00
res < < " ) " ;
2019-04-23 18:11:35 +00:00
2020-05-06 07:57:09 +00:00
return std : : string ( res . str ( ) ) ;
} ,
" converts the node into a readable string " )
. def_property_readonly (
" shape " , [ ] ( const onnxruntime : : NodeArg & na ) - > std : : vector < py : : object > {
auto shape = na . Shape ( ) ;
std : : vector < py : : object > arr ;
if ( shape = = nullptr | | shape - > dim_size ( ) = = 0 ) {
return arr ;
2019-09-13 18:25:18 +00:00
}
2020-03-11 21:25:37 +00:00
2020-05-06 07:57:09 +00:00
arr . resize ( shape - > dim_size ( ) ) ;
for ( int i = 0 ; i < shape - > dim_size ( ) ; + + i ) {
if ( utils : : HasDimValue ( shape - > dim ( i ) ) ) {
arr [ i ] = py : : cast ( shape - > dim ( i ) . dim_value ( ) ) ;
} else if ( utils : : HasDimParam ( shape - > dim ( i ) ) ) {
arr [ i ] = py : : cast ( shape - > dim ( i ) . dim_param ( ) ) ;
} else {
arr [ i ] = py : : none ( ) ;
}
}
return arr ;
} ,
" node shape (assuming the node holds a tensor) " ) ;
2018-11-20 00:48:22 +00:00
py : : class_ < SessionObjectInitializer > ( m , " SessionObjectInitializer " ) ;
py : : class_ < InferenceSession > ( m , " InferenceSession " , R " pbdoc(This is the main class used to run a model.)pbdoc " )
2019-12-04 00:56:07 +00:00
// In Python3, a Python bytes object will be passed to C++ functions that accept std::string or char*
// without any conversion. So this init method can be used for model file path (string)
// and model content (bytes)
2020-03-18 22:42:46 +00:00
. def ( py : : init ( [ & env ] ( const SessionOptions & so , const std : : string & arg , bool is_arg_file_name ) {
2019-12-04 00:56:07 +00:00
// Given arg is the file path. Invoke the corresponding ctor().
if ( is_arg_file_name ) {
2020-03-18 22:42:46 +00:00
return onnxruntime : : make_unique < InferenceSession > ( so , env , arg ) ;
2019-12-04 00:56:07 +00:00
}
// Given arg is the model content as bytes. Invoke the corresponding ctor().
std : : istringstream buffer ( arg ) ;
2020-03-18 22:42:46 +00:00
return onnxruntime : : make_unique < InferenceSession > ( so , env , buffer ) ;
2019-12-04 00:56:07 +00:00
} ) )
2018-12-05 22:03:45 +00:00
. def (
2019-12-04 00:56:07 +00:00
" load_model " , [ ] ( InferenceSession * sess , std : : vector < std : : string > & provider_types ) {
OrtPybindThrowIfError ( sess - > Load ( ) ) ;
2019-09-13 18:25:18 +00:00
InitializeSession ( sess , provider_types ) ;
2018-12-05 22:03:45 +00:00
} ,
R " pbdoc(Load a model saved in ONNX format.)pbdoc " )
2018-11-20 00:48:22 +00:00
. def ( " run " , [ ] ( InferenceSession * sess , std : : vector < std : : string > output_names , std : : map < std : : string , py : : object > pyfeeds , RunOptions * run_options = nullptr ) - > std : : vector < py : : object > {
NameMLValMap feeds ;
for ( auto _ : pyfeeds ) {
2019-05-17 14:52:59 +00:00
OrtValue ml_value ;
2019-10-10 22:58:49 +00:00
auto px = sess - > GetModelInputs ( ) ;
if ( ! px . first . IsOK ( ) | | ! px . second ) {
throw std : : runtime_error ( " Either failed to get model inputs from the session object or the input def list was null " ) ;
}
CreateGenericMLValue ( px . second , GetAllocator ( ) , _ . first , _ . second , & ml_value ) ;
2018-11-20 00:48:22 +00:00
if ( PyErr_Occurred ( ) ) {
PyObject * ptype , * pvalue , * ptraceback ;
PyErr_Fetch ( & ptype , & pvalue , & ptraceback ) ;
PyObject * pStr = PyObject_Str ( ptype ) ;
std : : string sType = py : : reinterpret_borrow < py : : str > ( pStr ) ;
Py_XDECREF ( pStr ) ;
pStr = PyObject_Str ( pvalue ) ;
sType + = " : " ;
sType + = py : : reinterpret_borrow < py : : str > ( pStr ) ;
Py_XDECREF ( pStr ) ;
throw std : : runtime_error ( sType ) ;
}
feeds . insert ( std : : make_pair ( _ . first , ml_value ) ) ;
}
2019-05-17 14:52:59 +00:00
std : : vector < OrtValue > fetches ;
2018-11-20 00:48:22 +00:00
common : : Status status ;
2019-05-16 01:11:14 +00:00
{
// release GIL to allow multiple python threads to invoke Run() in parallel.
py : : gil_scoped_release release ;
if ( run_options ! = nullptr ) {
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( sess - > Run ( * run_options , feeds , output_names , & fetches ) ) ;
2019-05-16 01:11:14 +00:00
} else {
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( sess - > Run ( feeds , output_names , & fetches ) ) ;
2019-05-16 01:11:14 +00:00
}
2018-11-20 00:48:22 +00:00
}
std : : vector < py : : object > rfetch ;
rfetch . reserve ( fetches . size ( ) ) ;
for ( auto _ : fetches ) {
if ( _ . IsTensor ( ) ) {
AddTensorAsPyObj ( _ , rfetch ) ;
} else {
AddNonTensorAsPyObj ( _ , rfetch ) ;
}
}
return rfetch ;
} )
. def ( " end_profiling " , [ ] ( InferenceSession * sess ) - > std : : string {
return sess - > EndProfiling ( ) ;
} )
2019-09-13 18:25:18 +00:00
. def ( " get_providers " , [ ] ( InferenceSession * sess ) - > const std : : vector < std : : string > & {
return sess - > GetRegisteredProviderTypes ( ) ;
} )
2019-12-04 00:56:07 +00:00
. def_property_readonly ( " session_options " , [ ] ( InferenceSession * sess ) - > const SessionOptions & {
return sess - > GetSessionOptions ( ) ;
} )
2018-11-20 00:48:22 +00:00
. def_property_readonly ( " inputs_meta " , [ ] ( const InferenceSession * sess ) - > const std : : vector < const onnxruntime : : NodeArg * > & {
auto res = sess - > GetModelInputs ( ) ;
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( res . first ) ;
return * ( res . second ) ;
2018-11-20 00:48:22 +00:00
} )
. def_property_readonly ( " outputs_meta " , [ ] ( const InferenceSession * sess ) - > const std : : vector < const onnxruntime : : NodeArg * > & {
auto res = sess - > GetModelOutputs ( ) ;
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( res . first ) ;
return * ( res . second ) ;
2018-11-20 00:48:22 +00:00
} )
2019-09-19 22:43:28 +00:00
. def_property_readonly ( " overridable_initializers " , [ ] ( const InferenceSession * sess ) - > const std : : vector < const onnxruntime : : NodeArg * > & {
auto res = sess - > GetOverridableInitializers ( ) ;
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( res . first ) ;
return * ( res . second ) ;
2019-09-19 22:43:28 +00:00
} )
2018-11-20 00:48:22 +00:00
. def_property_readonly ( " model_meta " , [ ] ( const InferenceSession * sess ) - > const onnxruntime : : ModelMetadata & {
auto res = sess - > GetModelMetadata ( ) ;
2019-09-24 18:13:14 +00:00
OrtPybindThrowIfError ( res . first ) ;
return * ( res . second ) ;
2020-03-11 21:25:37 +00:00
} )
. def ( " run_with_iobinding " , [ ] ( InferenceSession * sess , SessionIOBinding & io_binding , RunOptions * run_options = nullptr ) - > void {
Status status ;
if ( ! run_options )
status = sess - > Run ( * io_binding . Get ( ) ) ;
else
status = sess - > Run ( * run_options , * io_binding . Get ( ) ) ;
if ( ! status . IsOK ( ) )
throw std : : runtime_error ( " Error in execution: " + status . ErrorMessage ( ) ) ;
} ) ;
2020-03-17 23:10:23 +00:00
py : : enum_ < onnxruntime : : ArenaExtendStrategy > ( m , " ArenaExtendStrategy " , py : : arithmetic ( ) )
. value ( " kNextPowerOfTwo " , onnxruntime : : ArenaExtendStrategy : : kNextPowerOfTwo )
. value ( " kSameAsRequested " , onnxruntime : : ArenaExtendStrategy : : kSameAsRequested )
. export_values ( ) ;
}
# if defined(USE_MIMALLOC_ARENA_ALLOCATOR)
static struct {
PyMemAllocatorEx mem ;
PyMemAllocatorEx raw ;
PyMemAllocatorEx obj ;
} allocators ;
# endif
# ifdef ENABLE_TRAINING
2020-03-20 03:59:41 +00:00
void addObjectMethodsForTraining ( py : : module & m ) ;
2020-03-17 23:10:23 +00:00
# endif
2018-11-20 00:48:22 +00:00
PYBIND11_MODULE ( onnxruntime_pybind11_state , m ) {
m . doc ( ) = " pybind11 stateful interface to ONNX runtime " ;
2019-09-24 18:13:14 +00:00
RegisterExceptions ( m ) ;
2018-11-20 00:48:22 +00:00
2020-02-23 06:04:30 +00:00
# if defined(USE_MIMALLOC_ARENA_ALLOCATOR)
2019-10-24 05:34:00 +00:00
PyMemAllocatorEx alloc ;
2019-12-04 00:56:07 +00:00
alloc . malloc = [ ] ( void * ctx , size_t size ) {
2019-10-24 05:34:00 +00:00
ORT_UNUSED_PARAMETER ( ctx ) ;
2019-12-04 00:56:07 +00:00
return mi_malloc ( size ) ;
2019-10-24 05:34:00 +00:00
} ;
2019-12-04 00:56:07 +00:00
alloc . calloc = [ ] ( void * ctx , size_t nelem , size_t elsize ) {
2019-10-24 05:34:00 +00:00
ORT_UNUSED_PARAMETER ( ctx ) ;
2019-12-04 00:56:07 +00:00
return mi_calloc ( nelem , elsize ) ;
2019-10-24 05:34:00 +00:00
} ;
2019-12-04 00:56:07 +00:00
alloc . realloc = [ ] ( void * ctx , void * ptr , size_t new_size ) {
if ( mi_is_in_heap_region ( ptr ) ) {
return mi_realloc ( ptr , new_size ) ;
} else {
PyMemAllocatorEx * a = ( PyMemAllocatorEx * ) ctx ;
return a - > realloc ( ctx , ptr , new_size ) ;
2019-10-24 05:34:00 +00:00
}
} ;
2019-12-04 00:56:07 +00:00
alloc . free = [ ] ( void * ctx , void * ptr ) {
if ( mi_is_in_heap_region ( ptr ) ) {
2019-10-24 05:34:00 +00:00
mi_free ( ptr ) ;
2019-12-04 00:56:07 +00:00
} else {
2019-10-24 05:34:00 +00:00
PyMemAllocatorEx * a = ( PyMemAllocatorEx * ) ctx ;
a - > free ( ctx , ptr ) ;
}
} ;
2019-12-04 00:56:07 +00:00
2019-10-24 05:34:00 +00:00
alloc . ctx = & allocators . raw ;
PyMem_GetAllocator ( PYMEM_DOMAIN_RAW , & allocators . raw ) ;
PyMem_SetAllocator ( PYMEM_DOMAIN_RAW , & alloc ) ;
alloc . ctx = & allocators . mem ;
PyMem_GetAllocator ( PYMEM_DOMAIN_MEM , & allocators . mem ) ;
PyMem_SetAllocator ( PYMEM_DOMAIN_MEM , & alloc ) ;
alloc . ctx = & allocators . obj ;
PyMem_GetAllocator ( PYMEM_DOMAIN_OBJ , & allocators . obj ) ;
PyMem_SetAllocator ( PYMEM_DOMAIN_OBJ , & alloc ) ;
# endif
2020-03-23 23:23:34 +00:00
// Initialization of the module
( [ ] ( ) - > void {
// import_array1() forces a void return value.
import_array1 ( ) ;
} ) ( ) ;
Environment & env = get_env ( ) ;
addGlobalMethods ( m , env ) ;
addObjectMethods ( m , env ) ;
# ifdef ENABLE_TRAINING
addObjectMethodsForTraining ( m ) ;
# endif // ENABLE_TRAINING
# ifdef onnxruntime_PYBIND_EXPORT_OPSCHEMA
addOpSchemaSubmodule ( m ) ;
addOpKernelSubmodule ( m ) ;
# endif
}
2020-03-25 16:57:05 +00:00
// static variable used to create inference session and training session.
static std : : unique_ptr < Environment > session_env ;
2020-03-23 23:23:34 +00:00
2020-05-06 07:57:09 +00:00
void initialize_env ( ) {
2018-11-20 00:48:22 +00:00
auto initialize = [ & ] ( ) {
// Initialization of the module
( [ ] ( ) - > void {
// import_array1() forces a void return value.
import_array1 ( ) ;
} ) ( ) ;
2020-03-18 22:42:46 +00:00
OrtPybindThrowIfError ( Environment : : Create ( onnxruntime : : make_unique < LoggingManager > (
std : : unique_ptr < ISink > { new CLogSink { } } ,
Severity : : kWARNING , false , LoggingManager : : InstanceType : : Default ,
& SessionObjectInitializer : : default_logger_id ) ,
2020-03-23 23:23:34 +00:00
session_env ) ) ;
2018-11-20 00:48:22 +00:00
static bool initialized = false ;
if ( initialized ) {
return ;
}
initialized = true ;
} ;
initialize ( ) ;
2020-03-23 23:23:34 +00:00
}
2018-11-20 00:48:22 +00:00
2020-05-06 07:57:09 +00:00
onnxruntime : : Environment & get_env ( ) {
if ( ! session_env ) {
2020-03-23 23:23:34 +00:00
initialize_env ( ) ;
}
return * session_env ;
2018-11-20 00:48:22 +00:00
}
} // namespace python
2020-04-28 15:41:37 +00:00
} // namespace onnxruntime