/[MITgcm]/MITgcm/verification/testreport
ViewVC logotype

Diff of /MITgcm/verification/testreport

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.32 by edhill, Sun Dec 7 07:06:13 2003 UTC revision 1.119 by jmc, Mon Jan 26 04:09:34 2009 UTC
# Line 11  usage() Line 11  usage()
11      echo      echo
12      echo "where possible OPTIONS are:"      echo "where possible OPTIONS are:"
13      echo "  (-help|-h)               print usage"      echo "  (-help|-h)               print usage"
14      echo "  (-mpi)                   use MPI input files"      echo "  (-mth)                   run multi threaded (using eedata.mth)"
15        echo "  (-mpi)                   compile and run using MPI"
16      echo "  (-ieee|-noieee)          if possible, use IEEE compiler flags"      echo "  (-ieee|-noieee)          if possible, use IEEE compiler flags"
17      echo "                             (DEF=\"noieee\")"      echo "                             (DEF=\"-ieee\")"
18      echo "  (-optfile=|-of=)STRING   list of optfiles to use"      echo "  (-gsl)                   compile with \"-gsl\" flag"
19        echo "  (-of=|-optfile=)STRING   list of optfiles to use"
20      echo "  (-a|-addr) STRING        list of email recipients"      echo "  (-a|-addr) STRING        list of email recipients"
21      echo "                             (DEF=\"edhill@mitgcm.org\")"      echo "                             (DEF=\"\" no email is sent)"
22      echo "  (-t|-tdir) STRING        list of test dirs to use"      echo "  (-mpd|-mpackdir) DIR     location of the mpack utility"
23      echo "                             (DEF=\"\" which builds all)"      echo "                             (DEF=\"../tools/mpack-1.6\")"
24        echo "  (-t|-tdir) STRING        list of group and/or exp. dirs to test"
25        echo "                             (recognized groups: basic, tutorials)"
26        echo "                             (DEF=\"\" which test all)"
27        echo "  (-skd|-skipdir) STRING   list of exp. dirs to skip"
28        echo "                             (DEF=\"\" which test all)"
29      echo "  (-b|-bash) STRING        preferred location of a \"bash\" or"      echo "  (-b|-bash) STRING        preferred location of a \"bash\" or"
30      echo "                             Bourne-compatible \"sh\" shell"      echo "                             Bourne-compatible \"sh\" shell"
31      echo "                             (DEF=\"\" for \"bash\")"      echo "                             (DEF=\"\" for \"bash\")"
# Line 27  usage() Line 34  usage()
34      echo "                             (DEF=\"make output.txt\")"      echo "                             (DEF=\"make output.txt\")"
35      echo "  (-m|-make) STRING        command to use for \"make\""      echo "  (-m|-make) STRING        command to use for \"make\""
36      echo "                             (DEF=\"make\")"      echo "                             (DEF=\"make\")"
37        echo "  (-odir) STRING           used to build output directory name"
38        echo "                             (DEF=\"hostname\")"
39        echo "  (-ptr|-ptracers) STRING  specify which ptracers to test"
40        echo "                             (DEF=\"1 2 3 4 5\")"
41        echo "  (-match) NUMBER          Matching Criteria (number of digits)"
42        echo "                             (DEF=\"12\")"
43        echo "  (-j) JOBS                use \"make -j JOBS\" for parallel builds"
44      echo "  (-clean)                 *ONLY* run \"make CLEAN\""      echo "  (-clean)                 *ONLY* run \"make CLEAN\""
45      echo "  (-quick|-q)              same as \"-nogenmake -noclean -nodepend\""      echo "  (-quick|-q)              same as \"-nogenmake -noclean -nodepend\""
46      echo "  (-nogenmake|-ng)         skip the genmake stage"      echo "  (-nogenmake|-ng)         skip the genmake stage"
47      echo "  (-noclean|-nc)           skip the \"make clean\" stage"      echo "  (-noclean|-nc)           skip the \"make clean\" stage"
48      echo "  (-nodepend|-nd)          skip the \"make depend\" stage"      echo "  (-nodepend|-nd)          skip the \"make depend\" stage"
49        echo "  (-deldir|-dd)            on success, delete the output directory"
50        echo "  (-ts)                    provide timing information per timestep"
51        echo "  (-papis)                 provide MFlop/s per timestep using PAPI"
52        echo "  (-pcls)                  provide MFlop/s per timestep using PCL"
53      echo      echo
54      echo "and where STRING follows a whitespace-delimited format"      echo "and where STRING can be a whitespace-delimited list"
55      echo "such as:"      echo "such as:"
56        echo
57      echo "  -t 'exp0 exp2 exp3' "      echo "  -t 'exp0 exp2 exp3' "
58      echo "  -addr='abc@123.com testing@home.org'"      echo "  -addr='abc@123.com testing@home.org'"
59      echo      echo
60        echo "provided that the expression is properly quoted within the current"
61        echo "shell (note the use of single quotes to protect white space)."
62        echo
63      exit 1      exit 1
64  }  }
65    
66  #  build the mpack utility  #  build the mpack utility
67  build_mpack()  build_mpack()
68  {  {
69      echo -n "building the mpack utility...  "      printf "building the mpack utility...  "
70      if test ! -x "$MPACKDIR/mpack" ; then      MPACK="$MPACKDIR/mpack"
71        if test ! -x $MPACK ; then
72          if test ! -d $MPACKDIR ; then          if test ! -d $MPACKDIR ; then
73              echo              echo
74              echo "Error: can't find \"$MPACKDIR\""              echo "Error: can't find \"$MPACKDIR\""
# Line 54  build_mpack() Line 77  build_mpack()
77              echo              echo
78              HAVE_MPACK=f              HAVE_MPACK=f
79          fi          fi
         echo -n "building mpack...  "  
80          if test "x$CC" = x ; then          if test "x$CC" = x ; then
81              export CC=cc              export CC=cc
82          fi          fi
83            printf "building mpack (using CC=$CC)...  "
84          ( cd $MPACKDIR && ./configure && $MAKE ) > tr_build_mpack.out 2>&1          ( cd $MPACKDIR && ./configure && $MAKE ) > tr_build_mpack.out 2>&1
85          RETVAL=$?          RETVAL=$?
86          if test "x$RETVAL" != x0 ; then          if test "x$RETVAL" != x0 ; then
# Line 68  build_mpack() Line 91  build_mpack()
91          else          else
92              rm -f tr_build_mpack.out              rm -f tr_build_mpack.out
93              HAVE_MPACK=t              HAVE_MPACK=t
94                echo "done"
95          fi          fi
96      else      else
97          HAVE_MPACK=t          HAVE_MPACK=t
98            echo "already exist"
99      fi      fi
     echo "OK"  
100  }  }
101    
102  testoutput_for_prop()  testoutput_var()
103  {  {
104      # testoutput_for_prop dir s1 label subdir      # testoutput_var dir s1 label subdir reference_output
105      #      #
106      #  compares files in $dir/$subdir/output.txt and $dir/results/output.txt      #  compares 1 variable output selected from file $dir/$subdir/$OUTPUTFILE
107      #  using search strings s1 and text label      #     with same output from reference file $dir/results/$reference_output
108        #  using search strings s1 and text label
109    
110      if [ $debug -gt 0 ]; then      if [ $debug -gt 0 ]; then
111          echo testoutput_for_prop: grep "$2" $1/$4/output.txt 1>&2          echo testoutput_var: grep "$2" $1/$4/$OUTPUTFILE 1>&2
112      fi      fi
113      if [ -r $1/$4/output.txt ]; then      if [ -r $1/$4/$OUTPUTFILE ]; then
114          grep "$2" $1/$4/output.txt | sed 's/.*=//' | cat -n > tmp1.txt          grep "$2" $1/$4/$OUTPUTFILE | sed 's/.*=//' | cat -n > tmp1.txt
115          lncnt=`wc -l tmp1.txt | awk '{print $1}' `          lncntA=`wc -l tmp1.txt | awk '{print $1}' `
116          if [ $lncnt -lt 3 ]; then          if [ $lncntA -lt 2 ]; then
117              if [ $verbose -gt 0 ]; then              if [ $verbose -gt 0 ]; then
118                  echo Not enough lines of output when searching for "$2" 1>&2                  echo Not enough lines of output when searching for "$2" 1>&2
119              fi              fi
120              return 99              return 99
121          fi          fi
122      else      else
123          echo testoutput_for_prop: output.txt from model run was not readable 1>&2          echo testoutput_var: $OUTPUTFILE from model run was not readable 1>&2
124          return 99          return 99
125      fi      fi
126      if [ $debug -gt 0 ]; then      if [ $debug -gt 0 ]; then
127          echo testoutput_for_prop: grep "$2" $1/results/output.txt 1>&2          echo testoutput_var: grep "$2" $1/results/$5 1>&2
128      fi      fi
129      grep "$2" $1/results/output.txt | sed 's/.*=//' | cat -n > tmp2.txt      grep "$2" $1/results/$5 | sed 's/.*=//' | cat -n > tmp2.txt
130      lncnt=`wc -l tmp2.txt | awk '{print $1}' `      lncntB=`wc -l tmp2.txt | awk '{print $1}' `
131      if [ $lncnt -lt 3 ]; then      if [ $lncntB -lt 2 ]; then
132          if [ $verbose -gt 0 ]; then          if [ $verbose -gt 0 ]; then
133              echo Not enough lines of output when searching for "$2" 1>&2              echo Not enough lines of output when searching for "$2" 1>&2
134          fi          fi
135          return 99          return 99
136      fi      fi
137        if [ $lncntA -ne $lncntB ]; then
138            if [ $verbose -gt 0 ]; then
139                echo Not same Nb of lines when searching for "$2" ":" $lncntA $lncntB 1>&2
140            fi
141            return 99
142        fi
143        has_nan=`cat tmp1.txt | grep -i nan | wc -l`
144        if [ $has_nan -gt 0  ] ; then
145            echo testoutput_var: $OUTPUTFILE contains $has_nan NaN values  1>&2
146            return 99
147        fi
148        has_inf=`cat tmp1.txt | grep -i inf | wc -l`
149        if [ $has_inf -gt 0  ] ; then
150            echo testoutput_var: $OUTPUTFILE contains $has_inf Inf values  1>&2
151            return 99
152        fi
153      if [ $debug -gt 0 ]; then      if [ $debug -gt 0 ]; then
154          echo testoutput_for_prop: join tmp1.txt tmp2.txt 1>&2          echo testoutput_var: join tmp1.txt tmp2.txt 1>&2
155      fi      fi
156      join tmp1.txt tmp2.txt | awk '{print $1 " " $2 " " $3}' > tmp3.txt      join tmp1.txt tmp2.txt | awk '{print $1 " " $2 " " $3}' > tmp3.txt
157      if [ $debug -gt 0 ]; then      if [ $debug -gt 0 ]; then
158          echo testoutput_for_prop: compare_lines 1>&2          echo testoutput_var: compare_lines 1>&2
159      fi      fi
160      if [ $verbose -gt 1 ]; then      if [ $verbose -gt 1 ]; then
161          cat tmp3.txt 1>&2          cat tmp3.txt 1>&2
# Line 122  testoutput_for_prop() Line 163  testoutput_for_prop()
163      echo "-1" >> tmp3.txt      echo "-1" >> tmp3.txt
164      # On the SGI O3K (*not* the O2K), "cat -n" inserts a ":" after the line number      # On the SGI O3K (*not* the O2K), "cat -n" inserts a ":" after the line number
165      cat tmp3.txt | sed -e 's|:||g' > tmp4.txt      cat tmp3.txt | sed -e 's|:||g' > tmp4.txt
166      digits_of_similarity=`./tmp_cmpnum < tmp4.txt`      digits_of_similarity=`./tr_cmpnum < tmp4.txt`
167      if [ $digits_of_similarity -eq 99 ]; then      if [ $digits_of_similarity -eq 99 ]; then
168          if [ $verbose -gt 0 ]; then          if [ $verbose -gt 0 ]; then
169              echo testoutput_for_prop: No comparison was available for \"$2\" 1>&2              echo testoutput_var: No comparison was available for \"$3\" 1>&2
170          fi          fi
171          digits_of_similarity=99          digits_of_similarity=99
172      else      else
173          if [ $verbose -gt 0 ]; then          if [ $verbose -gt 0 ]; then
174              echo There were $digits_of_similarity decimal places of similarity for \"$2\" 1>&2              echo There were $digits_of_similarity decimal places of similarity for \"$3\" 1>&2
175          fi          fi
176      fi      fi
177      rm -f tmp1.txt tmp2.txt tmp3.txt tmp4.txt      rm -f tmp1.txt tmp2.txt tmp3.txt tmp4.txt
# Line 138  testoutput_for_prop() Line 179  testoutput_for_prop()
179      return $digits_of_similarity      return $digits_of_similarity
180  }  }
181    
182  dashnum()  testoutput_run()
 {  
     # dashnum n1 n2 n3 ...  
     #  
     #  print numbers using %3i format or "--" if number = 99  
   
     for num in $@ ; do  
         if [ $num = 99 ]; then  
             printf ' --'  
         else  
             printf '%3i' $num  
         fi  
     done  
 }  
   
 testoutput_ad()  
183  {  {
184      grep $3 $1/results_ad/output.txt_adm | awk '{print NR " " $5}' > t05.txt      # testoutput_run directory subdir reference_output
     grep $3 $1/$2/output.txt_adm | awk '{print NR " " $5}' > t15.txt  
     grep $3 $1/results_ad/output.txt_adm | awk '{print NR " " $6}' > t06.txt  
     grep $3 $1/$2/output.txt_adm | awk '{print NR " " $6}' > t16.txt  
     join t05.txt t15.txt > t5.txt  
     join t06.txt t16.txt > t6.txt  
     echo "-1" >> t5.txt  
     echo "-1" >> t6.txt  
     digits_5=`./tmp_cmpnum < t5.txt`  
     digits_6=`./tmp_cmpnum < t6.txt`  
     dashnum $digits_5 $digits_6  
     rm -f t[01][56].txt t[56].txt  
 }  
   
 testoutput()  
 {  
     # testoutput directory subdir  
185      #      #
186      #  test output in "directory"      #  test output from 1 run in "directory"
187      if test "x$ADM" = x ; then  # --> same processing for adjoint & forward test
188          if [ $debug -gt 0 ]; then          # default list of output variables to be checked:
189              echo testoutput: testoutput_for_prop $1 cg2d_init_res 1>&2          #  1rst : main variable used to decide if it pass or FAIL
190          fi          #  others : number of matching digits to be printed in summary.txt
191          testoutput_for_prop $1 "cg2d_init_res" "cg2d init. residual" $2; cg2dres=$?          listChk=$DEF_CHECK_LIST
192          if [ $debug -gt 0 ]; then          #  load experiment-specific list from file "tr_checklist" (if it exist)
193              echo testoutput: cg2dres=$cg2dres 1>&2          if test -r $1/$2/tr_checklist ; then listChk=`cat $1/$2/tr_checklist` ; fi
194          fi          sVar=`echo $listChk | awk '{print $1}'`
195          testoutput_for_prop $1 "dynstat_theta_min" "theta minimum" $2; tmin=$?          # remove 1rst var and expand the list: + => min max mean s.d
196          testoutput_for_prop $1 "dynstat_theta_max" "theta maximum" $2; tmax=$?          listVar=`echo $listChk | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' \
197          testoutput_for_prop $1 "dynstat_theta_mean" "theta mean" $2; tmean=$?                                 | sed 's/+//g' | sed "s/^$sVar//"`
198          testoutput_for_prop $1 "dynstat_theta_sd" "theta s.d." $2; tsd=$?          if [ $debug -gt 0 ]; then echo "testoutput_run: listVar(I)='$listVar'" 1>&2 ; fi
199          testoutput_for_prop $1 "dynstat_salt_min" "salt minimum" $2; smin=$?          # check for ptracer output in reference_output file :
200          testoutput_for_prop $1 "dynstat_salt_max" "salt maximum" $2; smax=$?          outpref=$1/results/$3
201          testoutput_for_prop $1 "dynstat_salt_mean" "salt mean" $2; smean=$?          ptr_mon="trcstat_ptracerXX_min trcstat_ptracerXX_max"
202          testoutput_for_prop $1 "dynstat_salt_sd" "salt s.d." $2; ssd=$?          ptr_mon="$ptr_mon trcstat_ptracerXX_mean trcstat_ptracerXX_sd"
203          testoutput_for_prop $1 "dynstat_uvel_min" "U minimum" $2; umin=$?          for ii in $PTRACERS_NUM ; do
204          testoutput_for_prop $1 "dynstat_uvel_max" "U maximum" $2; umax=$?              ptrfound=0
205          testoutput_for_prop $1 "dynstat_uvel_mean" "U mean" $2; umean=$?              for jj in $ptr_mon ; do
206          testoutput_for_prop $1 "dynstat_uvel_sd" "U s.d." $2; usd=$?                  name=`eval "echo $jj | sed -e 's|XX|0"$ii"|g'"`
207          testoutput_for_prop $1 "dynstat_vvel_min" "V minimum" $2; vmin=$?                  tst=`grep $name $outpref | wc -l | awk '{print $1}'`
208          testoutput_for_prop $1 "dynstat_vvel_max" "V maximum" $2; vmax=$?                  if test ! "x$tst" = x0 ; then ptrfound=1 ; fi
209          testoutput_for_prop $1 "dynstat_vvel_mean" "V mean" $2; vmean=$?              done
210          testoutput_for_prop $1 "dynstat_vvel_sd" "V s.d." $2; vsd=$?              if test $ptrfound = '1' ; then
211          dashnum $cg2dres $tmin $tmax $tmean $tsd $smin $smax $smean $ssd \                  eval "HAVE_PTR0"$ii"=t"
212              $umin $umax $umean $usd $vmin $vmax $vmean $vsd              else
213      else                  eval "HAVE_PTR0"$ii"=f"
214          testoutput_ad $1 $2 "precision_grdchk_result"                if test "x$ADM" = x ; then
215      fi                # remove this ptr from the list of output variable to check
216                  # echo "-- ptr test=" $tst "number of var=" `echo $listVar | awk '{print NF}'` 1>&2
217                    listVar=`echo "$listVar" | sed "s/ pt$ii..//g"`
218                  fi
219                fi
220            #   eval 'echo "HAVE_PTR0'$ii' = $HAVE_PTR0'$ii'"' 1>&2
221            done
222            tst=`echo $sVar $listVar | awk '{ for(i=2;i<=NF;i++){if($i==$1)t+=1}; print t }'`
223            if test $tst != 1 ; then
224              if test $tst = 0 ; then echo "==> WARNING: selected var >$sVar< not found" 1>&2
225                     else echo "==> WARNING: found selected var >$sVar< $tst times" 1>&2 ; fi
226              echo "==> WARNING: in checked list:" $listVar 1>&2
227            #- put it back once:
228              listVar=" $sVar "`echo "$listVar " | sed "s/ $sVar / /g"`
229            fi
230            if [ $debug -gt 0 ]; then echo "testoutput_run: listVar(M)='$listVar'" 1>&2 ; fi
231            echo "listVar='$listVar'" > $CDIR"/summary.txt"
232            allargs=""
233            for xx in $listVar
234            do
235              case $xx in
236               'PS')  if [ $debug -gt 0 ]
237                      then echo testoutput_run: testoutput_var $1 cg2d_init_res 1>&2 ; fi
238                      testoutput_var $1 "cg2d_init_res" "Press. Solver (cg2d)" $2 $3; yy=$?
239                      if [ $debug -gt 0 ] ; then echo testoutput_run: cg2dres=$yy 1>&2 ; fi ;;
240              'Cost') testoutput_var $1 "ADM  precision_derivative_cost" "ADM Cost" $2 $3; yy=$? ;;
241              'Grad') testoutput_var $1 "ADM  precision_derivative_grad" "ADM Grad" $2 $3; yy=$? ;;
242               'Tmn') testoutput_var $1 "dynstat_theta_min"  "Theta minimum"  $2 $3; yy=$? ;;
243               'Tmx') testoutput_var $1 "dynstat_theta_max"  "Theta maximum"  $2 $3; yy=$? ;;
244               'Tav') testoutput_var $1 "dynstat_theta_mean" "Theta mean"     $2 $3; yy=$? ;;
245               'Tsd') testoutput_var $1 "dynstat_theta_sd"   "Theta Std.Dev"  $2 $3; yy=$? ;;
246               'Smn') testoutput_var $1 "dynstat_salt_min"  "Salt minimum"    $2 $3; yy=$? ;;
247               'Smx') testoutput_var $1 "dynstat_salt_max"  "Salt maximum"    $2 $3; yy=$? ;;
248               'Sav') testoutput_var $1 "dynstat_salt_mean" "Salt mean"       $2 $3; yy=$? ;;
249               'Ssd') testoutput_var $1 "dynstat_salt_sd"   "Salt Std.Dev"    $2 $3; yy=$? ;;
250               'Umn') testoutput_var $1 "dynstat_uvel_min"  "U minimum"       $2 $3; yy=$? ;;
251               'Umx') testoutput_var $1 "dynstat_uvel_max"  "U maximum"       $2 $3; yy=$? ;;
252               'Uav') testoutput_var $1 "dynstat_uvel_mean" "U mean"          $2 $3; yy=$? ;;
253               'Usd') testoutput_var $1 "dynstat_uvel_sd"   "U Std.Dev"       $2 $3; yy=$? ;;
254               'Vmn') testoutput_var $1 "dynstat_vvel_min"  "V minimum"       $2 $3; yy=$? ;;
255               'Vmx') testoutput_var $1 "dynstat_vvel_max"  "V maximum"       $2 $3; yy=$? ;;
256               'Vav') testoutput_var $1 "dynstat_vvel_mean" "V mean"          $2 $3; yy=$? ;;
257               'Vsd') testoutput_var $1 "dynstat_vvel_sd"   "V Std.Dev"       $2 $3; yy=$? ;;
258            'pt1mn'|'pt2mn'|'pt3mn'|'pt4mn'|'pt5mn') ii=`echo $xx | sed 's/pt//' | sed 's/..$//'`
259               testoutput_var $1 "trcstat_ptracer0"$ii"_min"  "p0"$ii"_min"   $2 $3; yy=$? ;;
260            'pt1mx'|'pt2mx'|'pt3mx'|'pt4mx'|'pt5mx') ii=`echo $xx | sed 's/pt//' | sed 's/..$//'`
261               testoutput_var $1 "trcstat_ptracer0"$ii"_max"  "p0"$ii"_max"   $2 $3; yy=$? ;;
262            'pt1av'|'pt2av'|'pt3av'|'pt4av'|'pt5av') ii=`echo $xx | sed 's/pt//' | sed 's/..$//'`
263               testoutput_var $1 "trcstat_ptracer0"$ii"_mean" "p0"$ii"_mean" $2 $3; yy=$? ;;
264            'pt1sd'|'pt2sd'|'pt3sd'|'pt4sd'|'pt5sd') ii=`echo $xx | sed 's/pt//' | sed 's/..$//'`
265               testoutput_var $1 "trcstat_ptracer0"$ii"_sd"   "p0"$ii"_StDv"  $2 $3; yy=$? ;;
266             'Qntmn') testoutput_var $1 "extforcing_qnet_min" "Qnet minimum"  $2 $3; yy=$? ;;
267             'Qntmx') testoutput_var $1 "extforcing_qnet_max" "Qnet maximum"  $2 $3; yy=$? ;;
268             'Qntav') testoutput_var $1 "extforcing_qnet_mean" "Qnet mean"    $2 $3; yy=$? ;;
269             'Qntsd') testoutput_var $1 "extforcing_qnet_sd"  "Qnet Std.Dev"  $2 $3; yy=$? ;;
270             'aSImn') testoutput_var $1 "seaice_area_min"   "SIce Area min"   $2 $3; yy=$? ;;
271             'aSImx') testoutput_var $1 "seaice_area_max"   "SIce Area max"   $2 $3; yy=$? ;;
272             'aSIav') testoutput_var $1 "seaice_area_mean"  "SIce Area mean"  $2 $3; yy=$? ;;
273             'aSIsd') testoutput_var $1 "seaice_area_sd"    "SIce Area StDv"  $2 $3; yy=$? ;;
274             'hSImn') testoutput_var $1 "seaice_heff_min"   "SIce Heff min"   $2 $3; yy=$? ;;
275             'hSImx') testoutput_var $1 "seaice_heff_max"   "SIce Hell max"   $2 $3; yy=$? ;;
276             'hSIav') testoutput_var $1 "seaice_heff_mean"  "SIce Hell mean"  $2 $3; yy=$? ;;
277             'hSIsd') testoutput_var $1 "seaice_heff_sd"    "SIce Hell StDv"  $2 $3; yy=$? ;;
278            'AthSiG') testoutput_var $1 "thSI_Ice_Area_G" "thSIc Area Global" $2 $3; yy=$? ;;
279            'AthSiS') testoutput_var $1 "thSI_Ice_Area_S" "thSIc Area South"  $2 $3; yy=$? ;;
280            'AthSiN') testoutput_var $1 "thSI_Ice_Area_N" "thSIc Area North"  $2 $3; yy=$? ;;
281            'HthSiG') testoutput_var $1 "thSI_IceH_ave_G" "thSIc H Global"    $2 $3; yy=$? ;;
282            'HthSiS') testoutput_var $1 "thSI_IceH_ave_S" "thSIc H South"     $2 $3; yy=$? ;;
283            'HthSiN') testoutput_var $1 "thSI_IceH_ave_N" "thSIc H North"     $2 $3; yy=$? ;;
284                  *) yy=99; echo "WARNING: asking for var=$xx : not recognized !" 1>&2 ;;
285              esac
286              if test $xx = $sVar
287              then allargs="$allargs > $yy <"
288              else allargs="$allargs $yy"
289              fi
290            done
291    
292            nbVar=`echo $listVar | awk '{print NF}'`
293            if [ $nbVar -lt $LEN_CHECK_LIST ] ; then
294            #-- fill line (up to standard length) with dot:
295              adNul=`expr $LEN_CHECK_LIST - $nbVar | awk '{for(i=1;i<=$1;i++){print "."}}'`
296              echo $allargs $adNul
297            else
298              echo $allargs
299            fi
300    # <-- same processing for adjoint & forward test
301  }  }
302    
303  genmakemodel()  genmakemodel()
# Line 211  genmakemodel() Line 306  genmakemodel()
306      if test "x$NOGENMAKE" = xt ; then      if test "x$NOGENMAKE" = xt ; then
307          echo "genmake skipped!"          echo "genmake skipped!"
308      else      else
309          GENMAKE2="$BASH ../../../tools/genmake2"          if test "x$BASH" = x ; then
310                GENMAKE2="../../../tools/genmake2"
311            else
312                GENMAKE2="$BASH ../../../tools/genmake2 -bash $BASH"
313            fi
314          (          (
315              cd $1;              cd $1;
316              command="$GENMAKE2  -ds -m $MAKE"              command="$GENMAKE2  -ds -m $MAKE"
# Line 219  genmakemodel() Line 318  genmakemodel()
318                  command="$command --mods=../code"                  command="$command --mods=../code"
319              else              else
320                  command="$command --mods=../code_ad"                  command="$command --mods=../code_ad"
                 command="$command -adof=../../../tools/adjoint_options/adjoint_staf"  
321              fi              fi
322              if test "x$OPTFILE" != xNONE ; then              if test "x$OPTFILE" != xNONE ; then
323                  command="$command --optfile=$OPTFILE"                  command="$command --optfile=$OPTFILE"
# Line 227  genmakemodel() Line 325  genmakemodel()
325              if test "x$IEEE" != x ; then              if test "x$IEEE" != x ; then
326                  command="$command -ieee"                  command="$command -ieee"
327              fi              fi
328                if test "x$GSL" = xt ; then
329                    command="$command -gsl"
330                fi
331                if test "x$MPI" = xt ; then
332                    command="$command -mpi"
333                fi
334                if test "x$TS" = xt ; then
335                    command="$command -ts"
336                fi
337                if test "x$PAPIS" = xt ; then
338                    command="$command -papis"
339                else
340                if test "x$PCLS" = xt ; then
341                    command="$command -pcls"
342                fi
343                fi
344              printf 'genmake ... ' 1>&2              printf 'genmake ... ' 1>&2
345              $command > make.log 2>&1              $command > make.log 2>&1
346              RETVAL=$?              RETVAL=$?
347              cp Makefile $CDIR              #  Reduce the size of the testing emails!
348                head -100 Makefile > $CDIR/Makefile_head
349              if test "x$RETVAL" != x0 ; then              if test "x$RETVAL" != x0 ; then
350                  tail make.log                  tail make.log
351                  echo "genmakemodel: genmake failed" 1>&2                  echo "genmakemodel: genmake failed" 1>&2
# Line 247  makeclean() Line 362  makeclean()
362  {  {
363      # makeclean directory      # makeclean directory
364      if test "x$NOCLEAN" = xt ; then      if test "x$NOCLEAN" = xt ; then
365          echo "make CLEAN skipped!"          echo "make Clean skipped!"
366      else      else
367          (          (
368              cd $1;              cd $1;
369              if test -e output.txt ; then              #if test -e $OUTPUTFILE ; then rm -f $OUTPUTFILE ; fi
                 rm -f output.txt  
             fi  
             printf 'make CLEAN ... ' 2>&1  
370              if test -r Makefile ; then              if test -r Makefile ; then
371                  $MAKE CLEAN >> make.log 2>&1                  printf 'clean build-dir: make Clean ... ' 2>&1
372                    $MAKE Clean >> make.log 2>&1
373                  RETVAL=$?                  RETVAL=$?
374                  if test "x$RETVAL" != x0 ; then                  if test "x$RETVAL" != x0 ; then
375                      tail make.log                      tail make.log
376                      echo "makeclean: \"make CLEAN\" failed" 1>&2                      echo "makeclean: \"make Clean\" failed" 1>&2
377                      cp make.log $CDIR"/make.log"                      cp make.log $CDIR"/make.log"
378                      return 1                      return 1
379                  fi                  fi
# Line 271  makeclean() Line 384  makeclean()
384      fi      fi
385  }  }
386    
387    run_clean()
388    {
389        # run_clean directory
390        if test "x$NOCLEAN" = xt ; then
391            echo "run_clean skipped!"
392        else
393            (
394                cd $1;
395                printf 'clean run-dir ... ' 2>&1
396                # part of what is done after "make clean" when doing "make CLEAN"
397                find . -name "*.meta" -exec rm {} \;
398                find . -name "*.data" -exec rm {} \;
399                find . -name "fort.*" -exec rm {} \;
400                find . -type l -exec rm {} \;
401                rm -f $EXECUTABLE *.txt STD* *diagnostics.log datetime
402                rm -rf mnc_test_*
403                rm -f *_MIT_CE_000.opt0000 costfunction*0000
404                echo successful 1>&2
405                exit 0
406            )
407        fi
408    }
409    
410  makedependmodel()  makedependmodel()
411  {  {
412      # makedependmodel directory      # makedependmodel directory
# Line 302  makemodel() Line 438  makemodel()
438          if test -r Makefile ; then          if test -r Makefile ; then
439              printf 'make ... ' 1>&2              printf 'make ... ' 1>&2
440              if test "x$ADM" = x ; then              if test "x$ADM" = x ; then
441                  $MAKE >> make.log 2>&1                  if test "x$JOBS" = x ; then
442                        $MAKE >> make.log 2>&1
443                    else
444                        $MAKE -j $JOBS >> make.log 2>&1
445                    fi
446              else              else
447                  $MAKE adall >> make.log 2>&1                  $MAKE adall >> make.log 2>&1
448              fi              fi
# Line 329  symlink_mpifiles() Line 469  symlink_mpifiles()
469      code_dir=$2      code_dir=$2
470      BUILD_DIR=$dir/$3      BUILD_DIR=$dir/$3
471      CODE_DIR=$dir/$code_dir      CODE_DIR=$dir/$code_dir
472        
473      # These are files that should replace their counter-part when using -mpi      # These are files that should replace their counter-part when using -mpi
474      MPI_FILES=`(cd $CODE_DIR; find . -name "*_mpi")`      MPI_FILES=`(cd $CODE_DIR; find . -name "*_mpi" -print)`
475    
476      #  Is this an MPI run?      #  Is this an MPI run?
477      if test "x$MPI" = xt ; then      if test "x$MPI" = xt ; then
# Line 344  symlink_mpifiles() Line 484  symlink_mpifiles()
484              RETVAL=$?              RETVAL=$?
485              if test "x$RETVAL" != x0 ; then              if test "x$RETVAL" != x0 ; then
486                  if ! test -f $BUILD_DIR/$i ; then                  if ! test -f $BUILD_DIR/$i ; then
487                  #echo Linking $name to $i                      #echo Linking $name to $i
488                      (cd $BUILD_DIR; ln -sf ../$code_dir/$i $name)                      (cd $BUILD_DIR; ln -sf ../$code_dir/$i $name)
489                  fi                  fi
490              fi              fi
491          done          done
492      else      else
493      # NO: We undo any _mpi symbolically linked files          # NO: We undo any _mpi symbolically linked files
494          for ii in $MPI_FILES ; do          for ii in $MPI_FILES ; do
495              i=`echo $ii | sed 's:^\./::'`              i=`echo $ii | sed 's:^\./::'`
496              name=`echo $i | sed 's:_mpi::' `              name=`echo $i | sed 's:_mpi::' `
497              if test -L $BUILD_DIR/$name ; then              if test -L $BUILD_DIR/$name ; then
498                  linktarg=`(cd $BUILD_DIR; readlink $name)`                  cmp $BUILD_DIR/$name "../$code_dir/$name"_mpi > /dev/null 2>&1
499                  if test $linktarg = "../$code_dir/$name"_mpi ; then                  RETVAL=$?
500                  #echo Un-linking $name from $linktarg                  if test "x$RETVAL" = x0 ; then
501                        #echo Un-linking $name from $linktarg
502                      rm -f $BUILD_DIR/$name                      rm -f $BUILD_DIR/$name
503                  fi                  fi
504              fi              fi
# Line 368  symlink_mpifiles() Line 509  symlink_mpifiles()
509    
510  linkdata()  linkdata()
511  {  {
512      # linkdata flag      # linkdata run_dir input_dir_1 input_dir_2 ...
513      #      #
514      # symbolically link data files to run directory      # symbolically link data files to run directory
515      if test "x$1" = x1 ; then      if test -d $1 ; then
516          (          (
517              cd $2              cd $1 ; shift
518              if test "x$ADM" = x ; then              if test -r "../"$1"/eedata.mth" ; then
519                  files=`( cd ../input ; ls -1 | grep -v CVS )`              # found eedata.mth in 1rst input dir and it is readable
520                  for i in $files ; do                  if test "x$MULTI_THREAD" = "xt" ; then
521                      if test ! -d "../input/"$i ; then                  # multi-threaded test: remove symbolic link & link eedata.mth
522                          ln -sf "../input/"$i $i                      if test -h eedata ; then rm -f eedata ; fi
523                      fi                      if test ! -r eedata ; then
524                  done                          ln -sf "../"$1"/eedata.mth" eedata ;
525              else                          printf 'eedata.mth ' 1>&2
                 files=`( cd ../input ; ls -1 *.bin | grep -v CVS )`  
                 for i in $files ; do  
                     if test ! -d "../input/"$i ; then  
                         ln -sf "../input/"$i $i  
526                      fi                      fi
527                  done                  else
528                  files=`( cd ../input_ad ; ls -1 | grep -v CVS )`                  # not multi-threaded test: remove eedata symbolic link
529                  for i in $files ; do                      if test -h eedata ; then rm -f eedata ; fi
530                      if test ! -d "../input_ad/"$i ; then                  fi
                         ln -sf "../input_ad/"$i $i  
                     fi  
                 done  
531              fi              fi
532                prevDir='NONE'
533                for ldir in $* ; do
534                    if test -d "../"$ldir -a $ldir != $prevDir ; then
535                        printf 'ldir='${ldir} 1>&2
536                        files=`( cd "../"$ldir ; ls -1 | grep -v CVS )`
537                        for i in $files ; do
538                            if test ! -d "../"$ldir/$i ; then
539                                if test ! -r $i  ; then
540                                    printf ' '$i 1>&2
541                                    ln -sf "../"$ldir"/"$i $i
542                                fi
543                            fi
544                        done
545                        if test -x "../"$ldir"/"prepare_run ; then
546                            "../"$ldir"/"prepare_run
547                        fi
548                        printf ' ; ' 1>&2
549                    fi
550                    prevDir=$ldir
551                done
552          )          )
553      fi      fi
554  }  }
# Line 407  runmodel() Line 561  runmodel()
561      #  (where "$COMMAND" is relative to "directory")      #  (where "$COMMAND" is relative to "directory")
562      (      (
563          cd $1          cd $1
564          printf 'runmodel ... ' 1>&2          printf 'runmodel in %s ...' $1 1>&2
565          # make output.txt          # make output.txt
566          $COMMAND >> run.log 2>&1          echo
567          RETVAL=$?          if test -L $EXECUTABLE -a -x "../"$builddir"/"$EXECUTABLE ; then
568          if test "x$RETVAL" = x0 ; then              diff -q $EXECUTABLE "../"$builddir"/"$EXECUTABLE > /dev/null 2>&1
569              echo successful 1>&2              outD=$? ; if test $outD != 0 ; then rm -f $EXECUTABLE ; fi
570              if test "x$ADM" = x ; then          fi
571                  cp output.txt $CDIR"/output.txt"          if test ! -x $EXECUTABLE -a -x "../"$builddir"/"$EXECUTABLE ; then
572                echo " link" $EXECUTABLE "from dir ../"$builddir > run.log_tmp
573                ln -sf "../"$builddir"/"$EXECUTABLE .
574            fi
575            if test ! -x $EXECUTABLE ; then
576                    rm -f $RUNLOG ; touch $RUNLOG
577                    if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
578                    echo " no executable:" $EXECUTABLE >> $RUNLOG
579                    RETVAL=8
580                    ENDVAL=-1
581            else
582                if test ! -f $OUTPUTFILE -o $OUTPUTFILE -ot $EXECUTABLE ; then
583                  # output do not exist or is older than executable:
584                    rm -f $RUNLOG ; touch $RUNLOG
585                    if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
586                    ( eval $COMMAND ) >> $RUNLOG 2>&1
587                    RETVAL=$?
588              else              else
589                  cp output.txt_adm $CDIR"/output.txt_adm"                  RETVAL=0
590                    if test -f $RUNLOG ; then
591                        if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
592                        echo "---------->> $OUTPUTFILE is up to date " >> $RUNLOG 2>&1
593                    else
594                        touch $RUNLOG
595                        if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
596                        echo "---------->> $OUTPUTFILE is up to date " >> $RUNLOG 2>&1
597                        echo " no previous $RUNLOG: assume NORMAL END" >> $RUNLOG 2>&1
598                    fi
599              fi              fi
600                ENDVAL=`cat $RUNLOG | grep -v 'ABNORMAL END' | grep -c 'NORMAL END'`
601            fi
602            rm -f run.log_tmp
603            #if test "x$RETVAL" = x0 ; then
604            if [ $RETVAL -eq 0 -a $ENDVAL -gt 0 ] ; then
605                tail $RUNLOG
606                echo successful 1>&2
607                # === Reduce the size of the testing emails!
608                #cp $OUTPUTFILE $CDIR"/"$OUTPUTFILE
609                if test -s STDERR.0000 ; then cp STDERR.0000 $CDIR"/STDERR.0000" ; fi
610              return 0              return 0
611          else          else
612              tail run.log              tail $RUNLOG
613              echo failed 1>&2              echo failed '(run:' $RETVAL ' end:' $ENDVAL ')' 1>&2
614              cp run.log $CDIR"/run.log"              cp $RUNLOG $CDIR"/"$RUNLOG
615                if test -s STDERR.0000 ; then cp STDERR.0000 $CDIR"/STDERR.0000" ; fi
616              return 1              return 1
617          fi          fi
618      )      )
# Line 432  createcodelet() Line 622  createcodelet()
622  {  {
623      # create codelet for comparing model output      # create codelet for comparing model output
624    
625      echo -n "creating the comparison code...  "      printf "creating the comparison code (using CC=$CC)...  "
626      cat > tmp_cmpnum.c <<EOF      cat > tr_cmpnum.c <<EOF
627  #include <stdio.h>  #include <stdio.h>
628  #include <math.h>  #include <math.h>
629  int main( int argc, char** argv )  {  int main( int argc, char** argv )  {
630    int linnum,best;    int linnum,cmplin,best,lncnt;
631    double a,b,diff;    double a,b,abave,relerr;
632    best = -16;    best = -22;
633    while( 1 )  {    lncnt = 0;
634      while( 1 & ( (lncnt+=1) < 999 ) )  {
635      scanf("%d", &linnum);      scanf("%d", &linnum);
636      if (linnum == -1)  break;      if (linnum == -1)  break;
637      scanf("%lf", &a);  scanf("%lf", &b);      scanf("%lf", &a);  scanf("%lf", &b);
638      diff = 0.5*(fabs(a)+fabs(b));      abave = 0.5*(fabs(a)+fabs(b));
639      if (diff > 1.e-12) {      if ( abave == abave ) {
640        diff=fabs(a-b)/diff;        if (abave > 0.0) {
641        if (diff > 0.0) {          relerr=fabs(a-b)/abave;
642          linnum = (int)log10(diff);          if (relerr > 0.0) { cmplin = (int)rint(log10(relerr)); }
643          best = (best > linnum) ? best : linnum;          else { cmplin = -16 ; }
644            best = (best > cmplin) ? best : cmplin; }
645          else { cmplin = -22 ; }
646       /* printf("%d ; %lf ; %lf\n",cmplin,a,b); */
647        }        }
648        else {     else {
649          if (best == -16 && diff != 0)  best = -22;     /* printf("%lf ; %lf ; %lf\n",abave,a,b); */
650        }        break; }
     }  
651    }    }
652      if (lncnt == 999) best=-29;
653      if (linnum != -1) best=-99;
654    printf("%d\n", -best);    printf("%d\n", -best);
655    return 0;    return 0;
656  }  }
657  EOF  EOF
658      cc -o tmp_cmpnum tmp_cmpnum.c -lm      $CC -o tr_cmpnum tr_cmpnum.c -lm
659    
660      if [ -x ./tmp_cmpnum ]; then      if [ -x ./tr_cmpnum ]; then
661          echo "OK"          echo "OK"
662          return 0          return 0
663      else      else
664          echo          echo
665          echo "ERROR: failed to compile comparison code"          echo "ERROR: failed to compile comparison code -- please specify"
666            echo "  a C compiler using the CC environment variable."
667          exit 1          exit 1
668      fi      fi
669  }  }
# Line 479  formatresults() Line 675  formatresults()
675      nm=$1      nm=$1
676      printf '%s %s %s %s' $2 $3 $4 $5      printf '%s %s %s %s' $2 $3 $4 $5
677      shift; shift; shift; shift; shift;      shift; shift; shift; shift; shift;
678      printf '%3s' $@      listPrt=$@
679        listRes=`echo $listPrt | sed 's/>//' | sed 's/<//'`
680        xx=`echo $listPrt | sed 's/.*>//' | sed 's/<.*//' | awk '{print $1}'`
681        printf '%3s' $listPrt
682    #   line below does not work on hp-ux_ia64 : do those substitutions later on
683    #   printf '%3s' $listPrt | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</'
684            
685      if [ $1 = '--' ]; then      if [ $xx = '..' ]; then
686            printf ' N/O '
687        elif [ $xx = '--' ]; then
688            printf ' N/O '
689        elif [ $xx = 99 ]; then
690          printf ' N/O '          printf ' N/O '
691      else      else
692          if [ $1 -gt 12 ]; then          if [ $xx -ge $MATCH_CRIT ]; then
693              printf ' pass'              printf ' pass'
694          else          else
695              printf ' FAIL'              printf ' FAIL'
# Line 495  formatresults() Line 700  formatresults()
700            
701  }  }
702    
 show_help()  
 {  
     cat - << EOF  
 $0 [-help] [-quick] [-verbose] dir1 [dir2] [...]  
   
  -help|-h      Show this help message  
  -quiet     Reduce the amount of output  
  -verbose   Produce copious amounts of output  
  -debug     Produce even more output which will mean nothing to most  
  -force     Do "make CLEAN" before compiling. This forces a complete rebuild.  
  -clean     Do "make CLEAN" after compiling and testing.  
  -cleanup   Aggresively removes all model output, executables and object files  
             and then exits. Use with care.  
   
 Normal usage:  
  $0 *       Configure, compile, run and analyze in all experiment directories  
 EOF  
 }  
   
703  scandirs()  scandirs()
704  {  {
705      if [ $# -eq 0 ]; then      if [ $# -eq 1 ]; then
706          for arg in * ; do          for arg in * ; do
707              test -d $arg/input && echo $arg              test -f $arg/$1 && echo $arg
708          done          done
709      else      else
710          echo $*          echo $*
711      fi      fi
712  }  }
713    
# Line 533  scandirs() Line 719  scandirs()
719  debug=0  debug=0
720  verbose=1  verbose=1
721  clean=0  clean=0
 expts=''  
 # ieee=1  
722    
723  IEEE=  IEEE=true
724  if test "x$MITGCM_IEEE" != x ; then  if test "x$MITGCM_IEEE" != x ; then
725      IEEE=$MITGCM_IEEE      IEEE=$MITGCM_IEEE
726  fi  fi
727    GSL=f
728    
729  CLEANUP=f  CLEANUP=f
730  QUICK=f  QUICK=f
731  NOGENMAKE=f  NOGENMAKE=f
732  NOCLEAN=f  NOCLEAN=f
733  NODEPEND=f  NODEPEND=f
734    POSTCLEAN=f
735    
736  BASH=  BASH=
737  OPTFILE=NONE  OPTFILE=NONE
738  ADDRESSES=  ADDRESSES=
739  TESTDIRS=  TESTDIRS=
740    SKIPDIRS=
741  MPACKDIR="../tools/mpack-1.6"  MPACKDIR="../tools/mpack-1.6"
742  HAVE_MPACK=  HAVE_MPACK=
743  MPACK="$MPACKDIR/mpack"  MPACK=
744  COMMAND=  COMMAND=
745  MAKE=make  if test "x$MAKE" = x ; then
746        MAKE=make
747    fi
748    if test "x$CC" = x ; then
749        CC=cc
750    fi
751    JOBS=
752  MPI=f  MPI=f
753    MULTI_THREAD=f
754    OUTDIR=
755    DELDIR=
756    
757  ADM=  ADM=
758    
759  echo -n "parsing options...  "  # list of pTracers to check for monitor output
760    PTRACERS_NUM="1 2 3 4 5"
761    
762    MATCH_CRIT=13
763    
764    printf "parsing options...  "
765    
766  ac_prev=  ac_prev=
767  for ac_option ; do  for ac_option ; do
# Line 589  for ac_option ; do Line 789  for ac_option ; do
789              ac_prev=ADDRESSES ;;              ac_prev=ADDRESSES ;;
790          -addr=* | --addr=*)          -addr=* | --addr=*)
791              ADDRESSES=$ac_optarg ;;              ADDRESSES=$ac_optarg ;;
792            -mpackdir | --mpackdir | -mpd | --mpd)
793                ac_prev=MPACKDIR ;;
794            -mpackdir=* | --mpackdir=* | -mpd=* | --mpd=*)
795                MPACKDIR=$ac_optarg ;;
796    
797          -tdir | --tdir | -t | --t)          -tdir | --tdir | -t | --t)
798              ac_prev=TESTDIRS ;;              ac_prev=TESTDIRS ;;
799          -tdir=* | --tdir=*)          -tdir=* | --tdir=*)
800              TESTDIRS=$ac_optarg ;;              TESTDIRS=$ac_optarg ;;
801    
802            -skipdir | --skipdir | -skd | --skd)
803                ac_prev=SKIPDIRS ;;
804            -skipdir=* | --skipdir=*)
805                SKIPDIRS=$ac_optarg ;;
806    
807          -bash | --bash | -b | --b)          -bash | --bash | -b | --b)
808              ac_prev=BASH ;;              ac_prev=BASH ;;
809          -bash=* | --bash=*)          -bash=* | --bash=*)
# Line 610  for ac_option ; do Line 819  for ac_option ; do
819          -make=* | --make=*)          -make=* | --make=*)
820              MAKE=$ac_optarg ;;              MAKE=$ac_optarg ;;
821    
822            -odir | --odir)
823                ac_prev=OUTDIR ;;
824            -odir=* | --odir=*)
825                OUTDIR=$ac_optarg ;;
826    
827            -ptracers | --ptracers | -ptr | --ptr)
828                ac_prev=PTRACERS_NUM ;;
829            -ptracers=* | --ptracers=* | -ptr=* | --ptr=*)
830                PTRACERS_NUM=$ac_optarg ;;
831    
832            -match | --match ) ac_prev=MATCH_CRIT ;;
833            -match=* | --match=* ) MATCH_CRIT=$ac_optarg ;;
834    
835            -j) ac_prev=JOBS ;;
836            -j=*) JOBS=$ac_optarg ;;
837    
838          -clean | --clean)          -clean | --clean)
839              CLEANUP=t ;;              CLEANUP=t ; DELDIR=t ;;
840    
841          -quick | --quick | -q | --q)          -quick | --quick | -q | --q)
842              QUICK=t ;;              QUICK=t ;;
# Line 622  for ac_option ; do Line 847  for ac_option ; do
847          -nodepend | --nodepend | -nd | --nd)          -nodepend | --nodepend | -nd | --nd)
848              NODEPEND=t ;;              NODEPEND=t ;;
849    
850            -postclean | --postclean | -pc | --pc)
851                POSTCLEAN=t ;;
852    
853          -mpi) MPI=t ;;          -mpi) MPI=t ;;
854    
855            -mth) MULTI_THREAD=t ;;
856    
857          -adm | -ad) ADM=t ;;          -adm | -ad) ADM=t ;;
858    
859          -ieee) IEEE=true ;;          -ieee) IEEE=true ;;
860          -noieee) IEEE= ;;          -noieee) IEEE= ;;
861            -gsl) GSL=t ;;
862    
863          -verbose) verbose=2 ;;          -verbose) verbose=2 ;;
864          -debug) debug=1 ;;          -debug) debug=1 ;;
865          -quiet) verbose=0 ;;          -quiet) verbose=0 ;;
866    
867            -deldir | -dd) DELDIR=t ;;
868    
869            -ts) TS=t;;
870    
871            -papis) PAPIS=t;;
872    
873            -pcls) PCL=t;;
874    
875          -*)          -*)
876              echo "Error: unrecognized option: "$ac_option              echo "Error: unrecognized option: "$ac_option
877              usage              usage
# Line 653  if test "x$QUICK" = xt ; then Line 892  if test "x$QUICK" = xt ; then
892      NODEPEND=t      NODEPEND=t
893  fi  fi
894    
895    #- setting for forward or ADM testing
896    if test "x$ADM" = xt ; then
897        code_dir=code_ad
898        inputdir=input_ad
899        ref_outp="output_adm.txt"
900        EXECUTABLE="mitgcmuv_ad"
901    else
902        code_dir=code
903        inputdir=input
904        ref_outp="output.txt"
905        EXECUTABLE="mitgcmuv"
906    fi
907    
908  if test "x$TESTDIRS" = x ; then  if test "x$TESTDIRS" = x ; then
909      TESTDIRS=`scandirs`      LIST=`scandirs results/$ref_outp`
910    else
911        #- expand group of experiments:
912        LIST=" "
913        for xx in $TESTDIRS
914        do
915          case $xx in
916            'basic') LIST=${LIST}" aim.5l_cs hs94.128x64x5 ideal_2D_oce"
917                     LIST=${LIST}" lab_sea tutorial_baroclinic_gyre"
918                     LIST=${LIST}" tutorial_global_oce_latlon tutorial_plume_on_slope"
919                    ;;
920            'tutorials')
921                     LIST=${LIST}" "`ls | grep 'tutorial_'` ;;
922            *)       LIST=${LIST}" "$xx ;;
923          esac
924        done
925  fi  fi
926    #echo 'LIST='${LIST}'<'
927    #- skip dirs, remove duplicate and non-directory:
928    TESTDIRS=" "
929    count=0
930    for xx in $LIST
931    do
932        yy=`echo $SKIPDIRS | grep -c $xx`
933        if test $yy = 0 ; then
934            if test -d $xx ; then
935                yy=`echo $TESTDIRS | grep -c $xx`
936                if test $yy = 0 ; then TESTDIRS=${TESTDIRS}" "$xx ; fi
937            else count=1 ;
938                echo ""; echo -n " -- skip \"$xx\" (not a directory !)"
939            fi
940        else
941            if test $count = 1 ; then echo -n ", \"$xx\""
942            else count=1 ; echo "" ;  echo -n " skip: \"$xx\""
943            fi
944        fi
945    done
946    if test $count = 1 ; then echo "" ; echo -n " ... " ; fi
947    #echo 'TESTDIRS='${TESTDIRS}'<'
948    
949  if test "x$OPTFILE" = xNONE -a "x$MITGCM_OF" != x ; then  if test "x$OPTFILE" = xNONE -a "x$MITGCM_OF" != x ; then
950      OPTFILE=$MITGCM_OF      OPTFILE=$MITGCM_OF
951  fi  fi
952    
953  if test "x$ADM" = xt -a "x$COMMAND" = x ; then  RUNLOG="run.log"
954      COMMAND="./mitgcmuv_ad > output.txt_adm 2>&1"  OUTPUTFILE=$ref_outp
 fi  
   
955  if test "x$COMMAND" = x ; then  if test "x$COMMAND" = x ; then
956      COMMAND="make output.txt"      COMMAND="./$EXECUTABLE > $OUTPUTFILE"
957    fi
958    if test "x$MPI" = xt ; then
959        OUTPUTFILE="STDOUT.0000"
960  fi  fi
961    
962  echo "OK"  echo "OK (COMMAND= $COMMAND )"
963    
964    # set the Default List of output variables to be checked:
965    #  (use default or load experiment-specific list from file "tr_checklist")
966    # content : 1rst = main variable used to decide if it pass or FAIL
967    #         others = number of matching digits to be printed in summary.txt
968    if test "x$ADM" = x ; then
969        DEF_CHECK_LIST='PS PS T+ S+ U+ V+ pt1+ pt2+ pt3+ pt4+ pt5+'
970        EMPTY_RESULTS='.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..'
971        LEN_CHECK_LIST=`echo $DEF_CHECK_LIST | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' | awk '{print NF-1}'`
972        ii=`echo $EMPTY_RESULTS | awk '{print NF}'`
973        EMPTY_RESULTS=$EMPTY_RESULTS`expr $LEN_CHECK_LIST - $ii | awk 'BEGIN{FS=":"}{for(i=1;i<=$1;i++){printf "  ."}}'`
974    else
975        DEF_CHECK_LIST='Grad Cost Grad'
976        EMPTY_RESULTS='.. ..'
977        LEN_CHECK_LIST=`echo $DEF_CHECK_LIST | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' | awk '{print NF-1}'`
978    fi
979    
980  #  create the FORTRAN comparison code  #  create the FORTRAN comparison code
981  createcodelet  createcodelet
982    
983  #  build the mpack utility  #  build the mpack utility (if ADDRESSES = NONE, do it to test the build)
984  if test "x$ADDRESSES" = xNONE -o "x$ADDRESSES" = x ; then  if test "x$ADDRESSES" = x ; then
985      echo "skipping mpack build"      echo "skipping mpack build"
986  else  else
987      build_mpack      build_mpack
988  fi  fi
989    
990  #  Create a uniquely named directory to store results  #  Create a uniquely named directory to store results
991    CMDLINE=$0
992    for xx in "$@" ; do nw=`echo $xx | wc -w`
993        if test $nw = '1' ; then CMDLINE="$CMDLINE $xx"
994                            else CMDLINE="$CMDLINE '$xx'" ; fi
995    done
996    #for xx in "$@" ; do CMDLINE="$CMDLINE '$xx'" ; done
997  MACH=`hostname`  MACH=`hostname`
998  UNAMEA=`uname -a`  UNAMEA=`uname -a`
999  DATE=`date +%Y%m%d`  DATE=`date +%Y%m%d`
1000  BASE="tr_"$MACH"_"$DATE"_"  BASE="tr_"$MACH"_"$DATE"_"
1001    if test "x$OUTDIR" != x ; then
1002        BASE="tr_"$OUTDIR"_"$DATE"_"
1003    fi
1004  DNUM=0  DNUM=0
1005  DRESULTS="$BASE$DNUM"  DRESULTS="$BASE$DNUM"
1006  while test -e $DRESULTS ; do  while test -e $DRESULTS ; do
# Line 699  if test "x$RETVAL" != x0 ; then Line 1014  if test "x$RETVAL" != x0 ; then
1014      exit 1      exit 1
1015  fi  fi
1016  SUMMARY="$DRESULTS/summary.txt"  SUMMARY="$DRESULTS/summary.txt"
 echo -n "Start time:  " >> $SUMMARY  
1017  start_date=`date`  start_date=`date`
1018  echo $start_date > $SUMMARY  echo $start_date > $SUMMARY
1019    echo 'run:' $CMDLINE >> $SUMMARY
1020    echo 'on :' $UNAMEA  >> $SUMMARY
1021    
1022  of_path=  of_path=
1023  if test "x$OPTFILE" != xNONE ; then  if test "x$OPTFILE" != xNONE ; then
# Line 731  fi Line 1047  fi
1047  echo  echo
1048  echo >> $SUMMARY  echo >> $SUMMARY
1049  if test "x$ADM" = x ; then  if test "x$ADM" = x ; then
1050      cat << EOF | tee -a $SUMMARY      if [ $MATCH_CRIT -lt 10 ] ;
1051                  T           S           U           V      then line_0="default  "$MATCH_CRIT ;
1052  G D M    c        m  s        m  s        m  s        m  s      else line_0="default "$MATCH_CRIT ; fi
1053  E p a R  g  m  m  e  .  m  m  e  .  m  m  e  .  m  m  e  .         line_0="$line_0  ----T-----  ----S-----  ----U-----  ----V-----"
1054  N n k u  2  i  a  a  d  i  a  a  d  i  a  a  d  i  a  a  d  #   line_0="            ----T-----  ----S-----  ----U-----  ----V-----"
1055  2 d e n  d  n  x  n  .  n  x  n  .  n  x  n  .  n  x  n  .      line_1="G D M    c        m  s        m  s        m  s        m  s"
1056        line_2="E p a R  g  m  m  e  .  m  m  e  .  m  m  e  .  m  m  e  ."
1057  EOF      line_3="N n k u  2  i  a  a  d  i  a  a  d  i  a  a  d  i  a  a  d"
1058        line_4="2 d e n  d  n  x  n  .  n  x  n  .  n  x  n  .  n  x  n  ."
1059        for ii in $PTRACERS_NUM ; do
1060            line_0="$line_0  --PTR 0"$ii"--"
1061            line_1="$line_1        m  s"
1062            line_2="$line_2  m  m  e  ."
1063            line_3="$line_3  i  a  a  d"
1064            line_4="$line_4  n  x  n  ."
1065        done
1066        echo "$line_0" | tee -a $SUMMARY
1067        echo "$line_1" | tee -a $SUMMARY
1068        echo "$line_2" | tee -a $SUMMARY
1069        echo "$line_3" | tee -a $SUMMARY
1070        echo "$line_4" | tee -a $SUMMARY
1071        echo " "       | tee -a $SUMMARY
1072  else  else
1073      echo "ADJOINT=true" >> $SUMMARY      echo "ADJOINT=true" >> $SUMMARY
1074      echo >> $SUMMARY      echo >> $SUMMARY
1075        if [ $MATCH_CRIT -lt 10 ] ;
1076        then line_0="default     "$MATCH_CRIT ;
1077        else line_0="default    "$MATCH_CRIT ; fi
1078        echo "$line_0" | tee -a $SUMMARY
1079      cat << EOF | tee -a $SUMMARY      cat << EOF | tee -a $SUMMARY
1080  G D M    C  G  G D M    C  G
1081  E p a R  o  r  E p a R  o  r
# Line 754  fi Line 1088  fi
1088  #  ...and each test directory...  #  ...and each test directory...
1089  for dir in $TESTDIRS ; do  for dir in $TESTDIRS ; do
1090            
1091        # set builddir & rundir:
1092        builddir="build"
1093        if test ! -d $dir/$builddir ; then mkdir $dir/$builddir ; fi
1094        rundir="run"
1095        if test ! -d $dir/$rundir ; then
1096            rundir=$builddir
1097        fi
1098        CODE_DIR=$dir/$code_dir
1099        BUILD_DIR=$dir/$builddir
1100    
1101      #  Cleanup only!      #  Cleanup only!
1102      if test "x$CLEANUP" = xt ; then      if test "x$CLEANUP" = xt ; then
1103          if test -r $dir/build/Makefile ; then          if test -r $BUILD_DIR/Makefile ; then
1104              ( cd $dir/build ; make CLEAN )              echo '  ------  clean dir:' $dir/$builddir
1105                ( cd $BUILD_DIR ; make CLEAN )
1106          fi          fi
1107          if test -r $dir/input/Makefile ; then          if test -d $dir/$rundir/CVS ; then
1108              ( cd $dir/input ; make CLEAN )              echo '  ------  clean dir:' $dir/$rundir
1109                run_clean $dir/$rundir
1110          fi          fi
1111            (
1112                cd $dir
1113                rm -rf tr_run.*
1114            )
1115          continue          continue
1116      fi      fi
1117    
1118      #  Verify that the testdir exists and contains previous      #  Verify that the testdir exists and contains previous
1119      #  results in the correct location--or skip this directory!      #  results in the correct location--or skip this directory!
1120      fout=      fout=$dir"/results/"$ref_outp
     if test "x$ADM" = x ; then  
         fout=$dir"/results/output.txt"  
     else  
         fout=$dir"/results_ad/output.txt_adm"  
     fi  
1121      if test ! -r $fout ; then      if test ! -r $fout ; then
1122          echo "can't read \"$fout\" -- skipping $dir"          echo "can't read \"$fout\" -- skipping $dir"
1123          continue          continue
1124      fi      fi
1125    
1126      builddir="input"      # Check for specific files for particular type of run
     rundir="input"  
     use_seperate_build=0  
     if test -d $dir/build -a -r $dir/build ; then  
         builddir="build"  
         rundir="build"  
         use_seperate_build=1  
         linkdata $use_seperate_build $dir/$rundir  
     fi  
       
     if test "x$ADM" = x ; then  
         code_dir=code  
         CODE_DIR=$dir/code  
     else  
         code_dir=code_ad  
         CODE_DIR=$dir/code_ad  
     fi  
     BUILD_DIR=$dir/$builddir  
1127    
1128      if test ! -r $CODE_DIR"/SIZE.h_mpi" -a "x$MPI" = "xt" ; then      if test ! -r $CODE_DIR"/SIZE.h_mpi" -a "x$MPI" = "xt" ; then
1129          echo "can't find \"$CODE_DIR/SIZE.h_mpi\" -- skipping $dir"          echo "can't find \"$CODE_DIR/SIZE.h_mpi\" -- skipping $dir"
1130          continue          continue
1131      fi      fi
1132        if test ! -r $dir"/input/eedata.mth" -a "x$MULTI_THREAD" = "xt" ; then
1133            echo "can't find \"$dir/input/eedata.mth\" -- skipping $dir"
1134            continue
1135        fi
1136    
1137        #  Check whether there are "extra runs" for this testdir
1138        extra_runs=
1139        ex_run_dirs=`( cd $dir ; echo $inputdir.* )`
1140        #echo "ex_run_dirs='$ex_run_dirs'"
1141        for exd in $ex_run_dirs ; do
1142            name=`echo $exd | sed -e "s/$inputdir\.//"`
1143            refExOut=`echo $ref_outp | sed "s/\./.${name}./"`
1144            outf="$dir/results/$refExOut"
1145            if test -f $outf -a -r $outf ; then
1146                if test "x$MULTI_THREAD" = "xt" ; then
1147                    if test -r $dir"/"$exd"/eedata.mth" ; then
1148                        extra_runs="$extra_runs $name"
1149                    #else echo $dir"/"$exd"/eedata.mth: not found"
1150                    fi
1151                else
1152                    extra_runs="$extra_runs $name"
1153                fi
1154            fi
1155        done
1156    
1157      echo "-------------------------------------------------------------------------------"      echo "-------------------------------------------------------------------------------"
1158      echo      echo
1159      echo "Experiment:  $dir"      if test "x$extra_runs" = "x" ; then
1160           echo "Experiment:  $dir"
1161        else
1162           echo "Experiment:  $dir ; extra_runs=$extra_runs"
1163        fi
1164      echo      echo
1165      unset genmake makedepend make run      unset genmake makedepend make run
1166      results='-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --'      results=$EMPTY_RESULTS
1167    
1168      #  Create an output dir for each OPTFILE/tdir combination      #  Create an output dir for each OPTFILE/tdir combination
1169      rel_CDIR=$DRESULTS"/"$dir      rel_CDIR=$DRESULTS"/"$dir
# Line 815  for dir in $TESTDIRS ; do Line 1171  for dir in $TESTDIRS ; do
1171      CDIR=`pwd`"/$rel_CDIR"      CDIR=`pwd`"/$rel_CDIR"
1172            
1173      if test "x$CLEANUP" = xt ; then      if test "x$CLEANUP" = xt ; then
1174          makeclean $dir/$builddir          echo '====>>> this is to check that we never go through this part <<< ==='
1175            makeclean $dir/$builddir \
1176                && run_clean $dir/$rundir
1177      else      else
1178          genmakemodel $dir/$builddir && genmake=Y \          genmakemodel $dir/$builddir && genmake=Y \
1179              && makeclean $dir/$builddir \              && makeclean $dir/$builddir \
1180                && run_clean $dir/$rundir \
1181              && symlink_mpifiles $dir $code_dir $builddir \              && symlink_mpifiles $dir $code_dir $builddir \
1182              && makedependmodel $dir/$builddir && makedepend=Y \              && makedependmodel $dir/$builddir && makedepend=Y \
1183              && makemodel $dir/$builddir && make=Y \              && makemodel $dir/$builddir && make=Y \
1184              && linkdata $use_seperate_build $dir/$rundir \              && linkdata $dir/$rundir $inputdir input \
1185              && runmodel $dir/$rundir && run=Y \              && runmodel $dir/$rundir && run=Y \
1186              && results=`testoutput $dir $rundir`              && results=`testoutput_run $dir $rundir $ref_outp`
1187      fi      fi
1188            
1189      echo      echo
     if test "x$ADM" = x ; then  
1190          fres=`formatresults $dir ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N} $results`          fres=`formatresults $dir ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N} $results`
1191      else          echo
1192          fres=`printf '%s %s %s %s' ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N}`          echo "$fres" | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</' >> $SUMMARY
1193          fres=$fres"$results   $dir"          touch $CDIR"/summary.txt"
1194            echo "fresults='$fres'" | sed 's/ 99/ --/g' >> $CDIR"/summary.txt"
1195            echo "MACH='$MACH'" >> $CDIR"/summary.txt"
1196            echo "UNAMEA='$UNAMEA'" >> $CDIR"/summary.txt"
1197            echo "DATE='$DATE'" >> $CDIR"/summary.txt"
1198            echo "tdir='$dir'" >> $CDIR"/summary.txt"
1199            if test "x$ADM" = xt ; then
1200                head -1 $dir/$builddir/taf_ad.log >> $CDIR"/summary.txt"
1201                grep -A3 'Seconds in section "ALL' $dir/$rundir/$OUTPUTFILE \
1202                                    >> $CDIR"/summary.txt"
1203            fi
1204    
1205            for ex in $extra_runs ; do
1206                unset run
1207                results=$EMPTY_RESULTS
1208                #  reference output file
1209                refExOut=`echo $ref_outp | sed "s/\./.${ex}./g"`
1210                #  Create an output dir for each OPTFILE/tdir.ex combination
1211                rel_CDIR=$DRESULTS"/"$dir"."$ex
1212                mkdir $rel_CDIR
1213                CDIR=`pwd`"/$rel_CDIR"
1214                test ! -e "$dir/tr_run.$ex" && mkdir "$dir/tr_run.$ex"
1215                run_clean $dir/tr_run.$ex
1216                linkdata $dir/tr_run.$ex $inputdir.$ex $inputdir input
1217                runmodel $dir/tr_run.$ex && run=Y \
1218                && results=`testoutput_run $dir tr_run.$ex $refExOut`
1219                fres=`formatresults $dir ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N} $results`
1220                fres="$fres.$ex"
1221                echo
1222                echo "$fres" | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</' >> $SUMMARY
1223                touch $CDIR"/summary.txt"
1224                echo "fresults='$fres'" | sed 's/ 99/ --/g' >> $CDIR"/summary.txt"
1225                echo "MACH='$MACH'" >> $CDIR"/summary.txt"
1226                echo "UNAMEA='$UNAMEA'" >> $CDIR"/summary.txt"
1227                echo "DATE='$DATE'" >> $CDIR"/summary.txt"
1228                echo "tdir='$dir.$ex'" >> $CDIR"/summary.txt"
1229                if test "x$ADM" = xt ; then
1230                    head -1 $dir/$builddir/taf_ad.log >> $CDIR"/summary.txt"
1231                    grep -A3 'Seconds in section "ALL' $dir/tr_run.$ex/$OUTPUTFILE \
1232                                       >> $CDIR"/summary.txt"
1233                fi
1234                if test "x$POSTCLEAN" = xt ; then
1235                    run_clean $dir/tr_run.$ex
1236                fi
1237            done
1238    
1239        #postclean $dir/$builddir
1240        if test "x$POSTCLEAN" = xt ; then
1241            makeclean $dir/$builddir \
1242                && run_clean $dir/$rundir
1243      fi      fi
     echo  
     echo "$fres" >> $SUMMARY  
     echo "fresults='$fres'" > $CDIR"/summary.txt"  
     echo "MACH='$MACH'" >> $CDIR"/summary.txt"  
     echo "UNAMEA='$UNAMEA'" >> $CDIR"/summary.txt"  
     echo "DATE='$DATE'" >> $CDIR"/summary.txt"  
     echo "tdir='$dir'" >> $CDIR"/summary.txt"  
1244            
1245      echo "-------------------------------------------------------------------------------"      echo "-------------------------------------------------------------------------------"
1246            
1247  done  done
1248    
1249  echo -n "Start time:  " >> $SUMMARY  printf "Start time:  " >> $SUMMARY
1250  echo $start_date >> $SUMMARY  echo "$start_date" >> $SUMMARY
1251  echo -n "End time:    " >> $SUMMARY  printf "End time:    " >> $SUMMARY
1252  date >> $SUMMARY  date >> $SUMMARY
1253    
1254  #  If addresses were supplied and mpack built successfully, then try  #  If addresses were supplied and mpack built successfully, then try
# Line 859  else Line 1259  else
1259      if test "x$HAVE_MPACK" = xt ; then      if test "x$HAVE_MPACK" = xt ; then
1260          tar -cf $DRESULTS".tar" $DRESULTS > /dev/null 2>&1 \          tar -cf $DRESULTS".tar" $DRESULTS > /dev/null 2>&1 \
1261              && gzip $DRESULTS".tar" \              && gzip $DRESULTS".tar" \
1262              && $MPACK -s MITgcm-test -m 1500000 $DRESULTS".tar.gz" $ADDRESSES              && $MPACK -s MITgcm-test -m 3555000 $DRESULTS".tar.gz" $ADDRESSES
1263          RETVAL=$?          RETVAL=$?
1264          if test "x$RETVAL" != x0 ; then          if test "x$RETVAL" != x0 ; then
1265              echo              echo
# Line 878  else Line 1278  else
1278      fi      fi
1279  fi  fi
1280    
1281  # rm -f tmp_cmpnum.f a.out  rm -f tr_cmpnum.c tr_cmpnum
 rm -f tmp_cmpnum.c tmp_cmpnum  
1282    
1283  if test "x$CLEANUP" != xt ; then  if test "x$CLEANUP" != xt ; then
1284      cat $SUMMARY      cat $SUMMARY | sed 's/ \.  \.  \.  \.  \.  \.  \.  \.  \.  \.  \.  \. //'
1285      if test -e tr_out.txt ; then      if test -e tr_out.txt ; then
1286          mv tr_out.txt tr_out.txt.old          mv tr_out.txt tr_out.txt.old
1287      fi      fi
1288      cat $SUMMARY > tr_out.txt      cat $SUMMARY | sed '/^[YN] [YN] [YN] [YN]/ s/ \. //g' > tr_out.txt
1289    fi
1290    
1291    if test "x$DELDIR" = xt ; then
1292        rm -rf $DRESULTS
1293  fi  fi
1294    

Legend:
Removed from v.1.32  
changed lines
  Added in v.1.119

  ViewVC Help
Powered by ViewVC 1.1.22