From 6dd0079d133da09c286cb097b791f04ef387f5b2 Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Wed, 31 Jan 2024 12:25:34 +1000 Subject: [PATCH] Exclude more code from custom_ops.cc when not required in minimal build (#19142) ### Description - Split out the code that implements the OrtKernelContext API (used by compiled nodes and custom ops) and the code that implements the custom ops API. - Exclude based on minimal build settings using helpers - the main change is to simply wrap the implementation into a lambda so it can be easily enabled/disabled - actual implementation of all functions are unchanged - Re-organize so the related implementations are together - most diffs are from this, but without the reorg it would be much harder to know which helper to use - General cleanup of lines that were too long. ### Motivation and Context Saves ~10KB in a minimal build. Build command used for comparison ``` ./build --android --android_api=29 --android_sdk="d:\Android" --android_abi=arm64-v8a --parallel --android_ndk_path="D:\Android\ndk\26.0.10792818\" --build_shared_lib --cmake_generator Ninja --skip_tests --minimal_build --disable_rtti --disable_ml_ops --disable_exceptions --cmake_extra_defines=onnxruntime_BUILD_UNIT_TESTS=OFF --include_ops_by_config .\no_ops.config --config MinSizeRel ``` Main: 1,218,480 bytes With changes: 1,208,320 bytes --- onnxruntime/core/session/custom_ops.cc | 1010 +++++++++++++----------- 1 file changed, 534 insertions(+), 476 deletions(-) diff --git a/onnxruntime/core/session/custom_ops.cc b/onnxruntime/core/session/custom_ops.cc index 4bae42f4b8..7a233c57cf 100644 --- a/onnxruntime/core/session/custom_ops.cc +++ b/onnxruntime/core/session/custom_ops.cc @@ -26,8 +26,15 @@ #include "core/session/ort_apis.h" #include "core/platform/threadpool.h" +// NOTE: OrtKernelContext is used by both custom ops and compiled kernels. +// In a minimal build, ORT_EXTENDED_MINIMAL_BUILD is used to enable EPs like CoreML/NNAPI which use compiled kernels, +// and ORT_MINIMAL_BUILD_CUSTOM_OPS is used to allow external custom op libraries to be used. +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) +#define ENABLE_ORT_KERNEL_CONTEXT_API 1 +#endif + #if !defined(ORT_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) -#define ENABLE_CUSTOM_OP_API +#define ENABLE_CUSTOM_OP_API 1 #endif #if !defined(ORT_MINIMAL_BUILD) @@ -36,7 +43,7 @@ static constexpr uint32_t min_ort_version_with_variadic_io_support = 14; static constexpr uint32_t min_ort_version_with_custom_version = 17; #endif -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) +#if ENABLE_CUSTOM_OP_API static constexpr uint32_t min_ort_version_with_compute_v2_support = 16; static constexpr uint32_t min_ort_version_with_shape_inference = 17; #endif @@ -52,7 +59,8 @@ struct OrtShapeInferContext { size_t GetInputCount() const { return 0; } OrtTensorTypeAndShapeInfo* GetInputTypeShape(size_t) const { return {}; } onnxruntime::Status SetOutputTypeShape(size_t, const OrtTensorTypeAndShapeInfo*) const { - return ORT_MAKE_STATUS(ONNXRUNTIME, NOT_IMPLEMENTED, "OrtShapeInferContext::SetOutputTypeShape not implemented for minimal build"); + return ORT_MAKE_STATUS(ONNXRUNTIME, NOT_IMPLEMENTED, + "OrtShapeInferContext::SetOutputTypeShape not implemented for minimal build"); } const ONNX_NAMESPACE::AttributeProto* GetAttr(const char*) const { return {}; } }; @@ -63,13 +71,15 @@ struct OrtShapeInferContext { for (size_t ith_input = 0; ith_input < num_inputs; ++ith_input) { const auto* input_type = ctx_.getInputType(ith_input); const auto& value_case = input_type->value_case(); - ORT_ENFORCE(value_case == ONNX_NAMESPACE::TypeProto::kTensorType, "shape inference not yet supported for non-tensor types"); + ORT_ENFORCE(value_case == ONNX_NAMESPACE::TypeProto::kTensorType, + "shape inference not yet supported for non-tensor types"); const auto& shape_proto = input_type->tensor_type().shape(); const auto& type_proto = input_type->tensor_type(); auto elem_type = ::onnxruntime::utils::CApiElementTypeFromProtoType(type_proto.elem_type()); auto tensor_shape = ::onnxruntime::utils::GetTensorShapeFromTensorShapeProto(shape_proto); auto symbolic_dims = GetSymbolicDims(shape_proto); - input_type_shapes_.emplace_back(OrtTensorTypeAndShapeInfo::GetTensorShapeAndTypeHelper(elem_type, tensor_shape, &symbolic_dims).release()); + input_type_shapes_.emplace_back( + OrtTensorTypeAndShapeInfo::GetTensorShapeAndTypeHelper(elem_type, tensor_shape, &symbolic_dims).release()); } } @@ -121,305 +131,393 @@ struct OrtShapeInferContext { }; #endif -ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetInputCount, _In_ const OrtShapeInferContext* context, _Out_ size_t* out) { +#if ENABLE_ORT_KERNEL_CONTEXT_API +template +static OrtStatusPtr ExecuteIfKernelContextApiEnabled(const T& fn) { API_IMPL_BEGIN - *out = context->GetInputCount(); - return nullptr; + return fn(); API_IMPL_END } - -ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetInputTypeShape, _In_ const OrtShapeInferContext* context, _In_ size_t index, _Outptr_ OrtTensorTypeAndShapeInfo** info) { - API_IMPL_BEGIN - *info = context->GetInputTypeShape(index); - if (*info) { - return nullptr; - } else { - return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Failed to fetch type shape info for the index."); - } - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetAttribute, _In_ const OrtShapeInferContext* context, _In_ const char* attr_name, _Outptr_ const OrtOpAttr** attr) { - API_IMPL_BEGIN - *attr = reinterpret_cast(context->GetAttr(attr_name)); - if (*attr) { - return nullptr; - } else { - return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute does not exist."); - } - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::ReadOpAttr, - _In_ const OrtOpAttr* op_attr, - _In_ OrtOpAttrType type, - _Inout_ void* data, - _In_ size_t len, - _Out_ size_t* out) { - API_IMPL_BEGIN - - if (!op_attr) { - return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Invalid attribute."); - } - - auto attr = reinterpret_cast(op_attr); - OrtStatusPtr ret = nullptr; - *out = 0; - - if (type == OrtOpAttrType::ORT_OP_ATTR_FLOAT) { - if (len < sizeof(float)) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold a float."); - } else { - if (attr->has_f()) { - auto output_f = reinterpret_cast(data); - *output_f = attr->f(); - } else { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute has no float value."); - } - } - *out = sizeof(float); - - } else if (type == OrtOpAttrType::ORT_OP_ATTR_FLOATS) { - const auto& floats = attr->floats(); - auto num_floats = floats.size(); - - if (len < sizeof(float) * num_floats) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold the array of floats."); - } else { - auto output_f = reinterpret_cast(data); - for (auto f : floats) { - *output_f = f; - output_f++; - } - } - *out = num_floats * sizeof(float); - - } else if (type == OrtOpAttrType::ORT_OP_ATTR_INT) { - if (len < sizeof(int)) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold an int64."); - } else { - if (attr->has_i()) { - auto output_i = reinterpret_cast(data); - *output_i = attr->i(); - } else { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute has no int64 value."); - } - } - *out = sizeof(int64_t); - - } else if (type == OrtOpAttrType::ORT_OP_ATTR_INTS) { - const auto& ints = attr->ints(); - auto num_ints = ints.size(); - - if (len < sizeof(int64_t) * num_ints) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold the array of int64."); - } else { - auto output_i = reinterpret_cast(data); - for (auto i : ints) { - *output_i = i; - output_i++; - } - } - *out = num_ints * sizeof(int64_t); - - } else if (type == OrtOpAttrType::ORT_OP_ATTR_STRING) { - const auto& s = attr->s(); - if (len < s.size() + 1) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold the string."); - } else { - char* output_c = reinterpret_cast(data); - for (char c : s) { - *output_c++ = c; - } - *output_c = '\0'; - } - *out = s.size() + 1; - - } else if (type == OrtOpAttrType::ORT_OP_ATTR_STRINGS) { - const auto& ss = attr->strings(); - size_t num_bytes = 0; - for_each(ss.begin(), ss.end(), [&num_bytes](const std::string& s) { num_bytes += s.size() + 1; }); - - if (len < num_bytes) { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Size of data not large enough to hold the array of strings."); - } else { - char* output_c = reinterpret_cast(data); - for (const auto& s : ss) { - for (char c : s) { - *output_c++ = c; - } - *output_c++ = '\0'; - } - } - *out = num_bytes; - - } else { - ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Unknown attribute type."); - } - - return ret; - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_SetOutputTypeShape, _In_ const OrtShapeInferContext* context, _In_ size_t index, _In_ const OrtTensorTypeAndShapeInfo* info) { - API_IMPL_BEGIN - auto status = context->SetOutputTypeShape(index, info); - if (status.IsOK()) { - return nullptr; - } else { - return OrtApis::CreateStatus(static_cast(status.Code()), status.ErrorMessage().c_str()); - } - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_float, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ float* out) { - API_IMPL_BEGIN - auto status = reinterpret_cast(info)->GetAttr(name, out); - if (status.IsOK()) - return nullptr; - return onnxruntime::ToOrtStatus(status); - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_int64, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ int64_t* out) { - API_IMPL_BEGIN - auto status = reinterpret_cast(info)->GetAttr(name, out); - if (status.IsOK()) - return nullptr; - return onnxruntime::ToOrtStatus(status); - API_IMPL_END +#else +template +static OrtStatusPtr ExecuteIfKernelContextApiEnabled(const T&) { + return OrtApis::CreateStatus(ORT_NOT_IMPLEMENTED, "OrtKernelContext API is not enabled in this build"); } +#endif ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetInputCount, _In_ const OrtKernelContext* context, _Out_ size_t* out) { - API_IMPL_BEGIN - *out = reinterpret_cast(context)->InputCount(); - return nullptr; - API_IMPL_END + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + *out = reinterpret_cast(context)->InputCount(); + return nullptr; + }); }; ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetOutputCount, _In_ const OrtKernelContext* context, _Out_ size_t* out) { - API_IMPL_BEGIN - *out = reinterpret_cast(context)->OutputCount(); - return nullptr; - API_IMPL_END + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + *out = reinterpret_cast(context)->OutputCount(); + return nullptr; + }); }; -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetInput, _In_ const OrtKernelContext* context, _In_ size_t index, _Out_ const OrtValue** out) { - API_IMPL_BEGIN - *out = reinterpret_cast(reinterpret_cast(context)->GetInputMLValue(gsl::narrow_cast(index))); - return nullptr; - API_IMPL_END +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetInput, _In_ const OrtKernelContext* context, _In_ size_t index, + _Out_ const OrtValue** out) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + const auto* ctx = reinterpret_cast(context); + *out = reinterpret_cast(ctx->GetInputMLValue(onnxruntime::narrow(index))); + return nullptr; + }); }; -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetOutput, _Inout_ OrtKernelContext* context, _In_ size_t index, _In_ const int64_t* dim_values, size_t dim_count, _Out_ OrtValue** out) { - API_IMPL_BEGIN - onnxruntime::TensorShape shape(dim_values, dim_count); - *out = reinterpret_cast(reinterpret_cast(context)->OutputMLValue(gsl::narrow_cast(index), shape)); - return nullptr; - API_IMPL_END +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetOutput, _Inout_ OrtKernelContext* context, _In_ size_t index, + _In_ const int64_t* dim_values, size_t dim_count, _Out_ OrtValue** out) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + onnxruntime::TensorShape shape(dim_values, dim_count); + auto* ctx = reinterpret_cast(context); + *out = reinterpret_cast(ctx->OutputMLValue(onnxruntime::narrow(index), shape)); + return nullptr; + }); }; -ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_string, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ char* out, _Inout_ size_t* size) { - API_IMPL_BEGIN - std::string value; - auto status = reinterpret_cast(info)->GetAttr(name, &value); - if (status.IsOK()) { - if (out == nullptr) { // User is querying the true size of the attribute - *size = value.size() + 1; - return nullptr; - } else if (*size >= value.size() + 1) { - std::memcpy(out, value.data(), value.size()); - out[value.size()] = '\0'; - *size = value.size() + 1; - return nullptr; - } else { // User has provided a buffer that is not large enough - *size = value.size() + 1; - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Result buffer is not large enough"); +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetGPUComputeStream, _In_ const OrtKernelContext* context, + _Outptr_ void** out) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + auto* stream = reinterpret_cast(context)->GetComputeStream(); + if (stream) + *out = stream->GetHandle(); + else + *out = nullptr; + return nullptr; + }); +}; + +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetAllocator, _In_ const OrtKernelContext* context, + _In_ const OrtMemoryInfo* mem_info, _Outptr_ OrtAllocator** out) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + const auto* ctx = reinterpret_cast(context); + onnxruntime::AllocatorPtr allocator = ctx->GetAllocator(mem_info->device); + if (!allocator) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "No requested allocator available"); } - } - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + + auto p = std::make_unique(std::move(allocator)); + *out = p.release(); + return nullptr; + }); +}; + +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetResource, _In_ const OrtKernelContext* context, + _In_ int resource_version, _In_ int resource_id, _Outptr_ void** resource) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + *resource = {}; + const auto* ctx = reinterpret_cast(context); + auto* stream = reinterpret_cast(ctx->GetComputeStream()); + if (!stream) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Failed to fetch a stream hosting the requested resource"); + } + *resource = stream->GetResource(resource_version, resource_id); + return nullptr; + }); +}; + +ORT_API_STATUS_IMPL(OrtApis::KernelContext_ParallelFor, _In_ const OrtKernelContext* context, + _In_ void (*fn)(void*, size_t), _In_ size_t total, _In_ size_t num_batch, _In_ void* usr_data) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + if (!context) { + return OrtApis::CreateStatus(ORT_RUNTIME_EXCEPTION, "Invalid context"); + } + if (fn && total) { + const auto* ctx = reinterpret_cast(context); + auto* tp = ctx->GetOperatorThreadPool(); + if (num_batch) { + onnxruntime::concurrency::ThreadPool::TryBatchParallelFor( + tp, + static_cast(total), + [fn, usr_data](std::ptrdiff_t ith) { fn(usr_data, static_cast(ith)); }, + static_cast(num_batch)); + } else { + onnxruntime::concurrency::ThreadPool::TrySimpleParallelFor( + tp, + static_cast(total), + [fn, usr_data](std::ptrdiff_t ith) { fn(usr_data, static_cast(ith)); }); + } + } + return nullptr; + }); +}; + +ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetLogger, _In_ const OrtKernelContext* context, + _Outptr_ const OrtLogger** logger) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + const auto& kernel_ctx_logger = reinterpret_cast(context)->Logger(); + + *logger = reinterpret_cast(&kernel_ctx_logger); + return nullptr; + }); } +// Enabled via ExecuteIfKernelContextApiEnabled due to KernelContext_GetLogger +ORT_API_STATUS_IMPL(OrtApis::Logger_LogMessage, _In_ const OrtLogger* logger, OrtLoggingLevel log_severity_level, + _In_z_ const char* message, _In_z_ const ORTCHAR_T* file_path, int line_number, + _In_z_ const char* func_name) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + const auto& actual_logger = *reinterpret_cast(logger); + const auto severity = static_cast(log_severity_level); + const auto log_data_type = onnxruntime::logging::DataType::SYSTEM; + + if (actual_logger.OutputIsEnabled(severity, log_data_type)) { #ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 28196 6387) -#endif - -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetGPUComputeStream, _In_ const OrtKernelContext* context, _Outptr_ void** out) { - API_IMPL_BEGIN - auto* stream = reinterpret_cast(context)->GetComputeStream(); - if (stream) - *out = stream->GetHandle(); - else - *out = nullptr; - return nullptr; - API_IMPL_END -}; - -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetAllocator, _In_ const OrtKernelContext* context, _In_ const OrtMemoryInfo* mem_info, _Outptr_ OrtAllocator** out) { - API_IMPL_BEGIN - onnxruntime::AllocatorPtr allocator = reinterpret_cast(context)->GetAllocator(mem_info->device); - if (!allocator) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "No requested allocator available"); - } - std::unique_ptr p = std::make_unique(std::move(allocator)); - *out = p.release(); - return nullptr; - API_IMPL_END -}; - -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetResource, _In_ const OrtKernelContext* context, _In_ int resource_version, _In_ int resource_id, _Outptr_ void** resource) { - API_IMPL_BEGIN - *resource = {}; - const auto* ctx = reinterpret_cast(context); - auto* stream = reinterpret_cast(ctx->GetComputeStream()); - if (!stream) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Failed to fetch a stream hosting the requested resource"); - } - *resource = stream->GetResource(resource_version, resource_id); - return nullptr; - API_IMPL_END -}; - -ORT_API_STATUS_IMPL(OrtApis::KernelContext_ParallelFor, _In_ const OrtKernelContext* context, _In_ void (*fn)(void*, size_t), _In_ size_t total, _In_ size_t num_batch, _In_ void* usr_data) { -#ifdef ENABLE_CUSTOM_OP_API - API_IMPL_BEGIN - if (!context) { - return OrtApis::CreateStatus(ORT_RUNTIME_EXCEPTION, "Invalid context"); - } - if (fn && total) { - const auto* ctx = reinterpret_cast(context); - auto* tp = ctx->GetOperatorThreadPool(); - if (num_batch) { - onnxruntime::concurrency::ThreadPool::TryBatchParallelFor( - tp, - static_cast(total), - [fn, usr_data](std::ptrdiff_t ith) { fn(usr_data, static_cast(ith)); }, - static_cast(num_batch)); - } else { - onnxruntime::concurrency::ThreadPool::TrySimpleParallelFor( - tp, - static_cast(total), - [fn, usr_data](std::ptrdiff_t ith) { fn(usr_data, static_cast(ith)); }); - } - } - return nullptr; - API_IMPL_END + const std::string file_path_str = onnxruntime::ToUTF8String(file_path); + onnxruntime::CodeLocation location(file_path_str.c_str(), line_number, func_name); #else - ORT_UNUSED_PARAMETER(context); - ORT_UNUSED_PARAMETER(fn); - ORT_UNUSED_PARAMETER(total); - ORT_UNUSED_PARAMETER(num_batch); - ORT_UNUSED_PARAMETER(usr_data); - return OrtApis::CreateStatus(ORT_NOT_IMPLEMENTED, "ParallelFor API not implemented for this build"); + onnxruntime::CodeLocation location(file_path, line_number, func_name); #endif -}; -#ifdef _WIN32 -#pragma warning(pop) + onnxruntime::logging::Capture( + actual_logger, + severity, + onnxruntime::logging::Category::onnxruntime, + log_data_type, + location) + .Stream() + << message; + } + + return nullptr; + }); +} + +// Enabled via ExecuteIfKernelContextApiEnabled due to KernelContext_GetLogger +ORT_API_STATUS_IMPL(OrtApis::Logger_GetLoggingSeverityLevel, _In_ const OrtLogger* logger, + _Out_ OrtLoggingLevel* out) { + return ExecuteIfKernelContextApiEnabled([&]() -> OrtStatusPtr { + const auto& actual_logger = *reinterpret_cast(logger); + *out = static_cast(actual_logger.GetSeverity()); + return nullptr; + }); +} + +#if ENABLE_CUSTOM_OP_API +template +static OrtStatusPtr ExecuteIfCustomOpsApiEnabled(const T& fn) { + API_IMPL_BEGIN + return fn(); + API_IMPL_END +} +#else +template +static OrtStatusPtr ExecuteIfCustomOpsApiEnabled(const T&) { + return OrtApis::CreateStatus(ORT_NOT_IMPLEMENTED, "Custom operator API is not enabled in this build"); +} #endif +ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetInputCount, _In_ const OrtShapeInferContext* context, + _Out_ size_t* out) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + *out = context->GetInputCount(); + return nullptr; + }); +} + +ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetInputTypeShape, _In_ const OrtShapeInferContext* context, + _In_ size_t index, _Outptr_ OrtTensorTypeAndShapeInfo** info) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + *info = context->GetInputTypeShape(index); + if (*info) { + return nullptr; + } else { + return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Failed to fetch type shape info for the index."); + } + }); +} + +ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_GetAttribute, _In_ const OrtShapeInferContext* context, + _In_ const char* attr_name, _Outptr_ const OrtOpAttr** attr) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + *attr = reinterpret_cast(context->GetAttr(attr_name)); + if (*attr) { + return nullptr; + } else { + return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute does not exist."); + } + }); +} + +ORT_API_STATUS_IMPL(OrtApis::ShapeInferContext_SetOutputTypeShape, _In_ const OrtShapeInferContext* context, + _In_ size_t index, _In_ const OrtTensorTypeAndShapeInfo* info) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + auto status = context->SetOutputTypeShape(index, info); + if (status.IsOK()) { + return nullptr; + } else { + return OrtApis::CreateStatus(static_cast(status.Code()), status.ErrorMessage().c_str()); + } + }); +} + +ORT_API_STATUS_IMPL(OrtApis::ReadOpAttr, _In_ const OrtOpAttr* op_attr, _In_ OrtOpAttrType type, _Inout_ void* data, + _In_ size_t len, _Out_ size_t* out) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + if (!op_attr) { + return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Invalid attribute."); + } + + auto attr = reinterpret_cast(op_attr); + OrtStatusPtr ret = nullptr; + *out = 0; + + switch (type) { + case OrtOpAttrType::ORT_OP_ATTR_FLOAT: { + if (len < sizeof(float)) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold a float."); + } else { + if (attr->has_f()) { + auto output_f = reinterpret_cast(data); + *output_f = attr->f(); + } else { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute has no float value."); + } + } + *out = sizeof(float); + + break; + } + case OrtOpAttrType::ORT_OP_ATTR_FLOATS: { + const auto& floats = attr->floats(); + auto num_floats = floats.size(); + + if (len < sizeof(float) * num_floats) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold the array of floats."); + } else { + auto output_f = reinterpret_cast(data); + for (auto f : floats) { + *output_f = f; + output_f++; + } + } + *out = num_floats * sizeof(float); + break; + } + case OrtOpAttrType::ORT_OP_ATTR_INT: { + if (len < sizeof(int)) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold an int64."); + } else { + if (attr->has_i()) { + auto output_i = reinterpret_cast(data); + *output_i = attr->i(); + } else { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Attribute has no int64 value."); + } + } + *out = sizeof(int64_t); + break; + } + case OrtOpAttrType::ORT_OP_ATTR_INTS: { + const auto& ints = attr->ints(); + auto num_ints = ints.size(); + + if (len < sizeof(int64_t) * num_ints) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold the array of int64."); + } else { + auto output_i = reinterpret_cast(data); + for (auto i : ints) { + *output_i = i; + output_i++; + } + } + *out = num_ints * sizeof(int64_t); + break; + } + case OrtOpAttrType::ORT_OP_ATTR_STRING: { + const auto& s = attr->s(); + if (len < s.size() + 1) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold the string."); + } else { + char* output_c = reinterpret_cast(data); + for (char c : s) { + *output_c++ = c; + } + *output_c = '\0'; + } + *out = s.size() + 1; + break; + } + case OrtOpAttrType::ORT_OP_ATTR_STRINGS: { + const auto& ss = attr->strings(); + size_t num_bytes = 0; + for_each(ss.begin(), ss.end(), [&num_bytes](const std::string& s) { num_bytes += s.size() + 1; }); + + if (len < num_bytes) { + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, + "Size of data not large enough to hold the array of strings."); + } else { + char* output_c = reinterpret_cast(data); + for (const auto& s : ss) { + for (char c : s) { + *output_c++ = c; + } + *output_c++ = '\0'; + } + } + *out = num_bytes; + break; + } + default: + ret = OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Unexpected attribute type. "); + } + + return ret; + }); +} + +ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_float, _In_ const OrtKernelInfo* info, _In_ const char* name, + _Out_ float* out) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + auto status = reinterpret_cast(info)->GetAttr(name, out); + if (status.IsOK()) + return nullptr; + return onnxruntime::ToOrtStatus(status); + }); +} + +ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_int64, _In_ const OrtKernelInfo* info, _In_ const char* name, + _Out_ int64_t* out) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + auto status = reinterpret_cast(info)->GetAttr(name, out); + if (status.IsOK()) + return nullptr; + return onnxruntime::ToOrtStatus(status); + }); +} + +ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_string, _In_ const OrtKernelInfo* info, _In_ const char* name, + _Out_ char* out, _Inout_ size_t* size) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + std::string value; + auto status = reinterpret_cast(info)->GetAttr(name, &value); + if (status.IsOK()) { + if (out == nullptr) { // User is querying the true size of the attribute + *size = value.size() + 1; + return nullptr; + } else if (*size >= value.size() + 1) { + std::memcpy(out, value.data(), value.size()); + out[value.size()] = '\0'; + *size = value.size() + 1; + return nullptr; + } else { // User has provided a buffer that is not large enough + *size = value.size() + 1; + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "Result buffer is not large enough"); + } + } + return onnxruntime::ToOrtStatus(status); + }); +} + template ::value, int>::type = 0> static Status CopyDataFromVectorToMemory(const std::vector& values, T* out, size_t* size) { if (out == nullptr) { // User is querying the true size of the attribute @@ -438,256 +536,209 @@ static Status CopyDataFromVectorToMemory(const std::vector& values, T* out, s ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttributeArray_float, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ float* out, _Inout_ size_t* size) { - API_IMPL_BEGIN - std::vector values; - auto status = reinterpret_cast(info)->GetAttrs(name, values); - if (status.IsOK()) { - status = CopyDataFromVectorToMemory(values, out, size); - } - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + std::vector values; + auto status = reinterpret_cast(info)->GetAttrs(name, values); + if (status.IsOK()) { + status = CopyDataFromVectorToMemory(values, out, size); + } + return onnxruntime::ToOrtStatus(status); + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttributeArray_int64, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ int64_t* out, _Inout_ size_t* size) { - API_IMPL_BEGIN - std::vector values; - auto status = reinterpret_cast(info)->GetAttrs(name, values); - if (status.IsOK()) { - status = CopyDataFromVectorToMemory(values, out, size); - } - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + std::vector values; + auto status = reinterpret_cast(info)->GetAttrs(name, values); + if (status.IsOK()) { + status = CopyDataFromVectorToMemory(values, out, size); + } + return onnxruntime::ToOrtStatus(status); + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetAttribute_tensor, _In_ const OrtKernelInfo* info, _In_z_ const char* name, _Inout_ OrtAllocator* allocator, _Outptr_ OrtValue** out) { - API_IMPL_BEGIN - const auto* op_kinfo = reinterpret_cast(info); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_kinfo = reinterpret_cast(info); - // Get TensorProto attribute - onnx::TensorProto tensor_proto; - auto status = op_kinfo->GetAttr(name, &tensor_proto); - if (!status.IsOK()) { - return onnxruntime::ToOrtStatus(status); - } + // Get TensorProto attribute + onnx::TensorProto tensor_proto; + auto status = op_kinfo->GetAttr(name, &tensor_proto); + if (!status.IsOK()) { + return onnxruntime::ToOrtStatus(status); + } - // Determine the tensor's size in bytes. - size_t req_size = 0; - status = onnxruntime::utils::GetSizeInBytesFromTensorProto<0>(tensor_proto, &req_size); - if (!status.IsOK()) { - return onnxruntime::ToOrtStatus(status); - } + // Determine the tensor's size in bytes. + size_t req_size = 0; + status = onnxruntime::utils::GetSizeInBytesFromTensorProto<0>(tensor_proto, &req_size); + if (!status.IsOK()) { + return onnxruntime::ToOrtStatus(status); + } - // Create Tensor that owns buffer memory that will be allocated with the provided OrtAllocator. - onnxruntime::TensorShape tensor_shape = onnxruntime::utils::GetTensorShapeFromTensorProto(tensor_proto); - const auto* const type = onnxruntime::DataTypeImpl::TensorTypeFromONNXEnum(tensor_proto.data_type())->GetElementType(); - onnxruntime::AllocatorPtr alloc_ptr = std::make_shared(allocator); - auto tensorp = std::make_unique(type, tensor_shape, std::move(alloc_ptr)); + // Create Tensor that owns buffer memory that will be allocated with the provided OrtAllocator. + onnxruntime::TensorShape tensor_shape = onnxruntime::utils::GetTensorShapeFromTensorProto(tensor_proto); + const auto* type = onnxruntime::DataTypeImpl::TensorTypeFromONNXEnum(tensor_proto.data_type())->GetElementType(); + onnxruntime::AllocatorPtr alloc_ptr = std::make_shared(allocator); + auto tensorp = std::make_unique(type, tensor_shape, std::move(alloc_ptr)); - // Deserialize TensorProto into pre-allocated, empty Tensor. - status = onnxruntime::utils::TensorProtoToTensor(onnxruntime::Env::Default(), nullptr, tensor_proto, *tensorp); - if (!status.IsOK()) { - return onnxruntime::ToOrtStatus(status); - } + // Deserialize TensorProto into pre-allocated, empty Tensor. + status = onnxruntime::utils::TensorProtoToTensor(onnxruntime::Env::Default(), nullptr, tensor_proto, *tensorp); + if (!status.IsOK()) { + return onnxruntime::ToOrtStatus(status); + } - // Initialize OrtValue from Tensor. - auto ml_tensor = onnxruntime::DataTypeImpl::GetType(); - auto value = std::make_unique(); - value->Init(tensorp.release(), ml_tensor, ml_tensor->GetDeleteFunc()); + // Initialize OrtValue from Tensor. + auto ml_tensor = onnxruntime::DataTypeImpl::GetType(); + auto value = std::make_unique(); + value->Init(tensorp.release(), ml_tensor, ml_tensor->GetDeleteFunc()); - *out = value.release(); - return nullptr; - API_IMPL_END + *out = value.release(); + return nullptr; + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetInputCount, _In_ const OrtKernelInfo* info, _Out_ size_t* out) { - API_IMPL_BEGIN - *out = reinterpret_cast(info)->GetInputCount(); - return nullptr; - API_IMPL_END + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + *out = reinterpret_cast(info)->GetInputCount(); + return nullptr; + }); }; ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetOutputCount, _In_ const OrtKernelInfo* info, _Out_ size_t* out) { - API_IMPL_BEGIN - *out = reinterpret_cast(info)->GetOutputCount(); - return nullptr; - API_IMPL_END + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + *out = reinterpret_cast(info)->GetOutputCount(); + return nullptr; + }); }; -ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetInputName, _In_ const OrtKernelInfo* info, size_t index, _Out_ char* out, - _Inout_ size_t* size) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); - const auto input_defs = op_info->node().InputDefs(); +ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetInputName, _In_ const OrtKernelInfo* info, size_t index, + _Out_ char* out, _Inout_ size_t* size) { + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); + const auto input_defs = op_info->node().InputDefs(); - if (index >= input_defs.size()) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo input index is out of bounds"); - } + if (index >= input_defs.size()) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo input index is out of bounds"); + } - auto status = CopyStringToOutputArg(input_defs[index]->Name(), - "Output buffer is not large enough for ::OrtKernelInfo input name", out, size); + auto status = CopyStringToOutputArg(input_defs[index]->Name(), + "Output buffer is not large enough for ::OrtKernelInfo input name", out, size); - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + return onnxruntime::ToOrtStatus(status); + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetOutputName, _In_ const OrtKernelInfo* info, size_t index, _Out_ char* out, _Inout_ size_t* size) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); - const auto output_defs = op_info->node().OutputDefs(); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); + const auto output_defs = op_info->node().OutputDefs(); - if (index >= output_defs.size()) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo output index is out of bounds"); - } + if (index >= output_defs.size()) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo output index is out of bounds"); + } - auto status = CopyStringToOutputArg(output_defs[index]->Name(), - "Output buffer is not large enough for ::OrtKernelInfo output name", out, size); + auto status = CopyStringToOutputArg(output_defs[index]->Name(), + "Output buffer is not large enough for ::OrtKernelInfo output name", + out, size); - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + return onnxruntime::ToOrtStatus(status); + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetInputTypeInfo, _In_ const OrtKernelInfo* info, size_t index, _Outptr_ OrtTypeInfo** type_info) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); - const auto input_defs = op_info->node().InputDefs(); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); + const auto input_defs = op_info->node().InputDefs(); - if (index >= input_defs.size()) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo input index is out of bounds"); - } + if (index >= input_defs.size()) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo input index is out of bounds"); + } - const onnxruntime::NodeArg* node_arg = input_defs[index]; - const ONNX_NAMESPACE::TypeProto* type_proto = node_arg->TypeAsProto(); + const onnxruntime::NodeArg* node_arg = input_defs[index]; + const ONNX_NAMESPACE::TypeProto* type_proto = node_arg->TypeAsProto(); - if (type_proto == nullptr) { - return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo input does not have a type"); - } + if (type_proto == nullptr) { + return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo input does not have a type"); + } - auto type_info_ret = OrtTypeInfo::FromTypeProto(*type_proto); - *type_info = type_info_ret.release(); - return nullptr; - API_IMPL_END + auto type_info_ret = OrtTypeInfo::FromTypeProto(*type_proto); + *type_info = type_info_ret.release(); + return nullptr; + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetOutputTypeInfo, _In_ const OrtKernelInfo* info, size_t index, _Outptr_ OrtTypeInfo** type_info) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); - const auto output_defs = op_info->node().OutputDefs(); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); + const auto output_defs = op_info->node().OutputDefs(); - if (index >= output_defs.size()) { - return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo output index is out of bounds"); - } + if (index >= output_defs.size()) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "::OrtKernelInfo output index is out of bounds"); + } - const onnxruntime::NodeArg* node_arg = output_defs[index]; - const ONNX_NAMESPACE::TypeProto* type_proto = node_arg->TypeAsProto(); + const onnxruntime::NodeArg* node_arg = output_defs[index]; + const ONNX_NAMESPACE::TypeProto* type_proto = node_arg->TypeAsProto(); - if (type_proto == nullptr) { - return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo output does not have a type"); - } + if (type_proto == nullptr) { + return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo output does not have a type"); + } - auto type_info_ret = OrtTypeInfo::FromTypeProto(*type_proto); - *type_info = type_info_ret.release(); - return nullptr; - API_IMPL_END + auto type_info_ret = OrtTypeInfo::FromTypeProto(*type_proto); + *type_info = type_info_ret.release(); + return nullptr; + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfoGetConstantInput_tensor, _In_ const OrtKernelInfo* info, _In_ size_t index, _Out_ int* is_constant, _Outptr_ const OrtValue** out) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); - *is_constant = static_cast(op_info->TryGetConstantInput(gsl::narrow_cast(index), out)); - return nullptr; - API_IMPL_END + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); + *is_constant = static_cast(op_info->TryGetConstantInput(gsl::narrow_cast(index), out)); + return nullptr; + }); }; ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetNodeName, _In_ const OrtKernelInfo* info, _Out_ char* out, _Inout_ size_t* size) { - API_IMPL_BEGIN - const auto* op_info = reinterpret_cast(info); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* op_info = reinterpret_cast(info); - auto status = CopyStringToOutputArg(op_info->node().Name(), - "Output buffer is not large enough for ::OrtKernelInfo node name", out, size); + auto status = CopyStringToOutputArg(op_info->node().Name(), + "Output buffer is not large enough for ::OrtKernelInfo node name", out, size); - return onnxruntime::ToOrtStatus(status); - API_IMPL_END + return onnxruntime::ToOrtStatus(status); + }); } ORT_API_STATUS_IMPL(OrtApis::KernelInfo_GetLogger, _In_ const OrtKernelInfo* info, _Outptr_ const OrtLogger** logger) { - API_IMPL_BEGIN - const auto* ep = reinterpret_cast(info)->GetExecutionProvider(); + return ExecuteIfCustomOpsApiEnabled([&]() -> OrtStatusPtr { + const auto* ep = reinterpret_cast(info)->GetExecutionProvider(); - if (ep == nullptr) { - return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo does not have an execution provider"); - } + if (ep == nullptr) { + return OrtApis::CreateStatus(ORT_INVALID_GRAPH, "::OrtKernelInfo does not have an execution provider"); + } - const auto* ep_logger = ep->GetLogger(); + const auto* ep_logger = ep->GetLogger(); - if (ep_logger == nullptr) { - return OrtApis::CreateStatus(ORT_INVALID_GRAPH, - "::OrtKernelInfo cannot get a valid logger from " - "its execution provider"); - } + if (ep_logger == nullptr) { + return OrtApis::CreateStatus(ORT_INVALID_GRAPH, + "::OrtKernelInfo cannot get a valid logger from " + "its execution provider"); + } - *logger = reinterpret_cast(ep_logger); - return nullptr; - API_IMPL_END + *logger = reinterpret_cast(ep_logger); + return nullptr; + }); } -ORT_API_STATUS_IMPL(OrtApis::KernelContext_GetLogger, _In_ const OrtKernelContext* context, _Outptr_ const OrtLogger** logger) { - API_IMPL_BEGIN - const auto& kernel_ctx_logger = reinterpret_cast(context)->Logger(); - - *logger = reinterpret_cast(&kernel_ctx_logger); - return nullptr; - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::Logger_LogMessage, _In_ const OrtLogger* logger, OrtLoggingLevel log_severity_level, - _In_z_ const char* message, _In_z_ const ORTCHAR_T* file_path, int line_number, - _In_z_ const char* func_name) { - API_IMPL_BEGIN - const auto& actual_logger = *reinterpret_cast(logger); - const auto severity = static_cast(log_severity_level); - const auto log_data_type = onnxruntime::logging::DataType::SYSTEM; - - if (actual_logger.OutputIsEnabled(severity, log_data_type)) { -#ifdef _WIN32 - const std::string file_path_str = onnxruntime::ToUTF8String(file_path); - onnxruntime::CodeLocation location(file_path_str.c_str(), line_number, func_name); -#else - onnxruntime::CodeLocation location(file_path, line_number, func_name); -#endif - - onnxruntime::logging::Capture( - actual_logger, - severity, - onnxruntime::logging::Category::onnxruntime, - log_data_type, - location) - .Stream() - << message; - } - - return nullptr; - API_IMPL_END -} - -ORT_API_STATUS_IMPL(OrtApis::Logger_GetLoggingSeverityLevel, _In_ const OrtLogger* logger, _Out_ OrtLoggingLevel* out) { - API_IMPL_BEGIN - const auto& actual_logger = *reinterpret_cast(logger); - *out = static_cast(actual_logger.GetSeverity()); - return nullptr; - API_IMPL_END -} - -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) +#if ENABLE_CUSTOM_OP_API #include "core/framework/customregistry.h" namespace onnxruntime { - struct CustomOpKernel : OpKernel { CustomOpKernel(const OpKernelInfo& info, const OrtCustomOp& op) : OpKernel(info), op_(op) { if (op_.version > ORT_API_VERSION) { @@ -766,7 +817,8 @@ KernelCreateInfo CreateKernelCreateInfo(const std::string& domain, const OrtCust if (input_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED) { def_builder.TypeConstraint(input_name, SUPPORTED_TENSOR_TYPES); } else { - def_builder.TypeConstraint(input_name, DataTypeImpl::TensorTypeFromONNXEnum(static_cast(input_type))->AsTensorType()); + def_builder.TypeConstraint(input_name, + DataTypeImpl::TensorTypeFromONNXEnum(static_cast(input_type))->AsTensorType()); } } @@ -776,7 +828,8 @@ KernelCreateInfo CreateKernelCreateInfo(const std::string& domain, const OrtCust if (output_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED) { def_builder.TypeConstraint(output_name, SUPPORTED_TENSOR_TYPES); } else { - def_builder.TypeConstraint(output_name, DataTypeImpl::TensorTypeFromONNXEnum(static_cast(output_type))->AsTensorType()); + def_builder.TypeConstraint(output_name, + DataTypeImpl::TensorTypeFromONNXEnum(static_cast(output_type))->AsTensorType()); } } @@ -786,7 +839,8 @@ KernelCreateInfo CreateKernelCreateInfo(const std::string& domain, const OrtCust def_builder.Provider(onnxruntime::kCpuExecutionProvider); } - KernelCreateFn kernel_create_fn = [op](FuncManager&, const OpKernelInfo& info, std::unique_ptr& out) -> Status { + KernelCreateFn kernel_create_fn = [op](FuncManager&, const OpKernelInfo& info, + std::unique_ptr& out) -> Status { out = std::make_unique(info, *op); return Status::OK(); }; @@ -891,8 +945,8 @@ ONNX_NAMESPACE::OpSchema CreateSchema(const std::string& domain, const std::vect "There must be one (and only one) dynamic typed input to the custom op. " "Its type info at runtime will be used to infer the type info of this dynamic typed output " "which is required for the success of the model loading step. " - "More than one dynamic typed inputs are currently not supported as differing types at runtime means the output type " - "cannot be inferred without which model loading cannot proceed."); + "More than one dynamic typed inputs are currently not supported as differing types at runtime " + "means the output type cannot be inferred without which model loading cannot proceed."); } } create_type_constraint(op, static_cast(output_count), static_cast(i), false); @@ -1003,7 +1057,8 @@ void InferOutputTypes(const InlinedVector& kernel_defs, if (tc_iter != type_constraints.end()) { if (tc_iter->second.size() > 1) { undef = elem_type; - } else if (tc_iter->second.size() != 1 || tc_iter->second[0] != DataTypeImpl::TensorTypeFromONNXEnum(elem_type)) { + } else if (tc_iter->second.size() != 1 || + tc_iter->second[0] != DataTypeImpl::TensorTypeFromONNXEnum(elem_type)) { matched = false; } } else { @@ -1030,7 +1085,8 @@ void InferOutputTypes(const InlinedVector& kernel_defs, if (tc_iter->second.size() > 1) { output_type->mutable_tensor_type()->set_elem_type(undef); } else { - output_type->mutable_tensor_type()->set_elem_type(tc_iter->second[0]->GetTypeProto()->tensor_type().elem_type()); + output_type->mutable_tensor_type()->set_elem_type( + tc_iter->second[0]->GetTypeProto()->tensor_type().elem_type()); } } break; @@ -1052,7 +1108,8 @@ common::Status CreateCustomRegistry(gsl::span op_domai // If domain is empty, it is assumed to be part of the ONNX domain if (!domain->domain_.empty()) { // Add it to the DomainToVersion ONNX map if it doesn't already exist - // For example, two sessions using the same session_options should not add the same custom op domain to the version map twice + // For example, two sessions using the same session_options should not add the same custom op domain + // to the version map twice auto& domain_to_version_range_instance = ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange::Instance(); const auto& domain_to_version_map = domain_to_version_range_instance.Map(); @@ -1099,12 +1156,13 @@ common::Status CreateCustomRegistry(gsl::span op_domai schemas.push_back(schema_iter.second); InlinedVector kernel_defs = std::move(kernel_def_map[schema_iter.first]); auto infer_fn = schemas.back().GetTypeAndShapeInferenceFunction(); - ONNX_NAMESPACE::InferenceFunction extended_infer_fn = [infer_fn, kernel_defs](ONNX_NAMESPACE::InferenceContext& infer_ctx) { - InferOutputTypes(kernel_defs, infer_ctx); - if (infer_fn) { - infer_fn(infer_ctx); - } - }; + ONNX_NAMESPACE::InferenceFunction extended_infer_fn = + [infer_fn, kernel_defs](ONNX_NAMESPACE::InferenceContext& infer_ctx) { + InferOutputTypes(kernel_defs, infer_ctx); + if (infer_fn) { + infer_fn(infer_ctx); + } + }; schemas.back().TypeAndShapeInferenceFunction(extended_infer_fn); } @@ -1163,4 +1221,4 @@ common::Status CreateCustomRegistry(gsl::span op_domai } } // namespace onnxruntime -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) +#endif // ENABLE_CUSTOM_OP_API