// // IfModule.cpp // MNN // // Created by MNN on 2020/09/01. // Copyright © 2018, Alibaba Group Holding Limited // #include "IfModule.hpp" #include "MNN_generated.h" namespace MNN { namespace Express { static int _findPos(const std::vector& names, const std::string& key) { for (int i=0; i IfModule::onForward(const std::vector& inputs) { std::vector outputs(mOutputFromElse.size()); MNN_ASSERT(mOutputFromThen.size() == mOutputFromElse.size()); if (inputs[0]->readMap()[0] > 0) { std::vector subInputs(mInputForThen.size()); for (auto& p : mInputForThen) { subInputs[p.first] = inputs[p.second]; } auto subOutputs = mThen->onForward(subInputs); for (int i=0; i subInputs(mInputForElse.size()); for (auto& p : mInputForElse) { subInputs[p.first] = inputs[p.second]; } auto subOutputs = mElse->onForward(subInputs); for (int i=0; i& subGraph) { auto module = new IfModule; module->setType("IfModule"); auto ifParam = op->main_as_IfParam(); auto& thenG = subGraph.find(ifParam->then_graph()->str())->second; auto& elseG = subGraph.find(ifParam->else_graph()->str())->second; module->mElse = elseG.m; module->mThen = thenG.m; if (nullptr != op->name()) { module->setName(op->name()->str()); } /** Compute map index std::vector> mInputForThen; // First mElse' index, Second: inputs's index std::vector> mInputForElse; std::vector mOutputFromThen; std::vector mOutputFromElse; */ // Map Inputs for (int i=0; ialiases_inputs()->size(); ++i) { auto index = i; auto data = ifParam->aliases_inputs()->GetAs(i); if (nullptr == data->data()) { continue; } for (int s=0; sdata()->size(); ++s) { auto name = data->data()->GetAsString(s)->str(); auto thenPos = _findPos(thenG.inputs, name); if (thenPos >= 0) { module->mInputForThen.emplace_back(std::make_pair(thenPos, i)); } auto elsePos = _findPos(elseG.inputs, name); if (elsePos >= 0) { module->mInputForElse.emplace_back(std::make_pair(elsePos, i)); } } } MNN_ASSERT(module->mInputForElse.size() == elseG.inputs.size()); MNN_ASSERT(module->mInputForThen.size() == thenG.inputs.size()); // Map outputs auto output = ifParam->aliases_outputs(); if (output == nullptr) { // Onnx for (int i = 0; i < op->outputIndexes()->size(); ++i) { module->mOutputFromThen.push_back(i); module->mOutputFromElse.push_back(i); } return module; } module->mOutputFromThen.resize(output->size()); module->mOutputFromElse.resize(output->size()); for (int i=0; isize(); ++i) { auto data = output->GetAs(i); MNN_ASSERT(data->data()->size() == 2); auto thenPos = _findPos(thenG.outputs, data->data()->GetAsString(0)->str()); MNN_ASSERT(thenPos >= 0); auto elsePos = _findPos(elseG.outputs, data->data()->GetAsString(1)->str()); module->mOutputFromThen[i] = thenPos; module->mOutputFromElse[i] = elsePos; } return module; } Module* IfModule::clone(CloneContext* ctx) const { IfModule* module(new IfModule); module->mInputForThen = mInputForThen; module->mInputForElse = mInputForElse; module->mOutputFromThen = mOutputFromThen; module->mOutputFromElse = mOutputFromElse; module->mThen.reset(mThen->clone(ctx)); module->mElse.reset(mElse->clone(ctx)); return this->cloneBaseTo(ctx, module); } } // namespace Express } // namespace MNN