Skip to content

Commit

Permalink
Add NL Writer #30
Browse files Browse the repository at this point in the history
Templates, inline C++
  • Loading branch information
glebbelov committed Oct 23, 2023
1 parent de642b6 commit 6c00959
Show file tree
Hide file tree
Showing 23 changed files with 11,539 additions and 10 deletions.
18 changes: 13 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -454,16 +454,24 @@ check_cxx_source_compiles("
int main() {}" MP_VARIADIC_TEMPLATES)

# Option BUILD_EXAMPLES
option(BUILD_EXAMPLES "Build nl-example" ON)
option(BUILD_EXAMPLES "Build examples: nl reader, nl writer" ON)

# Build NLReader example
if (MP_VARIADIC_TEMPLATES AND BUILD_EXAMPLES)
message(STATUS
"Building nl-example. Set -DBUILD_EXAMPLES=off to switch off.")
add_executable(nl-example src/nl-example.cc)
add_to_folder(${MP_FOLDER_PREFIX}util nl-example)
target_link_libraries(nl-example mp)
"Building nl-reader-example. Set -DBUILD_EXAMPLES=off to switch off.")
add_executable(nl-reader-example examples/nl-reader-example.cc)
add_to_folder(${MP_FOLDER_PREFIX}util nl-reader-example)
target_link_libraries(nl-reader-example mp)
endif ()

# Build NLWriter2 example
if (BUILD_EXAMPLES)
message(STATUS
"Building NLWriter2 example. Set -DBUILD_EXAMPLES=off to switch off.")
add_subdirectory(nl-writer2)
endif()

option(BUILD_DOC "Build documentation" ON)
if(BUILD_DOC)
add_subdirectory(doc)
Expand Down
26 changes: 22 additions & 4 deletions doc/source/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ on :ref:`driver-setups`.

.. _NL-SOL-files:

NL and SOL files
----------------
Reading NL and writing SOL files
-----------------------------------

Any AMPL solver driver currenlty needs to input
an NL file and report results in a SOL file.
AMPL might add in-memory model communication for efficiency,
which would be provided via the
The details are taken care of in the
:ref:`recommended driver setup <driver-recommended-setup>`.
However, a :ref:`minimal driver setup <driver-minimal-setup>` might address the
corresponding APIs directly, as described below.
Expand Down Expand Up @@ -131,6 +130,25 @@ A standalone .sol file writer could be implemented by parameterizing the
templates by minimal implementations of the `mp::BasicSolver` and
`mp::ProblemBuilder` interfaces.


.. _write-nl-read-sol:

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.

The API is provided by classes `mp::NLSOL`, `mp::NLWriter2`,
`mp::NLHandler2`, `mp::SOLReader2`, `mp::SOLHandler2`.
See
`example </~https://github.com/ampl/mp/blob/develop/nl-writer2/examples/nlsol_ex.cc>`_
solving a small non-linear model.


.. _recommended-driver-logic:

Recommended driver logic
Expand Down
6 changes: 5 additions & 1 deletion doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ new AMPL solver drivers. It provides type-safe and flexible interfaces
suitable for linear and mixed-integer, non-linear, and
Constraint Programming solvers.

Moreover, MP library provides
a :ref:`lightweight NL writer <write-nl-read-sol>`.

MP replaces the previous
`AMPL Solver Library`__ for solvers not requiring automatic differentiation.
It is implemented in C++, parts of the API are exported in C.
Expand Down Expand Up @@ -46,7 +49,8 @@ The documentation is divided in two sections:
* :ref:`library-intro` shows instructions for downloading, installing and building the library
* :ref:`howto` illustrates how to get familiar with the framework and how to quickly obtain the
boilerplate code necessary to develop a new solver driver
* :ref:`components` shows the main components of the framework
* :ref:`components` shows the main components of the framework,
including NL reader and writer API
* :ref:`howto-test` illustrates how to execute tests during development
* :ref:`cppreference` contains the reference to all the classes in the framework

Expand Down
File renamed without changes.
32 changes: 32 additions & 0 deletions nl-writer2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.10)

project(NLWriter2)


set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)


set(NLW2_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(NLW2_LIB_FILES
${NLW2_DIR}/src/nl-writer2.cc
${NLW2_DIR}/src/nl-utils2.cc
${NLW2_DIR}/src/dtoa.c)

# Create library
set(NLW2_LIB_NAME "nlw2")
add_library(${NLW2_LIB_NAME} STATIC ${NLW2_LIB_FILES})
target_include_directories(
${NLW2_LIB_NAME} PUBLIC ${NLW2_DIR}/include)

if (MSVC) ## Set the same as for your parent project
## target_compile_options(
## ${NLW2_LIB_NAME} PRIVATE ${AMPL_MSVC_COMPILE_OPTIONS})
endif()

# NLW2 example
add_executable(nl-writer-example
${NLW2_DIR}/examples/nlsol_ex.cc)
target_include_directories(nl-writer-example PUBLIC
${NLW2_DIR}/include)
target_link_libraries(nl-writer-example ${NLW2_LIB_NAME})
3 changes: 3 additions & 0 deletions nl-writer2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A lightweight AMPL NL file writer and SOL file reader.

See mp.ampl.com.
55 changes: 55 additions & 0 deletions nl-writer2/examples/nlsol_ex.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Example using NLWriter2 and SOLReader2
* to write NL file, execute solver, and read SOL file.
*
*/

#include <cstdlib>

#include "nlsol_ex_mdl.h"
#include "nlsol_ex_nl.h"
#include "nlsol_ex_sol.h"

#include "mp/nlsol.h"
#include "mp/nl-writer2.h"
#include "mp/nl-writer2.hpp"
#include "mp/sol-reader2.h"
#include "mp/sol-reader2.hpp"

/// Invoke:
/// <this_exe> ipopt ["outlev=1 timelim=500" [text [filestub]]]
int main(int argc, const char* const* argv) {
if (argc<2) {
printf("%s\n",
"AMPL NL writer example.\n"
"Usage:\n"
" <this_exe> <solver> [\"<solver_options>\" [binary/text [<stub>]]],\n\n"
"where <solver> is ipopt, gurobi, minos, ...;\n"
"binary/text is the NL format (default: binary.)\n"
"Examples:\n"
" <this_exe> ipopt \"\" text /tmp/stub\n"
" <this_exe> gurobi \"nonconvex=2 funcpieces=-2 funcpieceratio=1e-4\"");
exit(0);
}
std::string solver = (argc>1) ? argv[1] : "minos";
std::string sopts = (argc>2) ? argv[2] : "";
bool binary = (argc<=3) || std::strcmp("text", argv[3]);
std::string stub = (argc>4) ? argv[4] : "stub";

ExampleModel emdl;
ExampleNLFeeder2 nlf(emdl, binary);
ExampleSOLHandler2 esolh(emdl);
mp::NLUtils utils;

mp::NLSOL<ExampleNLFeeder2, ExampleSOLHandler2>
nlsol(nlf, esolh, utils);
nlsol.SetSolver(solver);
nlsol.SetSolverOptions(sopts);
if (!nlsol.Solve(stub)) {
printf("%s\n", nlsol.GetErrorMessage());
exit(EXIT_FAILURE);
}
esolh.PrintSolution(stub);

return 0;
}
Loading

0 comments on commit 6c00959

Please sign in to comment.