Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add an example that shows how to replay multiple applications at the same time
[simgrid.git] / examples / smpi / replay_multiple / generate_multiple_deployment.sh
1 #! /bin/sh
2
3 # Copyright (c) 2007-2014. The SimGrid Team.
4 # All rights reserved.
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the license (GNU LGPL) which comes with this package.
8
9
10 #usage to print the way this script should be called
11 usage () {
12     cat <<EOF
13 Usage: $0 [OPTIONS] -platform <xmldesc> -hostfile <hostfile> replay-file output-file
14 EOF
15 }
16
17 #check if we have at least one parameter
18 if [ $# -eq 0 ]
19 then
20     usage
21     exit
22 fi
23
24 EXTOPT=""
25 WRAPPER=""
26 HOSTFILE=""
27
28 while true; do
29     case "$1" in
30         "-platform")
31             PLATFORM="$2"
32             if [ ! -f "${PLATFORM}" ]; then
33                 echo "[`basename $0`] ** error: the file '${PLATFORM}' does not exist. Aborting."
34                 exit 1
35             fi
36             shift 2
37             ;;
38         "-hostfile")
39             HOSTFILE="$2"
40             if [ ! -f "${HOSTFILE}" ]; then
41                 echo "[`basename $0`] ** error: the file '${HOSTFILE}' does not exist. Aborting."
42                 exit 1
43             fi
44             shift 2
45             ;;
46         "-machinefile")
47             HOSTFILE="$2"
48             if [ ! -f "${HOSTFILE}" ]; then
49                 echo "[`basename $0`] ** error: the file '${HOSTFILE}' does not exist. Aborting."
50                 exit 1
51             fi
52             shift 2
53             ;;
54         *)
55             break
56             ;;
57     esac
58 done
59
60 # steel --cfg and --logs options
61 while [ $# -gt 0 ]; do
62     case "$1" in
63         "--cfg="*|"--log="*)
64             for OPT in ${1#*=}
65             do
66                 SIMOPTS="$SIMOPTS ${1%%=*}=$OPT"
67             done
68             shift 1
69             ;;
70         *)
71             PROC_ARGS="${PROC_ARGS:+$PROC_ARGS }$1"
72             shift      
73             ;;
74     esac
75 done
76
77
78 ##-----------------------------------
79
80
81 if [ -z "${HOSTFILE}" ] && [ -z "${PLATFORM}" ] ; then
82     echo "No hostfile nor platform specified."
83     usage
84     exit 1
85 fi
86
87 HOSTFILETMP=0
88 if [ -z "${HOSTFILE}" ] ; then
89     HOSTFILETMP=1
90     HOSTFILE="$(mktemp tmphostXXXXXX)"
91     perl -ne 'print "$1\n" if /.*<host.*?id="(.*?)".*?\/>.*/' ${PLATFORM} > ${HOSTFILE}
92 fi
93 UNROLLEDHOSTFILETMP=0
94
95 #parse if our lines are terminated by :num_process
96 multiple_processes=`grep -c ":" $HOSTFILE`
97 if [ "${multiple_processes}" -gt 0 ] ; then
98     UNROLLEDHOSTFILETMP=1
99     UNROLLEDHOSTFILE="$(mktemp tmphostXXXXXX)"
100     perl -ne ' do{ for ( 1 .. $2 ) { print "$1\n" } } if /(.*?):(\d+).*/'  ${HOSTFILE}  > ${UNROLLEDHOSTFILE}
101     if [ ${HOSTFILETMP} = 1 ] ; then
102         rm ${HOSTFILE}
103         HOSTFILETMP=0
104     fi
105     HOSTFILE=$UNROLLEDHOSTFILE
106 fi
107
108
109 # Don't use wc -l to compute it to avoid issues with trailing \n at EOF
110 hostfile_procs=`grep -c "[a-zA-Z0-9]" $HOSTFILE`
111 if [ ${hostfile_procs} = 0 ] ; then
112    echo "[`basename $0`] ** error: the hostfile '${HOSTFILE}' is empty. Aborting." >&2
113    exit 1
114 fi
115
116 APP_TRACES=($PROC_ARGS)
117 ##-------------------------------- DEFAULT APPLICATION --------------------------------------
118
119 APPLICATIONTMP=${APP_TRACES[1]}
120
121 cat > ${APPLICATIONTMP} <<APPLICATIONHEAD
122 <?xml version='1.0'?>
123 <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
124 <platform version="3">
125 APPLICATIONHEAD
126
127 ##---- cache hostnames of hostfile---------------
128 if [ -n "${HOSTFILE}" ] && [ -f ${HOSTFILE} ]; then
129     hostnames=$(cat ${HOSTFILE} | tr '\n\r' '  ')
130     NUMHOSTS=$(cat ${HOSTFILE} | wc -l)
131 fi
132
133
134     if [ -n "${APP_TRACES[0]}" ] && [ -f "${APP_TRACES[0]}" ]; then
135         NUMINSTANCES=$(cat ${APP_TRACES[0]} | wc -l)
136         replayinstances=$(cat ${APP_TRACES[0]})
137         IFS_OLD=$IFS
138         IFS=$'\n'
139         NUMPROCS=0
140         for line in $replayinstances; do
141         # return IFS back if you need to split new line by spaces:
142         IFS=$IFS_OLD
143         IFS_OLD=
144         array=( $line )
145         # generate three lists, one with instance id, ont with instance size, one with files
146         instance=${array[0]}
147         hosttraces="$hosttraces$(cat ${array[1]}| tr '\n\r' '  ' )"
148         NUMPROCSMINE=$(cat ${array[1]} | wc -l)
149         
150         if [ $NUMPROCSMINE != ${array[2]} ];
151         then
152           echo "declared num of processes for instance $instance : ${array[2]} is not the same as the one in the replay files : $NUMPROCSMINE. Please check consistency of these information"
153           exit 1
154         fi
155         
156         sleeptime=${array[3]}
157         HAVE_SEQ="`which seq 2>/dev/null`"
158
159         if [ -n "${HAVE_SEQ}" ]; then
160             SEQ1=`${HAVE_SEQ} 0 $((${NUMPROCSMINE}-1))`
161         else
162             cnt=0
163             while (( $cnt < ${NUMPROCSMINE} )) ; do
164             SEQ1="$SEQ1 $cnt"
165             cnt=$((cnt + 1));
166             done
167         fi
168         NUMPROCS=$((${NUMPROCS}+${NUMPROCSMINE}));
169         for i in $SEQ1
170         do
171           instances="$instances$instance "
172           ranks="$ranks$SEQ1 "
173           sleeptimes="$sleeptimes$sleeptime "
174         done
175         # return IFS back to newline for "for" loop
176         IFS_OLD=$IFS
177         IFS=$'\n'
178         done 
179
180         # return delimiter to previous value
181         IFS=$IFS_OLD
182         IFS_OLD=
183     else
184         printf "File not found: %s\n", "${APP_TRACES[0]:-\${APP_TRACES[0]\}}" >&2
185         exit 1
186     fi
187
188
189 ##----------------------------------------------------------
190 ##  generate application.xml with hostnames from hostfile:
191 ##  the name of host_i (1<=i<=p, where -np p) is the line i
192 ##  in hostfile (where -hostfile hostfile), or "host$i" if
193 ##  hostfile has less than i lines.
194 ##----------------------------------------------------------
195
196 HAVE_SEQ="`which seq 2>/dev/null`"
197
198 if [ -n "${HAVE_SEQ}" ]; then
199     SEQ=`${HAVE_SEQ} 0 $((${NUMPROCS}-1))`
200 else
201     cnt=0
202     while (( $cnt < ${NUMPROCS} )) ; do
203         SEQ="$SEQ $cnt"
204         cnt=$((cnt + 1));
205     done
206 fi
207
208 ##---- generate <process> tags------------------------------
209
210 hostnames=($hostnames)
211 instances=($instances)
212 hosttraces=($hosttraces)
213 sleeptimes=($sleeptimes)
214 ranks=($ranks)
215 for i in ${SEQ}
216 do
217     if [ -n "${HOSTFILE}" ]; then
218         j=$(( $i % ${NUMHOSTS} ))
219     fi
220     ##---- optional display of ranks to process mapping
221     if [ -n "${MAPOPT}" ]; then
222         echo "[rank $i] -> ${hostnames[j]}"
223     fi
224
225     if [ -z "${hostnames[j]}" ]; then
226         host="host"$($j)
227     else
228         host="${hostnames[j]}"
229     fi
230     echo "  <process host=\"${host}\" function=\"${instances[i]}\"> <!-- function name used only for logging -->" >> ${APPLICATIONTMP}
231         echo "    <argument value=\"${instances[i]}\"/> <!-- instance -->" >> ${APPLICATIONTMP}
232     echo "    <argument value=\"${ranks[i]}\"/> <!-- rank -->" >> ${APPLICATIONTMP}
233         if  [ ${NUMPROCS} -gt 1 ]; then
234             echo "    <argument value=\"${hosttraces[i]}\"/>" >> ${APPLICATIONTMP}
235         else
236             echo "    <argument value=\"${hosttraces[i]}\"/>" >> ${APPLICATIONTMP}
237         fi
238     echo "    <argument value=\"${sleeptimes[i]}\"/> <!-- delay -->" >> ${APPLICATIONTMP}
239     echo "  </process>" >> ${APPLICATIONTMP}
240 done
241
242 cat >> ${APPLICATIONTMP} <<APPLICATIONFOOT
243 </platform>
244 APPLICATIONFOOT
245 ##-------------------------------- end DEFAULT APPLICATION --------------------------------------
246
247
248     if [ ${HOSTFILETMP} = 1 ] ; then
249         rm ${HOSTFILE}
250     fi
251     if [ ${UNROLLEDHOSTFILETMP} = 1 ] ; then
252         rm ${UNROLLEDHOSTFILE}
253     fi
254
255
256 exit 0