[CoreML EP] Fix failure for layer without name (#8399)

* Fix CoreML failure for layer without name

* Update clip op builder to new naming function
This commit is contained in:
Guoyu Wang 2021-07-15 11:52:01 -07:00 committed by GitHub
parent 963d883de8
commit bcd50afafb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 42 additions and 23 deletions

View file

@ -25,7 +25,7 @@ class ActivationOpBuilder : public BaseOpBuilder {
Status ActivationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& /* logger */) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& op_type(node.OpType());
if (op_type == "Sigmoid") {

View file

@ -27,7 +27,7 @@ class ArgMaxOpBuilder : public BaseOpBuilder {
Status ArgMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& /* logger */) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& graph_viewer = model_builder.GetGraphViewer();
NodeAttrHelper helper(node);
@ -46,7 +46,7 @@ Status ArgMaxOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
if (node.GetOutputEdgesCount() == 1) {
auto it = node.OutputEdgesBegin();
const auto* succ_node(graph_viewer.GetNode(it->GetNode().Index()));
// If Argmax's successive node is a Cast from int64 to int32 output
// If Argmax's successive node is a Cast from int64 to int32 output
// The 'cast to' type is checked in operater supported related, omit the check here
if (succ_node->OpType() == "Cast") {
// Skip the cast's input/argmax's output

View file

@ -50,10 +50,21 @@ Status BaseOpBuilder::AddToModelBuilder(ModelBuilder& model_builder, const Node&
return Status::OK();
}
/* static */ std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> BaseOpBuilder::CreateNNLayer(const Node& node) {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer =
std::make_unique<COREML_SPEC::NeuralNetworkLayer>();
layer->set_name(node.Name());
/* static */ std::unique_ptr<COREML_SPEC::NeuralNetworkLayer>
BaseOpBuilder::CreateNNLayer(ModelBuilder& model_builder, const Node& node) {
auto layer_name = node.Name();
if (layer_name.empty()) {
// CoreML requires layer has a name, while the node name is optional in ONNX
// In this case, create a unique name for the layer
layer_name = model_builder.GetUniqueName(MakeString("Node_", node.Index(), "_type_", node.OpType()));
}
return CreateNNLayer(layer_name);
}
/* static */ std::unique_ptr<COREML_SPEC::NeuralNetworkLayer>
BaseOpBuilder::CreateNNLayer(const std::string& layer_name) {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = std::make_unique<COREML_SPEC::NeuralNetworkLayer>();
layer->set_name(layer_name);
return layer;
}

View file

@ -24,7 +24,10 @@ class BaseOpBuilder : public IOpBuilder {
virtual Status AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node,
const logging::Logger& logger) const ORT_MUST_USE_RESULT = 0;
static std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> CreateNNLayer(const Node& node);
static std::unique_ptr<COREML_SPEC::NeuralNetworkLayer>
CreateNNLayer(ModelBuilder& model_builder, const Node& node);
static std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> CreateNNLayer(const std::string& layer_name);
// Operator support related
public:

View file

@ -45,7 +45,7 @@ void BatchNormalizationOpBuilder::AddInitializersToSkip(ModelBuilder& model_buil
Status BatchNormalizationOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& /* logger */) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& input_defs = node.InputDefs();
const auto& initializers(model_builder.GetInitializerTensors());

View file

@ -30,7 +30,7 @@ Status BinaryOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const
const auto& op_type(node.OpType());
const auto& input_defs(node.InputDefs());
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
if (op_type == "Add") {
layer->mutable_add();

View file

@ -53,7 +53,7 @@ Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
if (!has_min && !has_max) {
// Clip without min/max is an identity node
// In CoreML we don't have identity, use ActivationLinear instead
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
layer->mutable_activation()->mutable_linear()->set_alpha(1.0f);
*layer->mutable_input()->Add() = input_name;
*layer->mutable_output()->Add() = output_name;
@ -78,7 +78,8 @@ Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
// Handle clipping at min first
if (has_min) {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> min_layer = CreateNNLayer(node);
const auto clip_min_layer_name = model_builder.GetUniqueName(MakeString(node_name, "_Clip_min"));
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> min_layer = CreateNNLayer(clip_min_layer_name);
if (min == 0.0f) { // If min is 0. then this min will be handled by relu
min_layer->mutable_activation()->mutable_relu();
} else { // otherwise, min will be handled by unary->threshold
@ -93,9 +94,11 @@ Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
// Clipping at max is handled by -1 * (threshold (-min_output, -max))
if (has_max) {
const auto threshold_output_name = model_builder.GetUniqueName(node_name + "threshold_output");
const auto threshold_output_name = model_builder.GetUniqueName(MakeString(node_name, "threshold_output"));
{ // Add threshold layer, which is actually max( -1 * min_output, -max)
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> threshold_layer = CreateNNLayer(node);
const auto clip_max_threshold_layer_name =
model_builder.GetUniqueName(MakeString(node_name, "_Clip_max_threshold"));
auto threshold_layer = CreateNNLayer(clip_max_threshold_layer_name);
threshold_layer->mutable_unary()->set_alpha(-max);
threshold_layer->mutable_unary()->set_scale(-1.0f);
threshold_layer->mutable_unary()->set_type(COREML_SPEC::UnaryFunctionLayerParams::THRESHOLD);
@ -104,7 +107,9 @@ Status ClipOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
model_builder.AddLayer(std::move(threshold_layer));
}
{ // Add linear activation layer -1 * threshold_output
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> linear_layer = CreateNNLayer(node);
const auto clip_max_linear_layer_name =
model_builder.GetUniqueName(MakeString(node_name, "_Clip_max_linear"));
auto linear_layer = CreateNNLayer(clip_max_linear_layer_name);
linear_layer->mutable_activation()->mutable_linear()->set_alpha(-1.0f);
*linear_layer->mutable_input()->Add() = threshold_output_name;
*linear_layer->mutable_output()->Add() = output_name;

View file

@ -29,7 +29,7 @@ class ConcatOpBuilder : public BaseOpBuilder {
Status ConcatOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
layer->mutable_concat()->set_sequenceconcat(false);

View file

@ -43,7 +43,7 @@ void ConvOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const Nod
Status ConvOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& input_defs = node.InputDefs();

View file

@ -61,7 +61,7 @@ static std::vector<float> GetTensorFloatDataTransposed(const ONNX_NAMESPACE::Ten
Status GemmOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, const Node& node,
const logging::Logger& /* logger */) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& op_type = node.OpType();
const auto& input_defs = node.InputDefs();

View file

@ -30,7 +30,7 @@ class PoolOpBuilder : public BaseOpBuilder {
Status PoolOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
auto* coreml_pool = layer->mutable_pooling();
const auto& op_type = node.OpType();

View file

@ -41,7 +41,7 @@ void ReshapeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const
Status ReshapeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
const auto& input_defs = node.InputDefs();
const auto& initializers(model_builder.GetInitializerTensors());

View file

@ -83,7 +83,7 @@ void ResizeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const N
Status ResizeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
auto* coreml_upsample = layer->mutable_upsample();
NodeAttrHelper helper(node);

View file

@ -61,7 +61,7 @@ void SqueezeOpBuilder::AddInitializersToSkip(ModelBuilder& model_builder, const
Status SqueezeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& /* logger */) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
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);

View file

@ -23,7 +23,7 @@ class TransposeOpBuilder : public BaseOpBuilder {
Status TransposeOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder,
const Node& node,
const logging::Logger& logger) const {
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(node);
std::unique_ptr<COREML_SPEC::NeuralNetworkLayer> layer = CreateNNLayer(model_builder, node);
NodeAttrHelper helper(node);
std::vector<int64_t> perm = helper.Get("perm", std::vector<int64_t>());