当前位置: 首页 > news >正文

MNN 执行推理(九)

在这里插入图片描述

系列文章目录


MNN createFromBuffer(一)
MNN createRuntime(二)
MNN createSession 之 Schedule(三)
MNN createSession 之创建流水线后端(四)
MNN Session 之维度计算(五)
MNN Session 之几何计算(六)
MNN Session 之 CPU 算子(七)
MNN Session 之 Vulkan 算子(八)
MNN 执行推理(九)


文章目录

  • 系列文章目录
  • 1、Interpreter::runSession
    • 1.1 Session::run
    • 1.1.1 Pipeline::execute
    • 1.1.1.1 VulkanBackend::onExecuteBegin
    • 1.1.1.2 Execution::onExecute
    • 1.1.1.3 Backend::onExecuteEnd
    • 1.1.1.3.1 _finish


1、Interpreter::runSession

在这里插入图片描述

// source/core/Interpreter.cpp
ErrorCode Interpreter::runSession(Session* session) const {std::unique_lock<std::mutex> _l(mNet->lock);
#ifdef MNN_INTERNAL_ENABLEDTimer timer;
#endifErrorCode errorcode = session->run();#ifdef MNN_INTERNAL_ENABLEDif (shouldLog(FREQ_LOW)) {waitSessionFinish(session);float costTime = (float)timer.durationInUs() / (float)1000;logForRunSession(session, costTime, "Interpreter::runSession");}
#endif // MNN_INTERNAL_ENABLEDreturn errorcode;
}

1.1 Session::run

Pipeline

// source/core/Session.cpp
ErrorCode Session::run() const {if (mNeedResize) {MNN_ERROR("Can't run session because not resized\n");return COMPUTE_SIZE_ERROR;}// mPipelines 类型为 std::vector<std::shared_ptr<Pipeline>>for (auto& iter : mPipelines) {auto error = iter->execute();if (NO_ERROR != error) {return error;}}return NO_ERROR;
}

1.1.1 Pipeline::execute

OpCacheInfo 、BackendCache、Command、CommandBuffer

// source/core/Pipeline.cpp
// typedef std::pair<BackendCache, std::vector<OpCacheInfo>> PipelineInfo
ErrorCode Pipeline::execute() {_copyInputs();auto& mBackend = mInfo.first.cache.first;auto& mBackupBackend = mInfo.first.cache.second;mBackend->onExecuteBegin();// mInfo 类型为 std::pair<BackendCache, std::vector<OpCacheInfo>>for (auto& info : mInfo.second) {auto& buffer = info.executeBuffer;
//#define LOG_VERPOSE
#ifdef LOG_VERPOSEFUNC_PRINT_ALL(info.op->name()->c_str(), s);
#endiffor (auto& cmdP : buffer.command) {auto& cmd = *cmdP;auto code = cmd.execution->onExecute(cmd.workInputs, cmd.workOutputs);
// #define LOG_VERPOSE
#ifdef LOG_VERPOSEauto dumpT = [](Tensor* t) {auto size = TensorUtils::getRawSize(t);size = size > 10 ? 10 : size;if (t->getType() == halide_type_of<float>()) {for (int i=0; i<size; ++i) {MNN_PRINT("%f, ", t->host<float>()[i]);}} else {for (int i=0; i<size; ++i) {MNN_PRINT("%d, ", t->host<int>()[i]);}}MNN_PRINT("\n");};if (/* cmd.op->name() && cmd.op->name()->str() == "/embed/embed_/Gather_output_0"*/cmd.op->type() == OpType_Convolution) {MNN_PRINT("%s Input begin:\n", EnumNameOpType(cmd.op->type()));for (auto t : cmd.workInputs) {dumpT(t);}MNN_PRINT("%s Output begin:\n", EnumNameOpType(cmd.op->type()));for (auto t : cmd.workOutputs) {dumpT(t);}}
#endifif (NO_ERROR != code) {mBackend->onExecuteEnd();return code;}}}mBackend->onExecuteEnd();return NO_ERROR;
}

1.1.1.1 VulkanBackend::onExecuteBegin

    在函数 Pipeline::execute 中调用 Backend::onExecuteBegin 函数的代码如下:

	mBackend->onExecuteBegin();

    onExecuteBegin 函数是个虚函数, mBackend->onExecuteBegin 调用是个多态,其基类为 Backend,此处 mBackendVulkanBackend,其具体实现代码如下:

// source/backend/vulkan/image/backend/VulkanBackend.cpp
void VulkanBackend::onExecuteBegin() const {if (!mDirect) {mCmdBuffers.push_back(mCmdBuffer->get());}// FUNC_PRINT_ALL(mDynamicMemoryPool->computeSize(), f);
}

VulkanBasicExecutionDirect::onExecute

1.1.1.2 Execution::onExecute

    在函数 Pipeline::execute 中调用 Execution::onExecute 函数的代码如下:

            auto code = cmd.execution->onExecute(cmd.workInputs, cmd.workOutputs);

    Execution::onExecute 函数是个虚函数,对于 Vulkan 来说,主要有 VulkanBasicExecutionDirect 和 VulkanBasicExecutionInDirect,我们以 VulkanBasicExecutionDirect 进行分析:

// source/backend/vulkan/image/execution/VulkanBasicExecution.cpp
ErrorCode VulkanBasicExecutionDirect::onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {auto extra = static_cast<VulkanBackend *>(backend());extra->pushCommand(mCmdBuffer->get());return NO_ERROR;
}

1.1.1.3 Backend::onExecuteEnd

    在函数 Pipeline::execute 中调用 Backend::onExecuteEnd 函数的代码如下:

	mBackend->onExecuteEnd();

    Backend::onExecuteEnd 函数是个虚函数,对于 Vulkan 来说为 VulkanBackend ,以下为其代码:

// source/backend/vulkan/image/backend/VulkanBackend.cpp
void VulkanBackend::onExecuteEnd() const {_finish();
}

1.1.1.3.1 _finish

// source/backend/vulkan/image/backend/VulkanBackend.cpp
void VulkanBackend::_finish() const {if (mCmdBuffers.empty()) {return;}VkSubmitInfo submit_info = {/* .sType                = */ VK_STRUCTURE_TYPE_SUBMIT_INFO,/* .pNext                = */ nullptr,/* .waitSemaphoreCount   = */ 0,/* .pWaitSemaphores      = */ nullptr,/* .pWaitDstStageMask    = */ nullptr,/* .commandBufferCount   = */ (uint32_t)mCmdBuffers.size(),/* .pCommandBuffers      = */ mCmdBuffers.data(),/* .signalSemaphoreCount = */ 0,/* .pSignalSemaphores    = */ nullptr};auto fenceReal           = mFence->get();mFence->reset();CALL_VK(vkQueueSubmit(device().acquireDefaultDevQueue(), 1, &submit_info, fenceReal));auto res = mFence->wait();MNN_VK_CHECK(res);mCmdBuffers.clear();
}

   

http://www.lryc.cn/news/323826.html

相关文章:

  • 算法公式汇总
  • c语言管理课程信息系统
  • 大模型在天体物理学研究中的辅助作用与案例分析
  • 洛谷_P1873 [COCI 2011/2012 #5] EKO / 砍树_python写法
  • Android_NDK调试
  • 全量知识系统 概要设计(SmartChat回复)
  • 一、SpringBoot基础搭建
  • some/ip CAN CANFD
  • HTTP Header Fields
  • 基于FPGA的FFT图像滤波设计
  • WPF 立体Border
  • java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
  • 代码随想录(day8)——字符串
  • JavaScript 权威指南第七版(GPT 重译)(二)
  • 【python_往企业微信群中发送文件】
  • 华为校招机试 - 循环依赖(20240320)
  • 基于Spring Boot技术的幼儿园管理系统
  • 查找众数及中位数 - 华为OD统一考试(C卷)
  • bash命令执行.sh文件 windows python环境
  • refreactive vue3
  • 【项目实践Day06】异步请求与同步请求+Ajax+微信小程序上实现发送异步请求
  • Elasticsearch面试系列-01
  • QT tableWidget横向纵向设置
  • Unity Mesh简化为Cube mesh
  • openGauss学习笔记-249 openGauss性能调优-使用Plan Hint进行调优-Join顺序的Hint
  • 大规模预训练语言模型的可解释性研究与实践
  • Rust常用库之序列化和反序列化库serde(使用 Serde 处理json)
  • java设计模式(2)---六大原则
  • 数学建模(层次分析法 python代码 案例)
  • Gitlab介绍