HPX入门教程 假设您使用的是PBS或slurm.这些在HPC社区中可能很常见,但作为开发人员,我更习惯这里的场景是你可以安装的几台机器.
现在不是很明显是否需要像slurm这样的调度程序来利用多个物理机器或者只是方便管理集群.
我知道你可以在运行HPX应用程序时使用-l标志模拟多个地点(例如参见这个问题)我想要的是在2个节点上运行相同的应用程序并让它们相互通信.
告诉HPX需要的最低要求是:
这是另一台具有此IP地址的计算机,您可以向其发送任务吗?
或者,达到这个阶段的最低浆液配置是什么?
安装slurm很容易找到一个简单的2节点示例.虽然这个链接到播客可能会有所帮助
我还假设HPX的parcel端口只能在TCP上工作而无需安装任何额外的东西(例如MPI).它是否正确?
更新 我觉得我越来越近但我仍然缺少一些东西.首先我使用的是hello_world示例.难道它对于2节点测试来说太简单了吗?我希望类似的输出在同一节点上运行2个地点:
APP=$HPX/bin/hello_world
$APP --hpx:node 0 --hpx:threads 4 -l2 &
$APP --hpx:node 1 --hpx:threads 4
Run Code Online (Sandbox Code Playgroud)
样本输出:
hello world from OS-thread 2 on locality 0 hello world from OS-thread 0 on locality 0 hello world from OS-thread 1 on locality 1 hello world from OS-thread 3 on locality 1 hello world from OS-thread 2 on locality 1 hello world from OS-thread 1 on locality 0 hello world from OS-thread 0 on locality 1 hello world from OS-thread 3 on locality 0
但当我尝试远程时,两个进程都挂起:
$APP --hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx:hpx=$NODE0:7910 --hpx:threads 4 &
ssh $NODE1 $APP --hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx.hpx=$NODE1:7910 --hpx:threads 4
Run Code Online (Sandbox Code Playgroud)
我在两台机器上都打开了端口7910.$ APP的路径在两个节点上都是相同的.我不知道如何测试第二个进程是否与agas服务器通信.
如果我使用"--hpx:debug-agas-log = agas.log"和"--hpx:debug-hpx-log = hpx.log",我得到:
>cat hpx.log (T00000000/----------------.----/----------------) P--------/----------------.---- 14:18.29.042 [0000000000000001] [ERR] created exception: HPX(success) (T00000000/----------------.----/----------------) P--------/----------------.---- 14:18.29.042 [0000000000000002] [ERR] created exception: HPX(success)
在两台机器上.我不知道如何解释这一点.
我已经尝试了一些其他选项,例如--hpx:run-agas-server(我认为这可能暗示使用--hpx:agas =)
我也试过了
ssh $NODE1 $APP --hpx:nodes="$NODE0 $NODE1" &
$APP --hpx:nodes="$NODE0 $NODE1"
Run Code Online (Sandbox Code Playgroud)
正如其他人(现已删除?)的回答所说,没有运气.
更新2
我认为这可能是一个防火墙问题,即使防火墙被禁用似乎也没有发生.我已经尝试在系统调用上运行跟踪,但没有什么明显的:
echo "start server on agas master: node0=$NODE0"
strace -o node0.strace $APP \
--hpx:localities=2 --hpx:agas=$NODE0:7910 --hpx:hpx=$NODE0:7910 --hpx:threads 4 &
cat agas.log hpx.log
echo "start worker on slave: node1=$NODE1"
ssh $NODE1 \
strace -o node1.strace $APP \
--hpx:worker --hpx:agas=$NODE0:7910 --hpx.hpx=$NODE1:7910
echo "done"
exit 0
Run Code Online (Sandbox Code Playgroud)
node0.strace的尾部:
15:13:31 bind(7, {sa_family=AF_INET, sin_port=htons(7910), sin_addr=inet_addr("172.29.0.160")}, 16) = 0
15:13:31 listen(7, 128) = 0
15:13:31 ioctl(7, FIONBIO, [1]) = 0
15:13:31 accept(7, 0, NULL) = -1 EAGAIN (Resource temporarily unavailable)
...
15:13:32 mprotect(0x7f12b2bff000, 4096, PROT_NONE) = 0
15:13:32 clone(child_stack=0x7f12b33feef0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f12b33ff9d0, tls=0x7f12b33ff700, child_tidptr=0x7f12b33ff9d0) = 22394
15:13:32 futex(0x7ffe2c5df60c, FUTEX_WAIT_PRIVATE, 1, NULL) = 0
15:13:32 futex(0x7ffe2c5df5e0, FUTEX_WAKE_PRIVATE, 1) = 0
15:13:32 futex(0x7ffe2c5df4b4, FUTEX_WAIT_PRIVATE, 1, NULL
node1.strace的尾部:
6829 15:13:32 bind(7, {sa_family=AF_INET, sin_port=htons(7910), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
16829 15:13:32 listen(7, 128) = 0
16829 15:13:32 ioctl(7, FIONBIO, [1]) = 0
16829 15:13:32 accept(7, 0, NULL) = -1 EAGAIN (Resource temporarily unavailable)
16829 15:13:32 uname({sys="Linux", node="kmlwg-tddamstest3.grpitsrv.com", ...}) = 0
16829 15:13:32 eventfd2(0, O_NONBLOCK|O_CLOEXEC) = 8
16829 15:13:32 epoll_create1(EPOLL_CLOEXEC) = 9
16829 15:13:32 timerfd_create(CLOCK_MONOTONIC, 0x80000 /* TFD_??? */) = 10
16829 15:13:32 epoll_ctl(9, EPOLL_CTL_ADD, 8, {EPOLLIN|EPOLLERR|EPOLLET, {u32=124005464, u64=140359655238744}}) = 0
16829 15:13:32 write(8, "\1\0\0\0\0\0\0\0", 8) = 8
16829 15:13:32 epoll_ctl(9, EPOLL_CTL_ADD, 10, {EPOLLIN|EPOLLERR, {u32=124005476, u64=140359655238756}}) = 0
16829 15:13:32 futex(0x7fa8006f2d24, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fa8006f2d20, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
16830 15:13:32 ) = 0
16829 15:13:32 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP
16830 15:13:32 futex(0x7fa8076432f0, FUTEX_WAKE_PRIVATE, 1) = 0
16829 15:13:32 ) = 11
16830 15:13:32 epoll_wait(9,
16829 15:13:32 epoll_ctl(9, EPOLL_CTL_ADD, 11, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET, {u32=124362176, u64=140359655595456}}
16830 15:13:32 {{EPOLLIN, {u32=124005464, u64=140359655238744}}}, 128, -1) = 1
16829 15:13:32 ) = 0
16830 15:13:32 epoll_wait(9,
16829 15:13:32 connect(11, {sa_family=AF_INET, sin_port=htons(7910), sin_addr=inet_addr("172.29.0.160")}, 16
16830 15:13:32 {{EPOLLHUP, {u32=124362176, u64=140359655595456}}}, 128, -1) = 1
16830 15:13:32 epoll_wait(9,
如果我在master上执行一个strace -f,它的子进程循环执行如下操作:
22050 15:12:46 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 12
22050 15:12:46 epoll_ctl(5, EPOLL_CTL_ADD, 12, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET, {u32=2395115776, u64=140516545171712}}) = 0
22041 15:12:46 {{EPOLLHUP, {u32=2395115776, u64=140516545171712}}}, 128, -1) = 1
22050 15:12:46 connect(12, {sa_family=AF_INET, sin_port=htons(7910), sin_addr=inet_addr("127.0.0.1")}, 16
22041 15:12:46 epoll_wait(5,
22050 15:12:46 ) = -1 ECONNREFUSED (Connection refused)
22041 15:12:46 {{EPOLLHUP, {u32=2395115776, u64=140516545171712}}}, 128, -1) = 1
22050 15:12:46 futex(0x7fcc9cc20504, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1703, {1455808366, 471644000}, ffffffff
22041 15:12:46 epoll_wait(5,
22050 15:12:46 ) = -1 ETIMEDOUT (Connection timed out)
22050 15:12:46 futex(0x7fcc9cc204d8, FUTEX_WAKE_PRIVATE, 1) = 0
22050 15:12:46 close(12) = 0
22050 15:12:46 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 12
22050 15:12:46 epoll_ctl(5, EPOLL_CTL_ADD, 12, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET, {u32=2395115776, u64=140516545171712}}) = 0
22050 15:12:46 connect(12, {sa_family=AF_INET, sin_port=htons(7910), sin_addr=inet_addr("127.0.0.1")}, 16
22041 15:12:46 {{EPOLLHUP, {u32=2395115776, u64=140516545171712}}}, 128, -1) = 1
22050 15:12:46 ) = -1 ECONNREFUSED (Connection refused)
22041 15:12:46 epoll_wait(5,
22050 15:12:46 futex(0x7fcc9cc20504, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1705, {1455808366, 572608000}, ffffffff
22041 15:12:46 {{EPOLLHUP, {u32=2395115776, u64=140516545171712}}}, 128, -1) = 1
更新3
精明的你可能已经注意到在更新2中我偶然写了--hpx.hpx而不是--hpx:hpx.你猜怎么着!改变它修复它.所以从技术上来说,第一个答案是正确的,我只是愚蠢.我本来期望命令行选项解析器出错,但我想当你制作一个大规模并行运行时你不能拥有一切:).
感谢大家的帮助.
选项1:在网络层使用TCP/IP时(通常是默认值):
为了使HPX应用程序能够找到所有连接的节点,必须在批处理环境之外提供以下信息:
locality 0:
./yourapp --hpx:localities=2 --hpx:agas=node0:7910 --hpx:hpx=node0:7910
locality 1:
./yourapp --hpx:agas=node0:7910 --hpx:hpx=node1:7910 --hpx:worker
Run Code Online (Sandbox Code Playgroud)
这些节点的主机名在哪里node0,是一个(任意)TCP/IP端口.node17910
换一种说法,
--hpx:hpx=node0:7910的端口()以及活动全局地址空间(AGAS)引擎的主实例将侦听的端口(这将用于其他节点以建立初始连接) (--hpx:agas=node0:7910).您还指定整个2地区将连接(--hpx:localities=2).--hpx:hpx=node1:7910)上的传入消息的端口以及可在地点0(--hpx:agas=node0:7910)上到达主AGAS引擎的端口.您还指定此位置是工作者(而不是"控制台"),这是由--hpx:worker命令行选项完成的.请注意,所有这些选项都有一个字母的快捷键(--hpx:localities== -l,--hpx:hpx== -x,--hpx:agas== -a和--hpx:worker== -w)
您还可以在同一物理计算节点(或您的笔记本电脑)上运行多个位置.在这种情况下,指定一些东西有点乏味,例如:
./yourapp -l2 -0 &
./yourapp -1
Run Code Online (Sandbox Code Playgroud)
如果要在这种情况下使用扩展命令行选项,请确保用于的端口-x在同一节点上运行的所有位置都是唯一的.
选项2:使用MPI时(需要特殊的构建时间配置):
只需使用mpirun来执行您的应用程序.它将从批处理环境中获取设置,或者它将使用命令行选项来运行.例如:
mpirun -N1 -np2 ./yourapp
Run Code Online (Sandbox Code Playgroud)
这将在当前计算节点上运行应用程序的两个实例.
我无法对现有的答案发表评论,所以我将从@hkaiser的答案重复一些信息:在控制台/主节点上或我们通常认为的rank0你应该使用表格的命令
`bin/hello_world -l2 --hpx:agas=xx.xx.xx.AA:7910 --hpx:hpx=xx.xx.xx.AA:7910 `
Run Code Online (Sandbox Code Playgroud)
在您应该使用的工作节点上
`bin/hello_world --hpx:agas=xx.xx.xx.AA:7910 --hpx:hpx=xx.xx.xx.BB:7910 --hpx:worker`
Run Code Online (Sandbox Code Playgroud)
但重要的是,您使用的IP地址是由节点的外部网络返回的IP地址,而不是内部网络(在多个NIC/IP地址的情况下).为了确保我得到正确的地址,我通常会运行命令
ip route get 8.8.8.8 | awk 'NR==1 {print $NF}'
在每个节点上使用测试时的输出.
请注意,只有在手动启动作业而不使用mpirun或srun 启动作业时才需要此IP地址规范,因为这些命令将在批处理系统分配的节点上生成作业,并且HPX将正确处理通信内部.使用批处理系统时,无论如何都要手动启动作业(例如,在交互式shell中,您会发现--hpx:ignore-batch-env在命令行中添加选项将有助于阻止HPX获取不需要的参数.
今天早上我尝试使用HPX repo中的git commit 0c3174572ef5d2c,我的结果如下所示
bin/hello_world --hpx:agas=148.187.68.38:7910 --hpx:hpx=148.187.68.38:7910 -l2 --hpx:threads=4
hello world from OS-thread 3 on locality 1
hello world from OS-thread 6 on locality 1
hello world from OS-thread 2 on locality 1
hello world from OS-thread 7 on locality 1
hello world from OS-thread 5 on locality 1
hello world from OS-thread 0 on locality 1
hello world from OS-thread 4 on locality 1
hello world from OS-thread 1 on locality 1
hello world from OS-thread 0 on locality 0
hello world from OS-thread 2 on locality 0
hello world from OS-thread 1 on locality 0
hello world from OS-thread 3 on locality 0
bin/hello_world --hpx:agas=148.187.68.38:7910 --hpx:hpx=148.187.68.36:7910 --hpx:worker --hpx:threads=8
请注意,可以在不同节点上使用不同数量的线程,就像我在这里所做的那样(但通常节点是同构的,因此您使用相同数量的线程).
如果您已编译支持MPI(例如)并且您想确保使用TCP parcelport,则添加
-Ihpx.parcel.tcp.enable=1 -Ihpx.parcel.mpi.enable=0
到命令行(在所有节点上)以使HPX选择TCP parcelport.
| 归档时间: |
|
| 查看次数: |
880 次 |
| 最近记录: |