GPU-Accelerated Optimization with GAMS and NVIDIA cuOpt

Posted on: 01 Sep, 2025 GAMS Solvers

For a long time, GPUs were essential for various AI applications and other high-performance compute applications but had limited impact on mathematical optimization. That’s changing.

The paper “Practical Large-Scale Linear Programming using Primal-Dual Hybrid Gradient ” by Applegate et al. (2021) ignited considerable interest with its primal-dual linear programming (PDLP) implementation, proving the method’s effectiveness on real-world problems. This led many solvers to incorporate GPU-accelerated PDLP implementations into their algorithmic offerings. Public interest has further intensified with the open-sourcing of NVIDIA’s own GPU-accelerated LP/MIP and VRP solver, cuOpt .

At GAMS we’re deeply committed to improving computational efficiency for large-scale linear programming, such as those that occur in energy systems modeling. This commitment is demonstrated through projects like PEREGRINE , which develops and utilizes innovative solver technology such as PIPS-IPM++ , a parallel, high-performance computing (HPC) capable interior point method tailored for block-structured LPs, which often arise naturally in large-scale problems that have repetitive substructures. Our ongoing efforts also include exploring cutting-edge technologies like GPU-accelerated optimization with PDLP, to effectively address the challenges of modern optimization.

We are therefore happy to announce the GAMS/cuOpt Link , developed in collaboration with NVIDIA. This offering allows you to solve GAMS and GAMSPy models using cuOpt and further expands our collection of GPU-accelerated solvers, which already features COPT and HiGHS (both utilizing a GPU-accelerated implementation of PDLP).

This blog post focuses on the practical application of GAMS/cuOpt rather than extensive benchmarking. It aims to address:

  • What model types does cuOpt support
  • What hardware is needed
  • How can cuOpt be utilized through GAMS and GAMSPy

What model types does cuOpt support?

NVIDIA cuOpt offers a flexible set of solver methods and features for optimizing Linear Programming (LP), Mixed-Integer Linear Programming (MILP), and Vehicle Routing Problems (VRP)1. This versatility allows users to tailor its operation to specific problem characteristics and desired solution qualities.

cuOpt offers three LP methods. The default concurrent method runs both PDLP (GPU) and Dual Simplex (CPU) simultaneously, returning the faster solution. The GPU-based PDLP method is designed for large-scale memory-intensive LPs. Dual Simplex is a classic CPU-based method suited for small to medium-sized LPs, particularly when a high-quality basic solution is required.

For MIP, NVIDIA cuOpt uses a hybrid GPU/CPU method, running primal heuristics on the GPU and improving the dual bound on the CPU.

What hardware is needed?

cuOpt requires an NVIDIA GPU with a Volta architecture or newer. Powerful GPUs such as the NVIDIA V100, A100, and H100/H200 (as seen in benchmarks ) can be deployed on-premise but the seamless integration of GAMS/cuOpt into GAMS Engine SaaS makes these capabilities more accessible to those without GPU-accelerated infrastructure.This cloud-based solution provides users with access to the precise hardware needed for their optimization problems, eliminating the need for substantial upfront investment.

How can cuOpt be utilized through GAMS and GAMSPy?

GAMS/cuOpt can be set up to run locally or it can be run on the cloud via GAMS Engine SaaS.

Installing and using cuOpt locally with GAMS and GAMSPy

Before you begin, ensure your system meets the following system requirements:

  • Operating System: Linux
  • GAMS: Version 49 or newer.
  • GAMSPy: Version 1.12.1 or newer
  • NVIDIA GPU: Volta architecture or better
  • CUDA Runtime Libraries: 12.8+

Installation Steps

  1. Download and unpack cuopt-link-release.zip : Unpack the contents of cuopt-link-release.zip into your GAMS system directory2. Caution: This will overwrite any existing gamsconfig.yaml file in that directory. The provided gamsconfig.yaml includes a solverConfig section that enables cuOpt for use with GAMS.

  2. Download and unpack cuda_runtime.zip (if needed): If your machine is missing the CUDA runtime libraries, unpack cuda_runtime.zip into the same GAMS system directory.

Hint: The GAMSPy/cuOpt example notebook automates these steps and allows you to get started right away.

Running GAMS/cuOpt and GAMSPy/cuOpt locally

After installation, you can run a GAMS or GAMSPY model with cuOpt.


GAMS

To load and solve the trnsport model from the GAMS model library, execute:

gamslib trnsport
gams trnsport lp=cuopt

GAMSPy

To use cuOpt with GAMSPy (e.g. with the transport.py example), set cuOpt as solver in the solve function and set option gamspy.set_options({"SOLVER_VALIDATION": 0}).

[...] 
transport.solve(solver="cuopt")

Running cuOpt in the cloud via GAMS Engine SaaS

An alternative to a local installation is to use cuOpt via GAMS Engine SaaS. This cloud-based platform offers a centralized solution for submitting GAMS jobs. It supports various client applications such as GAMS Studio , GAMS MIRO , the GAMS Engine Web UI , and custom scripts in Python and other languages. This flexibility allows users to integrate cuOpt into existing GAMS and GAMSPy workflows and lowers the barrier to entry by avoiding the need for significant on-premise GPU investments. Users gain access to necessary hardware configurations without substantial upfront capital expenditure, making GPU-accelerated optimization more accessible and scalable.

Not yet a GAMS/Engine SaaS user? Request your free test account at sales@gams.com and let the team know you want to try GAMS/cuOpt.

Running GAMS/cuOpt on Engine SaaS through GAMS Studio

The process of running GAMS/cuOpt on Engine SaaS through GAMS Studio offers a user experience akin to executing GAMS jobs locally within Studio.

Hint: Are you a Windows or Mac user working with GAMS Studio? No Problem. While cuOpt is only available for Linux, you can submit your GAMS/cuOpt jobs from GAMS Studio under Windows and Mac as well.3

  1. Select “Run GAMS Engine” Remember to configure cuOpt as your LP solver, either through the command-line parameter (as demonstrated below) or by including an appropriate option statement within your GAMS code.
  1. Should you not already be logged in, the GAMS Engine Login Dialog will appear. Please choose your preferred sign-in method to proceed with logging in.
  1. The Submit Job dialog box will appear. Select the desired Namespace and instance for submission. Optionally, assign a tag to the job before clicking OK.
  1. Your job compiles locally and is then submitted to Engine SaaS for execution. You can monitor its progress in the Process Log. Upon completion, the results and all output files are downloaded and become accessible on your local system.
--- Job indus89.gms Start 06/23/25 22:07:03 50.1.0 12b75dde WEX-WEI x86 64bit/MS Windows  
[...]  
--- Starting compilation  
--- indus89.gms(3485) 4 Mb  
*** Status: Normal completion  
--- Job indus89.gms Stop 06/23/25 22:07:03 elapsed 0:00:00.038  
 adding: indus89.gms (164 bytes security) (stored 0%)  
 adding: indus89.g00 (164 bytes security) (deflated 5%)

--- GAMS Engine at https://engine.gams.com:443/api  
--- switch LOG to indus89-server.lst  
TOKEN: b88ca408-f993-42ff-afe6-972c2ac1fae0

--- Job queued (80 sec)  
--- Job indus89.gms Start 06/23/25 20:10:18 49.6.1 55d34574 LEX-LEG x86 64bit/Linux  
--- Applying:  
   /home/jail/opt/gams/gmsprmun.txt  
   /home/jail/opt/gams/gamsconfig.yaml  
--- GAMS Parameters defined  
   LP cuopt  
   Restart /home/gfreeman/indus89.g0?  
   Input /home/gfreeman/indus89.gms  
[...]  
--- Reset Solvelink = 1  
---   2,726 rows  6,570 columns  39,489 non-zeroes  
--- Range statistics (absolute non-zero finite values)  
--- RHS       [min, max] : [ 8.438E-04, 2.170E+04] - Zero values observed as well  
--- Bound     [min, max] : [ 5.000E-04, 2.713E+03] - Zero values observed as well  
--- Matrix    [min, max] : [ 4.104E-04, 1.000E+06]  
--- Executing CUOPT (Solvelink=1): elapsed 0:00:00.117  
Solving a problem with 2725 constraints 6569 variables (0 integers) and 36535 nonzeros  
Objective offset 0.000000 scaling_factor -1.000000  
Running concurrent

  Iter    Primal Obj.      Dual Obj.    Gap        Primal Res.  Dual Res.   Time  
Dual simplex finished in 1.69 seconds  
     0 +5.99317340e+01 +6.99889400e+03  6.94e+03   4.11e+04     1.64e+05   3.692s  
PDLP finished  
Concurrent time:  3.695s  
Solved with dual simplex  
Status: Optimal   Objective: 1.14873656e+05  Iterations: 5962  Time: 3.695s  
--- Reading solution for model wsisn[LS2:2523]  
--- Executing after solve: elapsed 0:01:00.859[LS2:12126]  
--- GDX File C:\Users\ffian\Documents\GAMS\Studio\workspace\indus89.gdx  
*** Status: Normal completion[LS2:12142]  
--- Job indus89.gms Stop 06/23/25 20:11:19 elapsed 0:01:00.869  
Archive:  solver-output.zip  
 inflating: indus89.lst               
 inflating: indus89.lxi               
--- extracting: .\indus89-temp\indus89.gms  
 inflating: solver.log                
 inflating: indus89.gdx               
 inflating: indus89.g00               
*** Local file updated: indus89.gdx  
*** Local file updated: indus89-server.lst  
*** Local file updated: indus89-server.lxi  
*** Local file updated: indus89-solver.log

Running GAMSPy/cuOpt on Engine SaaS

In order to submit your GAMSPy model to Engine SaaS for solving, you need to define the GAMS Engine configuration by importing EngineClient and creating an instance, which can then be passed to the solve method with the backend specified as ’engine'.

To adapt the GAMSPy model library’s mexss model for use with cuOpt under Engine, some modifications are necessary.

[...]
from gamspy import (
    Container,
    Equation,
    [...],
    EngineClient
)

[...]

#create EngineClient instance. Submit to namespace gpu_tests and select an instance with NVIDIA GPU
client = EngineClient(
    host="https://engine.gams.com/api",
    username=os.environ["ENGINE_USER"],
    password=os.environ["ENGINE_PASSWORD"],
    namespace="gpu_tests",
    engine_options={"labels": "instance=g6.4xlarge"}
)  

#solve with solver cuopt and engine backend
mexss.solve(solver="cuopt", backend="engine", client=client, output=sys.stdout)
[...]

The Terminal output will look as follows:

(gamspy) PS C:\Users\ffian> & C:/Users/ffian/.conda/envs/gamspy/python.exe c:/Users/ffian/Documents/projects/gamspy-examples/models/mexss/mexss.py  
[ENGINE - INFO] Job status is queued...  
[ENGINE - INFO] Job status is queued...  
[ENGINE - INFO] Job status is queued...  
--- Job __AcZmhoFQyKC4_Jc_7zWpQ.gms Start 06/30/25 11:36:04 49.6.1 55d34574 LEX-LEG x86 64bit/Linux  
--- Applying:  
   /home/jail/opt/gams/gmsprmun.txt  
   /home/jail/opt/gams/gamsconfig.yaml  
--- GAMS Parameters defined  
   LP cuopt  
[...]     
--- Generating LP model mexss  
--- __AcZmhoFQyKC4_Jc_7zWpQ.gms(459) 4 Mb  
--- Reset Solvelink = 1  
---   74 rows  78 columns  230 non-zeroes  
--- Range statistics (absolute non-zero finite values)  
--- RHS       [min, max] : [ 5.600E-01, 4.011E+00] - Zero values observed as well  
--- Bound     [min, max] : [        NA,        NA] - Zero values observed as well  
--- Matrix    [min, max] : [ 1.200E-01, 1.500E+02]  
--- Executing CUOPT (Solvelink=1): elapsed 0:00:00.002  
Solving a problem with 73 constraints 77 variables (0 integers) and 225 nonzeros  
Objective offset -0.000000 scaling_factor 1.000000  
Running concurrent

Dual simplex finished in 0.00 seconds  
  Iter    Primal Obj.      Dual Obj.    Gap        Primal Res.  Dual Res.   Time  
     0 +0.00000000e+00 +0.00000000e+00  0.00e+00   4.70e+00     2.00e+00   0.015s
PDLP finished  
Concurrent time:  0.017s  
Solved with dual simplex  
Status: Optimal   Objective: 5.38811204e+02  Iterations: 56  Time: 0.017s  
--- Reading solution for model mexss  
--- Executing after solve: elapsed 0:00:01.397  
--- __AcZmhoFQyKC4_Jc_7zWpQ.gms(518) 4 Mb  
--- GDX File /home/gfreeman/__AcZmhoFQyKC4_Jc_7zWpQout.gdx  
*** Status: Normal completion  
--- Job __AcZmhoFQyKC4_Jc_7zWpQ.gms Stop 06/30/25 11:36:06 elapsed 0:00:01.398  
[ENGINE - INFO] Results have been extracted to your working directory: C:\Users\ffian\AppData\Local\Temp\tmpizp77f7a.

Key considerations when working with GAMS/cuOpt:

cuOpt offers the prospect of considerable speedup, particularly for large-scale linear programming problems. However, discussions have arisen regarding the accuracy of solutions obtained by leveraging first-order methods like PDLP. In a recent webinar , Gurobi Co-Founder and Chairman Ed Rothberg noted that while PDLP can offer faster solve times, it may struggle to deliver high-precision solutions when compared to interior point methods. Julian Hall expanded on this in the HiGHS Newsletter 25.0 , where he presented experimental comparisons between cuPDLP-C and the HiGHS interior point solver. His findings showed that although PDLP was faster on several instances, some solutions exhibited notable deviations from true optimality.

These observations underscore a critical trade-off: while first-order methods can unlock substantial speedups, especially for very large models, users must weigh this against the level of accuracy required for their use case. Understanding these trade-offs and using solvers and algorithms thoughtfully is essential for making informed decisions when selecting a solver. Carefully comparing GAMS/cuOpt with solvers you’re already using can be a smart move. In the following section, we’ll briefly describe which GAMS model types cuOpt can solve, explore the solver options GAMS/cuOpt offers, and demonstrate how the GAMS tool Examiner can be effectively used to draw conclusions about solution quality.

Supported problem types and limitations

cuOpt can solve the following GAMS problem types:

  • LP (Linear Programming)
  • MIP (Mixed Integer Programming)
  • RMIP (Relaxed Mixed Integer Programming)

Note on Discrete Variables: The type of discrete variables is limited to binaries and integers.

cuOpt parameters

GAMS/cuOpt options can be set through a GAMS solver options file . The various GAMS/cuOpt options are listed here by category, with a few words about each to indicate its function.

For a more detailed documentation of the available parameters, consult the official NVIDIA cuOpt user guide .4


General Options:

Option Description Type Default
num_cpu_threads Controls the number of CPU threads used in the LP and MIP solvers (default GAMS Threads) integer 0
presolve Controls whether presolve is enabled. Presolve can reduce problem size and improve solve time. Enabled by default for MIP, disabled by default for LP. boolean 0 (LP) 1 (MIP)
prob_read reads a problem from an MPS file. When an instance is supplied via an MPS file no solution is reported back to GAMS. string
time_limit Controls the time limit in seconds after which the solver will stop and return the current solution (default GAMS ResLim) integer 0

Linear Programming Options:

Option Description Type Default
absolute_dual_tolerance Controls the absolute dual tolerance used in PDLP’s dual feasibility check double 0.0001
absolute_gap_tolerance Controls the absolute gap tolerance used in PDLP’s duality gap check double 0.0001
absolute_primal_tolerance Controls the absolute primal tolerance used in the primal feasibility check double 0.0001
crossover Controls whether PDLP should crossover to a basic solution after an optimal solution is found boolean 0
first_primal_feasible Controls whether PDLP should stop when the first primal feasible solution is found boolean 0
infeasibility_detection Controls whether PDLP should detect infeasibility boolean 0
iteration_limit Controls the iteration limit after which the solver will stop and return the current solution (default GAMS IterLim) integer maxint
method Controls the method to solve the linear programming problem 0 concurrent 1 pdlp 2 dual_simplex enumint 0
pdlp_solver_mode Controls the mode under which PDLP should operate 0 stable1 1 stable2 2 methodical1 3 fast1 enumint 1
per_constraint_residual Controls whether PDLP should compute the primal & dual residual per constraint instead of globally boolean 0
relative_dual_tolerance Controls the relative dual tolerance used in PDLP’s dual feasibility check double 0.0001
relative_gap_tolerance Controls the relative gap tolerance used in PDLP’s duality gap check double 0.0001
relative_primal_tolerance Controls the relative primal tolerance used in PDLP’s primal feasibility check double 0.0001
save_best_primal_so_far Controls whether PDLP should save the best primal solution so far boolean 0
strict_infeasibility Controls the strict infeasibility mode in PDLP boolean 0

Mixed Integer Linear Programming Options:

Option Description Type Default
mip_absolute_gap Controls the absolute tolerance used to terminate the MIP solve (default GAMS OptCA) double 1.00E-10
mip_absolute_tolerance Controls the MIP absolute tolerance double 0.0001
mip_heuristics_only Controls if only the GPU heuristics should be run boolean 0
mip_integrality_tolerance Controls the MIP integrality tolerance double 1.00E-05
mip_relative_gap Controls the relative tolerance used to terminate the MIP solve (default GAMS OptCR) double 1.00E-05
mip_relative_tolerance Controls the MIP relative tolerance double 0.0001
mip_scaling Controls if scaling should be applied to the MIP problem boolean 1

Solution quality

No single algorithm is universally optimal for all problem types. Within cuOpt, PDLP is well suited for large-scale, memory-intensive problems due to its ability to avoid explicit matrix factorizations. In contrast, Dual Simplex is better suited for smaller to medium-sized problems, where it can provide high-quality basic solutions.

Users can customize operations based on specific problem characteristics and desired solution qualities, thanks to a wide array of available options. GAMS/Examiner further aids users by providing an unbiased assessment of solution quality, verifying the validity of a solver’s reported optimal solution by checking for primal feasibility, dual feasibility, and optimality.

GAMS/Examiner is used “like a solver” and can be parameterized to use any solver available with GAMS and GAMSPy as a subsolver.

Running Examiner with cuOpt as subsolver

The Examiner options subsolver and subsolveropt allow to specify a subsolver and activate its corresponding option file. For the Examiner example we utilize cuOpt options method 1 and crossover 0.

The following code snippets illustrate one way to set these solver options in both GAMS and GAMSPy.


GAMS

[...]  
* Write GAMS/Examiner option file examiner.opt and instruct to use cuOpt as subsolver with a GAMS/cuOpt option file*  
file     opt_examiner / examiner.opt /;  
putclose opt_examiner 'subsolver cuopt' /  
                      'subsolveropt 1'  ;

* Write GAMS/cuOpt option file cuopt.opt and instruct to use*  
* PDLP without crossover*  
file opt_cuopt / cuopt.opt /;  
putclose opt_cuopt 'method 1'    /  
                   'crossover 0' ;      

option solver =examiner, optFile=1;  
solve myModel maximizing myObjective using lp;  
[...]

GAMSPy

[...]
#Write cuOpt option file in the container's working directory
cuopt_opt_file = os.path.join(myContainer.working_directory, "cuopt.opt")
with open(cuopt_opt_file, "w") as f:
    f.write("method = 1\n")
    f.write("crossover = 0\n") 

#set examiner as solver and define examiner options
myModel.solve(solver="examiner", solver_options={"subsolver": "cuopt", "subsolveropt": "1"})
[...]

When solving the indus89 model from the GAMS model library using Examiner and cuOpt, Examiner analyzes the solver’s solution and generates the following report. Note that we asked cuOpt to solve this problem with the default tolerance settings of 1e-4, which are likely to generate constraint violations due to the accuracy level resulting from this tolerance value. To reduce or completely eliminate these violations, we will also discuss additional steps and features provided by cuOpt below.

[...]
Status: Optimal   Objective: 1.15093789e+05  Iterations: 673080  Time: 42.146s
Subsolver cuopt returns modstat 1, solstat 1.


SolvPoint - solver-provided levels & marginals:
Scale range (observed but not applied): [1,999999]
Maximum element: row=objn, col=artwater(nwfp,fresh,jan): Aij = 999999
Primal variable bounds satisfied (tol = 1e-06)
Dual variable bounds satisfied (tol = 1e-06)
Primal infeasible w.r.t. constraints (tol = 1e-06):
  Max violation: watalcz.l(srws,saline,sep): 0 <= 1.70757 <= 0
  2-Norm of violation: 5.54794
Dual constraints satisfied (tol = 1e-06)
Primal CS is nonzero (tol = 1e-07):
  Max violation: canaldiv.l(44-ful,apr): 0.1021 <= 0.106234 <= 0.894
                 canaldiv.m(44-ful,apr): -INF <= 2.561 <= +INF
Dual CS is nonzero (tol = 1e-07):
  Max violation: watalcz.m(srws,saline,sep): -INF <= 0.00933685 <= +INF
                 watalcz.l(srws,saline,sep): 0 <= 1.70757 <= 0
Model attributes OK (tol = 1e-06)

As expected, the returned primal solution reveals significant constraint violations (max violation 1.70757 and 2-Norm of violations 5.54794). If this is unacceptable, mitigation strategies could for example be to reduce the relative primal tolerance by setting GAMS/cuOpt option ‘relative_primal_tolerance 1e-6’ (default 1e-4) or to enable crossover by setting GAMS/cuOpt option ‘crossover 1’.

With relative_primal_tolerance 1e-6 Examiner returns

[...]
Status: Optimal   Objective: 1.14889661e+05  Iterations: 898280  Time: 61.183s
Subsolver cuopt returns modstat 1, solstat 1.


SolvPoint - solver-provided levels & marginals:
Scale range (observed but not applied): [1,999999]
Maximum element: row=objn, col=artwater(nwfp,fresh,jan): Aij = 999999
Primal variable bounds satisfied (tol = 1e-06)
Dual variable bounds satisfied (tol = 1e-06)
Primal infeasible w.r.t. constraints (tol = 1e-06):
  Max violation: demnat.l(prw,buff-milk): 0 <= -0.057 <= 1e+299
  2-Norm of violation: 0.0958988
Dual constraints satisfied (tol = 1e-06)
Primal CS is nonzero (tol = 1e-07):
  Max violation: x.l(psw,saline,sc-mill,bullock,standard,standard): 0 <= 216.779 <= +INF
                 x.m(psw,saline,sc-mill,bullock,standard,standard): -INF <= -0.158928 <= 0
Dual CS is nonzero (tol = 1e-07):
  Max violation: demnat.m(prw,basmati): -INF <= -2.4166 <= 0
                 demnat.l(prw,basmati): 0 <= 0.0619937 <= +INF
Model attributes OK (tol = 1e-06)

As expected, we can observe that a tighter tolerance results in a smaller violation but also in a higher run time.

With ‘crossover 1’ all violations are gone and Examiner returns

[...]
Crossover time 0.36 seconds
Total time 42.69 seconds
Crossover status Optimal
Subsolver cuopt returns modstat 1, solstat 1.


SolvPoint - solver-provided levels & marginals:
Scale range (observed but not applied): [1,999999]
Maximum element: row=objn, col=artwater(nwfp,fresh,jan): Aij = 999999
Primal variable bounds satisfied (tol = 1e-06)
Dual variable bounds satisfied (tol = 1e-06)
Primal constraints satisfied (tol = 1e-06)
Dual constraints satisfied (tol = 1e-06)
Primal CS is zero (tol = 1e-07)
Dual CS is zero (tol = 1e-07)
Model attributes OK (tol = 1e-06)

Note: All experiments were conducted on an AWS EC g6.4xlarge instance, featuring an NVIDIA L4 Tensor Core GPU. Other instances supporting NVIDIA GPUs V100, A100, H100, and H200 are available upon request. This post aims to guide users on leveraging GAMS/cuOpt for their own experiments, rather than offering an exhaustive performance benchmark.

Conclusion

The new GAMS/cuOpt link empowers users to integrate cuOpt directly into their existing GAMS and GAMSPy models. Whether through local installation or the scalable GAMS Engine SaaS cloud solution, users can leverage cutting-edge GPU performance without the burden of major on-premise GPU investments.

Crucially, GAMS’ robust diagnostic tools—such as Examiner—are integral to this process, providing essential checks on solution feasibility and quality. This ensures that the benefits of GPU acceleration are complemented by the precision required for practical applications.

We invite you to explore the potential of cuOpt with GAMS and GAMSPy for your most challenging optimization tasks. To get started with cuOpt (or any other solver) on GAMS Engine SaaS, request a free test account by contacting sales@gams.com .

Your feedback and experiences are vital as we continue advancing large-scale decision-making. Please reach out to support@gams.com or join forum.gams.com with any questions, issues, or success stories you’d like to share.


  1. The cuOpt VRP Solver is not available through GAMS and GAMSPy ↩︎

  2. Run gamspy show base to identify the GAMS system directory for GAMSPy. ↩︎

  3. To make this work, make sure to add a “dummy” solverConfig section to the gamsconfig.yaml file:

    [...]  
    
    solverConfig:  
       - cuopt:  
         minVersion: 49  
         scriptName: dummy  
         executableName: dummy  
         modelTypes:  
           - LP  
           - MIP  
           - RMIP
    
     ↩︎
  4. Note that GAMS/cuOpt options omit the “CUOPT_” prefix from the original parameter name. For example, “CUOPT_METHOD” in cuOpt documentation becomes simply ‘method’ in a GAMS/cuOpt solver options file. ↩︎