Files
2026-07-13 13:33:03 +08:00

86 lines
3.2 KiB
C++

//
// 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 <typename T>
static void ResizeAndCopyData(std::vector<uint8_t> *vec_data, const T *src, const std::vector<int> &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<OpT> 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<uint8_t> tensor_data;
std::vector<int> tensor_shape;
halide_type_t data_type = halide_type_of<float>();
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<Attribute>(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<int32_t>();
ResizeAndCopyData<int>(&tensor_data, blob->int32s()->data(), tensor_shape);
} else if (blob->dataType() == DataType_DT_FLOAT) {
data_type = halide_type_of<float>();
ResizeAndCopyData<float>(&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<const void *>(tensor_data.data()), tensor_shape, NCHW, data_type);
} else {
// https://github.com/onnx/onnx/blob/master/docs/Operators.md#attributes-12
const_shape = _Scalar<float>(0.0f);
}
return Expr::create(mnnFill.get(), {inputs[0], const_shape});
}
};
static auto gRegister = []() {
OnnxExtraManager::get()->insert("ConstantOfShape",
std::shared_ptr<OnnxExtraManager::Transform>(new OnnxConstantOfShapeTransform));
return true;
}();
} // namespace Express
} // namespace MNN