如果我有一个MPI程序,我想用gdb调试,同时能够看到所有单独的进程'输出,我可以使用:
mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]
当我有一个GUI可以使用时,这是很好的。但情况并非总是如此。
我可以使用screen
进行类似设置,以便每个进程都有自己的窗口吗?这对于在远程环境中进行调试很有用,因为它允许我使用Ctrl+a n
在输出之间切换。
答案 0 :(得分:2)
我认为this在“我如何调试MPI程序?”中回答。线程做你想要的。
编辑:
在回应评论时,你可以更容易地做到这一点,虽然简洁不完全是我将使用的术语:
通过mpirun启动分离屏幕 - 运行调试器和进程。我已经调用了会话mpi,我通过我的库路径,因为它被屏幕剥离,我的演示需要它(我也在Mac上,因此lldb和DYLD):
mpirun -np 4 screen -AdmS mpi env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out
然后启动一个单独的屏幕会话,我称之为'debug':
screen -AdmS debug
使用screen -ls
列出正在运行的会话:
&GT;&GT;屏幕-ls
屏幕上有:
19871.mpi(独立)
19872.mpi(独立)
19875.mpi(独立)
19876.mpi(独立)
20105.debug(独立)
现在在调试会话中启动4个新选项卡,将每个选项卡附加到其中一个mpi会话:
screen -S debug -X screen -t tab0 screen -r 19871.mpi
screen -S debug -X screen -t tab1 screen -r 19872.mpi
screen -S debug -X screen -t tab2 screen -r 19875.mpi
screen -S debug -X screen -t tab3 screen -r 19876.mpi
然后只需使用screen -r debug
附加到调试会话即可。现在你有4个选项卡,每个选项卡都运行一个连接到mpi进程的调试器的串行实例,类似于你之前描述的xterm方法。它不是最快的命令集,但至少你不需要修改你的代码或追逐PID等。
我试过的另一种方法,但似乎不起作用:
启动分离的屏幕
screen -AdmS ashell
启动两个mpi进程,在分离的会话中启动新的屏幕选项卡,使用我的demo mpi应用程序启动lldb:
mpirun -np 1 screen -S ashell -X screen -t tab1 env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out : -np 1 screen -S ashell -X screen -t tab2 env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out
或者只是
mpirun -np 2 screen -S ashell -X screen env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out
然后用
附加到屏幕screen -r ashell
你将有3个标签,其中2个用你的程序运行lldb,另一个用你的标准shell。不幸的是,当你尝试运行这些程序时,每个进程都认为它是通用世界中唯一的进程,并且我不知道该怎么办...
答案 1 :(得分:2)
如何调试C / C ++ MPI程序?
一种方法是为每个开始一个单独的终端和gdb会话 过程:
mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]
其中NP
是进程数。
如果您没有方便的GUI会怎样?
(请参阅下面的一个方便的脚本。)
这是基于timofiend的回答here。
在许多屏幕会话中调试其调试器中的mpi程序:
mpirun -np 4 screen -AdmS mpi gdb ./parallel_pit_fill.exe one retain ./beauford.tif 500 500
启动新的屏幕会话以访问调试器:
screen -AdmS debug
将调试器的屏幕会话加载到新的屏幕会话
screen -list | #Get list of screen sessions
grep -E "[0-9]+.mpi" | #Extract the relevant ones
awk '{print NR-1,$1}' | #Generate tab #s and session ids, drop rest of the string
xargs -n 2 sh -c '
screen -S debug -X screen -t tab$0 screen -r $1
'
跳转到新的屏幕会话:
screen -r debug
我已将上述内容封装在一个方便的脚本中:
#!/bin/bash
if [ $# -lt 2 ]
then
echo "Parallel Debugger Syntax: $0 <NP> <PROGRAM> [arg1] [arg2] [...]"
exit 1
fi
the_time=`date +%s` #Use this so we can run multiple debugging sessions at once
#(assumes we are only starting one per second)
#The first argument is the number of processes. Everything else is what we want
#to run. Make a new mpi screen for each process.
mpirun -np $1 screen -AdmS ${the_time}.mpi gdb "${@:2}"
#Create a new screen for debugging from
screen -AdmS ${the_time}.debug
#The following are used for loading the debuggers into the debugging screen
firstpart="screen -S ${the_time}.debug"
secondpart=' -X screen -t tab$0 screen -r $1'
screen -list | #Get list of mpi screens
grep -E "[0-9]+.${the_time}.mpi" | #Extract the relevant ones
awk '{print NR-1,$1}' | #Generate tab #s and session ids, drop rest of the string
xargs -n 2 sh -c "$firstpart$secondpart"
screen -r ${the_time}.debug #Enter debugging screen