Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions onnxruntime/core/providers/coreml/builders/impl/builder_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

#ifdef __APPLE__

#include <core/common/safeint.h>
#include <core/providers/common.h>
#include "core/providers/coreml/builders/impl/builder_utils.h"
Comment thread
guoyu-wang marked this conversation as resolved.

#include "core/common/safeint.h"
#include "core/framework/tensorprotoutils.h"
#include "core/providers/coreml/builders/helper.h"
#include "core/providers/shared/utils/utils.h"

#include "builder_utils.h"
#include "coreml/NeuralNetwork.pb.h"
#include "core/providers/coreml/builders/helper.h"

namespace onnxruntime {
namespace coreml {
Expand Down Expand Up @@ -93,9 +94,10 @@ common::Status CreateCoreMLWeight(CoreML::Specification::WeightParams& weight,
const ONNX_NAMESPACE::TensorProto& tensor) {
auto data_type = tensor.data_type();
if (data_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT) {
const float* data = GetTensorFloatData(tensor);
std::vector<uint8_t> unpacked_tensor;
ORT_RETURN_IF_ERROR(onnxruntime::utils::UnpackInitializerData(tensor, unpacked_tensor));
auto num_elements = SafeInt<size_t>(Product(tensor.dims()));
CreateCoreMLWeight(weight, data, num_elements);
CreateCoreMLWeight(weight, reinterpret_cast<const float*>(unpacked_tensor.data()), num_elements);
} else {
// TODO: support other type
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <unordered_map>
#include "core/common/status.h"
#include "core/graph/basic_types.h"
#include "core/providers/common.h"

namespace CoreML {
namespace Specification {
Expand Down
18 changes: 12 additions & 6 deletions onnxruntime/core/providers/coreml/builders/impl/gemm_op_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

#include <core/common/safeint.h>
#include <core/framework/tensorprotoutils.h>
#include "core/providers/common.h"
#include "core/providers/shared/utils/utils.h"
#include "core/providers/coreml/builders/helper.h"
Expand Down Expand Up @@ -49,19 +50,22 @@ void GemmOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod

// This is an internal function, requires input tensor to be 2d float tensor
// TODO, add support of other data types
static std::vector<float> GetTensorFloatDataTransposed(const ONNX_NAMESPACE::TensorProto& tensor) {
const float* src_data = GetTensorFloatData(tensor);
static Status GetTensorFloatDataTransposed(const ONNX_NAMESPACE::TensorProto& tensor,
std::vector<float>& transposed_data) {
std::vector<uint8_t> unpacked_tensor;
ORT_RETURN_IF_ERROR(onnxruntime::utils::UnpackInitializerData(tensor, unpacked_tensor));
const float* src_data = reinterpret_cast<const float*>(unpacked_tensor.data());
const auto& tensor_shape = tensor.dims();
auto x_t = SafeInt<size_t>(tensor_shape[0]);
auto y_t = SafeInt<size_t>(tensor_shape[1]);
std::vector<float> transposed_data(x_t * y_t);
transposed_data.resize(x_t * y_t);
for (size_t x = 0; x < x_t; x++) {
for (size_t y = 0; y < y_t; y++) {
transposed_data[y * x_t + x] = src_data[x * y_t + y];
}
}

return transposed_data;
return Status::OK();
}

Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node,
Expand All @@ -82,15 +86,17 @@ Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const N
coreml_inner_product->set_inputchannels(b_shape[0]);
coreml_inner_product->set_outputchannels(b_shape[1]);
// Add weight (b of MatMul)
const auto b_transposed = GetTensorFloatDataTransposed(b_tensor);
std::vector<float> b_transposed;
ORT_RETURN_IF_ERROR(GetTensorFloatDataTransposed(b_tensor, b_transposed));
CreateCoreMLWeight(*coreml_inner_product->mutable_weights(), b_transposed.data(), b_transposed.size());
} else { // Gemm
NodeAttrHelper helper(node);
const auto transB = helper.Get("transB", 0);
if (transB == 0) {
coreml_inner_product->set_inputchannels(b_shape[0]);
coreml_inner_product->set_outputchannels(b_shape[1]);
const auto b_transposed = GetTensorFloatDataTransposed(b_tensor);
std::vector<float> b_transposed;
ORT_RETURN_IF_ERROR(GetTensorFloatDataTransposed(b_tensor, b_transposed));
CreateCoreMLWeight(*coreml_inner_product->mutable_weights(), b_transposed.data(), b_transposed.size());
} else {
coreml_inner_product->set_inputchannels(b_shape[1]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

#include "core/providers/common.h"
#include "core/framework/tensorprotoutils.h"
#include "core/providers/cpu/tensor/reshape_helper.h"

#include "core/providers/shared/utils/utils.h"
Expand Down Expand Up @@ -82,7 +83,14 @@ bool ReshapeOpBuilder::IsOpSupportedImpl(const Node& node, const OpBuilderInputP
}

const auto& perm_tensor = *initializers.at(perm_name);
const int64_t* raw_perm = GetTensorInt64Data(perm_tensor);
std::vector<uint8_t> unpacked_tensor;
auto status = onnxruntime::utils::UnpackInitializerData(perm_tensor, unpacked_tensor);
if (!status.IsOK()) {
LOGS(logger, ERROR) << "Error while unpacking perm_tensor: " << status.ErrorMessage();
return false;
}

const int64_t* raw_perm = reinterpret_cast<const int64_t*>(unpacked_tensor.data());
const auto& perm_dims = perm_tensor.dims();
if (perm_dims.empty() || perm_dims[0] == 0) {
LOGS(logger, VERBOSE) << "New shape of reshape cannot be empty";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
#include <math.h>

#include "core/providers/common.h"
#include "core/framework/tensorprotoutils.h"
#include "core/providers/coreml/builders/helper.h"
#include "core/providers/cpu/tensor/reshape_helper.h"

#include "core/providers/shared/utils/utils.h"
#include "core/providers/coreml/builders/helper.h"

#ifdef __APPLE__
#include "core/providers/coreml/builders/model_builder.h"
#endif
Expand Down Expand Up @@ -40,7 +41,9 @@ class ResizeOpBuilder : public BaseOpBuilder {
};

// Helper functions
bool GetResizeScales(const InitializedTensorSet& initializers, const Node& node, std::vector<float>& scales) {
bool GetResizeScales(const InitializedTensorSet& initializers,
const Node& node, std::vector<float>& scales,
const logging::Logger& logger) {
const auto& input_defs = node.InputDefs();
if (input_defs.size() < 3)
return false;
Expand All @@ -49,12 +52,20 @@ bool GetResizeScales(const InitializedTensorSet& initializers, const Node& node,
if (scales_tensor.dims_size() != 1 || scales_tensor.dims()[0] != 4)
return false;

const float* scales_data = GetTensorFloatData(scales_tensor);
std::vector<uint8_t> unpacked_tensor;
auto status = onnxruntime::utils::UnpackInitializerData(scales_tensor, unpacked_tensor);
if (!status.IsOK()) {
LOGS(logger, ERROR) << "Error while unpacking scales_tensor: " << status.ErrorMessage();
return false;
}
const float* scales_data = reinterpret_cast<const float*>(unpacked_tensor.data());
scales = std::vector<float>{scales_data, scales_data + 4};
return true;
}

bool GetResizeOutputSizes(const InitializedTensorSet& initializers, const Node& node, std::vector<int64_t>& sizes) {
bool GetResizeOutputSizes(const InitializedTensorSet& initializers,
const Node& node, std::vector<int64_t>& sizes,
const logging::Logger& logger) {
const auto& input_defs = node.InputDefs();
if (input_defs.size() < 4)
return false;
Expand All @@ -63,7 +74,13 @@ bool GetResizeOutputSizes(const InitializedTensorSet& initializers, const Node&
if (sizes_tensor.dims_size() != 1 || sizes_tensor.dims()[0] != 4)
return false;

const int64_t* sizes_data = GetTensorInt64Data(sizes_tensor);
std::vector<uint8_t> unpacked_tensor;
auto status = onnxruntime::utils::UnpackInitializerData(sizes_tensor, unpacked_tensor);
if (!status.IsOK()) {
LOGS(logger, ERROR) << "Error while unpacking sizes_tensor: " << status.ErrorMessage();
return false;
}
const int64_t* sizes_data = reinterpret_cast<const int64_t*>(unpacked_tensor.data());
sizes = std::vector<int64_t>{sizes_data, sizes_data + 4};
return true;
}
Expand Down Expand Up @@ -106,14 +123,15 @@ Status ResizeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,

if (input_defs.size() == 3) { // use scales
std::vector<float> scales;
ORT_RETURN_IF_NOT(GetResizeScales(initializers, node, scales), "Error getting resize scales");
ORT_RETURN_IF_NOT(GetResizeScales(initializers, node, scales, logger), "Error getting resize scales");
coreml_upsample->add_scalingfactor(static_cast<int64_t>(scales[2]));
coreml_upsample->add_scalingfactor(static_cast<int64_t>(scales[3]));
} else { // we already checked number of inputs in IsOpSupportedImpl
std::vector<int64_t> input_shape;
ORT_RETURN_IF_NOT(GetShape(*input_defs[0], input_shape, logger), "Error getting input shape");
std::vector<int64_t> output_sizes;
ORT_RETURN_IF_NOT(GetResizeOutputSizes(initializers, node, output_sizes), "Error getting resize output_sizes");
ORT_RETURN_IF_NOT(GetResizeOutputSizes(initializers, node, output_sizes, logger),
"Error getting resize output_sizes");
coreml_upsample->add_scalingfactor(static_cast<int64_t>(output_sizes[2] / input_shape[2]));
coreml_upsample->add_scalingfactor(static_cast<int64_t>(output_sizes[3] / input_shape[3]));
}
Expand Down Expand Up @@ -205,7 +223,7 @@ bool ResizeOpBuilder::IsOpSupportedImpl(const Node& node, const OpBuilderInputPa
// We want to check if the scales or sizes are not trying to resize on N/C channels here
if (input_defs.size() == 3) { // we are using scales
std::vector<float> scales;
if (!GetResizeScales(initializers, node, scales))
if (!GetResizeScales(initializers, node, scales, logger))
return false;

float scale_n = scales[0];
Expand Down Expand Up @@ -235,7 +253,7 @@ bool ResizeOpBuilder::IsOpSupportedImpl(const Node& node, const OpBuilderInputPa
} else {
// we are using sizes
std::vector<int64_t> output_sizes;
if (!GetResizeOutputSizes(initializers, node, output_sizes))
if (!GetResizeOutputSizes(initializers, node, output_sizes, logger))
return false;

auto output_size_n = output_sizes[0];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include <core/common/safeint.h>

#include "core/framework/tensorprotoutils.h"
#include "core/providers/common.h"
#include "core/providers/shared/utils/utils.h"
#ifdef __APPLE__
Expand Down Expand Up @@ -40,15 +40,16 @@ void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const
}
}

/* static */ std::vector<int64_t> GetAxes(ModelBuilder& model_builder, const Node& node) {
std::vector<int64_t> axes;
/* static */ Status GetAxes(ModelBuilder& model_builder, const Node& node, std::vector<int64_t>& axes) {
// Squeeze opset 13 use input as axes
if (node.SinceVersion() > 12) {
// If axes is not provided, return an empty axes as default to squeeze all
if (node.InputDefs().size() > 1) {
const auto& initializers(model_builder.GetInitializerTensors());
const auto& axes_tensor = *initializers.at(node.InputDefs()[1]->Name());
const int64_t* raw_axes = GetTensorInt64Data(axes_tensor);
std::vector<uint8_t> unpacked_tensor;
ORT_RETURN_IF_ERROR(onnxruntime::utils::UnpackInitializerData(axes_tensor, unpacked_tensor));
const int64_t* raw_axes = reinterpret_cast<const int64_t*>(unpacked_tensor.data());
const auto size = SafeInt<size_t>(axes_tensor.dims()[0]);
axes.resize(size);
for (size_t i = 0; i < size; i++) {
Expand All @@ -60,7 +61,7 @@ void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const
axes = helper.Get("axes", std::vector<int64_t>());
}

return axes;
return Status::OK();
}

Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
Expand All @@ -69,7 +70,8 @@ Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);

auto* coreml_squeeze = layer->mutable_squeeze();
std::vector<int64_t> axes = GetAxes(model_builder, node);
std::vector<int64_t> axes;
ORT_RETURN_IF_ERROR(GetAxes(model_builder, node, axes));
if (axes.empty()) {
coreml_squeeze->set_squeezeall(true);
} else {
Expand Down
16 changes: 13 additions & 3 deletions onnxruntime/core/providers/nnapi/nnapi_builtin/builders/helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,19 @@ bool HasValidQuantizationZeroPoints(const InitializedTensorSet& initializers, co
return true;
}

float GetQuantizationScale(const InitializedTensorSet& initializers, const Node& node, size_t idx) {
const auto& scale_tensor = *initializers.at(node.InputDefs()[idx]->Name());
return GetTensorFloatData(scale_tensor)[0];
common::Status GetQuantizationScale(const InitializedTensorSet& initializers, const Node& node,
size_t idx, float& scale) {
std::vector<uint8_t> unpacked_tensor;
const auto& name = node.InputDefs()[idx]->Name();
const auto& scale_tensor = *initializers.at(name);
ORT_RETURN_IF_ERROR(
onnxruntime::utils::UnpackInitializerData(scale_tensor, node.ModelPath(), unpacked_tensor));

// The scale should be one or more floats
ORT_RETURN_IF(unpacked_tensor.size() < 4, "The initializer [", name, "] should have one or more floats ",
"with size no less than 4, actual size: ", unpacked_tensor.size());
scale = reinterpret_cast<const float*>(unpacked_tensor.data())[0];
return Status::OK();
}

common::Status GetQuantizationZeroPoint(const InitializedTensorSet& initializers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ bool HasValidQuantizationScales(const InitializedTensorSet& initializers, const
bool HasValidQuantizationZeroPoints(const InitializedTensorSet& initializers, const Node& node,
const std::vector<size_t>& indices);

float GetQuantizationScale(const InitializedTensorSet& initializers, const Node& node, size_t idx);
common::Status GetQuantizationScale(const InitializedTensorSet& initializers, const Node& node,
size_t idx, float& scale);

common::Status GetQuantizationZeroPoint(const InitializedTensorSet& initializers,
const Node& node, size_t idx, int32_t& zero_point) ORT_MUST_USE_RESULT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,6 @@ Status ModelBuilder::RegisterInitializers() {
std::vector<uint8_t> unpacked_tensor;
switch (tensor.data_type()) {
case ONNX_NAMESPACE::TensorProto_DataType_FLOAT:
src = reinterpret_cast<const uint8_t*>(GetTensorFloatData(tensor));
break;
case ONNX_NAMESPACE::TensorProto_DataType_UINT8:
ORT_RETURN_IF_ERROR(
onnxruntime::utils::UnpackInitializerData(tensor, graph_viewer_.ModelPath(), unpacked_tensor));
Expand Down
Loading