Loading...
Searching...
No Matches
transport_neos.py
1import os
2import ssl
3import sys
4import time
5import xmlrpc.client
6import certifi
7from gams import GamsWorkspace
8
9# NEOS XML Template (to be filled)
10xml = r"""<document>
11<category>:category:</category>
12<solver>:solver:</solver>
13<inputType>GAMS</inputType>
14<email>:email:</email>
15<priority>short</priority>
16<model><![CDATA[:model:]]></model>
17<wantgdx><![CDATA[yes]]></wantgdx>
18<wantlog><![CDATA[yes]]></wantlog>
19<wantlst><![CDATA[yes]]></wantlst>
20</document>"""
21
22if __name__ == "__main__":
23 sys_dir = sys.argv[1] if len(sys.argv) > 1 else None
24 work_dir = sys.argv[2] if len(sys.argv) > 2 else None
25 ws = GamsWorkspace(system_directory=sys_dir, working_directory=work_dir)
26
27 model = "trnsport"
28 ws.gamslib(model)
29
30 ssl_context = ssl.create_default_context()
31
32 # explicitly point to 'certifi' *.pem file in case the OpenSSL default CA certificate path points to expired certificates
33 if sys.platform == "win32":
34 ssl_context.load_verify_locations(certifi.where())
35
36 neos = xmlrpc.client.ServerProxy(
37 "https://neos-server.org:3333", context=ssl_context
38 )
39 if "NeosServer is alive" not in neos.ping():
40 raise Exception("Could not make connection to NEOS server")
41
42 # can neither choose SoPlex nor CBC as LP solver on NEOS, so pretend its a MIP and use CBC
43 xml = xml.replace(":category:", "MILP")
44 xml = xml.replace(":solver:", "CBC")
45 if "NEOS_EMAIL" in os.environ:
46 xml = xml.replace(":email:", os.environ["NEOS_EMAIL"])
47 else:
48 raise Exception("Environment variable 'NEOS_EMAIL' not found")
49 with open(os.path.join(ws.working_directory, model + ".gms"), "r") as f:
50 xml = xml.replace(":model:", f.read())
51
52 job_number, password = neos.submitJob(xml)
53 print(f"Job number: {job_number}")
54 print(f"Job password: {password}")
55
56 if job_number == 0:
57 raise Exception(f"NEOS server error: {password}")
58
59 offset = 0
60 echo = True
61 status = ""
62 while status != "Done":
63 time.sleep(1)
64 result, offset = neos.getIntermediateResults(job_number, password, offset)
65 result = result.data.decode()
66 if echo:
67 if "Composing results." in result: # this removes the lst output
68 result = result.split("Composing results.", 1)[0]
69 echo = False
70 print(result, end="")
71 status = neos.getJobStatus(job_number, password)
72
73 result = neos.getFinalResults(job_number, password)
74 with open(
75 f"{job_number}-{os.path.splitext(os.path.basename(model + '.gms'))[0]}.lst", "w"
76 ) as f:
77 f.write(result.data.decode())
78 result = neos.getOutputFile(job_number, password, "solver-output.zip")
79 with open(f"{job_number}-solver-output.zip", "wb") as f:
80 f.write(result.data)