MPI अनुप्रयोगों को डिबग करने के लिए screen
एक साथ उपयोग करना gdb
अच्छी तरह से काम करता है, खासकर यदि xterm
अनुपलब्ध है या आप कुछ प्रोसेसर से अधिक के साथ काम कर रहे हैं। स्टैकओवरफ्लो खोजों के साथ रास्ते में कई नुकसान थे, इसलिए मैं अपने समाधान को पूरा करूँगा।
सबसे पहले, पीआईडी प्रिंट करने के लिए MPI_Init के बाद कोड जोड़ें और प्रोग्राम को अटैच करने के लिए रुकें। मानक समाधान एक अनंत लूप लगता है; मैं अंततः बस गया 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);
}
संकलित करने के बाद, पृष्ठभूमि में निष्पादन योग्य चलाएं, और स्टेडर को पकड़ें। फिर आप grep
प्रत्येक प्रक्रिया के PID और रैंक प्राप्त करने के लिए कुछ कीवर्ड (यहां शाब्दिक PID) के लिए stderr फाइल कर सकते हैं ।
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
बैश करने का विकल्प इसे इंटरैक्टिव मोड में शुरू करता है और जीडीबी को तुरंत बाहर निकलने से रोकता है।
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
एक बार जब स्क्रीन में जीडीबी शुरू हो जाता है, तो आप स्क्रीन पर स्क्रिप्ट इनपुट कर सकते हैं (ताकि आपको हर स्क्रीन में प्रवेश न करना पड़े और उसी चीज को टाइप करें) स्क्रीन की -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 सत्रों में कमांड भेजे जा सकते हैं।