Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
805bfb37c17faab0d70e89b49d528a5bedc06e55
[simgrid.git] / src / smpi / smpirun.in
1 #! /bin/sh
2
3 @CMAKE_SMPI_COMMAND@
4
5 DEFAULT_LOOPBACK_BANDWIDTH="498000000"
6 DEFAULT_LOOPBACK_LATENCY="0.000004"
7 DEFAULT_NETWORK_BANDWIDTH="$((26 * 1024 * 1024))"
8 DEFAULT_NETWORK_LATENCY="0.000005"
9 DEFAULT_NUMPROCS="4"
10 DEFAULT_POWER="100"
11
12 LOOPBACK_BANDWIDTH="${DEFAULT_LOOPBACK_BANDWIDTH}"
13 LOOPBACK_LATENCY="${DEFAULT_LOOPBACK_LATENCY}"
14 NETWORK_BANDWIDTH="${DEFAULT_NETWORK_BANDWIDTH}"
15 NETWORK_LATENCY="${DEFAULT_NETWORK_LATENCY}"
16 POWER="${DEFAULT_POWER}"
17
18 SIMOPTS="--cfg=maxmin/precision:1e-9 --cfg=network/model:SMPI --cfg=network/TCP_gamma:4194304"
19
20 #usage to print the way this script should be called
21 usage () {
22 cat <<EOF
23 Usage: $0 [OPTIONS] -platform <xmldesc> -hostfile <hostfile> program [program-options]
24 Options:
25   -keep-temps                # don't remove the generated files after execution
26   -wrapper <command>         # use command to run the program (e.g. "valgrind")
27   -map                       # display the machine on which each process rank is mapped
28   -np <numprocs>             # use that amount of processes from the hostfile.
29                              # By default, all processes of the hostfile are used.
30   -trace-ti                  # activate time independant tracing (for replay, default in smpi_simgrid.txt)
31   -trace                     # activate tracing (Paje, default in smpi_simgrid.trace)
32   -trace-comment <comment>   # put a comment on the top of the trace file
33   -trace-comment-file <file> # put file contents on the top of the trace file as comment
34   -trace-grouped             # group MPI processes by location
35   -trace-resource            # trace resource utilization
36   -trace-viva               # generate configuration for Viva's GraphView
37   -trace-file <tracefile>    # name of the tracefile (simgrid_smpi.trace)
38   -ext <value>               # additional parameter (reserved)
39
40 or (deprecated usage):
41   $0 [-keep-temps] [-np <numprocs>] [-bandwidth <bytes/sec>] [-latency <secs>] program [program-options]
42
43 EOF
44 }
45
46 #check if we have at least one parameter
47 if [ $# -eq 0 ]
48 then
49     usage
50     exit
51 fi
52
53 EXTOPT=""
54 WRAPPER=""
55
56 while true; do
57   case "$1" in
58    "-np" | "-n")
59       NUMPROCS="$2"
60       shift 2
61     ;;
62    "-bandwidth")
63       NETWORK_BANDWIDTH="$2"
64       shift 2
65     ;;
66    "-latency")
67       NETWORK_LATENCY="$2"
68       shift 2
69     ;;
70    "-platform")
71         PLATFORM="$2"
72       if [ ! -f "${PLATFORM}" ]; then
73                 echo "[$0] ** error: the file '${PLATFORM}' does not exist. Aborting."
74                 exit 1
75       fi
76         shift 2
77     ;;
78    "-hostfile")
79         HOSTFILE="$2"
80       if [ ! -f "${HOSTFILE}" ]; then
81                 echo "[$0] ** error: the file '${HOSTFILE}' does not exist. Aborting."
82                 exit 1
83       fi
84         shift 2
85     ;;
86
87    "-ext")
88       EXTOPT="$2"
89       shift 2
90    ;;
91
92    "-map")
93         MAPOPT="true"
94       shift 1
95    ;;
96
97    "-trace")
98       TRACE_ACTIVE="true"
99       shift 1
100    ;;
101
102    "-trace-ti")
103       TRACE_ACTIVE="true"
104       TRACE_TI_ACTIVE="true"
105       shift 1
106    ;;
107
108    "-trace-comment")
109       TRACE_COMMENT="$2"
110       shift 2
111    ;;
112
113    "-trace-comment-file")
114       TRACE_COMMENT_FILE="$2"
115       shift 2
116    ;;
117
118    "-trace-file")
119       TRACE_FILENAME="$2"
120       shift 2
121    ;;
122
123    "-trace-grouped")
124       TRACE_GROUPED="true"
125       shift 1
126    ;;
127
128    "-trace-resource")
129       TRACE_RESOURCE="true"
130       shift 1
131    ;;
132
133    "-trace-viva")
134         TRACE_VIVA="true"
135           shift 1
136    ;;
137
138    "-keep-temps")
139         KEEP="true"
140       shift 1
141    ;;
142
143    "-wrapper")
144       WRAPPER="$2"
145       shift 2
146       ;;
147
148    "-help" | "--help" | "-h")
149       usage
150       exit
151    ;;
152
153    "--cfg="*|"--log="*)
154      for OPT in ${1#*=}
155      do
156        SIMOPTS="$SIMOPTS ${1%%=*}=$OPT"
157      done
158      shift 1
159    ;;
160     *)
161       break
162     ;;
163   esac
164 done
165
166 if [ -n "$WRAPPER" ]; then
167     EXEC="$WRAPPER $1"
168 else
169     EXEC="$1"
170 fi
171 shift
172
173 # steel --cfg and --logs options
174 while [ $# -gt 0 ]; do
175   case "$1" in
176    "--cfg="*|"--log="*)
177      for OPT in ${1#*=}
178      do
179        SIMOPTS="$SIMOPTS ${1%%=*}=$OPT"
180      done
181      shift 1
182    ;;
183     *)
184       PROC_ARGS="${PROC_ARGS:+$PROC_ARGS }$1"
185       shift      
186     ;;
187   esac
188 done
189
190
191 ##-----------------------------------
192
193 # Basic checks on the provided arguments
194 if [ -z "${EXEC}" ] ; then
195     echo "You must provide a program to execute."
196     usage
197     exit 1
198 fi
199
200 if [ -z "${HOSTFILE}" ] && [ -z "${PLATFORM}" ] ; then
201     echo "No hostfile nor platform specified."
202     usage
203     exit 1
204 fi
205
206 HOSTFILETMP=0
207 if [ -z "${HOSTFILE}" ] ; then
208     HOSTFILETMP=1
209     HOSTFILE="$(mktemp tmphostXXXXXX)"
210     perl -ne 'print "$1\n" if /.*<host.*?id="(.*?)".*?\/>.*/' ${PLATFORM} > ${HOSTFILE}
211 fi
212
213 # Don't use wc -l to compute it to avoid issues with trailing \n at EOF
214 hostfile_procs=`grep -c "[a-zA-Z0-9]" $HOSTFILE`
215
216 if [ -z "${NUMPROCS}" ] ; then
217     # Use the amount of processes in the hostfile as default value for the -np parameter
218     NUMPROCS=$hostfile_procs
219 fi
220
221
222 if [ ${NUMPROCS} -gt ${hostfile_procs} ] ; then
223     echo "You requested to use ${NUMPROCS} processes, but there is only ${hostfile_procs} processes in your hostfile..." >&2
224 fi
225
226 ##-------------------------------- DEFAULT or SPECIFIED PLATFORM --------------------------------------
227 if [ -z "${PLATFORM}" ]; then
228         PLATFORMTMP="$(mktemp tmpXXXXXX)"
229
230         cat > ${PLATFORMTMP} <<PLATFORMHEAD
231 <?xml version='1.0'?>
232 <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
233 <platform version="3">
234 <AS id="AS0" routing="Full">
235 PLATFORMHEAD
236
237 for i in $(echo "for (i=${NUMPROCS};i>0;i--) i"|bc); do
238   echo "  <host id=\"host$i\" power=\"${POWER}\"/>" >> ${PLATFORMTMP}
239   echo "  <link id=\"loop$i\" bandwidth=\"${LOOPBACK_BANDWIDTH}\" latency=\"${LOOPBACK_LATENCY}\"/>" >> ${PLATFORMTMP}
240   echo "  <link id=\"link$i\" bandwidth=\"${NETWORK_BANDWIDTH}\" latency=\"${NETWORK_LATENCY}\"/>" >> ${PLATFORMTMP}
241 done
242
243 for i in $(echo "for (i=${NUMPROCS};i>0;i--) i"|bc); do
244   for j in $(echo "for (i=${NUMPROCS};i>0;i--) i"|bc); do
245     if [ $i -eq $j ]; then
246       echo "  <route src=\"host$i\" dst=\"host$j\"><link_ctn id=\"loop$i\"/></route>" >> ${PLATFORMTMP}
247     else
248       echo "  <route src=\"host$i\" dst=\"host$j\"><link_ctn id=\"link$i\"/><link_ctn id=\"link$j\"/></route>" >> ${PLATFORMTMP}
249     fi
250   done
251 done
252
253 cat >> ${PLATFORMTMP} <<PLATFORMFOOT
254 </AS>
255 </platform>
256 PLATFORMFOOT
257
258 else
259         PLATFORMTMP=${PLATFORM}
260 fi
261 ##-------------------------------- end DEFAULT or SPECIFIED PLATFORM --------------------------------------
262
263 ##-------------------------------- DEFAULT APPLICATION --------------------------------------
264 APPLICATIONTMP="$(mktemp tmpXXXXXX)"
265 #APPLICATIONTMP="app.xml"
266
267
268 cat > ${APPLICATIONTMP} <<APPLICATIONHEAD
269 <?xml version='1.0'?>
270 <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
271 <platform version="3">
272 APPLICATIONHEAD
273
274 ##---- cache hostnames of hostfile---------------
275 if [ -n "${HOSTFILE}" ] && [ -f ${HOSTFILE} ]; then
276   hostnames=$(cat ${HOSTFILE} | tr \\\n " ")
277   NUMHOSTS=$(cat ${HOSTFILE} | wc -l)
278 fi
279
280 if [ "${EXTOPT}" = "smpi_replay" ]; then
281   APP_TRACES=$PROC_ARGS
282   if [ -n "${APP_TRACES}" ] && [ -f "${APP_TRACES}" ]; then
283      hosttraces=$(cat ${APP_TRACES} | tr \\\n " ")
284      NUMTRACES=$(cat ${APP_TRACES} | wc -l)
285   else
286      printf "File not found: %s\n", "${APP_TRACES:-\${APP_TRACES\}}" >&2
287      exit 1
288   fi
289 fi
290
291 ##----------------------------------------------------------
292 ##  generate application.xml with hostnames from hostfile:
293 ##  the name of host_i (1<=i<=p, where -np p) is the line i
294 ##  in hostfile (where -hostfile hostfile), or "host$i" if
295 ##  hostfile has less than i lines.
296 ##----------------------------------------------------------
297
298 HAVE_SEQ="`which seq 2>/dev/null`"
299
300 if [ -n "${HAVE_SEQ}" ]; then
301         SEQ=`${HAVE_SEQ} 0 $((${NUMPROCS}-1))`
302 else
303       cnt=0
304         while (( $cnt < ${NUMPROCS} )) ; do
305             SEQ="$SEQ $cnt"
306             cnt=$((cnt + 1));
307         done
308 fi
309
310 ##---- generate <process> tags------------------------------
311
312 for i in ${SEQ}
313 do
314   if [ -n "${HOSTFILE}" ]; then
315         j=$(( $i % ${NUMHOSTS} + 1 ))
316   fi
317   ##---- optional display of ranks to process mapping
318   if [ -n "${MAPOPT}" ]; then
319         echo "[rank $i] -> $(echo $hostnames|cut -d' ' -f$j)"
320   fi
321
322   if [ -z "$(echo $hostnames|cut -d' ' -f$j)" ]; then
323         host="host"$($j)
324   else
325         host="$(echo $hostnames|cut -d' ' -f$j)"
326   fi
327   echo "  <process host=\"${host}\" function=\"$i\"> <!-- function name used only for logging -->" >> ${APPLICATIONTMP}
328   echo "    <argument value=\"$i\"/> <!-- rank -->" >> ${APPLICATIONTMP}
329   if [ "${EXTOPT}" = "smpi_replay" ]; then
330     if  [ ${NUMTRACES} -gt 1 ]; then
331       echo "    <argument value=\"$(echo $hosttraces|cut -d' ' -f$j)\"/>" >> ${APPLICATIONTMP}
332     else
333       echo "    <argument value=\"$(echo $hosttraces|cut -d' ' -f1)\"/>" >> ${APPLICATIONTMP}
334     fi
335   else 
336     for ARG in $PROC_ARGS; do
337        echo "    <argument value=\"${ARG}\"/>" >> ${APPLICATIONTMP}
338     done
339   fi
340   echo "  </process>" >> ${APPLICATIONTMP}
341 done
342
343 cat >> ${APPLICATIONTMP} <<APPLICATIONFOOT
344 </platform>
345 APPLICATIONFOOT
346 ##-------------------------------- end DEFAULT APPLICATION --------------------------------------
347
348 ##---------------------- SMPI TRACING OPTIONS ---------------------------------
349 if [ -n "${TRACE_ACTIVE}" ]; then
350   #define trace filename
351   if [ -n "${TRACE_TI_ACTIVE}" ]; then
352     if [ -z "${TRACE_FILENAME}" ]; then
353       TRACE_FILENAME="smpi_simgrid.txt"
354     fi
355     TRACEOPTIONS="--cfg=tracing:yes --cfg=tracing/filename:${TRACE_FILENAME} --cfg=tracing/smpi:yes --cfg=tracing/smpi/format:TI --cfg=tracing/smpi/computing:yes"
356   else
357     if [ -z "${TRACE_FILENAME}" ]; then
358       TRACE_FILENAME="smpi_simgrid.trace"
359     fi
360     TRACEOPTIONS="--cfg=tracing:yes --cfg=tracing/filename:${TRACE_FILENAME} --cfg=tracing/smpi:yes"
361   fi
362
363   if [ -n "${TRACE_COMMENT}" ]; then
364     TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/comment:${TRACE_COMMENT}"
365   fi
366
367   if [ -n "${TRACE_COMMENT_FILE}" ]; then
368     TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/comment_file:${TRACE_COMMENT_FILE}"
369   fi
370
371   if [ -n "${TRACE_GROUPED}" ]; then
372     TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/smpi/group:yes"
373   fi
374
375   if [ -n "${TRACE_RESOURCE}" ]; then
376     TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes"
377   fi
378
379   if [ -n "${TRACE_VIVA}" ]; then
380     TRACEOPTIONS="${TRACEOPTIONS} --cfg=viva/categorized:smpi_cat.plist --cfg=viva/uncategorized:smpi_uncat.plist"
381   fi
382 fi
383 ##---------------------- end SMPI TRACING OPTIONS ---------------------------------
384
385 export SMPI_GLOBAL_SIZE=${NUMPROCS}
386 if [ -n "${KEEP}" ] ; then
387   echo ${EXEC} ${TRACEOPTIONS} ${SIMOPTS} ${PLATFORMTMP} ${APPLICATIONTMP}
388   if [ ${HOSTFILETMP} = 1 ] ; then
389     echo "Generated hostfile ${HOSTFILE} keeped."
390   fi
391 fi
392 ${EXEC} ${TRACEOPTIONS} ${SIMOPTS} ${PLATFORMTMP} ${APPLICATIONTMP}
393 status=$?
394
395 if [ -z "${KEEP}" ] ; then
396    if [ -z "${PLATFORM}" ]; then
397         rm ${PLATFORMTMP}
398    fi
399    if [ ${HOSTFILETMP} = 1 ] ; then
400         rm ${HOSTFILE}
401    fi
402    rm ${APPLICATIONTMP}
403 fi
404
405 exit $status