- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
整个问题可以概括为我正在尝试复制调用system
(或fork
)的行为,但在 mpi 环境中。 (事实证明,你不能并行调用system
。)这意味着我有一个程序在许多节点上运行,每个节点上有一个进程,然后我希望每个进程调用一个外部程序(所以对于 n
个节点,我将运行外部程序的 n
个副本),等待所有这些副本完成,然后继续运行原始程序。
为了以并行环境中安全的方式实现这一点,我一直在使用MPI_COMM_SPAWN
和阻塞发送的组合。以下是我的实现的一些示例父程序和子程序(代码采用 Fortran 90,但语法与 C 程序类似):
父级.f90:
program parent
include 'mpif.h'
!usual mpi variables
integer :: size, rank, ierr
integer :: status(MPI_STATUS_SIZE)
integer MPI_COMM_CHILD, ri
integer tag
character *128 message
call MPI_Init(ierr)
call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
write(*, *) "I am parent on rank", rank, "of", size
call MPI_COMM_SPAWN('./child', MPI_ARGV_NULL, 1, MPI_INFO_NULL, 0, &
MPI_COMM_SELF, MPI_COMM_CHILD, MPI_ERRCODES_IGNORE, ierr)
write(*, *) "Parent", MPI_COMM_SELF, "child comm", MPI_COMM_CHILD
tag = 1
call MPI_RECV(message, 128, MPI_CHARACTER, 0, tag, MPI_COMM_CHILD,&
status, ierr)
write(*, *) "Parent", MPI_COMM_SELF, "child comm", MPI_COMM_CHILD,&
"!!!"//trim(message)//"!!!"
call mpi_barrier(mpi_comm_world, ierr)
call MPI_Finalize(ierr)
end program parent
子.f90:
program child
include 'mpif.h'
!usual mpi variables
integer :: size, rank, ierr, parent
integer :: status(MPI_STATUS_SIZE)
integer MPI_COMM_PARENT, psize, prank
integer tag
character *128 message
call MPI_init(ierr)
call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
call MPI_Comm_get_parent(MPI_COMM_PARENT)
call MPI_Comm_size(MPI_COMM_PARENT, psize, ierr)
call MPI_Comm_rank(MPI_COMM_PARENT, prank, ierr)
write(*, *) "I am child on rank", rank, "of", size, "with comm",&
MPI_COMM_WORLD, "and parent", MPI_COMM_PARENT,&
psize, prank
tag = 1
message = 'Hello Mom and/or Dad!'
call MPI_SEND(message, 128, MPI_CHARACTER, 0, tag, MPI_COMM_PARENT, ierr)
call mpi_barrier(MPI_COMM_WORLD, ierr)
call MPI_Finalize(ierr)
end program child
使用 ifort 16.0.3 和 intel openmpi 1.10.3 进行编译并使用(例如)mpirun -np 4 ./parent
运行后,我得到以下输出:
I am parent on rank 0 of 4
I am parent on rank 1 of 4
I am parent on rank 2 of 4
I am parent on rank 3 of 4
Parent 1 child comm 3
I am child on rank 0 of 1 with comm 0 and parent
3 1 0
Parent 1 child comm 3 !!!Hello Mom and/or Dad!!!!
Parent 1 child comm 3
I am child on rank 0 of 1 with comm 0 and parent
3 1 0
Parent 1 child comm 3
I am child on rank 0 of 1 with comm 0 and parent
3 1 0
Parent 1 child comm 3 !!!Hello Mom and/or Dad!!!!
Parent 1 child comm 3 !!!Hello Mom and/or Dad!!!!
Parent 1 child comm 3
I am child on rank 0 of 1 with comm 0 and parent
3 1 0
Parent 1 child comm 3 !!!Hello Mom and/or Dad!!!!
这本质上就是我想要的行为。据我了解,通过使用 maxprocs=1
、root=0
和 MPI_COMM_SELF
作为父通信器,我告诉每个父进程生成 1 个仅了解其父级的子级,因为它是 MPI_COMM_SELF
范围的 root=0
(也是唯一的进程)。然后我要求它等待来自子进程的消息。子进程获取父进程的 (SELF
) 通信器,并将其消息发送到只能是父进程的 root=0
。所以这一切都很好。
我希望每个进程都能在自己的节点上生成其子进程。我运行的 mpi 进程数等于节点数,当我调用 mpirun
时,我使用标志 --map-by node
来确保一个进程每个节点。我希望子进程能够以某种方式继承它,否则不知道任何其他节点的存在。但我看到的行为是非常不可预测的,一些进程分布在节点上,而其他节点(特别是主 mpi 进程的 root=0
)上有很多堆积。
是否有某种方法可以确保将进程绑定(bind)到父进程的节点?也许通过我可以传递给 MPI_COMM_SPAWN
的 MPI_Info
选项?
最佳答案
Open MPI 中的每个 MPI 作业都以分布在一台或多台主机上的一组插槽开始。这些槽由初始 MPI 进程和作为子 MPI 作业的一部分生成的任何进程使用。在您的情况下,可以在类似于以下内容的主机文件中提供主机:
host1 slots=2 max_slots=2
host2 slots=2 max_slots=2
host3 slots=2 max_slots=2
...
slots=2 max_slots=2
将 Open MPI 限制为每个主机仅运行两个进程。
初始作业启动应为每个主机指定一个进程,否则 MPI 将使用父作业中的进程填充所有槽位。 --map-by ppr:1:node
可以解决这个问题:
mpiexec --hostfile hosts --map-by ppr:1:node ./parent
现在的问题是,随着新的子作业的产生,Open MPI 将继续以先到先得的方式填充插槽,因此不能保证子进程将在与其父进程相同的主机上启动。要强制执行此操作,请按照 Gilles Gouaillardet 的建议将 info
参数的 host
键设置为 MPI_Get_processor_name
返回的主机名:
character(len=MPI_MAX_PROCESSOR_NAME) :: procn
integer :: procl
integer :: info
call MPI_Get_processor_name(procn, procl, ierr)
call MPI_Info_create(info, ierr)
call MPI_Info_set(info, 'host', trim(procn), ierr)
call MPI_Comm_spawn('./child', MPI_ARGV_NULL, 1, info, 0, &
...
您的 MPI 作业可能会中止并显示以下消息:
--------------------------------------------------------------------------
All nodes which are allocated for this job are already filled.
--------------------------------------------------------------------------
这基本上意味着请求的主机要么已满(所有插槽已满)或者该主机不在原始主机列表中,因此没有分配插槽它。前者显然不是这种情况,因为主机文件为每个主机列出了两个插槽,而父作业仅使用一个插槽。 host
键值对中提供的主机名必须与初始主机列表中的条目完全匹配。通常情况下,主机文件仅包含不合格的主机名,如第一段中的示例主机文件,而如果设置了域部分,则 MPI_Get_processor_name
返回 FQDN,例如 node1。 some.domain.local
、node2.some.domain.local
等。解决方案是在主机文件中使用 FQDN:
host1.example.local slots=2 max_slots=2
host2.example.local slots=2 max_slots=2
host3.example.local slots=2 max_slots=2
...
如果分配是由 SLURM 等资源管理器提供的,则解决方案是转换 MPI_Get_processor_name
的结果以匹配 RM 提供的结果。
请注意 MPI_Comm_spawn
的手册页列出了 add-host
键,该键应该将值中的主机名添加到作业的主机列表中:
add-host char * Add the specified host to the list of
hosts known to this job and use it for
the associated process. This will be
used similarly to the -host option.
根据我的经验,这从未起作用(使用 Open MPI 至 1.10.4 进行测试)。
关于控制 MPI_COMM_SPAWN 的节点映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47743425/
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我正在尝试将图像拖放到div上。图像没有被拖到div上并给出以下错误 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': pa
我正在 android studio 中创建内部构建 AR 导航。我正在寻找一种方法将 anchor 与其他 anchor 或 anchor 节点/节点“连接”起来。我不确定使用哪一个。基于我将强制用
我在 Hive 上运行一些作业:首先是 4 节点,然后是 2 节点。令我惊讶的是,我的 2 节点性能比我的 4 节点更好。 首先,我在一个 4 节点(4 个事件节点)上运行查询,然后关闭 2 个节点(
我有 Node* current ,我在其中存储指向列表“顶部”当前节点的指针。当我将一个新节点设置为当前节点时,出现错误: '=' : cannot convert from 'CircularDo
我是 dcos Mesos 的新手,在本地 Ubuntu 机器上安装了 dc os。 我可以查看 dcos 仪表板。 但我无法使用 dcos node ssh --master-proxy --lea
在 JavaFX 中,是否有类似 setLayout(); 的东西?或 setBounds(); ? 例如,我想将按钮定位到我想要的位置。 最佳答案 JavaFX 场景图上的所有内容都是 Node .
我正在开发一个 JavaFX 应用程序,其中我开发的类(从 javafx.scene.Parent 扩展)是根据用户在 ListView 控件中单击的条目动态创建的。 只是要清楚这个节点,它不是使用像
我正在尝试为节点-边缘关系创建一个类图,因为它可以在有向图中找到。我想传达的是,Nodes 引用了 Edges,Edges 也引用了 Nodes。每个 Edge 都恰好需要两个 Node(源和目标)。
在mapreduce作业期间,单个任务将在随机节点上运行,是否有任何方法限制应在其中运行任务的节点? 最佳答案 Hadoop不会选择节点来随机运行任务。考虑到数据局部性,否则将有很多网络开销。 任务与
有什么区别: a) nodetool 重建 b) nodetool 修复 [-pr] 换句话来说,各个命令到底是做什么的? 最佳答案 nodetool重建:类似于引导过程(当您向集群添加新节点时),但
我已将第一个 OneToMany 关系添加到我的 hibernate 3.6.10 项目中。这是一个类: /** * */ package com.heavyweightsoftware.leal
是否有可能找到正在监听触发当前函数的事件的元素? 在下面的代码中,event.target 返回 #xScrollPane 和 event.currentTarget 和 event 的最低子节点.f
我正在尝试覆盖我数据库中的一些数据。结构很简单,就是: recipes { user_1{ recipe_1{data} recipe_2{data} } user_2{
我使用 setInterval 来运行该函数,但它会多次执行函数 2... 如何在输入中插入一个值后执行函数 第一个输入与其余输入的距离不同 如何在插入 val(tab 选项)后将插入从 1 个输入移
我不知道代码有什么问题,但在 visual studio 中不断收到这些错误消息。 Error 18 error C1903: unable to recover from previous e
我正在尝试从其类中获取 SharePoint 搜索导航节点的对象。 var nodes = $("div.ms-qSuggest-listItem"); 我正在获取节点对象,现在想要获取“_promp
D:\nodeP>node main.js module.js:327 抛出错误; ^ 错误:在 Function.Module 的 Function.Module._resolveFilename
struct node{ int key, prior, cnt, val; node *l, *r; node(){} node(int nkey) : key(nkey),
我有以下代码使用迭代器将项目插入双链表。这就是我们被要求这样做的方式。代码有效,但问题是我有 24 字节的绝对内存泄漏。 NodeIterator insert(NodeIterator & itrP
我是一名优秀的程序员,十分优秀!