This section highlights the major library components,
ranging from basic building blocks necessary for any AMPL driver,
to more advanced utilities. The choice of API for a driver may depend
on Solver driver setups.
Reading NL and writing SOL files
Any AMPL solver driver currenlty needs to input
an NL file and report results in a SOL file.
The details are taken care of in the
recommended driver setup.
However, a minimal driver setup might address the
corresponding APIs directly, as described below.
NL file reader
MP provides a high-performance nl file reader
which is up to 6x faster
than the one provided by the traditional
AMPL Solver Library (ASL).
This section describes the C++ API of an NL reader which is
Reusable: the reader can be used to process NL files in different ways
and not limited to a single problem representation
High performance: fast mmap-based reader
with SAX-like API and no
dynamic memory allocations in the common case
Easy to use: clean, modern code base and simple API
Complete: supports all NL constructs including extensions implemented in
AMPL Solver Library
Reliable: extensively and continuously tested on a variety of platforms
Easy-to-use functions
The mp/nl.h
header only contains declarations of
mp::ReadNLFile()
and mp::ReadNLString()
, and can be used to read the standard optimization problem
object of class mp::Problem
, for example:
#include "mp/nl.h"
#include "mp/problem.h"
mp::Problem p;
ReadNLFile("diet.nl", p);
Full NL-reader API
If you want to provide a custom NL handler, include mp/nl-reader.h
instead.
Class mp::NLHandler
can be customized for most efficient translation of NL format into
solver API using the ProblemBuilder concept.
Note that mp/nl.h
is a much smaller header than mp/nl-reader.h
so prefer
it unless you need access to the full NL reader API, described below.
SOL file writer
Writing solution/results output is easiest as part of the general workflow,
see Model manager.
A standalone .sol file writer could be implemented by parameterizing the
mp::internal::AppSolutionHandlerImpl
(or mp::internal::SolutionWriterImpl
)
templates by minimal implementations of the mp::BasicSolver
and
mp::ProblemBuilder
interfaces.
Writing NL and reading SOL files
For modeling systems and applications using AMPL solvers,
MP provides a library to write NL and read SOL files.
The library is zero-overhead: it does not store the model,
nor does it require any intermediate objects to represent
model information.
NL Writer design
The library was designed with efficiency in mind.
It allows most efficient conversion of the user model
internal representation to NL format by providing
NL component writer callbacks
(and solution reader callbacks to receive solutions.)
In turn, the library is flexible to use because
various components of the user model will be provided
on the library’s request from a user-specialized
NLFeeder2
object (for solution input,
solution components will be received by methods
of a custom SOLHandler2
class.)
Recommended driver logic
Using the mp::StdBackend and the derived classes is the
recommended approach to building a new solver interface.
They provide a convenient API for common solver driver actions,
options and suffixes.
The high-level application structure is suggested as follows:
In the recommended driver setup,
the interaction of the Backend with the solver API is
separated in two channels:
model manipulation is delegated to Model manager.
ModelManager addresses solver API via a separate modeling API wrapper:
More details are given in Model/solution I/O and reformulations.
Thus, solver API is wrapped by two separate classes specializing in model manipulation
vs. process logic. A reason for this design is maintainability and recompilation speed.
Creating such a driver is
described in the HowTo.
BackendApp
mp::BackendApp
supports basic application functions, such as screen output
and interrupts handling. It calls a CustomBackend which should implement
the mp::BasicBackend
interface.
The Backend classes
mp::StdBackend
and mp::MIPBackend
implement the mp::BasicBackend
interface and
standardize some common AMPL app behaviour, such as
solver messages and status reporting,
LP basis statuses, and other suffix I/O.
Their solver-specific subclasses can be customized for a particular solver.
They rely on the Model manager interface
for model and solution I/O.
As an example, if the driver should read and write simplex basis status suffixes,
the derived Backend class can declare
ALLOW_STD_FEATURE( BASIS, true )
SolutionBasis GetBasis() override;
void SetBasis(SolutionBasis ) override;
and define the GetBasis
, SetBasis
methods.
See Implement standard & custom features
for further details.
Solver, SolverImpl [deprecated]
Classes mp::SolverApp
, mp::Solver
and mp::SolverImpl
enable very basic
standard behaviour (e.g., multiobj, solution output). They are deprecated
in favor of the BackendApp/Backend classes and
can be discontinued in future.