OpenMPI源码剖析3:try_kill_peers 和 ompi_rte_abort 函数
接着上一篇的疑问,我们说道,会执行 try_kill_peers 函数,它的函数定义在 ompi_mpi_abort.c 下:
// 这里注释也说到了,主要是杀死在同一个communicator的进程(不包括自己)
/*
* Local helper function to build an array of all the procs in a
* communicator, excluding this process.
*
* Killing a just the indicated peers must be implemented for
* MPI_Abort() to work according to the standard language for
* a 'high-quality' implementation.
*
* It would be nifty if we could differentiate between the
* abort scenarios (but we don't, currently):
* - MPI_Abort()
* - MPI_ERRORS_ARE_FATAL
* - Victim of MPI_Abort()
*/
// 调用时传入了对应通信子
static void try_kill_peers(ompi_communicator_t *comm,
int errcode)
{
// 1. 第一部分: 给 ompi_process_name_t 指针申请空间,得到进程个数
int nprocs;
ompi_process_name_t *procs; nprocs = ompi_comm_size(comm);
/* ompi_comm_remote_size() returns 0 if not an intercomm, so
this is safe */
nprocs += ompi_comm_remote_size(comm); procs = (ompi_process_name_t*) calloc(nprocs, sizeof(ompi_process_name_t));
if (NULL == procs) {
/* quick clean orte and get out */
ompi_rte_abort(errno, "Abort: unable to alloc memory to kill procs");
} // 2. 第二部分: 将进程放入数组中
/* put all the local group procs in the abort list */
int rank, i, count;
rank = ompi_comm_rank(comm); //这里可以获取到自己在该 communicator 中的 rank————疑问1
for (count = i = 0; i < ompi_comm_size(comm); ++i) {
if (rank == i) {
/* Don't include this process in the array */
--nprocs;
} else {
assert(count <= nprocs);
procs[count++] =
*OMPI_CAST_RTE_NAME(&ompi_group_get_proc_ptr(comm->c_remote_group, i, true)->super.proc_name);
}
} // 3. 第三部分: 远程的 group 进程也放入数组中
/* if requested, kill off remote group procs too */
for (i = 0; i < ompi_comm_remote_size(comm); ++i) {
assert(count <= nprocs);
procs[count++] =
*OMPI_CAST_RTE_NAME(&ompi_group_get_proc_ptr(comm->c_remote_group, i, true)->super.proc_name);
} // 4. 第四部分: 杀死进程
if (nprocs > 0) {
ompi_rte_abort_peers(procs, nprocs, errcode);
} /* We could fall through here if ompi_rte_abort_peers() fails, or
if (nprocs == 0). Either way, tidy up and let the caller
handle it. */
free(procs);
}
这个时候,就得去看看 ompi_rte_abort_peers(procs, nprocs, errcode) 函数的定义,
它在 rte_orte.h 中其实是一个宏定义:
#define ompi_rte_abort_peers(a, b, c) orte_errmgr.abort_peers(a, b, c)
orte_errmgr 是一个结构体对象,调用了abort_peers成员函数,最后在 errmgr.h 中找到了 orte_errmgr 对象:
/*
* Module Structure
*/
struct orte_errmgr_base_module_2_3_0_t {
/** Initialization Function */
orte_errmgr_base_module_init_fn_t init;
/** Finalization Function */
orte_errmgr_base_module_finalize_fn_t finalize; orte_errmgr_base_module_log_fn_t logfn;
orte_errmgr_base_module_abort_fn_t abort;
orte_errmgr_base_module_abort_peers_fn_t abort_peers;
};
typedef struct orte_errmgr_base_module_2_3_0_t orte_errmgr_base_module_2_3_0_t;
typedef orte_errmgr_base_module_2_3_0_t orte_errmgr_base_module_t;
ORTE_DECLSPEC extern orte_errmgr_base_module_t orte_errmgr; //这是一个导出的extern全局变量
再顺便附上该结构体中的函数的定义,也在 rte_orte.h 头文件中:
/*
* Framework Interfaces
*/
/**
* Module initialization function.
*
* @retval ORTE_SUCCESS The operation completed successfully
* @retval ORTE_ERROR An unspecifed error occurred
*/
typedef int (*orte_errmgr_base_module_init_fn_t)(void); /**
* Module finalization function.
*
* @retval ORTE_SUCCESS The operation completed successfully
* @retval ORTE_ERROR An unspecifed error occurred
*/
typedef int (*orte_errmgr_base_module_finalize_fn_t)(void); /**
* This is not part of any module so it can be used at any time!
*/
typedef void (*orte_errmgr_base_module_log_fn_t)(int error_code, char *filename, int line); /**
* Alert - self aborting
* This function is called when a process is aborting due to some internal error.
* It will finalize the process
* itself, and then exit - it takes no other actions. The intent here is to provide
* a last-ditch exit procedure that attempts to clean up a little.
*/
typedef void (*orte_errmgr_base_module_abort_fn_t)(int error_code, char *fmt, ...)
__opal_attribute_format_funcptr__(__printf__, 2, 3); /**
* Alert - abort peers
* This function is called when a process wants to abort one or more peer processes.
* For example, MPI_Abort(comm) will use this function to terminate peers in the
* communicator group before aborting itself.
*/
typedef int (*orte_errmgr_base_module_abort_peers_fn_t)(orte_process_name_t *procs,
orte_std_cntr_t num_procs,
int error_code);
这里呢,对 杀死进程 这一块的探索呢,就先到此了————这里已经知道,接下来的步骤就是遍历数组,杀死进程,
这里留下 疑问2: orte_errmgr 这个 orte_errmgr_base_module_2_3_0_t 对象是在哪里初始化的?它的函数在哪里赋值了?我猜是在初始化MPI_Init()的过程中
上一篇文章,还有一个 ompi_rte_abort 函数,在 rte.h 中的注释说明有提及:
* (d) Error handling objects and operations
* 1. void ompi_rte_abort(int err_code, char *fmt, ...) - Abort the current
* process with the specified error code and message.
* 2. int ompi_rte_abort_peers(ompi_process_name_t *procs, size_t nprocs) -
* Abort the specified list of peers
* 3. OMPI_ERROR_LOG(rc) - print error message regarding the given return code
也就是说,ompi_rte_abort 这个函数就是 abort 自身进程了。
那么,我们就把这2个函数的大概交代清楚了。 在 rte.h 这个头文件中,我们还找到了一个比较有价值的注释说明。这个将会留在下一篇文章中说明。
重复一下本文留下的疑点:
1. ompi_comm_rank(comm) 这个函数
2. orte_errmgr 这个 orte_errmgr_base_module_2_3_0_t 对象是在哪里初始化的?
OpenMPI源码剖析3:try_kill_peers 和 ompi_rte_abort 函数的更多相关文章
- OpenMPI源码剖析1:MPI_Init初探
OpenMPI的底层实现: 我们知道,OpenMPI应用起来还是比较简单的,但是如果让我自己来实现一个MPI的并行计算,你会怎么设计呢?————这就涉及到比较底层的东西了. 回想起我们最简单的代码,通 ...
- c++ stl源码剖析学习笔记(一)uninitialized_copy()函数
template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...
- OpenMPI源码剖析:网络通信原理(二) 如何选择网络协议?
因为比较常用的是 TCP 协议,所以在 opal/mca/btl/tcp/btl_tcp.h 头文件中找到对应的 struct mca_btl_tcp_component_t { mca_btl_ba ...
- OpenMPI源码剖析2:ompi_mpi_errors_are_fatal_comm_handler函数
上一篇文章说道,初始化失败会有一个函数调用: ompi_mpi_errors_are_fatal_comm_handler(NULL, NULL, message); 所以这里简单地进入了 ompi_ ...
- STL源码剖析之list的sort函数实现
SGI STL的list的函数的实现源码大致如下: //list 不能使用sort函数,因为list的迭代器是bidirectional_iterator, 而sort //sort函数要求rand ...
- OpenMPI源码剖析:网络通信原理(一)
MPI中的网络通信的原理,需要解决以下几个问题: 1. MPI使用什么网络协议进行通信? 2.中央数据库是存储在哪一台机器上? 3.集群中如果有一台机器挂掉了是否会影响其他机器? 参考: https: ...
- OpenMPI源码剖析4:rte.h 头文件的说明信息
上一篇文章中说道,我们在 rte.h 中发现了有价值的说明: 我们一块一块来分析,首先看到第一块,关于 Process name Object: * (a) Process name objects ...
- 【Opencv 源码剖析】 一、 create函数
1. inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows) { initEmpty();//将data.cols.row ...
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
随机推荐
- 基于VC++的WinCE网口通信
基于VC++的WinCE网口通信 WinCE下的网络编程与Windows下的非常类似,只是个别API函数有所不同.同样分为UDP和TCP两种,UDP就是无连接的通信,通过“用户数据报协议”(UDP)来 ...
- 课时25.a标签基本使用(掌握)
什么是a标签? 我们打开百度或者淘宝网页,观察任何一个超链接都会发现它有如下特质: 有下划线 移上去有小手指 可以点击 a标签的作用:就是用于控制页面与页面之间跳转的 a标签的格式:<a hre ...
- css左固定右自适应常用方法
下面是几种方法的公用部分(右自适应也是一样的,换一下方向) html: <div class="demo"> <div class="sidebar&q ...
- php 当不确定用户输入的是浮点 还是整数 还是字符串时
$price = (floatval($price))?intval(floatval($price)*100)/100:0;
- CRT7.3.1版本安装步骤
工具: Setup.exe安装程序 keygen.exe注册机 zwt.nfo 查看电脑信息(主要看自己电脑是x86还x64版本) 安装步骤(所有程序尽量以管理员身份启动) 1.安装SecureCRT ...
- 谷歌浏览器添加flash白名单
69以前的版本: 打开 chrome://settings/content/flash 上图中应该有一个"添加"选项 , 依次输入: *.]com [*.]net [*.]org ...
- 支付宝H5、APP支付服务端的区别(php)
php支付宝H5和APP支付1.准备工作需要前往 蚂蚁金服开放平台申请https://openhome.alipay.com/developmentDocument.htm 2.大致流程1.用户添加商 ...
- Set的源码分析
Set的内部实现其实是一个Map.即HashSet的内部实现是一个HashMap,TreeSet的内部实现是一个TreeMap,LinkedHashSet的内部实现是一个LinkedHashMap. ...
- Struts2+Datagrid表格显示(可显示多表内容)
概述 最近学到EasyUI的Datagrid数据网格,然后就做了一个小例子,中间层利用Struts2来完成,DAO层用的是Hibernate. 数据库 数据库涉及到stuednt(name,noid, ...
- Spark运行模式_local(本地模式)
本地运行模式 (单机) 该模式被称为Local[N]模式,是用单机的多个线程来模拟Spark分布式计算,直接运行在本地,便于调试,通常用来验证开发出来的应用程序逻辑上有没有问题. 其中N代表可以使用N ...