diff --git a/.gitignore b/.gitignore index caf2099..00bfb09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Ignoring onnxruntime libs -/libs/onnxruntime/lib/* +# /libs/onnxruntime/lib/* example-*/config.make example-*/*.sln diff --git a/libs/onnxruntime/include/onnxruntime_c_api.h b/libs/onnxruntime/include/onnxruntime_c_api.h index fcf3239..7c334a2 100644 --- a/libs/onnxruntime/include/onnxruntime_c_api.h +++ b/libs/onnxruntime/include/onnxruntime_c_api.h @@ -38,7 +38,7 @@ * * This value is used by some API functions to behave as this version of the header expects. */ -#define ORT_API_VERSION 20 +#define ORT_API_VERSION 21 #ifdef __cplusplus extern "C" { @@ -46,7 +46,7 @@ extern "C" { //! @} // SAL2 Definitions -#ifndef _WIN32 +#ifndef _MSC_VER #define _In_ #define _In_z_ #define _In_opt_ @@ -626,8 +626,13 @@ typedef struct OrtMIGraphXProviderOptions { } OrtMIGraphXProviderOptions; /** \brief OpenVINO Provider Options - * - * \see OrtApi::SessionOptionsAppendExecutionProvider_OpenVINO + * \brief This Struct is frozen since ORT 1.13.0. Its maintained part of Legacy API for compatibility. + * \brief For latest OpenVINO Provider Options update to the ProviderOptions map. + * \brief Latest OpenVINO Provider Options are listed in the + * \htmlonly + * onnxruntime document. + * \endhtmlonly + * \see OrtApi::SessionOptionsAppendExecutionProvider() */ typedef struct OrtOpenVINOProviderOptions { #ifdef __cplusplus @@ -645,7 +650,7 @@ typedef struct OrtOpenVINOProviderOptions { * Valid settings are one of: "CPU_FP32", "CPU_FP16", "GPU_FP32", "GPU_FP16" */ const char* device_type; - unsigned char enable_npu_fast_compile; + unsigned char enable_npu_fast_compile; ///< 0 = disabled, nonzero = enabled const char* device_id; size_t num_of_threads; ///< 0 = Use default number of threads const char* cache_dir; // path is set to empty by default @@ -3660,8 +3665,19 @@ struct OrtApi { * - "1": Enabled. * "offload_graph_io_quantization": Offload graph input quantization and graph output dequantization to another * execution provider (typically CPU EP). - * - "0": Default. Disabled. QNN EP will handle quantization and dequantization of graph I/O. + * - "0": Disabled. QNN EP will handle quantization and dequantization of graph I/O. + * - "1": Enabled. This is the default value. + * "enable_htp_spill_fill_buffer": Enable HTP spill fill buffer setting. The flag is used while generating context binary. + * - "0": Default. Disabled. + * - "1": Enabled. + * "enable_htp_shared_memory_allocator": Enable the QNN HTP shared memory allocator. Requires libcdsprpc.so/dll to + * be available. + * - "0": Default. Disabled. * - "1": Enabled. + * "dump_json_qnn_graph": Set to "1" to dump QNN graphs generated by QNN EP as JSON files. Each graph partition + * assigned to QNN EP is dumped to a separate file. + * "json_qnn_graph_dir": Directory in which to dump QNN JSON graphs. If not specified, QNN graphs are dumped in the + * program's current working directory. Ignored if "dump_json_qnn_graph" is not set. * * SNPE supported keys: * "runtime": SNPE runtime engine, options: "CPU", "CPU_FLOAT32", "GPU", "GPU_FLOAT32_16_HYBRID", "GPU_FLOAT16", @@ -4607,6 +4623,8 @@ struct OrtApi { * \param[in] num_keys * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.17. */ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_OpenVINO_V2, _In_ OrtSessionOptions* options, @@ -4624,6 +4642,8 @@ struct OrtApi { * \param[in] num_keys * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.18. */ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_VitisAI, _In_ OrtSessionOptions* options, @@ -4637,7 +4657,10 @@ struct OrtApi { * \param[in] mem_info OrtMemoryInfo instance * \param[in] count_or_bytes How many bytes is this scratch buffer * \param[out] out A pointer to the scrach buffer + * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.18. */ ORT_API2_STATUS(KernelContext_GetScratchBuffer, _In_ const OrtKernelContext* context, _In_ const OrtMemoryInfo* mem_info, _In_ size_t count_or_bytes, _Outptr_ void** out); @@ -4648,6 +4671,8 @@ struct OrtApi { * \param[out] out A pointer to OrtAllocator * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.18. */ ORT_API2_STATUS(KernelInfoGetAllocator, _In_ const OrtKernelInfo* info, _In_ OrtMemType mem_type, _Outptr_ OrtAllocator** out); @@ -4669,6 +4694,8 @@ struct OrtApi { * \param[in] num_external_initializer_files Number of external files * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.18. */ ORT_API2_STATUS(AddExternalInitializersFromFilesInMemory, _In_ OrtSessionOptions* options, _In_reads_(num_external_initializer_files) const ORTCHAR_T* const* external_initializer_file_names, @@ -4691,6 +4718,8 @@ struct OrtApi { * OrtApi::ReleaseLoraAdapter. * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.20. */ ORT_API2_STATUS(CreateLoraAdapter, const ORTCHAR_T* adapter_file_path, _In_ OrtAllocator* allocator, _Outptr_ OrtLoraAdapter** out); @@ -4709,6 +4738,8 @@ struct OrtApi { * OrtApi::ReleaseLoraAdapter. * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.20. */ ORT_API2_STATUS(CreateLoraAdapterFromArray, _In_ const void* bytes, size_t num_bytes, _In_ OrtAllocator* allocator, _Outptr_ OrtLoraAdapter** out); @@ -4730,6 +4761,8 @@ struct OrtApi { * \param[in] adapter OrtLoraAdapter instance * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.20. */ ORT_API2_STATUS(RunOptionsAddActiveLoraAdapter, _Inout_ OrtRunOptions* options, _In_ const OrtLoraAdapter* adapter); @@ -4748,6 +4781,8 @@ struct OrtApi { * \param[in] kv_len Number of elements in the keys and values arrays * * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.20. */ ORT_API2_STATUS(SetEpDynamicOptions, _Inout_ OrtSession* sess, _In_reads_(kv_len) const char* const* keys, _In_reads_(kv_len) const char* const* values, _In_ size_t kv_len); diff --git a/libs/onnxruntime/include/onnxruntime_cxx_api.h b/libs/onnxruntime/include/onnxruntime_cxx_api.h index ff196cf..82169c3 100644 --- a/libs/onnxruntime/include/onnxruntime_cxx_api.h +++ b/libs/onnxruntime/include/onnxruntime_cxx_api.h @@ -650,6 +650,9 @@ using AllocatedStringPtr = std::unique_ptr; * constructors to construct an instance of a Status object from exceptions. */ struct Status : detail::Base { + using Base = detail::Base; + using Base::Base; + explicit Status(std::nullptr_t) noexcept {} ///< Create an empty object, must be assigned a valid one to be used explicit Status(OrtStatus* status) noexcept; ///< Takes ownership of OrtStatus instance returned from the C API. explicit Status(const Exception&) noexcept; ///< Creates status instance out of exception @@ -728,6 +731,9 @@ struct Env : detail::Base { * */ struct CustomOpDomain : detail::Base { + using Base = detail::Base; + using Base::Base; + explicit CustomOpDomain(std::nullptr_t) {} ///< Create an empty CustomOpDomain object, must be assigned a valid one to be used /// \brief Wraps OrtApi::CreateCustomOpDomain @@ -963,8 +969,10 @@ struct SessionOptions : detail::SessionOptionsImpl { * */ struct ModelMetadata : detail::Base { - explicit ModelMetadata(std::nullptr_t) {} ///< Create an empty ModelMetadata object, must be assigned a valid one to be used - explicit ModelMetadata(OrtModelMetadata* p) : Base{p} {} ///< Used for interop with the C API + using Base = detail::Base; + using Base::Base; + + explicit ModelMetadata(std::nullptr_t) {} ///< Create an empty ModelMetadata object, must be assigned a valid one to be used /** \brief Returns a copy of the producer name. * @@ -1237,6 +1245,9 @@ using ConstTensorTypeAndShapeInfo = detail::TensorTypeAndShapeInfoImpl { + using Base = detail::TensorTypeAndShapeInfoImpl; + using Base::Base; + explicit TensorTypeAndShapeInfo(std::nullptr_t) {} ///< Create an empty TensorTypeAndShapeInfo object, must be assigned a valid one to be used explicit TensorTypeAndShapeInfo(OrtTensorTypeAndShapeInfo* p) : TensorTypeAndShapeInfoImpl{p} {} ///< Used for interop with the C API ConstTensorTypeAndShapeInfo GetConst() const { return ConstTensorTypeAndShapeInfo{this->p_}; } @@ -1258,6 +1269,9 @@ using ConstSequenceTypeInfo = detail::SequenceTypeInfoImpl { + using Base = detail::SequenceTypeInfoImpl; + using Base::Base; + explicit SequenceTypeInfo(std::nullptr_t) {} ///< Create an empty SequenceTypeInfo object, must be assigned a valid one to be used explicit SequenceTypeInfo(OrtSequenceTypeInfo* p) : SequenceTypeInfoImpl{p} {} ///< Used for interop with the C API ConstSequenceTypeInfo GetConst() const { return ConstSequenceTypeInfo{this->p_}; } @@ -1293,6 +1307,9 @@ using ConstMapTypeInfo = detail::MapTypeInfoImpl { + using Base = detail::MapTypeInfoImpl; + using Base::Base; + explicit MapTypeInfo(std::nullptr_t) {} ///< Create an empty MapTypeInfo object, must be assigned a valid one to be used explicit MapTypeInfo(OrtMapTypeInfo* p) : MapTypeInfoImpl{p} {} ///< Used for interop with the C API ConstMapTypeInfo GetConst() const { return ConstMapTypeInfo{this->p_}; } @@ -1324,6 +1341,9 @@ using ConstTypeInfo = detail::TypeInfoImpl>; /// the information about contained sequence or map depending on the ONNXType. /// struct TypeInfo : detail::TypeInfoImpl { + using Base = detail::TypeInfoImpl; + using Base::Base; + explicit TypeInfo(std::nullptr_t) {} ///< Create an empty TypeInfo object, must be assigned a valid one to be used explicit TypeInfo(OrtTypeInfo* p) : TypeInfoImpl{p} {} ///< C API Interop @@ -1661,11 +1681,11 @@ using UnownedValue = detail::ValueImpl>; */ struct Value : detail::ValueImpl { using Base = detail::ValueImpl; + using Base::Base; using OrtSparseValuesParam = detail::OrtSparseValuesParam; using Shape = detail::Shape; - explicit Value(std::nullptr_t) {} ///< Create an empty Value object, must be assigned a valid one to be used - explicit Value(OrtValue* p) : Base{p} {} ///< Used for interop with the C API + explicit Value(std::nullptr_t) {} ///< Create an empty Value object, must be assigned a valid one to be used Value(Value&&) = default; Value& operator=(Value&&) = default; @@ -1941,6 +1961,10 @@ struct ArenaCfg : detail::Base { /// This struct provides life time management for custom op attribute /// struct OpAttr : detail::Base { + using Base = detail::Base; + using Base::Base; + + explicit OpAttr(std::nullptr_t) {} OpAttr(const char* name, const void* data, int len, OrtOpAttrType type); }; @@ -2106,10 +2130,10 @@ struct KernelContext { explicit KernelContext(OrtKernelContext* context); size_t GetInputCount() const; size_t GetOutputCount() const; - // If input is optional and is not present, the method returns en empty ConstValue + // If input is optional and is not present, the method returns an empty ConstValue // which can be compared to nullptr. ConstValue GetInput(size_t index) const; - // If outout is optional and is not present, the method returns en empty UnownedValue + // If output is optional and is not present, the method returns an empty UnownedValue // which can be compared to nullptr. UnownedValue GetOutput(size_t index, const int64_t* dim_values, size_t dim_count) const; UnownedValue GetOutput(size_t index, const std::vector& dims) const; @@ -2183,6 +2207,8 @@ using ConstKernelInfo = detail::KernelInfoImpl struct KernelInfo : detail::KernelInfoImpl { + using Base = detail::KernelInfoImpl; + using Base::Base; explicit KernelInfo(std::nullptr_t) {} ///< Create an empty instance to initialize later explicit KernelInfo(OrtKernelInfo* info); ///< Take ownership of the instance ConstKernelInfo GetConst() const { return ConstKernelInfo{this->p_}; } @@ -2192,6 +2218,9 @@ struct KernelInfo : detail::KernelInfoImpl { /// Create and own custom defined operation. /// struct Op : detail::Base { + using Base = detail::Base; + using Base::Base; + explicit Op(std::nullptr_t) {} ///< Create an empty Operator object, must be assigned a valid one to be used explicit Op(OrtOp*); ///< Take ownership of the OrtOp diff --git a/libs/onnxruntime/include/onnxruntime_cxx_inline.h b/libs/onnxruntime/include/onnxruntime_cxx_inline.h index f1f4904..b2b2e5c 100644 --- a/libs/onnxruntime/include/onnxruntime_cxx_inline.h +++ b/libs/onnxruntime/include/onnxruntime_cxx_inline.h @@ -51,7 +51,7 @@ inline void ThrowOnError(const Status& st) { } } -inline Status::Status(OrtStatus* status) noexcept : Base{status} { +inline Status::Status(OrtStatus* status) noexcept : detail::Base{status} { } inline Status::Status(const std::exception& e) noexcept { @@ -1908,7 +1908,7 @@ inline void attr_utils::GetAttrs(const OrtKernelInfo* p, const char* name, std:: inline KernelInfo::KernelInfo(OrtKernelInfo* info) : detail::KernelInfoImpl{info} {} -inline Op::Op(OrtOp* p) : Base(p) {} +inline Op::Op(OrtOp* p) : detail::Base(p) {} inline Op Op::Create(const OrtKernelInfo* info, const char* op_name, const char* domain, int version, const char** type_constraint_names, diff --git a/libs/onnxruntime/include/onnxruntime_session_options_config_keys.h b/libs/onnxruntime/include/onnxruntime_session_options_config_keys.h index a9216c3..ddfb665 100644 --- a/libs/onnxruntime/include/onnxruntime_session_options_config_keys.h +++ b/libs/onnxruntime/include/onnxruntime_session_options_config_keys.h @@ -250,6 +250,51 @@ static const char* const kOrtSessionOptionsOptimizedModelExternalInitializersFil static const char* const kOrtSessionOptionsOptimizedModelExternalInitializersMinSizeInBytes = "session.optimized_model_external_initializers_min_size_in_bytes"; +// When loading model from memory buffer and the model has external initializers +// Use this config to set the external data file folder path +// All external data files should be in the same folder +static const char* const kOrtSessionOptionsModelExternalInitializersFileFolderPath = + "session.model_external_initializers_file_folder_path"; + +// Use this config when saving pre-packed constant initializers to an external data file. +// This allows you to memory map pre-packed initializers on model load and leave it to +// to the OS the amount of memory consumed by the pre-packed initializers. Otherwise, +// pre-packed data resides on the heap. +// +// - "0": Default is not save pre-packed initializers to a data file. +// - "1": Save pre-packed constant initializers to an external data file. +// Sample usage: sess_options.add_session_config_entry(kOrtSessionOptionsSavePrePackedConstantInitializers, "1") +static const char* const kOrtSessionOptionsSavePrePackedConstantInitializers = + "session.save_external_prepacked_constant_initializers"; + +// Use this config when you want to collect memory stats for each node in the graph. +// The file format is a CSV file with the following columns: +// The file will be created if it does not exist, and will be overwritten if it does. +// +// The content of the file can be used to estimate memory requirements at run time including +// the temporary allocations. This operation is preferably done on a CPU device, as the model may exceed +// device memory limits in constrained environments. When enabling this option, it is important to disable +// memory patterns, as they tend to allocate large blocks to avoid fragmentation and accommodate needs of multiple +// kernels. Memory patterns may make it difficult to allocate on a device with limited memory. +// +// The collected stats then can be used to partition the graph among the devices in a way that only the +// required memory is allocated on each device. +// +// node_name, initializers_memory, dynamic_outputs_sizes, temp_allocations_size +// +// - "full path to file": there is not a default for this option. If the file can not be opened for writing, an error will be returned. +static const char* const kOrtSessionOptionsCollectNodeMemoryStatsToFile = "session.collect_node_memory_stats_to_file"; + +/// This is a composite CSV setting formatted as "memory limit in kb,file name for collected stats" +/// "limit > 0": enables Capacity Aware Partitioning for Cuda EP. `limit` is optional and when absent +/// the provider may attempt to figure out the memory available automatically. +/// The setting with no limit is expected to look like: ",file name for collected stats" +/// The EP will place nodes on device "file name" : +/// this file is expected to be found at the same folder with the model. The file contains +/// pre-recorded stats collected when running with kOrtSessionOptionsCollectNodeMemoryStatsToFile enforce (see above) +static const char* const kOrtSessionOptionsResourceCudaPartitioningSettings = + "session.resource_cuda_partitioning_settings"; + // Enable EP context feature to dump the partitioned graph which includes the EP context into Onnx file. // The dumped Onnx model with EP context can be used for future inference to avoid the EP graph partitioning/compile overhead. // "0": disable. (default) @@ -258,11 +303,12 @@ static const char* const kOrtSessionOptionEpContextEnable = "ep.context_enable"; // Specify the file path for the Onnx model which has EP context. // Default to original_file_name_ctx.onnx if not specified +// Folder is not a valid option static const char* const kOrtSessionOptionEpContextFilePath = "ep.context_file_path"; // Flag to specify whether to dump the EP context into the Onnx model. -// "0": dump the EP context into separate file, keep the file name in the Onnx model. -// "1": dump the EP context into the Onnx model. (default). +// "0": dump the EP context into separate file, keep the file name in the Onnx model. (default). +// "1": dump the EP context into the Onnx model. static const char* const kOrtSessionOptionEpContextEmbedMode = "ep.context_embed_mode"; // Specify the EPContext node name prefix to make it unique @@ -272,6 +318,11 @@ static const char* const kOrtSessionOptionEpContextNodeNamePrefix = "ep.context_ // Share EP related resources across EPs static const char* const kOrtSessionOptionShareEpContexts = "ep.share_ep_contexts"; +// Use this config when dumping EP context model with an external initializers file +// All initializers will be inside the external data file if specified, otherwise all in Onnx file +static const char* const kOrtSessionOptionsEpContextModelExternalInitializersFileName = + "ep.context_model_external_initializers_file_name"; + // Gemm fastmath mode provides fp32 gemm acceleration with bfloat16 based matmul. // Option values: // - "0": Gemm FastMath mode is not enabled. [DEFAULT] diff --git a/libs/onnxruntime/lib/msys2/onnxruntime.dll b/libs/onnxruntime/lib/msys2/onnxruntime.dll new file mode 100644 index 0000000..c16e5a8 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime.dll differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime.lib b/libs/onnxruntime/lib/msys2/onnxruntime.lib new file mode 100644 index 0000000..4d5ab03 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime.lib differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.dll b/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.dll new file mode 100644 index 0000000..3884d9d Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.dll differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.lib b/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.lib new file mode 100644 index 0000000..677d421 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_cuda.lib differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.dll b/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.dll new file mode 100644 index 0000000..7bf7a74 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.dll differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.lib b/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.lib new file mode 100644 index 0000000..d9d9316 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_shared.lib differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.dll b/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.dll new file mode 100644 index 0000000..45ef213 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.dll differ diff --git a/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.lib b/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.lib new file mode 100644 index 0000000..9c30282 Binary files /dev/null and b/libs/onnxruntime/lib/msys2/onnxruntime_providers_tensorrt.lib differ diff --git a/src/ofxOnnxRuntime.cpp b/src/ofxOnnxRuntime.cpp index c8d7c6f..b91b0e2 100644 --- a/src/ofxOnnxRuntime.cpp +++ b/src/ofxOnnxRuntime.cpp @@ -41,11 +41,11 @@ namespace ofxOnnxRuntime void BaseHandler::setup2(const std::string & onnx_path, const Ort::SessionOptions & session_options) { std::string path = ofToDataPath(onnx_path, true); -#ifdef _MSC_VER - ort_session = std::make_shared(ort_env, to_wstring(path).c_str(), session_options); -#else - ort_session = std::make_shared(ort_env, path.c_str(), session_options); -#endif + + std::wstring wpath(path.begin(), path.end()); // basic conversion + + ort_session = std::make_shared(ort_env, wpath.c_str(), session_options); + Ort::AllocatorWithDefaultOptions allocator; @@ -132,7 +132,7 @@ namespace ofxOnnxRuntime } // Prints the shape of the given tensor (ex. input: (1, 1, 512, 512)) - std::string BaseHandler::PrintShape(const std::vector& v) { + std::string BaseHandler::PrintShape(const std::vector& v) { std::stringstream ss; for (std::size_t i = 0; i < v.size() - 1; i++) ss << v[i] << "x"; ss << v[v.size() - 1]; @@ -169,13 +169,13 @@ namespace ofxOnnxRuntime return VectorToTensor(batch_values, batched_dims); } - int BaseHandler::CalculateProduct(const std::vector& v) { + int BaseHandler::CalculateProduct(const std::vector& v) { int total = 1; for (auto& i : v) total *= i; return total; } - Ort::Value BaseHandler::VectorToTensor(std::vector& data, const std::vector& shape) { + Ort::Value BaseHandler::VectorToTensor(std::vector& data, const std::vector& shape) { //// Allocate memory using CPU memory allocator //Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); diff --git a/src/ofxOnnxRuntime.h b/src/ofxOnnxRuntime.h index 4340565..ec54088 100644 --- a/src/ofxOnnxRuntime.h +++ b/src/ofxOnnxRuntime.h @@ -32,10 +32,10 @@ namespace ofxOnnxRuntime std::vector& run(); // Utilities - std::string PrintShape(const std::vector& v); + std::string PrintShape(const std::vector& v); Ort::Value GenerateTensor(int batch_size); - int CalculateProduct(const std::vector& v); - Ort::Value VectorToTensor(std::vector& data, const std::vector& shape); + int CalculateProduct(const std::vector& v); + Ort::Value VectorToTensor(std::vector& data, const std::vector& shape); protected: Ort::Env ort_env;