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
Small Model of Type : GAMS
Category : GAMS Test library
Main file : nlpec03.gms
$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
$offText
scalar errCount;
$if set VERBOSE $setEnv VERBOSE true
$onEmbeddedCode Python:
# verify normal operation of NLPEC
#
# Run NLPEC over a wide range of combinations of reformulation options
import 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 NLPEC
def makeOptFile(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
def getXtraArgs(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 is not None) or (d_initMU is not 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 successfully
def processGMS(gms,opt):
# verify the options file exists
assert(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)
return True
def getCombos(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 = 0
try:
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 successful
continue
nOptFiles += 1
if 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))
if not brc:
nDeltas += 1
if 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 errCount
display errCount;
abort$errCount "There were errors in the test run", errCount;