onnxruntime的C接口,位置为include/onnxruntime/core/session/onnxruntime_c_api.h。

上述文件包含了C函数的声明,对应的实现在onnxruntime/core/session/onnxruntime_c_api.cc内。

与定义的时候类似,实现的函数使用宏ORT_API_STATUS_IMPL进行定义。

一、OrtEnv

OrtEnv在onnxruntime_c_api.h中声明,通过宏ORT_RUNTIME_CLASS(Env)。

在头文件中,只会用到OrtEnv的指针,不会用到实现,因此不会发生编译错误。

OrtEnv的实现在onnxruntime_c_api.cc中,这里的实现用的是class,但是声明为struct。

这在C++中是允许的,因为C++不区分class和struct,两者只有默认访问权限的区别。

// struct与class混用
#include <iostream>
struct A;
void my_print(A* a);
class A {
public:
void print() {
std::cout << "Hello\n";
}
};
void my_print(A* a) {
a->print();
};
int main() {
A x;
my_print(&x);
return 0;
}

OrtEnv实现了一个单例类,主要负责日志和会话间共享分配器的管理。

OrtEnv实际上只是对onnxruntime::Environment的简单封装,日志管理和分配器的管理都在onnxruntime::Environment中实现。

OrtEnv相当于一个中间层,或者说,充当C接口与C++实现的兼容的中间类。

onnxruntime的C接口中的,其他一些类也与OrtEnv类相似。

引用计数

可以注意到,这里的OrtEnv作为一个单例,与通常设计模式的单例,稍有区别。

主要添加了一个引用计数ref_count_。

当GetInstance()时,如果还没有创建局部静态对象OrtEnv,那么创建一个OrtEnv,用p_instance_保存。

如果已经创建了p_instance_,那么只要ref_count_加一,返回p_instance_。

Release()释放时,检查ref_count_即可。

线程间互斥锁

OrtEnv是被全局共享的,不同的会话session在不同的线程。因此需要mutex。

onnxruntime使用OrtMutex代替std::mutex。说明如下,

// Q: Why OrtMutex is better than std::mutex
// A: OrtMutex supports static initialization but std::mutex doesn't. Static initialization helps us prevent the "static
// initialization order problem". // Q: Why std::mutex can't make it?
// A: VC runtime has to support Windows XP at ABI level. But we don't have such requirement. // Q: Is OrtMutex faster than std::mutex?
// A: Sure

二、onnxruntime::Environment

前面说到OrtEnv只是对onnxruntime::Enviroonment的简单封装。

Environment里面主要包含了,1个日志管理器,1个会话间共享的分配器,2个线程池(分别用于Op内和Op间)。

Environment类通过静态函数Create去创建自己,类似工厂方法;而不是直接在构造函数内进行初始化。

这样可以更好的控制对象的初始化,在初始化过程做更多的操作。在Initialize函数内实现。

Initialize函数内,主要做了3件事。

1. 传入一个日志管理器。

2. 创建2个线程池。

3. 根据不同的编译选项,注册各组的Op

onnxruntime源码解析之C接口实现的更多相关文章

  1. identityserver4源码解析_2_元数据接口

    目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4 ...

  2. identityserver4源码解析_3_认证接口

    目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4 ...

  3. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...

  4. Java基础——集合源码解析 List List 接口

    今天我们来学习集合的第一大体系 List. List 是一个接口,定义了一组元素是有序的.可重复的集合. List 继承自 Collection,较之 Collection,List 还添加了以下操作 ...

  5. IdentityServer4源码解析_4_令牌发放接口

    目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4 ...

  6. IdentityServer4源码解析_5_查询用户信息接口

    协议简析 UserInfo接口是OAuth2.0中规定的需要认证访问的接口,可以返回认证用户的声明信息.请求UserInfo接口需要使用通行令牌.响应报文通常是json数据格式,包含了一组claim键 ...

  7. IdentityServer4源码解析_1_项目结构

    目录 IdentityServer4源码解析_1_项目结构 IdentityServer4源码解析_2_元数据接口 IdentityServer4源码解析_3_认证接口 IdentityServer4 ...

  8. Spring-cloud & Netflix 源码解析:Eureka 服务注册发现接口 ****

    http://www.idouba.net/spring-cloud-source-eureka-client-api/?utm_source=tuicool&utm_medium=refer ...

  9. MyBatis源码解析【7】接口式编程

    前言 这个分类比较连续,如果这里看不懂,或者第一次看,请回顾之前的博客 http://www.cnblogs.com/linkstar/category/1027239.html 修改例子 在我们实际 ...

  10. 2) 接口规范 原生django接口、单查群查 postman工具 CBV源码解析

    内容了解 """ .接口:什么是接口.restful接口规范 .CBV生命周期源码 - 基于restful规范下的CBV接口 .请求组件.解析组件.响应组件 .序列化组件 ...

随机推荐

  1. Python批量读取HDF多波段栅格数据并绘制像元直方图

      本文介绍基于Python语言gdal模块,实现多波段HDF栅格图像文件的读取.处理与像元值可视化(直方图绘制)等操作.   另外,基于gdal等模块读取.tif格式栅格图层文件的方法可以查看Pyt ...

  2. LeetCode-689 三个无重叠子数组的最大和

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays 题目描述 ...

  3. 【调试】ftrace(一)基本使用方法

    简介 Ftrace是Linux Kernel的官方tracing系统,支持Function trace.静态tracepoint.动态Tracepoint的跟踪,还提供各种Tracer,用于统计最大i ...

  4. nginx中多ip多域名多端口配置

    1.Nginx中多IP配置: server { listen 80; server_name 192.168.15.7; location / { root /opt/Super_Marie; ind ...

  5. Linux操作命令(一)1.ls命令 2.cd命令 3.pwd命令

    1.ls 命令 ls 命令就是 list 的缩写, ls 用来打印出当前目录的清单. 参数 描述 -a –all 列出目录下的所有文件,包括以 . 开头的隐含文件 -l 除了文件名之外,还将文件的权限 ...

  6. RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!

    错误原因:数据有的在cpu上有的在gpu上debug:断点到出错位置查看类型,或者打印`x.is_cuda`查看修改:将cpu上的数据通过`.to(device)`加载到gpu上

  7. web实践学习2

    20201303张奕博 2023.1.25 创建浮岛 如以下 两幅图所示,整个浮岛造型是一个四棱椎,整体分为四部分,顶部是由地面和河流构成的四方体.底部三块是倒置的三角.生成这些三维模型的其实也并没有 ...

  8. JavaWeb 之 Http

    0x01:为什么会有Http? 在 HTTP 建立之初,主要目的就是为了将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器 0x02:什么是Http? http是一个简单的,请求-响应 ...

  9. LINUX 简单命令学习总结

    命令知识点大纲: 一.默认目录的简单介绍 1)/root/用户名:如/root/test1,该目录为普通用户的家目录,所有用户创建后都能在该目录下找到自己对应的目录信息 /etc:该目录为配置文件存放 ...

  10. Vue项目中怎样把参数(对象)转成formdata传给后端? 封装函数 亲测有效

    普通传参格式如下: 想要的formData参数格式如下: 首先封装参数(对象)转换为formData格式 getFormData(object) { const formData = new Form ...