nlpec03.gms : NLPEC test suite - loop over option combos
Description
This test is similar in nature to nlpec01.
This model takes a set of NLPEC option combinations and runs the NLPEC solver
on the mpec01 model from testlib for each combination. Any errors
(e.g. internal to NLPEC, in the syntax or semantics of the
reforumulated NLP model, etc.) should get flagged because mpec01
includes internal tests that a correct solution has been obtained and
will abort otherwise.
The options combinations to test are chosen strategically so that:
1. there are not so many to test with
2. they give good test coverage
3. they can be easily extended
The set of models to test is only mpec01 in this file, but that can be
changed easily so this model is good for use during development.
Contributor: Steven Dirkse, Aug 2023
$title 'NLPEC test suite - options test'(NLPEC03,SEQ=943)$onText
This test is similar in nature to nlpec01.
This model takes a set of NLPEC option combinations and runs the NLPEC solver
on the mpec01 model from testlib for each combination. Any errors
(e.g. internal to NLPEC, in the syntax or semantics of the
reforumulated NLP model, etc.) should get flagged because mpec01
includes internal tests that a correct solution has been obtained and
will abort otherwise.
The options combinations to test are chosen strategically so that:
1. there are not so many to test with
2. they give good test coverage
3. they can be easily extended
The set of models to test is only mpec01 in this file, but that can be
changed easily so this model is good for use during development.
Contributor: Steven Dirkse, Aug 2023
$offTextscalar errCount;
$if set VERBOSE $setEnv VERBOSE true$onEmbeddedCode Python:# verify normal operation of NLPEC## Run NLPEC over a wide range of combinations of reformulation optionsimport os, sys
import subprocess
import gams.transfer as gt
pySysdir = os.environ.get("PYSYSDIR")if None == pySysdir:
gamscmd = os.path.join(r"%gams.sysdir% ".strip(),"gams")else:
gamscmd = os.path.join(pySysdir,"gams")
optFmt ="{:<12} {:>12} {:>12}\n"# create an option file for NLPECdefmakeOptFile(fname,sname,optS,optD,*args):with open(fname,'w')as f:
f.write("dotGams {}\n".format(sname))
f.write("\n")
f.write(optFmt.format("refType",optS[0],optD[0]))
f.write(optFmt.format("slack",optS[1],optD[1]))
f.write(optFmt.format("constraint",optS[2],optD[2]))
f.write(optFmt.format("aggregate",optS[3],optD[3]))
f.write(optFmt.format("NCPBounds",optS[4],optD[4]))for t in args:for o in t:
f.write("{}\n".format(o))# print ("")# print ("makeOptFile: #args = {}".format(len(args)))return# for some reformulations we need additional args defgetXtraArgs(optS,optD):
xx =[]
s_initMU = None
d_initMU = None
if optS[0]in["fCMfx","fCMxf"]:
s_initMU ="5e-6"if optS[0]in["CMfx","CMxf"]:
s_initMU ="8e-3"if optS[0]in["fVUsin","fVUpow"]:
s_initMU ="1e-3"if optS[0]in["penalty"]:
s_initMU ="5e-3"if optD[0]in["fCMfx","fCMxf"]:
d_initMU ="5e-6"if optD[0]in["CMfx","CMxf"]:
d_initMU ="8e-3"if optD[0]in["fVUsin","fVUpow"]:
d_initMU ="1e-3"if optD[0]in["penalty"]:
d_initMU ="5e-3"if(s_initMU isnot None)or(d_initMU isnot None):if s_initMU is None:
s_initMU ="*"if d_initMU is None:
d_initMU ="*"
xx.append(optFmt.format("initMU",s_initMU,d_initMU))return tuple(xx)# solve model <gms> using optfile=<opt> with NLPEC# return true if the solve completes successfullydefprocessGMS(gms,opt):# verify the options file existsassert(opt>=100)
optFileOld ="nlpec.{}".format(opt)assert(os.path.isfile(optFileOld))assert(os.path.isfile(gms))# run NLPEC
cmd =[ gamscmd, gms,"solver=nlpec","optfile={}".format(opt)]
p = subprocess.run(cmd, capture_output=True, text=True)if p.returncode !=0:print("failure in processGMS({},{}): NLPEC run failed".format(gms,opt))print("cmd: ", cmd)print("rc: ", p.returncode)with open("stdout.txt","w")as sss:
sss.write(p.stdout)print("stdout available in file 'stdout.txt'")assert(p.returncode ==0)returnTruedefgetCombos(row):return[ row.iloc[2*k]for k in range(5)],[ row.iloc[2*k+1]for k in range(5)]if __name__ =="__main__":
verbose =False
eCount =0try:if None == pySysdir:
m = gt.Container("nlpec03_opts.gdx", system_directory=r"%gams.sysdir% ".strip())else:
m = gt.Container("nlpec03_opts.gdx", system_directory=pySysdir)
df = m['valid10'].records
verbose =(None != os.environ.get("VERBOSE"))# rS, rD = getCombos(df.iloc[0])
nOptFiles =0
nTests =0
nDeltas =0
gmsfiles =["mpec01.gms"]for idx, row in df.iterrows():
rS, rD = getCombos(row)if(nOptFiles >=999999):# easy way to be quick and successfulcontinue
nOptFiles +=1if verbose:print("Testing row {}: {}".format(idx,row.to_list()))
xargs = getXtraArgs(rS,rD)
makeOptFile("nlpec.100","scalar100.gms",rS,rD,xargs)for gms in gmsfiles:
nTests +=1# print ("GAMS file to process: {}".format(gms))
brc = processGMS(gms,100)if verbose:print(" GAMS file: {} result: {}".format(gms,brc))ifnot brc:
nDeltas +=1if verbose:print("")print("ALL DONE: {} option files, {} comparisons, {} deltas".format(nOptFiles,nTests,nDeltas))assert(0== nDeltas)except Exception as e:print(repr(e))
eCount = eCount +1
gams.set('errCount',[eCount])$offEmbeddedCode errCountdisplay errCount;abort$errCount "There were errors in the test run", errCount;