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

123 lines
5.0 KiB
C++

//
// NPUStridedSlice.cpp
// MNN
//
// Created by MNN on 2019/09/07.
// Copyright © 2018, Alibaba Group Holding Limited
//
#include "NPUStridedSlice.hpp"
#include "NPUBackend.hpp"
using namespace std;
namespace MNN {
NPUStridedSlice::NPUStridedSlice(Backend *b, const Op *op, const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) : MNN::NPUCommonExecution(b,op)
{
isConst1 = TensorUtils::getDescribe(inputs[1])->usage==Tensor::InsideDescribe::Usage::CONSTANT;
isConst2 = TensorUtils::getDescribe(inputs[2])->usage==Tensor::InsideDescribe::Usage::CONSTANT;
isConst3 = false;
isConst4 = false;
auto opName = mOp->name()->str();
Tensor *begin = inputs[1];
Tensor *end = inputs[2];
if(isConst1) {
mConst_b = hiai::op::Const(opName + "_b_const");
ge::TensorDesc fdesc(ge::Shape({begin->elementSize()}), ge::DT_INT32);
ge::TensorPtr filter = std::make_shared<ge::Tensor>();
filter->SetTensorDesc(fdesc);
filter->SetData((uint8_t*)begin->host<int32_t>(), begin->elementSize()*sizeof(int32_t));
mConst_b.set_attr_value(filter);
}
if(isConst2) {
mConst_e = hiai::op::Const(opName + "_e_const");
ge::TensorDesc fdesc(ge::Shape({end->elementSize()}), ge::DT_INT32);
ge::TensorPtr filter = std::make_shared<ge::Tensor>();
filter->SetTensorDesc(fdesc);
filter->SetData((uint8_t *)end->host<int32_t>(), end->elementSize()*sizeof(int32_t));
mConst_e.set_attr_value(filter);
}
auto parameter = mOp->main_as_StridedSliceParam();
beginMask = convertMask(begin, parameter->beginMask(),1);
endMask = convertMask(begin, parameter->endMask(),1);
ellipsisMask = parameter->ellipsisMask(); //框架未使用
newAxisMask = parameter->newAxisMask();
shrinkAxisMask = convertMask(begin, parameter->shrinkAxisMask());
}
ErrorCode NPUStridedSlice::onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
mNpuBackend->setNetworkInput(inputs, mOp);
auto opName = mOp->name()->str();
Tensor *axis = nullptr;
Tensor *strides = nullptr;
if (inputs.size() > 3) {
axis = inputs[3];
isConst3 = TensorUtils::getDescribe(inputs[3])->usage==Tensor::InsideDescribe::Usage::CONSTANT;
}
if (inputs.size() > 4) {
strides = inputs[4];
isConst4 = TensorUtils::getDescribe(inputs[4])->usage==Tensor::InsideDescribe::Usage::CONSTANT;
}
if (isConst3) {
vector<int32_t> axisdims;
vector<int32_t> axisdims1;
for (int32_t i = 0; i < axis->elementSize(); i++) {
axisdims.push_back(i);
if (count(axisdims1.begin(), axisdims1.end(), axis->host<int32_t>()[i]) == 0) {
axisdims1.push_back(axis->host<int32_t>()[i]);
}
}
mConst_a = hiai::op::Const(opName + "_a_const");
ge::TensorDesc fdesc(ge::Shape({axis->elementSize()}), ge::DT_INT32);
ge::TensorPtr filter = std::make_shared<ge::Tensor>();
filter->SetTensorDesc(fdesc);
if (axisdims1.size() != axisdims.size() || (axisdims.size() == 1 && axisdims1[0] == 1)) {
filter->SetData((uint8_t*)axisdims.data(), axis->elementSize()*sizeof(int32_t));
} else {
filter->SetData((uint8_t*)axisdims1.data(), axis->elementSize()*sizeof(int32_t));
}
mConst_a.set_attr_value(filter);
}
if (isConst4) {
mConst_s = hiai::op::Const(opName + "_s_const");
ge::TensorDesc fdesc(ge::Shape({strides->elementSize()}), ge::DT_INT32);
ge::TensorPtr filter = std::make_shared<ge::Tensor>();
filter->SetTensorDesc(fdesc);
filter->SetData((uint8_t*)strides->host<int32_t>(), strides->elementSize()*sizeof(int32_t));
mConst_s.set_attr_value(filter);
} else {
vector<int32_t> axisdims;
for (int32_t i = 0; i < axis->elementSize(); i++) {
axisdims.push_back(1);
}
mConst_s = hiai::op::Const(opName + "_s_const");
ge::TensorDesc fdesc(ge::Shape({axis->elementSize()}), ge::DT_INT32);
ge::TensorPtr filter = std::make_shared<ge::Tensor>();
filter->SetTensorDesc(fdesc);
filter->SetData((uint8_t*)axisdims.data(), axis->elementSize()*sizeof(int32_t));
mConst_s.set_attr_value(filter);
}
shared_ptr<hiai::op::StridedSliceV2> stride_slice(new hiai::op::StridedSliceV2(opName));
auto inputIndex = mOp->inputIndexes()->data()[0];
auto iops = mNpuBackend->mGrapMap[inputIndex]; // x
auto xOp = iops.back().first;
(*stride_slice)
.set_input_x(*xOp.get())
.set_input_begin(mConst_b)
.set_input_end(mConst_e);
if (isConst3) {
(*stride_slice).set_input_axes(mConst_a);
}
(*stride_slice).set_input_strides(mConst_s);
mNpuBackend->setOutputOps(mOp, {stride_slice}, outputs);
return NO_ERROR;
}
NPUCreatorRegister<TypedCreator<NPUStridedSlice>> __stride_slice_op(OpType_StridedSlice);
} // namespace MNN