Architecture

This section contains an overview of the architecture of the solvers API.

The first diagram presents the classes storing the AMPL models themselves:

digraph hierarchy { size="6,6" node[shape=record,style=filled,fillcolor=white] edge[dir=back, arrowtail=empty] AMPLModel[label = "{AMPLModel|...|+ enableLazyConstraints()\l+ getFileName()\l+ getVarMap()\l+ getVarMapInverse()\l+ getVarMapFiltered()\l+ setCallback()\l+ getNumVars()\l+ getObj()\l+ getSolutionVector()\l+ getStatus()\l+ optimize()\l+ writeSol()\l}"] GurobiModel[label = "{GurobiModel|...|+ getIntAttr()\l+ getDoubleAttr()\l+ getIntAttrArray()\l+ getDoubleAttrArray()\l+ getIntParam()\l+ getIntAttr()\l+ getDoubleParam()\l+ getStrParam()\l+ setIntParam()\l+ setDoubleParam()\l+ setStrParam()\l|+ getGRBmodel()\l+ getGRBenv()\l}"] CPLEXModel[label = "{CPLEXModel|...|+ getCPXmodel()\l+ getCPLEXenv()\l}"] XPRESSModel[label = "{XPRESSModel|...|+ getXPRESSprob()\l}"] XPRESSModel[label = "{XPRESSModel|...|+ getXPRESSprob() \l}"] AMPLModel->GurobiModel AMPLModel->CPLEXModel AMPLModel->XPRESSModel }

The following diagram presents the classes encapsulating the callbacks:

Core Concepts

Generic vs specific

There are two ways to use the solvers API:

  1. Generic: using only the base classes (ampls::AMPLModel and ampls::GenericCallback) methods, the resulting program is fully portable between solvers

  2. Specific: using methods present the specialized version of the classes (e.g. ampls::GurobiModel and ampls::GurobiCallback). It is to be noted that, as an extreme case of specific usage, it is always possible to retrieve from the Model object the pointer to the underlying solver model instance, that can be then be used using the solver’s native C API (e.g. retrieve the model pointer with ampls::GurobiModel::getGRBmodel() and use it in Gurobi’s C API function GRBtunemodel() to execute a solver tuning)

AMPLS vs AMPL

An AMPLS object can generally be instantiated starting with an NL file, as generated by the AMPL interpreter, and it has facilities to export the model in a format suitable to be read back by AMPL (a sol file). It is normally much more convenient to use the AMPLAPI (https://ampl.com/products/ampl/apis/) to generate such model and read back the results; when using both APIs, defining USE_amplapi before including the ampls.h file adds two functions (:func:`ampls::AMPLAPIInterface::exportModel() and :func:`ampls::AMPLAPIInterface::importModel) that can be used to create an AMPLS Model instance and to import back the results respectively.