MNN createRuntime(二)

在这里插入图片描述

系列文章目录


MNN createFromBuffer(一)
MNN createRuntime(二)
MNN createSession 之 Schedule(三)
MNN createSession 之创建流水线后端(四)
MNN Session::resize 之流水线编码(五)
MNN Session 创建执行器(六)


文章目录

  • 系列文章目录
  • 1、createRuntime
    • 1.1 RuntimeInfo
    • 1.2 Schedule::getApprociateType
    • 1.2.1 MNNGetExtraRuntimeCreator
    • 1.2.1.1 registerBackend
    • 1.2.1.2 GetExtraCreator
    • 1.3 RuntimeFactory::create
    • 1.3.1 VulkanRuntimeCreator
    • 1.3.2 VulkanRuntimeCreator
    • 1.4 ScheduleConfig
    • 1.5 BackendConfig


1、createRuntime

    根据 ScheduleConfig 创建运行时 RuntimeRuntimeInfo 的定义见 2.1,其 first 用来存放根据 configs 创建的 Runtime(如 VulkanRuntime,CUDARuntime),它的 second 存放的是默认 Runtime,一般为 CPURuntime

在这里插入图片描述

RuntimeInfo Interpreter::createRuntime(const std::vector<ScheduleConfig>& configs) {RuntimeInfo res;// 根据 configs 创建的 Runtime 存放在这里auto& mRuntimes = res.first;for (auto& config : configs) {Backend::Info compute;compute.type      = Schedule::getApprociateType(config);compute.numThread = config.numThread;if(config.type == MNN_FORWARD_AUTO) {if(compute.type == MNN_FORWARD_OPENCL || compute.type == MNN_FORWARD_METAL) {// AUTO set default gpu-mode MNN_GPU_TUNING_FASTcompute.numThread = 16;}}compute.user      = config.backendConfig;if (mRuntimes.find(compute.type) == mRuntimes.end()) {auto newBn = RuntimeFactory::create(compute);if (nullptr == newBn) {MNN_ERROR("Can't create Runtime: %s\n", EnumNameForwardType((ForwardType)compute.type));continue;}mRuntimes[compute.type].reset(newBn);}}_getDefaultBackend(res);return res;
}

1.1 RuntimeInfo

typedef std::pair< std::map<MNNForwardType, std::shared_ptr<Runtime>>, \std::shared_ptr<Runtime>> RuntimeInfo;

1.2 Schedule::getApprociateType

// source/core/Schedule.cpp
MNNForwardType Schedule::getApprociateType(const ScheduleConfig& config) {MNNForwardType type = config.type;// FIXME: Support Auto determine// MNN_FORWARD_AUTO 的处理逻辑if (MNN_FORWARD_AUTO == config.type) {//Define Auto choose prioritystd::vector<MNNForwardType> priorityList;priorityList.push_back(MNN_FORWARD_USER_0); //HIAIpriorityList.push_back(MNN_FORWARD_NN);     //CoreMLpriorityList.push_back(MNN_FORWARD_USER_1); //TensoRTpriorityList.push_back(MNN_FORWARD_CUDA);   //CUDApriorityList.push_back(MNN_FORWARD_OPENCL); //OpenCLpriorityList.push_back(MNN_FORWARD_METAL);  //METALpriorityList.push_back(MNN_FORWARD_VULKAN); //VulkanpriorityList.push_back(MNN_FORWARD_CPU);    //CPUfor (auto bn : priorityList) {if (MNNGetExtraRuntimeCreator(bn) != nullptr) {type = (MNNForwardType)bn;break;}}}auto creator = MNNGetExtraRuntimeCreator(type);if (nullptr == creator) {MNN_PRINT("Can't Find type=%d backend, use %d instead\n", type, config.backupType);type = config.backupType;} else {// TODO : Not Limited to openclif(type == MNN_FORWARD_OPENCL && config.backendConfig != nullptr) {if(config.backendConfig->power == BackendConfig::Power_Low) {Backend::Info info;info.type = type;std::shared_ptr<Runtime> bn(creator->onCreate(info));bool isSupportLowPower = bn->onGetRuntimeStatus(RuntimeStatus::STATUS_SUPPORT_POWER_LOW);if(!isSupportLowPower) {MNN_PRINT("type=%d backend don't Support Low Power, use %d instead\n", type, config.backupType);type = config.backupType;}}}}return type;
}

1.2.1 MNNGetExtraRuntimeCreator

// source/core/Backend.cpp
const RuntimeCreator* MNNGetExtraRuntimeCreator(MNNForwardType type) {registerBackend();// 获取运行时创建器// (std::map<MNNForwardType, std::pair<const RuntimeCreator*, bool>>类型)auto& gExtraCreator = GetExtraCreator();// 根据推理类型查找运行时创建器auto iter           = gExtraCreator.find(type);if (iter == gExtraCreator.end()) {return nullptr;}// iter->second 的类型为 std::pair<const RuntimeCreator* creator, bool needCheck>if (!iter->second.second) {return iter->second.first;}Backend::Info info;info.type = type;std::shared_ptr<Runtime> bn(iter->second.first->onCreate(info));if (nullptr != bn.get()) {return iter->second.first;}return nullptr;
}

1.2.1.1 registerBackend

static std::once_flag s_flag;
void registerBackend() {std::call_once(s_flag, [&]() {
#ifdef MNN_INTERNAL_ENABLEDLogInit();
#endif// 注册 CPU 的运行时创建器和一些核心函数registerCPURuntimeCreator();
#ifndef MNN_BUILD_MINISizeComputerSuite::init();// 图像着色器 ?GeometryComputer::init();
#endif
#if MNN_COREML_ENABLEDregisterCoreMLRuntimeCreator();
#endif
#ifdef MNN_NNAPI_ENABLEDregisterNNAPIRuntimeCreator();
#endif
#if MNN_OPENCL_ENABLEDOpenCL::registerOpenCLRuntimeCreator();
#endif
#if MNN_METAL_ENABLEDregisterMetalRuntimeCreator();
#endif});
}

1.2.1.2 GetExtraCreator

static std::map<MNNForwardType, std::pair<const RuntimeCreator*, bool>>& GetExtraCreator() {static std::once_flag gInitFlag;static std::map<MNNForwardType, std::pair<const RuntimeCreator*, bool>>* gExtraCreator;std::call_once(gInitFlag,[&]() { gExtraCreator = new std::map<MNNForwardType, std::pair<const RuntimeCreator*, bool>>; });return *gExtraCreator;
}

    获取 RuntimeCreator ,然后根据类型创建对应的 Runtime。gExtraCreator 是一个 map 类型,其是通过函数 MNNInsertExtraRuntimeCreator 进行注册的。

// source/core/Backend.cpp
bool MNNInsertExtraRuntimeCreator(MNNForwardType type, const RuntimeCreator* creator, bool needCheck) {auto& gExtraCreator = GetExtraCreator();if (gExtraCreator.find(type) != gExtraCreator.end()) {MNN_ASSERT(false && "duplicate type");return false;}gExtraCreator.insert(std::make_pair(type, std::make_pair(creator, needCheck)));return true;
}
  • VULKAN 注册
// source/backend/vulkan/runtime/VulkanRuntime.cpp
static bool gResistor = []() {MNNInsertExtraRuntimeCreator(MNN_FORWARD_VULKAN, new VulkanRuntimeCreator, false);return false;
}();
  • CUDA 注册
// source/backend/cuda/Register.cpp
static const auto __cuda_global_initializer = []() {MNNInsertExtraRuntimeCreator(MNN_FORWARD_CUDA, new CUDARuntimeCreator, false);return true;
}();
  • OPENGL 注册
// source/backend/opengl/GLBackend.cpp
bool placeholder = []() {static std::once_flag createOnce;std::call_once(createOnce, []() {MNNInsertExtraRuntimeCreator(MNN_FORWARD_OPENGL, new GLRuntimeCreator, false);});return true;
}();
  • Metal 注册,在 registerBackend 中主动调用
// source/backend/metal/MetalBackend.mm
void registerMetalRuntimeCreator() {// according to// https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/HardwareGPUInformation/HardwareGPUInformation.html// not all device with iOS 8+ supports metal.id<MTLDevice> device = MTLCreateSystemDefaultDevice();if (nil != device) {registerMetalOps();
#ifdef MNN_SUPPORT_RENDERregisterMetalRenderOps();
#endifMNNInsertExtraRuntimeCreator(MNN_FORWARD_METAL, new MetalRuntimeCreator(device), false);} else {MNN_ERROR("Init Metal Error\n");}
}

1.3 RuntimeFactory::create

Runtime* RuntimeFactory::create(const Backend::Info& info) {auto creator = MNNGetExtraRuntimeCreator(info.type);if (nullptr == creator) {MNN_PRINT("Create Runtime Failed because no creator for %d\n", info.type);return nullptr;}// 调用具体 RuntimeCreator,如 VulkanRuntimeCreator,MetalRuntimeCreator,GLRuntimeCreatorauto runtime = creator->onCreate(info);if (nullptr == runtime) {MNN_PRINT("Create Runtime failed, the creator return nullptr, type = %d\n", info.type);}return runtime;
}

1.3.1 VulkanRuntimeCreator

    若 RuntimeFactory::createinfo.typeMNN_FORWARD_VULKAN,则 creator->onCreate(info) 实际调用的是 VulkanRuntimeCreator::onCreate 函数。

// source/backend/vulkan/runtime/VulkanRuntime.cpp
class VulkanRuntimeCreator : public RuntimeCreator {
public:virtual Runtime* onCreate(const Backend::Info& info) const {// 初始化 Vulkan 库,获取相应的 API 函数if (InitVulkan()) {if (_testVulkan()) {// 创建 Vulkan 运行时return new VulkanRuntime(info);}}return nullptr;}virtual bool onValid(Backend::Info& info) const {return true;}
};static bool gResistor = []() {MNNInsertExtraRuntimeCreator(MNN_FORWARD_VULKAN, new VulkanRuntimeCreator, false);return false;
}();
}

1.3.2 VulkanRuntimeCreator

    若 RuntimeFactory::createinfo.typeMNN_FORWARD_CPU,则 creator->onCreate(info) 实际调用的是 CPURuntimeCreator ::onCreate 函数。

class CPURuntimeCreator : public RuntimeCreator {
public:virtual Runtime* onCreate(const Backend::Info& info) const override {return new CPURuntime(info);}
};#ifdef MNN_SUPPORT_BF16
extern void registerBF16Backend();
#endif
#ifdef ENABLE_ARMV82
extern void registerArm82RuntimeCreator();
#endif
void registerCPURuntimeCreator() {CPUBackend::initCreatorMap();registerCPUOps();
#ifdef MNN_SUPPORT_BF16registerBF16Backend();
#endif
#ifdef MNN_USE_ARMV82registerArm82RuntimeCreator();
#endif// TODO: Merge _initCoreFunction MNNFunctionInit and cpuinfo_arm_initMNNCoreFunctionInit();MNNInsertExtraRuntimeCreator(MNN_FORWARD_CPU, new CPURuntimeCreator);
};

1.4 ScheduleConfig

// project/android/demo/app/includes/MNN/Interpreter.hpp
/** session schedule config */
struct ScheduleConfig {/** which tensor should be kept */std::vector<std::string> saveTensors;/** forward type */MNNForwardType type = MNN_FORWARD_CPU;/** number of threads in parallel */int numThread = 4;/** subpath to run */struct Path {std::vector<std::string> inputs;std::vector<std::string> outputs;enum Mode {/*** Op Mode* - inputs means the source op, can NOT be empty.* - outputs means the sink op, can be empty.* The path will start from source op, then flow when encounter the sink op.* The sink op will not be compute in this path.*/Op = 0,/*** Tensor Mode (NOT supported yet)* - inputs means the inputs tensors, can NOT be empty.* - outputs means the outputs tensors, can NOT be empty.* It will find the pipeline that compute outputs from inputs.*/Tensor = 1};/** running mode */Mode mode = Op;};Path path;/** backup backend used to create execution when desinated backend do NOT support any op */MNNForwardType backupType = MNN_FORWARD_CPU;/** extra backend config */BackendConfig* backendConfig = nullptr;
};

1.5 BackendConfig

// project/android/demo/app/includes/MNN/MNNForwardType.h
struct BackendConfig {enum MemoryMode {Memory_Normal = 0,Memory_High,Memory_Low};MemoryMode memory = Memory_Normal;enum PowerMode {Power_Normal = 0,Power_High,Power_Low};PowerMode power = Power_Normal;enum PrecisionMode {Precision_Normal = 0,Precision_High,Precision_Low};PrecisionMode precision = Precision_Normal;/** user defined context */void* sharedContext = nullptr;
};

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/755780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

飞天使-k8s知识点27-kubernetes温故知新2-deployment

文章目录 RC和RS无状态应用管理 deployment有状态应用statefulSetdaemonSet RC和RS RC不会使用在生产环境 RS 比RC 多了标签选择器 &#xff0c;RS 用deployment管理&#xff0c;用于容器编排无状态应用管理 deployment apiVersion: apps/v1 kind: Deployment metadata:name:…

C# Onnx Yolov9 Detect 物体检测

目录 介绍 效果 项目 模型信息 代码 下载 C# Onnx Yolov9 Detect 物体检测 介绍 yolov9 github地址&#xff1a;https://github.com/WongKinYiu/yolov9 Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information …

jQuery遍历DOM元素

自下而上(获取父节点) 通过jQuery对象可以向上遍历DOM树 parent()返回被选元素的直接父元素。该方法只会向上一级对DOM 树进行遍历。返回要给jQuery对象parents([type]) 返回被选元素的祖先元素可传入字符串过滤类型&#xff0c;返回被选元素中为该类型的祖先元素 parentsUn…

IPD流程学习

集成开发的概念学习&#xff0c; IPD是把产品纳入经营的理念&#xff0c;分为两件事&#xff1a;1是做正确的事&#xff0c;2正确的事情怎么做 1、做正确的事&#xff0c; 市场调研&#xff0c;不是闭门造车需求管理&#xff0c;怎么把客户的需求转变成产品的开发需求&#…

构建Helm chart和chart使用管道与函数简介

目录 一.创建helm chart&#xff08;以nginx为例&#xff09; 1.通过create去创建模板 2.查看模板下的文件 3.用chart模版安装nginx 二.版本更新和回滚问题 1.使用upgrade -f values.yaml或者命令行--set来设置 2.查看历史版本并回滚 三.helm模板内管道和函数 1.defau…

软件工程-第6章 面向对象方法UML

UML是一种图形化语言&#xff0c;简称画图。 6.1 表达客观事物的术语 6.2 表达关系的术语 1.关联 表达关联语义相关术语&#xff1a;关联名、导航、角色、可见性、多重性、限定符、聚合、组合。 2.泛化 3.细化 6.3 组织信息的一种通用机制-包 6.4 模型表达工具 一个用况图包含6…

Springboot+Redis:实现缓存 减少对数据库的压力

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

【Vue3】走进Pinia,学习Pinia,使用Pinia

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

杰发科技AC7801——读取Flash数据做CRC校验

查看Keil的编译结果发现总共6160个字节。计算结果如下&#xff0c; 代码如下 #include "ac780x_crc.h" #include "ac780x.h" #include "ac780x_debugout.h" #include "string.h" #include "ac780x_eflash.h"#define TestSi…

Leetcode 239 滑动窗口最大值

题目信息 LeetoCode地址: . - 力扣&#xff08;LeetCode&#xff09; 题目理解 题意是很好理解的&#xff0c;一个固定长度(k)的滑块从一个数组的左端一步一步向右滑&#xff0c;然后挑出滑块盖住的那些数字中最大的&#xff0c;组成的数组就是结果。 难点在于&#xff0c;…

html5cssjs代码 026 canvas示例

html5&css&js代码 026 canvas示例 一、代码二、解释 这段HTML代码定义了一个页面&#xff0c;其中包含一个容器和一个canvas元素。通过JavaScript代码&#xff0c;使用canvas绘制了一个矩形、一个填充了颜色的矩形、一个文本以及一个圆形。 一、代码 <!DOCTYPE ht…

nodejs基于vue超市信息管理系统flask-django-php

互联网的快速发展&#xff0c;使世界各地的各种组织的管理方式发生了根本性的变化&#xff0c;我国政府、企业等组织在上个世纪90年代就已开始考虑使用互联网来管理信息。由于以前的种种因素&#xff0c;比如网络的普及率不高&#xff0c;用户对它的认知度不够&#xff0c;以及…

Zenlayer如何将万台设备监控从Zabbix迁移到Flashcat

作为全球首家以超连接为核心的云服务商&#xff0c;Zenlayer 致力于将云计算、内容服务和边缘技术融合&#xff0c;为客户提供全面的解决方案。通过构建可靠的网络架构和高效的数据传输&#xff0c;Zenlayer 帮助客户实现更快速、更可靠的连接&#xff0c;提升用户体验和业务效…

局域网内监控别人电脑屏幕

想要在局域网内可以监控他人的屏幕的方法&#xff0c;无疑是使用一款&#xff0c;屏幕监控软件了。 什么是局域网屏幕监控软件&#xff1f; 局域网屏幕监控软件是一种专门用于监控局域网内电脑屏幕活动的软件工具。它通常集成在局域网监控系统中&#xff0c;能够实时捕捉和记…

使用Java JDBC连接数据库

在Java应用程序中&#xff0c;与数据库交互是一个常见的任务。Java数据库连接&#xff08;JDBC&#xff09;是一种用于在Java应用程序和数据库之间建立连接并执行SQL查询的标准API。通过JDBC&#xff0c;您可以轻松地执行各种数据库操作&#xff0c;如插入、更新、删除和查询数…

2024蓝桥杯每日一题(递归)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一&#xff1a;有序分数 试题二&#xff1a;正则问题 试题三&#xff1a;带分数 试题四&#xff1a;约数之和 试题五&#xff1a;分形之城 试题一&#xff1a;有序分数 【题目描述】 【输入格…

@Builder用法

一.场景模拟Data两个缺点 假如有一结果api结果返回值的类Result&#xff0c;其在代码中频繁被使用&#xff1a; Data public class Result<T> {private int code;private String message;private T data;public Result(int code, String message, T data) {this.code …

AI换脸软件rope最新更新的蓝宝石中文版下载

rope换脸软件蓝宝石版下载地址&#xff1a;点击下载 最近AI软件非常的火爆&#xff0c;今天就给大家带来一个可以AI替换人脸的工具rope&#xff0c;得益于机器学习技术的不断发展&#xff0c;rope经过深度神经网络的无数次迭代优化&#xff0c;最终得出的模型可以自动学习和识…

如何在一个阶段中后期调整心态

在阶段中后期调整心态和自我鼓励的方法涉及心理调适、目标回顾、计划调整和积极心理暗示等多个层面。以下是一些建议&#xff1a; 回顾和调整目标&#xff1a; 回顾初始目标是否依然符合当前情境和自身需求&#xff0c;如有必要&#xff0c;适度调整目标使之更具可行性&#…

【商业成长】Ai 中英字幕:英伟达 NVIDIA GTC 黄仁勋——见证 AI 的变革时刻,听他分享塑造未来的 AI 突破!

英伟达官网&#xff1a;人工智能计算领域的领导者 | NVIDIA Ai 中英字幕 仅供学习使用&#xff0c;不得商用&#xff0c;侵删&#xff0c;感谢&#xff01; 【Ai 中英 舒适字幕】英伟达 NVIDIA GTC 黄仁勋&#xff1a;见证 AI 的变革时刻&#xff0c;听他分享塑造未来的 AI 突破…