การใช้งานscreen
ร่วมกับgdb
เพื่อดีบักแอปพลิเคชั่น MPI ทำงานได้ดีโดยเฉพาะอย่างยิ่งหากxterm
ไม่สามารถใช้งานได้หรือคุณกำลังติดต่อกับโปรเซสเซอร์มากกว่าสองสามตัว มีข้อผิดพลาดมากมายระหว่างการค้นหา stackoverflow ที่มาพร้อมกันดังนั้นฉันจะทำซ้ำโซลูชันของฉันทั้งหมด
ขั้นแรกเพิ่มรหัสหลังจาก MPI_Init เพื่อพิมพ์ PID และหยุดโปรแกรมเพื่อรอให้คุณแนบ โซลูชันมาตรฐานดูเหมือนจะวนซ้ำไม่สิ้นสุด ในที่สุดฉันก็ตัดสินใจraise(SIGSTOP);
ซึ่งจำเป็นต้องมีสายพิเศษcontinue
เพื่อหลบหนีภายใน gdb
}
int i, id, nid;
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&nid);
for (i=0; i<nid; i++) {
MPI_Barrier(MPI_COMM_WORLD);
if (i==id) {
fprintf(stderr,"PID %d rank %d\n",getpid(),id);
}
MPI_Barrier(MPI_COMM_WORLD);
}
raise(SIGSTOP);
}
หลังจากรวบรวมแล้วให้เรียกใช้ไฟล์ปฏิบัติการในพื้นหลังและตรวจจับ stderr จากนั้นคุณสามารถgrep
ไฟล์ stderr สำหรับคำหลักบางคำ (นี่คือ PID ที่แท้จริง) เพื่อรับ PID และอันดับของแต่ละกระบวนการ
MDRUN_EXE=../../Your/Path/To/bin/executable
MDRUN_ARG="-a arg1 -f file1 -e etc"
mpiexec -n 1 $MDRUN_EXE $MDRUN_ARG >> output 2>> error &
sleep 2
PIDFILE=pid.dat
grep PID error > $PIDFILE
PIDs=(`awk '{print $2}' $PIDFILE`)
RANKs=(`awk '{print $4}' $PIDFILE`)
เซสชั่น gdb gdb $MDRUN_EXE $PID
สามารถแนบไปกับแต่ละขั้นตอนด้วย การทำเช่นนั้นภายในเซสชันหน้าจอช่วยให้เข้าถึงเซสชัน gdb ใด ๆ ได้อย่างง่ายดาย -d -m
เริ่มหน้าจอในโหมดเดี่ยว-S "P$RANK"
ช่วยให้คุณตั้งชื่อหน้าจอเพื่อให้เข้าถึงได้ง่ายในภายหลังและ-l
ตัวเลือกในการทุบตีจะเริ่มในโหมดโต้ตอบและป้องกันไม่ให้ gdb ออกจากทันที
for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
PID=${PIDs[$i]}
RANK=${RANKs[$i]}
screen -d -m -S "P$RANK" bash -l -c "gdb $MDRUN_EXE $PID"
done
เมื่อ gdb เริ่มทำงานในหน้าจอคุณสามารถป้อนสคริปต์ไปยังหน้าจอ (เพื่อให้คุณไม่ต้องป้อนทุกหน้าจอและพิมพ์สิ่งเดียวกัน) โดยใช้-X stuff
คำสั่งของหน้าจอ จำเป็นต้องขึ้นบรรทัดใหม่เมื่อสิ้นสุดคำสั่ง ที่นี่หน้าจอสามารถเข้าถึงได้โดย-S "P$i"
ใช้ชื่อที่ให้ไว้ก่อนหน้านี้ -p 0
ตัวเลือกที่มีความสำคัญมิฉะนั้นคำสั่งเป็นระยะ ๆ ล้มเหลว (ขึ้นอยู่กับว่าหรือไม่คุณได้แนบไปก่อนหน้านี้หน้าจอ)
for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
screen -S "P$i" -p 0 -X stuff "set logging file debug.$i.log
"
screen -S "P$i" -p 0 -X stuff "set logging overwrite on
"
screen -S "P$i" -p 0 -X stuff "set logging on
"
screen -S "P$i" -p 0 -X stuff "source debug.init
"
done
ณ จุดนี้คุณสามารถแนบไปยังหน้าจอใด ๆ ที่ใช้และถอดออกใช้screen -rS "P$i"
Ctrl+A+D
คำสั่งอาจถูกส่งไปยังเซสชัน gdb ทั้งหมดในการเปรียบเทียบกับส่วนของรหัสก่อนหน้า