Files
alibaba--mnn/tools/converter/source/torch/LoopTorch.cpp
T
2026-07-13 13:33:03 +08:00

70 lines
2.5 KiB
C++

//
// LoopTorch.cpp
// MNNConverter
//
// Created by MNN on 2021/07/22.
// Copyright © 2018, Alibaba Group Holding Limited
//
#include <stdio.h>
#include "torchOpConverter.hpp"
DECLARE_OP_CONVERTER(LoopTorch);
MNN::OpType LoopTorch::opType() {
return MNN::OpType_While;
}
MNN::OpParameter LoopTorch::type() {
return MNN::OpParameter_WhileParam;
}
std::vector<int> LoopTorch::inputTensorIdx() {
return {-1};
}
void LoopTorch::run(MNN::OpT* dstOp, const torch::jit::Node* node, TorchScope* scope) {
auto param = new MNN::WhileParamT;
const auto bodyBlock = node->blocks()[0];
param->cond_graph = dstOp->name + "/cond";
param->body_graph = dstOp->name + "/body";
// loop: for (int i = 0; i < M && keep_going; i++)
// i - iName; mName - M; kName - keep_going
std::string iName = bodyBlock->inputs().at(0)->debugName(),
mName = node->input(0)->debugName(),
kName = node->input(1)->debugName();
// declare int i = 0;
int idxI = scope->buildIntConstOp({0}, iName);
if (std::find(dstOp->inputIndexes.begin(), dstOp->inputIndexes.end(), idxI) == dstOp->inputIndexes.end()) {
dstOp->inputIndexes.push_back(idxI);
}
// build cond
scope->buildCondGraph(param->cond_graph, iName, mName, kName);
// build body
scope->buildSubGraph(bodyBlock, param->body_graph, true);
scope->dealSubgraphDepsForOp(dstOp);
for (int idx : dstOp->inputIndexes) {
std::unique_ptr<MNN::StringVecT> inputT(new MNN::StringVecT);
inputT->data.emplace_back(scope->lookupTensorByIdx(idx));
param->aliases_inputs.emplace_back(std::move(inputT));
}
// update block[0]->outputs: [ keep_going, user_def_vars... ]
for (int i = 0; i < bodyBlock->outputs().size(); i++) {
std::unique_ptr<MNN::StringVecT> updateT(new MNN::StringVecT);
auto bodyOutput = bodyBlock->outputs().at(i)->debugName();
updateT->data.emplace_back(bodyOutput);
updateT->data.emplace_back(node->inputs().at(1 + i)->debugName());
param->aliases_updates.emplace_back(std::move(updateT));
if (i > 0) {
param->aliases_outputs.push_back(bodyOutput);
}
}
// update i
std::unique_ptr<MNN::StringVecT> updateT(new MNN::StringVecT);
updateT->data.emplace_back(param->body_graph + "/increment_i");
updateT->data.emplace_back(iName);
param->aliases_updates.emplace_back(std::move(updateT));
dstOp->main.value = param;
}
REGISTER_CONVERTER(LoopTorch, Loop);