Skip to content

Commit

Permalink
MiniJSONWriter #232
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Feb 29, 2024
1 parent ff32650 commit 73cc5c7
Show file tree
Hide file tree
Showing 13 changed files with 504 additions and 67 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,9 @@ add_prefix(MP_HEADERS include/mp/
rstparser.h safeint.h sol.h
solver.h solver-opt.h solver-base.h solver-io.h solver-app-base.h solver-app.h
suffix.h
utils-file.h utils-hash.h utils-hash-stream.h
utils-file.h
util-json-write.h util-json-write.hpp
utils-hash.h utils-hash-stream.h
utils-string.h utils-math.h)

add_prefix(MP_FLAT_HEADERS include/mp/flat/
Expand Down
15 changes: 15 additions & 0 deletions include/mp/flat/constr_general.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,21 @@ using SOS1Constraint = SOS_1or2_Constraint<1>;
using SOS2Constraint = SOS_1or2_Constraint<2>;


/// Write a SOS1, SOS2 constraint
template <class Writer, int type>
inline void WriteJSON(Writer& wrt, const SOS_1or2_Constraint<type>& sos) {
wrt.write("{} ", '{');
wrt.write("\"sos_type\": {}, ", sos.get_sos_type());
wrt.write("\"vars\": ");
WriteJSONVec(wrt, sos.get_vars());
wrt.write(", \"weights\": ");
WriteJSONVec(wrt, sos.get_weights());
auto bnds = sos.get_sum_of_vars_range();
wrt.write(", \"sum_of_vars_range\": [{}, {}]",
bnds.lb_, bnds.ub_);
wrt.write(" {}", '}');
}

////////////////////////////////////////////////////////////////////////
/// Complementarity constraint.
/// \a Expr complements a variable.
Expand Down
43 changes: 38 additions & 5 deletions include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "mp/format.h"
#include "mp/env.h"
#include "mp/utils-math.h"
#include "mp/utils-file.h"
#include "mp/util-json-write.hpp"

#include "mp/flat/model_api_base.h"
#include "mp/flat/constr_hash.h"
Expand Down Expand Up @@ -513,6 +515,13 @@ class BasicConstraintKeeper {
/// Compute violations
virtual void ComputeViolations(SolCheck& ) = 0;

/// Set logger
void SetLogger(BasicLogger* lg) { exporter_=lg; }
/// Get logger, if provided and open and ok.
BasicLogger* GetLogger() const {
return exporter_ && exporter_->IsOpen()
? exporter_ : nullptr;
}

protected:
int& GetAccLevRef() { return acceptance_level_; }
Expand All @@ -524,6 +533,7 @@ class BasicConstraintKeeper {
const char* const solver_opt_nm_;
mutable std::string type_name_short_;
int acceptance_level_ {-1};
BasicLogger* exporter_{};
};

const char*
Expand Down Expand Up @@ -668,6 +678,7 @@ class ConstraintKeeper final
int AddConstraint(int d, Args&&... args)
{
cons_.emplace_back( d, std::move(args)... );
ExportConstraint(cons_.size()-1, cons_.back());
return cons_.size()-1;
}

Expand Down Expand Up @@ -860,6 +871,20 @@ class ConstraintKeeper final
++n_bridged_or_unused_;
}

protected:
/// Export last added constraint
void ExportConstraint(int i_con, const Container& cnt) {
if (GetLogger()) {
fmt::MemoryWriter wrt;
MiniJSONWriter<fmt::MemoryWriter> jw(wrt);
jw["con_type"] = cnt.con_.GetTypeName();
jw["index"] = i_con;
jw["depth"] = cnt.GetDepth();
// wrt.write("\"data\": ");
// WriteJSON(wrt, cnt.con_);
GetLogger()->Append(wrt);
}
}

public:
/// Mark cons[\a i] as reformulated.
Expand Down Expand Up @@ -1120,13 +1145,12 @@ bool operator==(std::reference_wrapper<
////////////////////////////////////////////////////////////////////////////////////
/// Manage ConstraintKeepers for different constraint types
class ConstraintManager {
std::multimap<double, BasicConstraintKeeper&> con_keepers_;


public:
/// Add a new CKeeper with given conversion priority (smaller = sooner)
void AddConstraintKeeper(BasicConstraintKeeper& ck, double priority)
{ con_keepers_.insert( { priority, ck } ); }
void AddConstraintKeeper(BasicConstraintKeeper& ck, double priority) {
con_keepers_.insert( { priority, ck } );
ck.SetLogger(&*graph_exporter_app_);
}

/// This should be called after adding all constraint keepers
void ConsiderAcceptanceOptions(
Expand Down Expand Up @@ -1177,6 +1201,15 @@ class ConstraintManager {
for (const auto& ck: con_keepers_)
ck.second.ComputeViolations(chk);
}

/// Retrieve file logger
BasicFileAppender& GetFileAppender() { return *graph_exporter_app_; }

private:
std::multimap<double, BasicConstraintKeeper&> con_keepers_;
/// Conversion graph exporter file appender
std::unique_ptr<BasicFileAppender>
graph_exporter_app_{MakeFileAppender()};
};

} // namespace mp
Expand Down
18 changes: 5 additions & 13 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "mp/flat/redef/std/range_con.h"
#include "mp/flat/redef/conic/cones.h"
#include "mp/flat/redef/conic/qcones2qc.h"
#include "mp/utils-file.h"
#include "mp/ampls-ccallbacks.h"

namespace mp {
Expand Down Expand Up @@ -235,9 +234,9 @@ class FlatConverter :

void OpenGraphExporter() {
if (graph_export_file().size()) {
if (!graph_exporter_app_->Open(graph_export_file().c_str(), true))
if (!GetModel().GetFileAppender().Open(
graph_export_file().c_str(), true))
MP_RAISE("Failed to open the graph export file.");
value_presolver_.SetExport(true);
}
}

Expand All @@ -256,7 +255,7 @@ class FlatConverter :

void CloseGraphExporter() {
value_presolver_.FinishExportingLinkEntries();
graph_exporter_app_->Close();
GetModel().GetFileAppender().Close();
}

//////////////////////// WHOLE-MODEL PREPROCESSING /////////////////////////
Expand Down Expand Up @@ -646,6 +645,7 @@ class FlatConverter :
}

/// Add several variables once.
/// @note this is only to be called once for the original vars.
/// @return value node range for them
pre::NodeRange AddVars(const typename BaseFlatModel::VarBndVec& lbs,
const typename BaseFlatModel::VarBndVec& ubs,
Expand Down Expand Up @@ -1215,19 +1215,11 @@ class FlatConverter :
/// We store ModelApi in the converter for speed.
/// Should be before constraints
ModelAPIType modelapi_;
/// Conversion graph exporter file appender
std::unique_ptr<BasicFileAppender> graph_exporter_app_{MakeFileAppender()};
/// Conversion graph exporter functor
pre::ValuePresolver::ExporterFn graph_exporter_fn_{
[this](const char* s){
graph_exporter_app_->Append(s);
}
};
/// ValuePresolver: should be init before constraint keepers
/// and links
pre::ValuePresolver value_presolver_
{
GetModel(), GetEnv(), graph_exporter_fn_,
GetModel(), GetEnv(), (BasicLogger&)GetModel().GetFileAppender(),
[this](
ArrayRef<double> x,
const pre::ValueMapDbl& y,
Expand Down
48 changes: 46 additions & 2 deletions include/mp/flat/converter_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class FlatModel
using VarTypeVec = std::vector<var::Type>;
using VarNameVec = std::vector<const char*>;

using ConstraintManager::GetFileAppender;

///////////////////////////// VARIABLES ////////////////////////////////
/// Add variable, return its index
Var AddVar__basic(double lb=MinusInf(), double ub=Inf(),
Expand All @@ -43,6 +45,7 @@ class FlatModel
var_lb_.push_back(lb);
var_ub_.push_back(ub);
var_type_.push_back(type);
ExportVars(var_type_.size()-1, {lb}, {ub}, {type});
return var_type_.size()-1;
}

Expand All @@ -55,9 +58,32 @@ class FlatModel
var_ub_.insert(var_ub_.end(), ubs.begin(), ubs.end());
var_type_.insert(var_type_.end(), types.begin(), types.end());
assert(check_vars());
assert(!num_vars_orig_);
num_vars_orig_ = var_lb_.size();
ExportVars(var_type_.size()-1, lbs, ubs, types);
}

protected:
/// Export new variables
template <class BndVec=std::array<double, 1>,
class TypeVec=std::array<var::Type, 1> >
void ExportVars(int i_start, const BndVec& lbs, const BndVec& ubs,
const TypeVec types) {
for (int i=0;
GetFileAppender().IsOpen() && i<(int)lbs.size(); ++i) {
fmt::MemoryWriter wrt;
wrt.write("{} ", '{');
wrt.write("\"var_index\": {}, ", i+i_start);
wrt.write("\"bounds\": [{}, {}], ", lbs[i], ubs[i]);
wrt.write("\"type\": {}, ", (int)types[i]);
wrt.write("\"is_from_nl\": {}, ", (int)is_var_original(i));
wrt.write(" {}\n", '}'); // with EOL
GetFileAppender().Append(wrt);
}
}

public:
/// Set var names vector
void AddVarNames(const std::vector<std::string>& names) {
var_names_storage_ = names;
}
Expand All @@ -68,6 +94,7 @@ class FlatModel
? var_names_storage_[i].c_str() : nullptr;
}

/// N vars
int num_vars() const
{ assert(check_vars()); return (int)var_lb_.size(); }

Expand Down Expand Up @@ -198,9 +225,26 @@ class FlatModel
return false;
}
/// Add an objective
void AddObjective(QuadraticObjective&& obj)
{ get_objectives().push_back(std::move(obj)); }
void AddObjective(QuadraticObjective&& obj) {
get_objectives().push_back(std::move(obj));
ExportObjective(num_objs()-1, get_objectives().back());
}

protected:
void ExportObjective(int i_obj, const QuadraticObjective& obj) {
if (GetFileAppender().IsOpen()) {
fmt::MemoryWriter wrt;
wrt.write("{} ", '{');
wrt.write("\"obj_index\": {}, ", i_obj);
wrt.write("\"sense\": {}, ", obj.obj_sense());
wrt.write("\"qp_terms\": ");
WriteJSON(wrt, obj.GetQPTerms());
wrt.write("\"lin_terms\": ");
WriteJSON(wrt, obj.GetLinTerms());
wrt.write(" {}\n", '}'); // with EOL
GetFileAppender().Append(wrt);
}
}

///////////////////////////// FLAT CONSTRAINTS ////////////////////////////
protected:
Expand Down
9 changes: 9 additions & 0 deletions include/mp/flat/expr_algebraic.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ class AlgebraicExpression : public Body {
double constant_term_ = 0.0;
};

/// Very general template to write
/// a JSON representation of anything
template <class Writer, class Obj>
void WriteJSON(Writer& , const Obj& );

/// Write JSON string of a vector
template <class Writer, class Vec>
void WriteJSONVec(Writer& wrt, const Vec& vec);

} // namespace mp

#endif // EXPR_ALGEBRAIC_H
Loading

0 comments on commit 73cc5c7

Please sign in to comment.