Skip to content

Commit

Permalink
To #184: finish .funcpieces
Browse files Browse the repository at this point in the history
By fixing autolinking
  • Loading branch information
glebbelov committed Jul 20, 2022
1 parent ff7435d commit 1180d7a
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 46 deletions.
15 changes: 14 additions & 1 deletion CHANGES.mp.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
Summary of recent updates to the AMPL MP Library
================================================

## 20220720
- *Propagating suffixes via expression trees into flat constraints*
Partially implemented #184. x-gurobi accepts options
'funcpieces...' and corresponding suffixes which are passed into
GRBaddgenconstrExp etc.

Subexpressions: note that if a subexpression is contained in several
constraints, for contradicting suffix values the maximum is taken.

- *Option 'cvt:writegraph'*
Exporting the flattening / conversion graph in JSON Lines format (WIP).


## 20220617
- *PowConstraint is reduced to quadratics in some cases*
For constant non-negative integer exponent and base variables
with negative lower bound, PowConstraint
is reduced to quadratics (possibly ewith auxiliary variables).
is reduced to quadratics (possibly with auxiliary variables).
Reason: Gurobi's GRBaddgenconstrPow
not accepting negative bases.

Expand Down
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,6 @@ endif ()

option(BUILD_DOC "Build documentation" ON)
if(BUILD_DOC)
message(STATUS
"Building documentation (if the requirements are installed). "
"Set BUILD_DOC=off otherwise.")
add_subdirectory(doc)
endif()
add_subdirectory(src/asl)
Expand Down
2 changes: 0 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ AMPL/MP
MP Library is a set of tools recommended to create new AMPL solver interfaces.
See `documentation <https://amplmp.readthedocs.io/en/latest/>`_.

If the above link is not accessible, see documentation sources in folder ``doc``.


Links
-----
Expand Down
9 changes: 7 additions & 2 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# Check requirements.
# Use specific version of Sphinx which fixes local search and has
# better C++ support.
# Use the specific version of Sphinx (see requirements.txt)
# which fixes local search and has better C++ support.
find_program(DOXYGEN doxygen)
if (NOT DOXYGEN)
message(STATUS "Target doc disabled (requires doxygen)")
return ()
endif ()

find_package(Sphinx)
if(NOT SPHINX_EXECUTABLE)
message(STATUS "Documentation generation disabled (requires sphinx)")
return()
endif()

message(STATUS
"Documentation building configured. "
"Set BUILD_DOC=off otherwise.")

add_prefix(doc_deps ../ ${MP_ALL_HEADERS})

set(DOC_BASEDIR ${CMAKE_CURRENT_SOURCE_DIR})
Expand Down
24 changes: 22 additions & 2 deletions doc/rst/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ via the solver's modeling API wrapper:
* :ref:`value-presolver` transforms solutions and suffixes between the
original NL model and the flat model.

* :ref:`conversion-graph` discusses exporting of the flattening / conversion graph.


.. _flat-model-api:

Expand Down Expand Up @@ -380,10 +382,28 @@ To implement value pre- / postsolving, the following API is used:

- `mp::pre::BasicLink` is the interface to various implementations of links
between nodes, such as
`mp::pre::CopyLink`. Templates `mp::pre::BasicIndivEntryLink` and
`mp::pre::BasicStaticIndivEntryLink` are base classes for links such as
`mp::pre::CopyLink`, `mp::pre::One2ManyLink`, and
`mp::pre::RangeCon2Slack`.

- Expression tree flattenings into new constraints and variables,
as well as subsequent conversions,
are by default automatically linked by `mp::pre::One2ManyLink`.
To implement a specific link, see the example of `mp::pre::RangeCon2Slack`.
In particular, autolinking should normally be turned off.


.. _conversion-graph:

Conversion graph
~~~~~~~~~~~~~~~~

The flattening and conversion graph can be exported by the `cvt:writegraph`
option (WIP).

At the moment only arcs are exported. Terminal nodes (variables, constraints,
objectives) can be seen in the NL model (ampl: `expand`) and the
final flat model (x-gurobi: option `writeprob`).


C++ ASL adapter
---------------
Expand Down
23 changes: 16 additions & 7 deletions doc/rst/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ An included `CMake build script`__ can be used to build the MP library,
solver interfaces and function libraries on a wide range of platforms.
You can download CMake for free from http://www.cmake.org/download/.

__ CMakeLists.txt
__ /~https://github.com/ampl/mp/tree/master/CMakeLists.txt

CMake workflow
``````````````

CMake works by generating native makefiles or project files that can
be used in the compiler environment of your choice. The typical
Expand Down Expand Up @@ -151,12 +154,18 @@ the index.
Building the documentation
``````````````````````````

To build the documentation (automatically, via CMake) you need Python 3.x with Sphinx and Breathe,
see :file:`doc/requirements.txt` (install automatically by :code:`pip install -r requirements.txt`).
The HTML output is located in :file:`(build folder)/doc/index.html`. To have the alphabetic index
automatically generated, install `pandoc`.
Configure CMake with
:code:`-DBUILD_DOC=off` to switch off.
To build the documentation (automatically, via CMake) you need `Doxygen`__
as well as Python 3.x with Sphinx and Breathe,
see :file:`doc/requirements.txt` (install automatically by
:code:`pip install -r requirements.txt`).
The HTML output is located in :file:`(build folder)/doc/index.html`.
To have the alphabetic index automatically generated, install `pandoc`.

__ https://doxygen.nl/

Configure CMake with :code:`-DBUILD_DOC=off` to switch documentation
building off.




Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/convert_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class BasicFCC {
if (GetConverter().DoingAutoLinking()) { // Autolink known targets
auto& varvn = GetConverter().GetVarValueNode();
GetConverter().AutoLink( varvn.Select(GetResultVar()) );
auto& ck = GetConverter().template GetConstraintKeeper(
auto& ck = GetConverter().GetConstraintKeeper(
(Constraint*)0 );
GetConverter().AutoLink( ck.SelectValueNodeRange(i) );
}
Expand Down
13 changes: 5 additions & 8 deletions include/mp/flat/redef/std/range_con.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,31 +55,27 @@ class RangeCon2Slack :
/// (3 is the base class template parameter)
/// and means the following indexes: {range_con, lin_con, slack_index}

/// MaxAmongNon0 double: a generic value presolve method.
/// TODO move these to BasicLink via abstract interface.
/// PresolveGeneric double
void PresolveGenericDblEntry(const typename Base::LinkEntry& be) {
auto src_val = GetDbl(be, CON_SRC);
SetDbl(be, CON_TARGET, src_val);
SetDbl(be, VAR_SLK, src_val);
}

/// MaxAmongNon0 double: a generic value postsolve method.
/// Assume we don't meet another value.
/// PostsolveGeneric double
void PostsolveGenericDblEntry(const typename Base::LinkEntry& be) {
SetDbl(be, CON_SRC, std::max(
GetDbl(be, CON_TARGET), GetDbl(be, VAR_SLK)));
}

/// MaxAmongNon0 int: a generic value presolve method.
/// Assume we don't meet another value.
/// PresolveGeneric int
void PresolveGenericIntEntry(const typename Base::LinkEntry& be) {
auto src_val = GetInt(be, CON_SRC);
SetInt(be, CON_TARGET, src_val);
SetInt(be, VAR_SLK, src_val);
}

/// MaxAmongNon0 int: a generic value postsolve method.
/// Assume we don't meet another value.
/// PostsolveGeneric int
void PostsolveGenericIntEntry(const typename Base::LinkEntry& be) {
SetInt(be, CON_SRC, std::max(
GetInt(be, CON_TARGET), GetInt(be, VAR_SLK)));
Expand Down Expand Up @@ -143,6 +139,7 @@ class RangeCon2Slack :
}

protected:
/// Get the model converter
ModelConverter& GetMC() { return cvt_; }

using Base::GetInt;
Expand Down
2 changes: 1 addition & 1 deletion include/mp/utils-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace mp {
class BasicFileAppender {
public:
/// Destruct
~BasicFileAppender() { }
virtual ~BasicFileAppender() { }

/// Open file
virtual bool Open(const std::string& fln, bool fErase) = 0;
Expand Down
17 changes: 9 additions & 8 deletions include/mp/valcvt-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ValueMap {
template <class SomeArray>
ValueMap(SomeArray r) :
map_{ {0, std::move(r) } } {
SetValueNodeName(map_.at(0), name_ + "[0]");
SetValueNodeName(map_.at(0), name_ + "()");
}

/// Construct from the low-level MapType
Expand Down Expand Up @@ -116,9 +116,10 @@ class ValueMap {
Array& operator()() {
if (map_.empty())
SetValueNodeName(
*map_.insert({ 0,
CreateArray<Array, Param>(prm_) }).first,
name_ + "[0]");
map_.insert({ 0,
CreateArray<Array, Param>(prm_) }).
first->second,
name_ + "()");
else
assert(IsSingleKey());
return map_.at(0);
Expand All @@ -134,8 +135,8 @@ class ValueMap {
if (map_.end() == map_.find(i)) {
Array arr = CreateArray<Array, Param>(prm_);
SetValueNodeName(
*map_.insert({ i, std::move(arr) }).first,
name_ + std::to_string(i));
map_.insert({ i, std::move(arr) }).first->second,
name_ + '(' + std::to_string(i) + ')');
}
return map_.at(i);
}
Expand All @@ -156,7 +157,7 @@ class ValueMap {

private:
Param prm_;
std::string name_ { "default_value_map" };
std::string name_ { "VMapName__unset" };
MapType map_;
};

Expand All @@ -181,7 +182,7 @@ class ModelValues {
using ParamType = typename VMap::ParamType;

/// Constructor
ModelValues(ParamType prm, std::string nm) :
ModelValues(ParamType prm, const std::string& nm) :
name_{nm}, vars_(prm), cons_(prm), objs_(prm) {
vars_.SetName(nm+"_vars");
cons_.SetName(nm+"_cons");
Expand Down
2 changes: 1 addition & 1 deletion include/mp/valcvt-link.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ class AutoLinkScope {
for (const auto& t: targets) {
assert(t.IsValid());
cvt_.GetOne2ManyLink().AddEntry( // use One2ManyLink
{ cvt_.GetAutoLinkSource(), targets.front() } );
{ cvt_.GetAutoLinkSource(), t } );
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions include/mp/valcvt-node.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,13 @@ void ValueNode::SetVal<int>(size_t i, int v) { SetInt(i, v); }

/// Specialize SetValueNodeName() for ValueNode
inline void
SetValueNodeName(ValueNode& vn, std::string nm) { vn.SetName(nm); }
SetValueNodeName(ValueNode& vn, std::string nm)
{ vn.SetName(std::move(nm)); }


/// Default CreateArray() for ValueNode
/// Specialize CreateArray() for ValueNode
template <>
inline
ValueNode CreateArray(BasicValuePresolver& vp) { return ValueNode{vp}; }


Expand Down
4 changes: 2 additions & 2 deletions include/mp/valcvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ class ValuePresolver : public BasicValuePresolver {

/// val_nodes_ should be before src_ / dest_
mutable ModelValuesTerminal
src_{*this, "src__"},
dest_{*this, "dest__"};
src_{*this, "src"},
dest_{*this, "dest"};

/// The link ranges
LinkRangeList brl_;
Expand Down
12 changes: 11 additions & 1 deletion solvers/gurobi/CHANGES.gurobi.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
Summary of recent updates to x-gurobi for AMPL
==============================================

## 20220720
- *Options 'funcpieces', 'funcpiecelength', 'funcpieceratio', 'funcpieceerror'*
The above options (and corresponding suffixes) are passed to Gurobi. The
suffixes can specialize the values for individual constraints.

Subexpressions: note that if a subexpression is contained in several
constraints, for contradicting suffix values the maximum is taken.


## 20220706
- Relinked with Gurobi 9.5.2, which contains bug fixes
- *Relinked with Gurobi 9.5.2, which contains bug fixes*


## 20220511
- *Complementarity constraints: also quadratics*
Expand Down
2 changes: 0 additions & 2 deletions solvers/gurobi/gurobibackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2209,8 +2209,6 @@ static void DoPlayGrbObjNParams(
void GurobiBackend::GrbPlayObjNParams() {
int nobj;
GRB_CALL( GRBgetintattr(model(), GRB_INT_ATTR_NUMOBJ, &nobj) );
if (debug_mode())
printf("Number of objectives: %d\n", nobj);
DoPlayGrbObjNParams(objnparam_int_, model(), env());
DoPlayGrbObjNParams(objnparam_dbl_, model(), env());
}
Expand Down
8 changes: 5 additions & 3 deletions src/utils_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ class FileAppender__fstream : public BasicFileAppender {
public:
/// Open file
bool Open(const std::string& fln, bool fErase=false) override {
fs_.open(fln,
fErase ? std::ios::app|std::ios::ate : std::ios::app);
if (fErase) {
std::ofstream ofs(fln, std::ios::trunc | std::ios::out);
}
fs_.open(fln, std::ios::app | std::ios::out);
return fs_.good();
}

Expand All @@ -47,7 +49,7 @@ class FileAppender__fstream : public BasicFileAppender {


private:
std::fstream fs_;
std::ofstream fs_;
};

/// FileAppender maker
Expand Down

0 comments on commit 1180d7a

Please sign in to comment.