#!/bin/bash # these are some basic instructions to an optimization of # MITgcm/verification/tutorial_global_oce_optim with # MITgcm_offline/mlosch/optim_m1qn3 # Some tweaking is definitely possible and not described here. # # cd MITgcm/verification # this is just to compile and run the model for testing. # I use TAF (just because I have it and OpenAD is a pain to compile on a Mac), # but that should not make any difference ./testreport -t tutorial_global_oce_optim -adm -j 4 -ncad # this is the result: # G D M C A F # e p a R o d D # n n k u s G G # 2 d e n t r r # Y Y Y Y 15>16< 7 pass tutorial_global_oce_optim (e=0, w=2) # here is the cost function value that I get # (PID.TID 0000.0001) local fc = 0.620023228182336D+01 # (PID.TID 0000.0001) global fc = 0.620023228182336D+01 # now I download and compile optim_m1qn3 cd ../../ cvs co MITgcm_contrib/mlosch/optim_m1qn3 cd MITgcm_contrib/mlosch/optim_m1qn3 # edit Makefile to adjust to your platform. For me this involves choosing # the correct CPP command and setting SUFF=for (because MacOS is # case-insensitive in my case) make depend make # then I get optim.x cd ../../../MITgcm/verification/tutorial_global_oce_optim/run cp ../../../../MITgcm_contrib/mlosch/optim_m1qn3/optim.x . # - turn off the gradient check (in data.pkg: useGrdchk = .FALSE.) # - tweak the namelist files to the compiler needs (I need a "/" to terminate # a namelist # - I would replace fmin with dfminFrac = 0.1 (expected reduction of 10%) # in data.optim&OPTIM to be independent of the absolute value of the # cost function. When you run ./mitgcmuv_ad with this you need to comment # out dfminFrac, because mitgcmuv_ad does not know about this. # - set numiter=100, nfunc=100, or some other large value. nfunc should actually # be larger than numiter, because you may need more than one function call # (= run of mitgcmuv_ad) per iteration, see m1qn3 docs for details # - add an empty namelist &M1QN3 to data.optim # &M1QN3 # / ./optim.x > opt0.txt # I get a lot of output in opt0.txt, which is easier to read with # less -S opt0.out (to truncate long lines) # essentially I have the same value for the cost function # ================================================== # Large Scale Optimization with off-line capability. # ================================================== # Version 3.1.0 # OPTIM_READPARMS: Control options have been read. # OPTIM_READPARMS: Minimization options have been read. # pathei-lsopt in optim_readdata # OPTIM_READDATA: Reading cost function and # gradient of cost function # for optimization cycle: 0 # opened file ecco_cost_MIT_CE_000.opt0000 # pathei: nvartype 1 # pathei: nvarlength 2315 # pathei: yctrlid MIT_CE_000 # pathei: filenopt 0 # pathei: fileff 6.2002322818233591 # pathei: fileiG 1 # pathei: filejG 1 # pathei: filensx 2 # pathei: filensy 2 # [...] # OPTIM_READPARMS: Iteration number = 0 # number of control variables = 2315 # cost function value in ecco_ctrl = 6.2002322818233591 # expected cost function minimum = 5.7400000000000002 # expected cost function decrease = 0.46023228182335885 # Data will be read from the following file: ecco_ctrl_MIT_CE_000.opt0000 # OPTIM_SUB: Calling m1qn3_optim for iteration: 0 # OPTIM_SUB: with nn, REAL_BYTE = 2315 4 # OPTIM_SUB: read model state # pathei-lsopt in optim_readdata # OPTIM_READDATA: Reading control vector # for optimization cycle: 0 # opened file ecco_ctrl_MIT_CE_000.opt0000 # pathei: nvartype 1 # pathei: nvarlength 2315 # pathei: yctrlid MIT_CE_000 # pathei: filenopt 0 # pathei: fileff 6.2002322818233591 # pathei: fileiG 1 # pathei: filejG 1 # pathei: filensx 2 # pathei: filensy 2 # [...] # pathei-lsopt in optim_readdata # OPTIM_READDATA: Reading cost function and # gradient of cost function # for optimization cycle: 0 # opened file ecco_cost_MIT_CE_000.opt0000 # pathei: nvartype 1 # pathei: nvarlength 2315 # pathei: yctrlid MIT_CE_000 # pathei: filenopt 0 # pathei: fileff 6.2002322818233591 # pathei: fileiG 1 # pathei: filejG 1 # pathei: filensx 2 # pathei: filensy 2 # [...] # OPTIM_SUB after reading ecco_ctrl and ecco_cost: # OPTIM_SUB nn = 2315 # OPTIM_SUB objf = 6.2002322818233591 # OPTIM_SUB xx(1) = 0.0000000000000000 # OPTIM_SUB adxx(1) = -6.7879882408306003E-005 # OPTIM_SUB: cold start, optimcycle = 0 # OPTIM_SUB: call m1qn3_offline ........ # OPTIM_SUB: ........................... # OPTIM_SUB: returned from m1qn3_offline # OPTIM_SUB: nn = 2315 # OPTIM_SUB: xx(1) = 0.38550331655973830 0.54187150690787089 # OPTIM_SUB: adxx(1) = -6.7879882408306003E-005 -9.5413379312958568E-005 # OPTIM_SUB: omode = -1 # OPTIM_SUB: niter = 1 # OPTIM_SUB: nsim = 3 # OPTIM_SUB: reverse = 1 # OPTIM_SUB: mean(xx) = 0.12147501041949339 # OPTIM_SUB: max(xx) = 3.4534949169848264 # OPTIM_SUB: min(xx) = -6.9274397317493612 # OPTIM_SUB: std(xx) = 8.6027463877459223 # OPTIM_STORE_M1QN3: saving the state of m1qn3 in OPWARM.opt0001 # OPTIM_SUB: writing 2315 sized control to file ecco_ctrl # OPTIM_WRITEDATA: Writing new control vector to file(s) # for optimization cycle: 1 # pathei: nvartype 1 # pathei: nvarlength 2315 # pathei: yctrlid MIT_CE_000 # pathei: nopt 1 # pathei: ff 1.3934405203552992E+098 # pathei: iG 1 # pathei: jG 1 # pathei: nsx 2 # pathei: nsy 2 # [...] # end of optim_writedata: icvoffset 2315 # ====================================== # Large Scale Optimization run finished. # ====================================== # I would not worry about ff = 1.39e98. It's a dummy value. # now you can organize the rest in loop. In bash it could look like this # first comment out dfminFrac, because mitgcmuv_ad does not know about this, # it is really only needed in the zeroth iteration # tabula rasa rm ecco_c* OPWARM.* m1qn3_output.txt myiter=0 cat > data.optim < output${myiter}.txt # add dfminFrac = 0.1, sed -i '' 's/#dfminFrac.*/ dfminFrac = 0.1,/' data.optim ./optim.x > opt${myiter}.txt # increase counter for next iteration ((myiter++)) done # grep "fc " output1.txt # (PID.TID 0000.0001) early fc = 0.000000000000000D+00 # (PID.TID 0000.0001) local fc = 0.132325873958879D+02 # (PID.TID 0000.0001) global fc = 0.132325873958879D+02 # grep "global fc " output?.txt # output0.txt:(PID.TID 0000.0001) global fc = 0.620023228182336D+01 # output1.txt:(PID.TID 0000.0001) global fc = 0.132325873958879D+02 # output2.txt:(PID.TID 0000.0001) global fc = 0.615567811433600D+01 # output3.txt:(PID.TID 0000.0001) global fc = 0.615556878869932D+01 # output4.txt:(PID.TID 0000.0001) global fc = 0.615547009131471D+01 # as you can see, the improvement is not very good after thie initial steps. # checkout m1qn3_output.txt, which records the output of m1qn3