// // OnnxConstantOfShape.cpp // MNNConverter // // Created by MNN on 2019/10/31. // Copyright © 2018, Alibaba Group Holding Limited // #include "MNN_generated.h" #include "OnnxExtraManager.hpp" namespace MNN { namespace Express { template static void ResizeAndCopyData(std::vector *vec_data, const T *src, const std::vector &shape) { int64_t count = sizeof(T); for (const auto &d : shape) { count *= d; } MNN_ASSERT(count > 0); vec_data->resize(count); memcpy(vec_data->data(), src, count); } class OnnxConstantOfShapeTransform : public OnnxExtraManager::Transform { public: virtual EXPRP onExecute(EXPRP expr) const override { auto inputs = expr->inputs(); MNN_THROW_CHECK(1 == inputs.size(), "Onnx ConstantOfShape should have one input!"); std::unique_ptr mnnFill(new OpT); mnnFill->name = expr->name(); mnnFill->defaultDimentionFormat = MNN_DATA_FORMAT_NCHW; mnnFill->type = OpType_Fill; mnnFill->main.type = OpParameter_NONE; mnnFill->main.value = nullptr; std::vector tensor_data; std::vector tensor_shape; halide_type_t data_type = halide_type_of(); auto extraParam = expr->get()->main_as_Extra(); VARP const_shape; if (extraParam->attr() != nullptr) { for (int i = 0; i < extraParam->attr()->size(); ++i) { auto attr = extraParam->attr()->GetAs(i); const auto &key = attr->key()->str(); if (key == "value") { auto blob = attr->tensor(); // Process tensor shape. tensor_shape.resize(blob->dims()->size()); for (int j = 0; j < tensor_shape.size(); ++j) { tensor_shape[j] = blob->dims()->Get(j); } if (blob->dataType() == DataType_DT_INT32) { data_type = halide_type_of(); ResizeAndCopyData(&tensor_data, blob->int32s()->data(), tensor_shape); } else if (blob->dataType() == DataType_DT_FLOAT) { data_type = halide_type_of(); ResizeAndCopyData(&tensor_data, blob->float32s()->data(), tensor_shape); } else { MNN_ERROR("Not support data type."); } break; // Break out of the loop if value has been processed. } } const_shape = _Const(static_cast(tensor_data.data()), tensor_shape, NCHW, data_type); } else { // https://github.com/onnx/onnx/blob/master/docs/Operators.md#attributes-12 const_shape = _Scalar(0.0f); } return Expr::create(mnnFill.get(), {inputs[0], const_shape}); } }; static auto gRegister = []() { OnnxExtraManager::get()->insert("ConstantOfShape", std::shared_ptr(new OnnxConstantOfShapeTransform)); return true; }(); } // namespace Express } // namespace MNN