gamsapi 52.5.0__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. gams/__init__.py +27 -0
  2. gams/_version.py +1 -0
  3. gams/connect/__init__.py +28 -0
  4. gams/connect/agents/__init__.py +24 -0
  5. gams/connect/agents/_excel/__init__.py +32 -0
  6. gams/connect/agents/_excel/excelagent.py +312 -0
  7. gams/connect/agents/_excel/workbook.py +155 -0
  8. gams/connect/agents/_sqlconnectors/__init__.py +42 -0
  9. gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
  10. gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
  11. gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
  12. gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
  13. gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
  14. gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
  15. gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
  16. gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
  17. gams/connect/agents/concatenate.py +440 -0
  18. gams/connect/agents/connectagent.py +743 -0
  19. gams/connect/agents/csvreader.py +675 -0
  20. gams/connect/agents/csvwriter.py +151 -0
  21. gams/connect/agents/domainwriter.py +143 -0
  22. gams/connect/agents/excelreader.py +756 -0
  23. gams/connect/agents/excelwriter.py +467 -0
  24. gams/connect/agents/filter.py +223 -0
  25. gams/connect/agents/gamsreader.py +112 -0
  26. gams/connect/agents/gamswriter.py +239 -0
  27. gams/connect/agents/gdxreader.py +109 -0
  28. gams/connect/agents/gdxwriter.py +146 -0
  29. gams/connect/agents/labelmanipulator.py +303 -0
  30. gams/connect/agents/projection.py +539 -0
  31. gams/connect/agents/pythoncode.py +71 -0
  32. gams/connect/agents/rawcsvreader.py +248 -0
  33. gams/connect/agents/rawexcelreader.py +312 -0
  34. gams/connect/agents/schema/CSVReader.yaml +92 -0
  35. gams/connect/agents/schema/CSVWriter.yaml +44 -0
  36. gams/connect/agents/schema/Concatenate.yaml +52 -0
  37. gams/connect/agents/schema/DomainWriter.yaml +25 -0
  38. gams/connect/agents/schema/ExcelReader.yaml +121 -0
  39. gams/connect/agents/schema/ExcelWriter.yaml +78 -0
  40. gams/connect/agents/schema/Filter.yaml +74 -0
  41. gams/connect/agents/schema/GAMSReader.yaml +20 -0
  42. gams/connect/agents/schema/GAMSWriter.yaml +47 -0
  43. gams/connect/agents/schema/GDXReader.yaml +23 -0
  44. gams/connect/agents/schema/GDXWriter.yaml +32 -0
  45. gams/connect/agents/schema/LabelManipulator.yaml +99 -0
  46. gams/connect/agents/schema/Projection.yaml +24 -0
  47. gams/connect/agents/schema/PythonCode.yaml +6 -0
  48. gams/connect/agents/schema/RawCSVReader.yaml +34 -0
  49. gams/connect/agents/schema/RawExcelReader.yaml +42 -0
  50. gams/connect/agents/schema/SQLReader.yaml +75 -0
  51. gams/connect/agents/schema/SQLWriter.yaml +103 -0
  52. gams/connect/agents/sqlreader.py +301 -0
  53. gams/connect/agents/sqlwriter.py +276 -0
  54. gams/connect/connectdatabase.py +275 -0
  55. gams/connect/connectvalidator.py +93 -0
  56. gams/connect/errors.py +34 -0
  57. gams/control/__init__.py +136 -0
  58. gams/control/database.py +2231 -0
  59. gams/control/execution.py +1900 -0
  60. gams/control/options.py +2792 -0
  61. gams/control/workspace.py +1198 -0
  62. gams/core/__init__.py +24 -0
  63. gams/core/cfg/__init__.py +26 -0
  64. gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
  65. gams/core/cfg/cfgmcc.py +519 -0
  66. gams/core/dct/__init__.py +26 -0
  67. gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
  68. gams/core/dct/dctmcc.py +574 -0
  69. gams/core/embedded/__init__.py +26 -0
  70. gams/core/embedded/gamsemb.py +1024 -0
  71. gams/core/emp/__init__.py +24 -0
  72. gams/core/emp/emplexer.py +89 -0
  73. gams/core/emp/empyacc.py +281 -0
  74. gams/core/gdx/__init__.py +26 -0
  75. gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
  76. gams/core/gdx/gdxcc.py +866 -0
  77. gams/core/gev/__init__.py +26 -0
  78. gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
  79. gams/core/gev/gevmcc.py +855 -0
  80. gams/core/gmd/__init__.py +26 -0
  81. gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
  82. gams/core/gmd/gmdcc.py +917 -0
  83. gams/core/gmo/__init__.py +26 -0
  84. gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
  85. gams/core/gmo/gmomcc.py +2046 -0
  86. gams/core/idx/__init__.py +26 -0
  87. gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
  88. gams/core/idx/idxcc.py +510 -0
  89. gams/core/numpy/__init__.py +29 -0
  90. gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
  91. gams/core/numpy/gams2numpy.py +1048 -0
  92. gams/core/opt/__init__.py +26 -0
  93. gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
  94. gams/core/opt/optcc.py +840 -0
  95. gams/engine/__init__.py +204 -0
  96. gams/engine/api/__init__.py +13 -0
  97. gams/engine/api/auth_api.py +7653 -0
  98. gams/engine/api/cleanup_api.py +751 -0
  99. gams/engine/api/default_api.py +887 -0
  100. gams/engine/api/hypercube_api.py +2629 -0
  101. gams/engine/api/jobs_api.py +5229 -0
  102. gams/engine/api/licenses_api.py +2220 -0
  103. gams/engine/api/namespaces_api.py +7783 -0
  104. gams/engine/api/usage_api.py +5627 -0
  105. gams/engine/api/users_api.py +5931 -0
  106. gams/engine/api_client.py +804 -0
  107. gams/engine/api_response.py +21 -0
  108. gams/engine/configuration.py +601 -0
  109. gams/engine/exceptions.py +216 -0
  110. gams/engine/models/__init__.py +86 -0
  111. gams/engine/models/bad_input.py +89 -0
  112. gams/engine/models/cleanable_job_result.py +104 -0
  113. gams/engine/models/cleanable_job_result_page.py +113 -0
  114. gams/engine/models/engine_license.py +107 -0
  115. gams/engine/models/files_not_found.py +93 -0
  116. gams/engine/models/forwarded_token_response.py +112 -0
  117. gams/engine/models/generic_key_value_pair.py +89 -0
  118. gams/engine/models/hypercube.py +160 -0
  119. gams/engine/models/hypercube_page.py +111 -0
  120. gams/engine/models/hypercube_summary.py +91 -0
  121. gams/engine/models/hypercube_token.py +97 -0
  122. gams/engine/models/identity_provider.py +107 -0
  123. gams/engine/models/identity_provider_ldap.py +121 -0
  124. gams/engine/models/identity_provider_oauth2.py +146 -0
  125. gams/engine/models/identity_provider_oauth2_scope.py +89 -0
  126. gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
  127. gams/engine/models/identity_provider_oidc.py +133 -0
  128. gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
  129. gams/engine/models/inex.py +91 -0
  130. gams/engine/models/invitation.py +136 -0
  131. gams/engine/models/invitation_quota.py +106 -0
  132. gams/engine/models/invitation_token.py +87 -0
  133. gams/engine/models/job.py +165 -0
  134. gams/engine/models/job_no_text_entry.py +138 -0
  135. gams/engine/models/job_no_text_entry_page.py +111 -0
  136. gams/engine/models/license.py +91 -0
  137. gams/engine/models/log_piece.py +96 -0
  138. gams/engine/models/message.py +87 -0
  139. gams/engine/models/message_and_token.py +99 -0
  140. gams/engine/models/message_with_webhook_id.py +89 -0
  141. gams/engine/models/model_auth_token.py +87 -0
  142. gams/engine/models/model_configuration.py +125 -0
  143. gams/engine/models/model_default_instance.py +99 -0
  144. gams/engine/models/model_default_user_instance.py +98 -0
  145. gams/engine/models/model_hypercube_job.py +106 -0
  146. gams/engine/models/model_hypercube_usage.py +130 -0
  147. gams/engine/models/model_instance_info.py +116 -0
  148. gams/engine/models/model_instance_info_full.py +123 -0
  149. gams/engine/models/model_instance_pool_info.py +112 -0
  150. gams/engine/models/model_job_labels.py +179 -0
  151. gams/engine/models/model_job_usage.py +133 -0
  152. gams/engine/models/model_pool_usage.py +124 -0
  153. gams/engine/models/model_usage.py +115 -0
  154. gams/engine/models/model_user.py +96 -0
  155. gams/engine/models/model_userinstance_info.py +119 -0
  156. gams/engine/models/model_userinstancepool_info.py +95 -0
  157. gams/engine/models/model_version.py +91 -0
  158. gams/engine/models/models.py +120 -0
  159. gams/engine/models/namespace.py +104 -0
  160. gams/engine/models/namespace_quota.py +96 -0
  161. gams/engine/models/namespace_with_permission.py +96 -0
  162. gams/engine/models/not_found.py +91 -0
  163. gams/engine/models/password_policy.py +97 -0
  164. gams/engine/models/perm_and_username.py +89 -0
  165. gams/engine/models/quota.py +117 -0
  166. gams/engine/models/quota_exceeded.py +97 -0
  167. gams/engine/models/status_code_meaning.py +89 -0
  168. gams/engine/models/stream_entry.py +89 -0
  169. gams/engine/models/system_wide_license.py +92 -0
  170. gams/engine/models/text_entries.py +87 -0
  171. gams/engine/models/text_entry.py +101 -0
  172. gams/engine/models/time_span.py +95 -0
  173. gams/engine/models/time_span_pool_worker.py +99 -0
  174. gams/engine/models/token_forward_error.py +87 -0
  175. gams/engine/models/user.py +127 -0
  176. gams/engine/models/user_group_member.py +96 -0
  177. gams/engine/models/user_groups.py +108 -0
  178. gams/engine/models/vapid_info.py +87 -0
  179. gams/engine/models/webhook.py +138 -0
  180. gams/engine/models/webhook_parameterized_event.py +99 -0
  181. gams/engine/py.typed +0 -0
  182. gams/engine/rest.py +258 -0
  183. gams/magic/__init__.py +32 -0
  184. gams/magic/gams_magic.py +142 -0
  185. gams/magic/interactive.py +402 -0
  186. gams/tools/__init__.py +30 -0
  187. gams/tools/errors.py +34 -0
  188. gams/tools/toolcollection/__init__.py +24 -0
  189. gams/tools/toolcollection/alg/__init__.py +24 -0
  190. gams/tools/toolcollection/alg/rank.py +51 -0
  191. gams/tools/toolcollection/data/__init__.py +24 -0
  192. gams/tools/toolcollection/data/csvread.py +444 -0
  193. gams/tools/toolcollection/data/csvwrite.py +311 -0
  194. gams/tools/toolcollection/data/exceldump.py +47 -0
  195. gams/tools/toolcollection/data/sqlitewrite.py +276 -0
  196. gams/tools/toolcollection/gdxservice/__init__.py +24 -0
  197. gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
  198. gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
  199. gams/tools/toolcollection/linalg/__init__.py +24 -0
  200. gams/tools/toolcollection/linalg/cholesky.py +57 -0
  201. gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
  202. gams/tools/toolcollection/linalg/eigenvector.py +58 -0
  203. gams/tools/toolcollection/linalg/invert.py +55 -0
  204. gams/tools/toolcollection/linalg/ols.py +138 -0
  205. gams/tools/toolcollection/tooltemplate.py +321 -0
  206. gams/tools/toolcollection/win32/__init__.py +24 -0
  207. gams/tools/toolcollection/win32/excelmerge.py +93 -0
  208. gams/tools/toolcollection/win32/exceltalk.py +76 -0
  209. gams/tools/toolcollection/win32/msappavail.py +49 -0
  210. gams/tools/toolcollection/win32/shellexecute.py +54 -0
  211. gams/tools/tools.py +116 -0
  212. gams/transfer/__init__.py +35 -0
  213. gams/transfer/_abcs/__init__.py +37 -0
  214. gams/transfer/_abcs/container_abcs.py +433 -0
  215. gams/transfer/_internals/__init__.py +63 -0
  216. gams/transfer/_internals/algorithms.py +436 -0
  217. gams/transfer/_internals/casepreservingdict.py +124 -0
  218. gams/transfer/_internals/constants.py +270 -0
  219. gams/transfer/_internals/domainviolation.py +103 -0
  220. gams/transfer/_internals/specialvalues.py +172 -0
  221. gams/transfer/containers/__init__.py +26 -0
  222. gams/transfer/containers/_container.py +1794 -0
  223. gams/transfer/containers/_io/__init__.py +28 -0
  224. gams/transfer/containers/_io/containers.py +164 -0
  225. gams/transfer/containers/_io/gdx.py +1029 -0
  226. gams/transfer/containers/_io/gmd.py +872 -0
  227. gams/transfer/containers/_mixins/__init__.py +26 -0
  228. gams/transfer/containers/_mixins/ccc.py +1274 -0
  229. gams/transfer/syms/__init__.py +33 -0
  230. gams/transfer/syms/_methods/__init__.py +24 -0
  231. gams/transfer/syms/_methods/tables.py +120 -0
  232. gams/transfer/syms/_methods/toDict.py +115 -0
  233. gams/transfer/syms/_methods/toList.py +83 -0
  234. gams/transfer/syms/_methods/toValue.py +60 -0
  235. gams/transfer/syms/_mixins/__init__.py +32 -0
  236. gams/transfer/syms/_mixins/equals.py +626 -0
  237. gams/transfer/syms/_mixins/generateRecords.py +499 -0
  238. gams/transfer/syms/_mixins/pivot.py +313 -0
  239. gams/transfer/syms/_mixins/pve.py +627 -0
  240. gams/transfer/syms/_mixins/sa.py +27 -0
  241. gams/transfer/syms/_mixins/sapve.py +27 -0
  242. gams/transfer/syms/_mixins/saua.py +27 -0
  243. gams/transfer/syms/_mixins/sauapve.py +199 -0
  244. gams/transfer/syms/_mixins/spve.py +1528 -0
  245. gams/transfer/syms/_mixins/ve.py +936 -0
  246. gams/transfer/syms/container_syms/__init__.py +31 -0
  247. gams/transfer/syms/container_syms/_alias.py +984 -0
  248. gams/transfer/syms/container_syms/_equation.py +333 -0
  249. gams/transfer/syms/container_syms/_parameter.py +973 -0
  250. gams/transfer/syms/container_syms/_set.py +604 -0
  251. gams/transfer/syms/container_syms/_universe_alias.py +461 -0
  252. gams/transfer/syms/container_syms/_variable.py +321 -0
  253. gamsapi-52.5.0.dist-info/METADATA +150 -0
  254. gamsapi-52.5.0.dist-info/RECORD +257 -0
  255. gamsapi-52.5.0.dist-info/WHEEL +5 -0
  256. gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
  257. gamsapi-52.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1198 @@
1
+ #
2
+ # GAMS - General Algebraic Modeling System Python API
3
+ #
4
+ # Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
5
+ # Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+ #
25
+
26
+ import filecmp
27
+ import tempfile
28
+ import os
29
+ import shutil
30
+ from subprocess import Popen
31
+ import threading
32
+ from warnings import warn
33
+ from gams import __version__
34
+ from gams.control.database import *
35
+ from gams.control.execution import *
36
+ from gams.control.options import *
37
+
38
+ import sys
39
+
40
+ _is_win = _is_linux = _is_osx = False
41
+ if sys.platform == "win32":
42
+ _is_win = True
43
+ elif sys.platform.startswith("linux"):
44
+ _is_linux = True
45
+ elif sys.platform == "darwin":
46
+ _is_osx = True
47
+ else:
48
+ raise Exception("Unknown operating system")
49
+
50
+
51
+ ## @brief Exception class thrown for GAMS exceptions
52
+ class GamsException(Exception):
53
+ def __init__(self, value, workspace=None):
54
+ Exception.__init__(self, value)
55
+ self.value = value
56
+ if workspace is not None:
57
+ workspace._has_error = True
58
+
59
+ def __str__(self):
60
+ return self.value
61
+
62
+
63
+ ## @brief Exception class thrown for GAMS execution exceptions
64
+ class GamsExceptionExecution(GamsException):
65
+ def __init__(self, value, exit_code, workspace=None):
66
+ self.value = value
67
+ self._rc = exit_code
68
+ if workspace is not None:
69
+ workspace._has_error = True
70
+
71
+ ## brief GAMS return code
72
+ def get_rc(self):
73
+ return self._rc
74
+
75
+ rc = property(get_rc)
76
+
77
+ def __str__(self):
78
+ return self.value
79
+
80
+
81
+ ## @brief GAMS exit code
82
+ class GamsExitCode(object):
83
+ ## @brief Normal Return
84
+ NormalReturn = 0
85
+ ## @brief Solver is to be called, the system should never return this number
86
+ SolverToBeCalled = 1
87
+ ## @brief There was a compilation error
88
+ CompilationError = 2
89
+ ## @brief There was an execution error
90
+ ExecutionError = 3
91
+ ## @brief System limits were reached
92
+ SystemLimitsReached = 4
93
+ ## @brief There was a file error
94
+ FileError = 5
95
+ ## @brief There was a parameter error
96
+ ParameterError = 6
97
+ ## @brief There was a licensing error
98
+ LicensingError = 7
99
+ ## @brief There was a GAMS system error
100
+ GAMSSystemError = 8
101
+ ## @brief GAMS cold not be started
102
+ GAMSCouldNotBeStarted = 9
103
+ ## @brief Out of memory
104
+ OutOfMemory = 10
105
+ ## @brief Out of of disk
106
+ OutOfDisk = 11
107
+ ## @brief Could not create process/scratch directory
108
+ CouldNotCreateScratchDir = 109
109
+ ## @brief Too many process/scratch directorie
110
+ TooManyScratchDirs = 110
111
+ ## @brief Could not delete the process/scratch directory
112
+ CouldNotDeleteScratchDir = 112
113
+ ## @brief Could not write "gamsnext" script
114
+ CouldNotWriteGamsNext = 113
115
+ ## @brief Could not write "parameter" file
116
+ CouldNotWriteParamFile = 114
117
+ ## @brief Could not read environment variable
118
+ CouldNotReadEnvVar = 115
119
+ ## @brief Could not spawn the GAMS language compiler (gamscmex)
120
+ CouldNotSpawnGAMScmex = 400
121
+ ## @brief Current directory (curdir) does not exist
122
+ CurDirNotFound = 401
123
+ ## @brief Cannot set current directory (curdir)
124
+ CurDirNotSet = 402
125
+ ## @brief Blank in system directory (UNIX only)
126
+ BlankInSysDir = 404
127
+ ## @brief Blank in current directory (UNIX only)
128
+ BlankInCurDir = 405
129
+ ## @brief Blank in scratch extension (scrext)
130
+ BlankInScrExt = 406
131
+ ## @brief Unexpected cmexRC
132
+ UnexpectedCmexRC = 407
133
+ ## @brief Could not find the process directory (procdir)
134
+ ProcDirNotFound = 408
135
+ ## @brief CMEX library not found (experimental)
136
+ CmexLibNotFound = 409
137
+ ## @brief Entry point in CMEX library not found (experimental)
138
+ CmexLibEPNotFound = 410
139
+ ## @brief Cannot add path / Unknown UNIX environment / Cannot set environment variable
140
+ CannotAddPath = 909
141
+ ## @brief Driver error: Missing command line parameter for gams.exe
142
+ MissingCommandLineParameter = 1000
143
+ ## @brief Driver error: Internal error: Cannot install interrupt handler
144
+ CannotInstallInterrupt = 2000
145
+ ## @brief Driver error: Problems getting current directory (sometimes caused by specifying the current directory in Microsoft UNC format)
146
+ CouldNotGetCurrentDir = 3000
147
+ ## @brief Driver error: Internal error: GAMS compile and execute module not found
148
+ CmexNotFound = 4000
149
+ ## @brief Driver error: Internal error: Cannot load option handling library
150
+ OptNotFound = 5000
151
+
152
+
153
+ # TODO: move this to __init__.py to be loaded with the module
154
+ ## @brief Equation subtype
155
+ class EquType(object):
156
+ ## @brief Equality - =E=
157
+ E = 0
158
+ ## @brief Greater or equal than inequality - =G=
159
+ G = 1
160
+ ## @brief Less or equal than inequality - =L=
161
+ L = 2
162
+ ## @brief Non-binding equation - =N=
163
+ N = 3
164
+ ## @brief External equation - =X=
165
+ X = 4
166
+ ## @brief Cone equation - =C=
167
+ C = 5
168
+
169
+
170
+ # TODO: move this to __init__.py to be loaded with the module
171
+ ## @brief Variable subtype
172
+ class VarType(object):
173
+ ## @brief Unknown variable type
174
+ Unknown = 0
175
+ ## @brief Binary variable
176
+ Binary = 1
177
+ ## @brief Integer Variable
178
+ Integer = 2
179
+ ## @brief Positive variable
180
+ Positive = 3
181
+ ## @brief Negative variable
182
+ Negative = 4
183
+ ## @brief Free variable
184
+ Free = 5
185
+ ## @brief Special Ordered Set 1
186
+ SOS1 = 6
187
+ ## @brief Special Ordered Set 2
188
+ SOS2 = 7
189
+ ## @brief Semi-continuous variable
190
+ SemiCont = 8
191
+ ## @brief Semi-integer variable
192
+ SemiInt = 9
193
+
194
+
195
+ ## @brief Set subtype
196
+ class SetType(object):
197
+ ## @brief Multi Set - The Default
198
+ Multi = 0
199
+ ## @brief Singleton Set - Zero or one element
200
+ Singleton = 1
201
+
202
+
203
+ # TODO: move this to __init__.py to be loaded with the module
204
+ ## @brief Solver termination condition
205
+ class SolveStat(object):
206
+ ## @brief Normal termination
207
+ Normal = 1
208
+ ## @brief Solver ran out of iterations
209
+ Iteration = 2
210
+ ## @brief Solver exceeded time limit
211
+ Resource = 3
212
+ ## @brief Solver quit with a problem
213
+ Solver = 4
214
+ ## @brief Solver quit with nonlinear term evaluation errors
215
+ EvalError = 5
216
+ ## @brief Solver terminated because the model is beyond the solvers capabilities
217
+ Capability = 6
218
+ ## @brief Solver terminated with a license error
219
+ License = 7
220
+ ## @brief Solver terminated on users request (e.g. Ctrl-C)
221
+ User = 8
222
+ ## @brief Solver terminated on setup error
223
+ SetupErr = 9
224
+ ## @brief Solver terminated with error
225
+ SolverErr = 10
226
+ ## @brief Solver terminated with error
227
+ InternalErr = 11
228
+ ## @brief Solve skipped
229
+ Skipped = 12
230
+ ## @brief Other error
231
+ SystemErr = 13
232
+
233
+
234
+ # TODO: move this to __init__.py to be loaded with the module
235
+ ## @brief Model Solution Status
236
+ class ModelStat(object):
237
+ ## @brief Optimal solution achieved
238
+ OptimalGlobal = 1
239
+ ## @brief Local optimal solution achieved
240
+ OptimalLocal = 2
241
+ ## @brief Unbounded model found
242
+ Unbounded = 3
243
+ ## @brief Infeasible model found
244
+ InfeasibleGlobal = 4
245
+ ## @brief Locally infeasible model found
246
+ InfeasibleLocal = 5
247
+ ## @brief Solver terminated early and model was still infeasible
248
+ InfeasibleIntermed = 6
249
+ ## @brief Solver terminated early and model was feasible but not yet optimal
250
+ Feasible = 7
251
+ ## @brief Integer solution found
252
+ Integer = 8
253
+ ## @brief Solver terminated early with a non integer solution found
254
+ NonIntegerIntermed = 9
255
+ ## @brief No feasible integer solution could be found
256
+ IntegerInfeasible = 10
257
+ ## @brief Licensing problem
258
+ LicenseError = 11
259
+ ## @brief Error - No cause known
260
+ ErrorUnknown = 12
261
+ ## @brief Error - No solution attained
262
+ ErrorNoSolution = 13
263
+ ## @brief No solution returned
264
+ NoSolutionReturned = 14
265
+ ## @brief Unique solution in a CNS models
266
+ SolvedUnique = 15
267
+ ## @brief Feasible solution in a CNS models
268
+ Solved = 16
269
+ ## @brief Singular in a CNS models
270
+ SolvedSingular = 17
271
+ ## @brief Unbounded - no solution
272
+ UnboundedNoSolution = 18
273
+ ## @brief Infeasible - no solution
274
+ InfeasibleNoSolution = 19
275
+
276
+
277
+ ## @brief GAMS Debug Level
278
+ class DebugLevel(object):
279
+ ## @brief No debug
280
+ Off = 0
281
+ ## @brief Keep temporary files only if GamsException/GamsExceptionExecution was raised in GamsJob.run(), GamsJob.run_engine(), or GamsModelInstance.solve()
282
+ KeepFilesOnError = 1
283
+ ## @brief Keep temporary files
284
+ KeepFiles = 2
285
+ ## @brief Send GAMS log to stdout and keep temporary files
286
+ ShowLog = 3
287
+ ## @brief Send highly technical info and GAMS log to stdout and keep temporary files
288
+ Verbose = 4
289
+
290
+
291
+ class GamsWorkspace(object):
292
+ """
293
+ @brief The GamsWorkspace is the base class of the gams.control API.
294
+ @details <p>Most objects of the
295
+ control API (e.g. GamsDatabase and GamsJob) should be created by an "add"
296
+ method of GamsWorkspace instead of using the constructors. </p>
297
+ <p>Unless a GAMS system directory is specified during construction of
298
+ GamsWorkspace, GamsWorkspace determines the location of the GAMS installation
299
+ automatically. This is a source of potential problems if more than one GAMS
300
+ installation exist on the machine. </p>
301
+ <p>Furthermore, a working directory (the anchor into the file system) can be
302
+ provided when constructing the GamsWorkspace instance. All file based
303
+ operation inside a GAMS model should be relative to this location (e.g. $GDXIN
304
+ and $include). There are options to add input search paths (e.g. IDir) and
305
+ output path (e.g. PutDir) to specify other file system locations. If no working
306
+ directory is supplied, GamsWorkspace creates a temporary folder and on
307
+ instance destruction removes this temporary folder. </p>
308
+ <p>In a typical Python application a single instance of GamsWorkspace will
309
+ suffice, since the class is thread-safe. </p>
310
+ <h5>Working with different GAMS Versions on one Machine</h5>
311
+ <p>When creating a new instance of GamsWorkspace, one way of defining the GAMS system
312
+ directory is setting the system_directory parameter of the constructor accordingly. If it
313
+ is not set, it is tried to be defined automatically (see \ref API_PY_CONTROL for details). However, this can be tricky if there
314
+ is more than one version of GAMS installed on a machine and especially if there are
315
+ different applications running with different GAMS versions.</p>
316
+ <p>On Windows, the automatic identification relies on information left in the Windows registry by the
317
+ GAMS installer. Hence the system directory of the last GAMS installation will be found in
318
+ this automatic identification step. One way of resetting the information in the registry
319
+ is running the executable "findthisgams.exe" from the directory that should be detected
320
+ automatically. While this can be done from the outside of the application it is not much
321
+ more convenient than the system_directory argument in the GamsWorkspace constructor.</p>
322
+ <p>If one has a very structured way of organizing the GAMS installations (e.g. following
323
+ the GAMS default installation location) one can use GamsWorkspace.api_version to point to
324
+ the best matching GAMS system directory:</p>
325
+ @code{.py}
326
+ sysdir = "C:\\GAMS\\" + GamsWorkspace.api_version[:2]
327
+ ws = GamsWorkspace(system_directory=sysdir)
328
+ @endcode
329
+ <p>This avoids the automatic identification of the GAMS system directory but might be the
330
+ most convenient solution for systems running multiple applications using different versions
331
+ of the GAMS Python API together with different versions of GAMS.</p>
332
+ """
333
+
334
+ def set_eps(self, value):
335
+ self._eps = value
336
+
337
+ ## @brief Reset value to be stored in and read from GamsDatabase for Epsilon
338
+ def get_eps(self):
339
+ return self._eps
340
+
341
+ ## @brief Get value to be stored in and read from GamsDatabase for Epsilon
342
+ my_eps = property(get_eps, set_eps)
343
+
344
+ def get_working_directory(self):
345
+ return self._working_directory
346
+
347
+ ## @brief GAMS working directory, anchor for all file-based operations
348
+ working_directory = property(get_working_directory)
349
+
350
+ def get_system_directory(self):
351
+ return self._system_directory
352
+
353
+ ## @brief GAMS system directory
354
+ system_directory = property(get_system_directory)
355
+
356
+ def get_version(self):
357
+ return self._version
358
+
359
+ ## @brief GAMS Version used
360
+ version = property(get_version)
361
+
362
+ def get_major_rel_number(self):
363
+ return self._major_rel_number
364
+
365
+ ## @brief GAMS Major Release Number
366
+ major_rel_number = property(get_major_rel_number)
367
+
368
+ def get_minor_rel_number(self):
369
+ return self._minor_rel_number
370
+
371
+ ## @brief GAMS Minor Release Number
372
+ minor_rel_number = property(get_minor_rel_number)
373
+
374
+ def get_gold_rel_number(self):
375
+ return self._gold_rel_number
376
+
377
+ ## @brief GAMS GOLD Release Number
378
+ gold_rel_number = property(get_gold_rel_number)
379
+
380
+ ## @brief GAMS API version
381
+ api_version = __version__
382
+
383
+ ## @brief GAMS API Major Release Number
384
+ api_major_rel_number = int(__version__.split(".")[0])
385
+
386
+ ## @brief GAMS API Minor Release Number
387
+ api_minor_rel_number = int(__version__.split(".")[1])
388
+
389
+ ## @brief GAMS API GOLD Release Number
390
+ api_gold_rel_number = int(__version__.split(".")[2])
391
+
392
+ @staticmethod
393
+ def _find_gams_win():
394
+ gams_dir = ""
395
+ if sys.version_info[0] >= 3:
396
+ import winreg as wreg
397
+ else:
398
+ import _winreg as wreg
399
+
400
+ try:
401
+ gams_dir = wreg.QueryValue(
402
+ wreg.HKEY_CURRENT_USER, r"Software\Classes\gams.location"
403
+ )
404
+ except:
405
+ try:
406
+ gams_dir = wreg.QueryValue(
407
+ wreg.HKEY_LOCAL_MACHINE, r"Software\Classes\gams.location"
408
+ )
409
+ except:
410
+ pass
411
+ return gams_dir
412
+
413
+ @staticmethod
414
+ def _sysdir_from_envvar(ld_string):
415
+ gams_dir = ""
416
+ try:
417
+ if ld_string in os.environ:
418
+ paths = os.environ[ld_string].split(":")
419
+ for p in paths:
420
+ if os.path.exists(
421
+ os.path.join(p, "gamsstmp.txt")
422
+ ) and not os.path.exists(
423
+ os.path.join(p, "gams.exe")
424
+ ): # prevent finding Windows installation under WSL
425
+ gams_dir = p
426
+ break
427
+ except:
428
+ pass
429
+ return gams_dir
430
+
431
+ @staticmethod
432
+ def is_same_system_directory(first, second):
433
+ if os.path.exists(os.path.join(first, "gamsstmp.txt")) and os.path.exists(
434
+ os.path.join(second, "gamsstmp.txt")
435
+ ):
436
+ if filecmp.cmp(
437
+ os.path.join(first, "gamsstmp.txt"),
438
+ os.path.join(second, "gamsstmp.txt"),
439
+ ):
440
+ return True
441
+ else:
442
+ return False
443
+ else:
444
+ return False
445
+
446
+ def _run_gams_audit(self):
447
+ if _is_win:
448
+ si = subprocess.STARTUPINFO()
449
+ si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
450
+ si.wShowWindow = subprocess.SW_HIDE
451
+ try:
452
+ self._p = subprocess.Popen(
453
+ self._system_directory + os.sep + "gams.exe audit lo=3",
454
+ stdout=subprocess.PIPE,
455
+ cwd=self._working_directory,
456
+ startupinfo=si,
457
+ creationflags=subprocess.CREATE_NEW_CONSOLE,
458
+ )
459
+ except:
460
+ raise GamsException("Error retrieving audit info")
461
+ else:
462
+ try:
463
+ self._p = subprocess.Popen(
464
+ [self._system_directory + os.sep + "gams", "audit", "lo=3"],
465
+ stdout=subprocess.PIPE,
466
+ cwd=self._working_directory,
467
+ )
468
+ except:
469
+ raise GamsException("Error retrieving audit info")
470
+
471
+ version_string = ""
472
+ new_data = ""
473
+ while True:
474
+ # we don't want to get an exception when interrupting with ctrl-c
475
+ try:
476
+ new_data = self._p.stdout.readline()
477
+ if sys.version_info[0] >= 3:
478
+ new_data = new_data.decode()
479
+ version_string += new_data
480
+ except KeyboardInterrupt:
481
+ pass
482
+ if new_data == "" and self._p.poll() != None:
483
+ break
484
+ exitcode = self._p.wait()
485
+ if exitcode != 0:
486
+ raise GamsException("Error retrieving audit info")
487
+ self._p.stdout.close()
488
+ self._p = None
489
+ return version_string
490
+
491
+ def _parse_gams_version(self, version_string):
492
+ major, minor, patch = self._version.split(".")
493
+ self._major_rel_number = int(major)
494
+ self._minor_rel_number = int(minor)
495
+ self._gold_rel_number = int(patch)
496
+
497
+ def _init_gams_version(self):
498
+ # read version from gamsstmp.txt (fast)
499
+ try:
500
+ with open(os.path.join(self._system_directory, "gamsstmp.txt"), "r") as f:
501
+ self._version = f.read()
502
+ # wei 48.1.0 (Oct 12, 2024): Sat 12 Oct 11:24:04 AM EST 2024
503
+ self._version = self._version.split()[1].strip()
504
+ self._parse_gams_version(self._version)
505
+ except: # we could not derive the version from gamsstmp.txt, try 'gams audit' instead (slow)
506
+ if self._debug >= DebugLevel.Verbose:
507
+ warn(
508
+ f"Unable to read version information from gamsstmp.txt. Switching to 'gams audit' which might result in decreased performance.",
509
+ stacklevel=2,
510
+ )
511
+ self._version = self._run_gams_audit()
512
+ try:
513
+ # GAMSX 24.1.0 r38765 ALFA Released 1Mar13 VS8 x86/MS Windows
514
+ self._version = self._version.split()[1].strip()
515
+ self._parse_gams_version(self._version)
516
+ # for compatibility with GAMS version before 24.1
517
+ except:
518
+ # e.g. GAMSX Feb 14, 2013 24.0.2 WIN 38380.38394 VS8 x86/MS Windows
519
+ self._version = self._version.split()[4].strip()
520
+ self._parse_gams_version(self._version)
521
+
522
+ def __init__(
523
+ self,
524
+ working_directory=None,
525
+ system_directory=None,
526
+ debug=DebugLevel.KeepFilesOnError,
527
+ ):
528
+ """
529
+ @brief constructor
530
+ @param working_directory GAMS working directory, anchor for all file-based operations (determined automatically if omitted, in user's temporary folder)
531
+ @param system_directory GAMS system directory (determined automatically if omitted)
532
+ @param debug Debug Flag (default: DebugLevel.KeepFilesOnError)
533
+ """
534
+
535
+ self._debug = debug
536
+ self._has_error = False
537
+
538
+ # Allow to overwrite Debug setting with environment variable
539
+ if "GAMSOOAPIDEBUG" in os.environ:
540
+ env_debug = os.environ["GAMSOOAPIDEBUG"].lower()
541
+ if env_debug == "off":
542
+ self._debug = DebugLevel.Off
543
+ elif env_debug == "keepfilesonerror":
544
+ self._debug = DebugLevel.KeepFilesOnError
545
+ elif env_debug == "keepfiles":
546
+ self._debug = DebugLevel.KeepFiles
547
+ elif env_debug == "showlog":
548
+ self._debug = DebugLevel.ShowLog
549
+ elif env_debug == "verbose":
550
+ self._debug = DebugLevel.Verbose
551
+
552
+ self._checkpoint_lock = threading.Lock()
553
+ self._database_lock = threading.Lock()
554
+ self._job_lock = threading.Lock()
555
+ self._modelinstance_lock = threading.Lock()
556
+ self._debug_lock = threading.Lock()
557
+
558
+ self._debug_out("---- Entering GamsWorkspace constructor ----", 0)
559
+
560
+ self._system_directory = None
561
+ self._working_directory = None
562
+ self._using_tmp_working_dir = None
563
+
564
+ self._eps = None
565
+
566
+ self._gmdHandles = []
567
+ self._gevHandles = []
568
+
569
+ ## @brief A string used to prefix automatically generated files
570
+ self.scratch_file_prefix = "_gams_py_"
571
+
572
+ # TODO: can we use lists instead of dictionaries?
573
+ self._gams_checkpoints = {}
574
+ self._gams_databases = {}
575
+ self._gams_jobs = {}
576
+ self._gams_modelinstances = {}
577
+
578
+ self._def_job_name_cnt = 0
579
+ self._def_job_name_stem = "gjo"
580
+
581
+ self._def_database_name_cnt = 0
582
+ self._def_database_name_stem = "gdb"
583
+
584
+ self._def_checkpoint_name_cnt = 0
585
+ self._def_checkpoint_name_stem = "gcp"
586
+
587
+ self._def_modelinstance_name_cnt = 0
588
+ self._def_modelinstance_name_stem = "gmi"
589
+
590
+ if working_directory is None:
591
+ self._using_tmp_working_dir = True
592
+ self._working_directory = tempfile.mkdtemp()
593
+ else:
594
+ if working_directory == "":
595
+ raise GamsException("Empty string is not allowd as working directory")
596
+ self._working_directory = os.path.abspath(working_directory)
597
+ # if the directory doesn't exist, create it
598
+ if not os.path.exists(self._working_directory):
599
+ os.mkdir(self._working_directory)
600
+
601
+ if _is_win:
602
+ if system_directory is None:
603
+ self._system_directory = GamsWorkspace._find_gams_win()
604
+ if not self._system_directory or not os.path.exists(
605
+ os.path.join(os.path.abspath(self._system_directory), "optgams.def")
606
+ ):
607
+ raise GamsException(
608
+ "GAMS System directory "
609
+ + self._system_directory
610
+ + " not found or invalid. Either specify a valid system directory by passing it to the GamsWorkspace constructor or run findthisgams.exe in the GAMS system directory you want to use."
611
+ )
612
+
613
+ else:
614
+ if system_directory == "":
615
+ raise GamsException(
616
+ "Empty string is not allowd as system directory"
617
+ )
618
+ self._system_directory = os.path.abspath(system_directory)
619
+ if not os.path.exists(
620
+ os.path.join(self._system_directory, "optgams.def")
621
+ ):
622
+ raise GamsException(
623
+ "Invalid GAMS system directory: " + self._system_directory
624
+ )
625
+ else:
626
+ if system_directory is None:
627
+ if _is_linux:
628
+ ld_string = "LD_LIBRARY_PATH"
629
+ elif _is_osx:
630
+ ld_string = "DYLD_LIBRARY_PATH"
631
+ path = GamsWorkspace._sysdir_from_envvar("PATH")
632
+ ld_library_path = GamsWorkspace._sysdir_from_envvar(ld_string)
633
+
634
+ if path and os.path.exists(
635
+ os.path.join(os.path.abspath(path), "optgams.def")
636
+ ):
637
+ self._system_directory = path
638
+ elif ld_library_path and os.path.exists(
639
+ os.path.join(os.path.abspath(ld_library_path), "optgams.def")
640
+ ):
641
+ self._system_directory = ld_library_path
642
+ else:
643
+ raise GamsException(
644
+ "GAMS System directory not found or invalid. You need to set either PATH or "
645
+ + ld_string
646
+ + " to a valid GAMS system directory or to specify one in the GamsWorkspace constructor."
647
+ )
648
+
649
+ if self._debug > DebugLevel.KeepFilesOnError:
650
+ if not GamsWorkspace.is_same_system_directory(
651
+ os.path.abspath(path), os.path.abspath(ld_library_path)
652
+ ):
653
+ warn(
654
+ f"Found different GAMS system directories in PATH and {ld_string}. Using the one from PATH",
655
+ stacklevel=2,
656
+ )
657
+ else:
658
+ if system_directory == "":
659
+ raise GamsException(
660
+ "Empty string is not allowd as system directory"
661
+ )
662
+ self._system_directory = os.path.abspath(system_directory)
663
+ if not os.path.exists(
664
+ os.path.join(self._system_directory, "optgams.def")
665
+ ) or os.path.exists(
666
+ os.path.join(
667
+ self._system_directory, "gams.exe"
668
+ ) # prevent using Windows installation under WSL
669
+ ):
670
+ raise GamsException(
671
+ "Invalid GAMS system directory: " + self._system_directory
672
+ )
673
+ self._system_directory = os.path.realpath(
674
+ os.path.abspath(self._system_directory)
675
+ )
676
+
677
+ prefix = ""
678
+ suffix = ".dll"
679
+ if _is_linux:
680
+ prefix = "lib"
681
+ suffix = ".so"
682
+ elif _is_osx:
683
+ prefix = "lib"
684
+ suffix = ".dylib"
685
+
686
+ # Check that none of the required GAMS libraries can be found in the working directory
687
+ if os.path.normcase(self._system_directory) != os.path.normcase(
688
+ self._working_directory
689
+ ):
690
+ libstems = ["gdxcc", "gdxdc", "gmdcc", "joatdc", "optdc"]
691
+ for stem in libstems:
692
+ lib_name = prefix + stem + "lib64" + suffix
693
+ if os.path.exists(os.path.join(self._working_directory, lib_name)):
694
+ warn(
695
+ f"Found library {lib_name} "
696
+ + f"in the Working Directory ({self._working_directory}). "
697
+ + f"This could cause a problem when it is a different version than the one in the System Directory ({self._system_directory}).",
698
+ stacklevel=2,
699
+ )
700
+
701
+ # need to set the path for windows
702
+ if _is_win:
703
+ # GamsJob.run_engine() requires urllib3 which loads libssl-1_1-x64.dll. We need to import urllib3
704
+ # before we prepend the GAMS system directory to the PATH in order to prevent loading an incompatible version
705
+ # of libssl-1_1-x64.dll from the GAMS system directory.
706
+ try:
707
+ import urllib3
708
+ except:
709
+ pass
710
+ env_var = "PATH"
711
+ if env_var in os.environ:
712
+ if not os.environ[env_var].startswith(
713
+ self._system_directory + os.pathsep
714
+ ):
715
+ os.environ[env_var] = (
716
+ self._system_directory + os.pathsep + os.environ[env_var]
717
+ )
718
+ else:
719
+ os.environ[env_var] = self._system_directory
720
+
721
+ self._init_gams_version()
722
+ if self._version != __version__:
723
+ warn(
724
+ f"The GAMS version ({self.version}) differs from the API version ({__version__}).",
725
+ stacklevel=2,
726
+ )
727
+
728
+ def _debug_out(self, msg, lvl):
729
+ self._debug_lock.acquire()
730
+ if self._debug >= DebugLevel.Verbose:
731
+ for i in range(lvl):
732
+ print(" ", end="")
733
+ print(msg)
734
+ sys.stdout.flush()
735
+ self._debug_lock.release()
736
+
737
+ def closedown(self):
738
+ """
739
+ @brief Closes down all network sessions of all GamsModelInstances belonging to the current GamsWorkspace
740
+ """
741
+ import gc
742
+ model_instances = []
743
+ for obj in gc.get_objects():
744
+ try:
745
+ if isinstance(obj, GamsModelInstance) and obj.sync_db.workspace is self:
746
+ model_instances.append(obj)
747
+ except ReferenceError: # silently skip objects that cause a ReferenceError in isinstance(), e.g. weakref
748
+ pass
749
+ for mi in model_instances:
750
+ mi.cleanup()
751
+
752
+ def __del__(self):
753
+ self._debug_out("---- Entering GamsWorkspace destructor ----", 0)
754
+ for g in self._gmdHandles:
755
+ if gmdHandleToPtr(g) != None:
756
+ gmdFree(g)
757
+ for g in self._gevHandles:
758
+ if gevHandleToPtr(g) != None:
759
+ gevFree(g)
760
+ try:
761
+ if self._using_tmp_working_dir and (
762
+ self._debug == DebugLevel.Off
763
+ or (self._debug == DebugLevel.KeepFilesOnError and not self._has_error)
764
+ ):
765
+ shutil.rmtree(self._working_directory)
766
+ except:
767
+ pass
768
+
769
+ def _xxxlib(self, libname, model):
770
+ if _is_win:
771
+ p = Popen(
772
+ self._system_directory + os.sep + libname + "lib.exe " + model,
773
+ cwd=self._working_directory,
774
+ )
775
+ else:
776
+ p = Popen(
777
+ [self._system_directory + os.sep + libname + "lib", model],
778
+ cwd=self._working_directory,
779
+ )
780
+ exitcode = p.wait()
781
+ if exitcode != 0:
782
+ raise GamsException(
783
+ libname + "lib return code not 0 (" + str(exitcode) + ")"
784
+ )
785
+
786
+ def gamslib(self, model):
787
+ """
788
+ @brief Retrieves model from GAMS Model Library
789
+ @param model Model name
790
+ """
791
+ self._xxxlib("gams", model)
792
+
793
+ def testlib(self, model):
794
+ """
795
+ @brief Retrieves model from GAMS Test Library
796
+ @param model Model name
797
+ """
798
+ self._xxxlib("test", model)
799
+
800
+ def emplib(self, model):
801
+ """
802
+ @brief Retrieves model from Extended Math Programming Library
803
+ @param model Model name
804
+ """
805
+ self._xxxlib("emp", model)
806
+
807
+ def datalib(self, model):
808
+ """
809
+ @brief Retrieves model from GAMS Data Utilities Library
810
+ @param model Model name
811
+ """
812
+ self._xxxlib("data", model)
813
+
814
+ def finlib(self, model):
815
+ """
816
+ @brief Retrieves model from Practical Financial Optimization Library
817
+ @param model Model name
818
+ """
819
+ self._xxxlib("fin", model)
820
+
821
+ def noalib(self, model):
822
+ """
823
+ @brief Retrieves model from Nonlinear Optimization Applications Using the GAMS Technology Library
824
+ @param model Model name
825
+ """
826
+ self._xxxlib("noa", model)
827
+
828
+ def psoptlib(self, model):
829
+ """
830
+ @brief Retrieves model from Power System Optimization Modelling Library
831
+ @param model Model name
832
+ """
833
+ self._xxxlib("psopt", model)
834
+
835
+ def apilib(self, model):
836
+ """
837
+ @brief Retrieves model from GAMS API Library
838
+ @param model Model name
839
+ """
840
+ self._xxxlib("api", model)
841
+
842
+ def add_database(
843
+ self, database_name=None, source_database=None, in_model_name=None
844
+ ):
845
+ """
846
+ @brief Database creation
847
+ @param database_name Identifier of GamsDatabase (determined automatically if omitted)
848
+ @param source_database Source GamsDatabase to initialize Database from (empty Database if omitted)
849
+ @param in_model_name GAMS string constant that is used to access this database
850
+ @return Instance of type GamsDatabase
851
+ """
852
+ return GamsDatabase(self, database_name, None, source_database, in_model_name)
853
+
854
+ def add_database_from_gdx(
855
+ self, gdx_file_name, database_name=None, in_model_name=None
856
+ ):
857
+ """
858
+ @brief Database creation from an existing GDX file
859
+ @param gdx_file_name GDX File to initialize Database from
860
+ @param database_name Identifier of GamsDatabase (determined automatically if omitted)
861
+ @param in_model_name GAMS string constant that is used to access this database
862
+ @return Instance of type GamsDatabase
863
+ """
864
+ if gdx_file_name == None or len(gdx_file_name) == 0:
865
+ raise GamsException(
866
+ "Could not create GamsDatabase instance with gdx_file_name being None or empty string"
867
+ )
868
+ return GamsDatabase(self, database_name, gdx_file_name, None, in_model_name)
869
+
870
+ def _add_database_from_gmd(
871
+ self, gmd_handle, database_name=None, in_model_name=None
872
+ ):
873
+ """
874
+ @brief Database creation from an existing GMD handle. This will alter setting for special values and debug settings using the functions: gmdSetDebug and gmdSetSpecialValues. Meant for internal use only
875
+ @param gmd_handle The already created and initialised GMD handle
876
+ @param database_name Identifier of GamsDatabase (determined automatically if omitted)
877
+ @param in_model_name GAMS string constant that is used to access this database
878
+ @return Instance of type GamsDatabase
879
+ """
880
+ return GamsDatabase(
881
+ self, database_name, None, None, in_model_name, False, gmd_handle
882
+ )
883
+
884
+ def add_job_from_string(self, gams_source, checkpoint=None, job_name=None):
885
+ """
886
+ @brief Create GamsJob from string model source
887
+ @param gams_source GAMS model as string
888
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
889
+ @param job_name Job name (determined automatically if omitted)
890
+ @return GamsJob instance
891
+ """
892
+ return GamsJob(
893
+ self, source=gams_source, checkpoint=checkpoint, job_name=job_name
894
+ )
895
+
896
+ def add_job_from_file(self, file_name, checkpoint=None, job_name=None):
897
+ """
898
+ @brief Create GamsJob from model file
899
+ @param file_name GAMS source file name
900
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
901
+ @param job_name Job name (determined automatically if omitted)
902
+ @return GamsJob instance
903
+ """
904
+ return GamsJob(
905
+ self, file_name=file_name, checkpoint=checkpoint, job_name=job_name
906
+ )
907
+
908
+ def add_job_from_gamslib(self, model, checkpoint=None, job_name=None):
909
+ """
910
+ @brief Create GamsJob from model from GAMS Model Library
911
+ @param model model name
912
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
913
+ @param job_name Job name (determined automatically if omitted)
914
+ @return GamsJob instance
915
+ """
916
+ self.gamslib(model)
917
+ return GamsJob(
918
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
919
+ )
920
+
921
+ def add_job_from_testlib(self, model, checkpoint=None, job_name=None):
922
+ """
923
+ @brief Create GamsJob from model from GAMS Test Library
924
+ @param model model name
925
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
926
+ @param job_name Job name (determined automatically if omitted)
927
+ @return GamsJob instance
928
+ """
929
+ self.testlib(model)
930
+ return GamsJob(
931
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
932
+ )
933
+
934
+ def add_job_from_apilib(self, model, checkpoint=None, job_name=None):
935
+ """
936
+ @brief Create GamsJob from model from GAMS API Library
937
+ @param model model name
938
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
939
+ @param job_name Job name (determined automatically if omitted)
940
+ @return GamsJob instance
941
+ """
942
+ self.apilib(model)
943
+ return GamsJob(
944
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
945
+ )
946
+
947
+ def add_job_from_emplib(self, model, checkpoint=None, job_name=None):
948
+ """
949
+ @brief Create GamsJob from model from GAMS Extended Math Programming Library
950
+ @param model model name
951
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
952
+ @param job_name Job name (determined automatically if omitted)
953
+ @return GamsJob instance
954
+ """
955
+ self.emplib(model)
956
+ return GamsJob(
957
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
958
+ )
959
+
960
+ def add_job_from_datalib(self, model, checkpoint=None, job_name=None):
961
+ """
962
+ @brief Create GamsJob from model from GAMS Data Utilities Library
963
+ @param model model name
964
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
965
+ @param job_name Job name (determined automatically if omitted)
966
+ @return GamsJob instance
967
+ """
968
+ self.datalib(model)
969
+ return GamsJob(
970
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
971
+ )
972
+
973
+ def add_job_from_finlib(self, model, checkpoint=None, job_name=None):
974
+ """
975
+ @brief Create GamsJob from model from Practical Financial Optimization Library
976
+ @param model model name
977
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
978
+ @param job_name Job name (determined automatically if omitted)
979
+ @return GamsJob instance
980
+ """
981
+ self.finlib(model)
982
+ return GamsJob(
983
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
984
+ )
985
+
986
+ def add_job_from_noalib(self, model, checkpoint=None, job_name=None):
987
+ """
988
+ @brief Create GamsJob from model from GAMS Non-linear Optimization Applications Library
989
+ @param model model name
990
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
991
+ @param job_name Job name (determined automatically if omitted)
992
+ @return GamsJob instance
993
+ """
994
+ self.noalib(model)
995
+ return GamsJob(
996
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
997
+ )
998
+
999
+ def add_job_from_psoptlib(self, model, checkpoint=None, job_name=None):
1000
+ """
1001
+ @brief Create GamsJob from model from Power System Optimization Modelling Library
1002
+ @param model model name
1003
+ @param checkpoint GamsCheckpoint to initialize GamsJob from
1004
+ @param job_name Job name (determined automatically if omitted)
1005
+ @return GamsJob instance
1006
+ """
1007
+ self.psoptlib(model)
1008
+ return GamsJob(
1009
+ self, file_name=model + ".gms", checkpoint=checkpoint, job_name=job_name
1010
+ )
1011
+
1012
+ def add_options(self, gams_options_from=None, opt_file=None):
1013
+ """
1014
+ @brief Create GamsOptions
1015
+ @param gams_options_from GamsOptions used to initialize the new object
1016
+ @param opt_file Parameter file used to initialize the new object
1017
+ @return GamsOptions instance
1018
+ """
1019
+ if gams_options_from and opt_file:
1020
+ raise GamsException(
1021
+ "Specify either gams_options_from or opt_file but not both"
1022
+ )
1023
+ return GamsOptions(self, gams_options_from, opt_file)
1024
+
1025
+ def add_checkpoint(self, checkpoint_name=None):
1026
+ """
1027
+ @brief Create GamsCheckpoint
1028
+ @param checkpoint_name checkpoint_name Identifier of GamsCheckpoint or filename for existing checkpoint (determined automatically if omitted)
1029
+ @return GamsCheckpoint instance
1030
+ """
1031
+ return GamsCheckpoint(self, checkpoint_name)
1032
+
1033
+ def _job_add(self, job_name=None):
1034
+ if not job_name:
1035
+ self._job_lock.acquire()
1036
+ name = (
1037
+ self.scratch_file_prefix
1038
+ + self._def_job_name_stem
1039
+ + str(self._def_job_name_cnt)
1040
+ )
1041
+ while name in self._gams_jobs:
1042
+ self._def_job_name_cnt += 1
1043
+ name = (
1044
+ self.scratch_file_prefix
1045
+ + self._def_job_name_stem
1046
+ + (self._def_job_name_cnt)
1047
+ )
1048
+ self._def_job_name_cnt += 1
1049
+
1050
+ self._gams_jobs[name] = self._def_job_name_cnt - 1
1051
+ self._job_lock.release()
1052
+ return name
1053
+ else:
1054
+ self._job_lock.acquire()
1055
+ if job_name in self._gams_jobs:
1056
+ self._job_lock.release()
1057
+ return False
1058
+ else:
1059
+ self._gams_jobs[job_name] = 0
1060
+ self._job_lock.release()
1061
+ return True
1062
+
1063
+ def _database_add(self, database_name=None):
1064
+ if not database_name:
1065
+ self._database_lock.acquire()
1066
+ name = (
1067
+ self.scratch_file_prefix
1068
+ + self._def_database_name_stem
1069
+ + str(self._def_database_name_cnt)
1070
+ )
1071
+ while name in self._gams_databases:
1072
+ self._def_database_name_cnt += 1
1073
+ name = (
1074
+ self.scratch_file_prefix
1075
+ + self._def_database_name_stem
1076
+ + (self._def_database_name_cnt)
1077
+ )
1078
+ self._def_database_name_cnt += 1
1079
+
1080
+ self._gams_databases[name] = self._def_database_name_cnt - 1
1081
+ self._database_lock.release()
1082
+ return name
1083
+ else:
1084
+ self._database_lock.acquire()
1085
+ if database_name in self._gams_databases:
1086
+ self._database_lock.release()
1087
+ return False
1088
+ else:
1089
+ self._gams_databases[database_name] = 0
1090
+ self._database_lock.release()
1091
+ return True
1092
+
1093
+ def _checkpoint_add(self, checkpoint_name=None):
1094
+ if not checkpoint_name:
1095
+ self._checkpoint_lock.acquire()
1096
+ name = (
1097
+ self.scratch_file_prefix
1098
+ + self._def_checkpoint_name_stem
1099
+ + str(self._def_checkpoint_name_cnt)
1100
+ )
1101
+ while name in self._gams_checkpoints:
1102
+ self._def_checkpoint_name_cnt += 1
1103
+ name = (
1104
+ self.scratch_file_prefix
1105
+ + self._def_checkpoint_name_stem
1106
+ + (self._def_checkpoint_name_cnt)
1107
+ )
1108
+ self._def_checkpoint_name_cnt += 1
1109
+
1110
+ self._gams_checkpoints[name] = self._def_checkpoint_name_cnt - 1
1111
+ self._checkpoint_lock.release()
1112
+ return name
1113
+ else:
1114
+ self._checkpoint_lock.acquire()
1115
+ if checkpoint_name in self._gams_checkpoints:
1116
+ self._checkpoint_lock.release()
1117
+ return False
1118
+ else:
1119
+ self._gams_checkpoints[checkpoint_name] = 0
1120
+ self._checkpoint_lock.release()
1121
+ return True
1122
+
1123
+ def _modelinstance_add(self, modelinstance_name=None):
1124
+ if not modelinstance_name:
1125
+ self._modelinstance_lock.acquire()
1126
+ name = (
1127
+ self.scratch_file_prefix
1128
+ + self._def_modelinstance_name_stem
1129
+ + str(self._def_modelinstance_name_cnt)
1130
+ )
1131
+ while name in self._gams_modelinstances:
1132
+ self._def_modelinstance_name_cnt += 1
1133
+ name = (
1134
+ self.scratch_file_prefix
1135
+ + self._def_modelinstance_name_stem
1136
+ + (self._def_modelinstance_name_cnt)
1137
+ )
1138
+ self._def_modelinstance_name_cnt += 1
1139
+
1140
+ self._gams_modelinstances[name] = self._def_modelinstance_name_cnt - 1
1141
+ self._modelinstance_lock.release()
1142
+ return name
1143
+ else:
1144
+ self._modelinstance_lock.acquire()
1145
+ if modelinstance_name in self._gams_modelinstances:
1146
+ self._modelinstance_lock.release()
1147
+ return False
1148
+ else:
1149
+ self._gams_modelinstances[modelinstance_name] = 0
1150
+ self._modelinstance_lock.release()
1151
+ return True
1152
+
1153
+ def _job_delete(self, job_name):
1154
+ self._job_lock.acquire()
1155
+ try:
1156
+ del self._gams_jobs[job_name]
1157
+ return True
1158
+ except KeyError:
1159
+ return False
1160
+
1161
+ def _database_delete(self, database_name):
1162
+ self._database_lock.acquire()
1163
+ try:
1164
+ del self._gams_databases[database_name]
1165
+ return True
1166
+ except KeyError:
1167
+ return False
1168
+
1169
+ def _checkpoint_delete(self, checkpoint_name):
1170
+ self._checkpoint_lock.acquire()
1171
+ try:
1172
+ del self._gams_checkpoints[checkpoint_name]
1173
+ return True
1174
+ except KeyError:
1175
+ return False
1176
+
1177
+ def _modelinstance_delete(self, modelinstance_name):
1178
+ self._modelinstance_lock.acquire()
1179
+ try:
1180
+ del self._gams_modelinstances[modelinstance_name]
1181
+ return True
1182
+ except KeyError:
1183
+ return False
1184
+
1185
+ def _opt_file_extension(self, optfile):
1186
+ if optfile < 2:
1187
+ return "opt"
1188
+ elif optfile < 10:
1189
+ return "op" + str(optfile)
1190
+ elif optfile < 100:
1191
+ return "o" + str(optfile)
1192
+ elif optfile <= 999:
1193
+ return "" + str(optfile)
1194
+ else:
1195
+ raise GamsException(
1196
+ "Index Out of Bounds when writing opt file, must be between 1 and 999, saw "
1197
+ + str(optfile)
1198
+ )