Skip to content

Commit

Permalink
Default SOL suffix readers #30
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Nov 29, 2023
1 parent 07ab899 commit 0f8fca6
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 31 deletions.
21 changes: 17 additions & 4 deletions nl-writer2/include/api/c/sol-handler2-c-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,28 @@ class NLW2_SOLHandler2_C_Impl
* if (mp::SOL_Read_OK == sr.ReadResult()) // Can check
* RegisterSuffix(kind, name, table, suf);
*/
// template <class SuffixReader>
// void OnIntSuffix(SuffixReader& ) { }
template <class SuffixReader>
void OnIntSuffix(SuffixReader& sr) {
assert(SH().OnIntSuffix);
const auto& si = sr.SufInfo();
NLW2_SuffixInfo_C si_c
{si.Kind(), si.Name().c_str(), si.Table().c_str()};
SH().OnIntSuffix(SH().p_user_data_, si_c, &sr);
}

/**
* Same as OnIntSuffix(), but
* sr.ReadNext() returns pair<int, double>
*/
// template <class SuffixReader>
// void OnDblSuffix(SuffixReader& ) { }
template <class SuffixReader>
void OnDblSuffix(SuffixReader& sr) {
assert(SH().OnDblSuffix);
const auto& si = sr.SufInfo();
NLW2_SuffixInfo_C si_c
{si.Kind(), si.Name().c_str(), si.Table().c_str()};
SH().OnDblSuffix(SH().p_user_data_, si_c, &sr);
}


protected:
const NLW2_SOLHandler2_C& SH() const { return solh2_c_; }
Expand Down
68 changes: 50 additions & 18 deletions nl-writer2/include/api/c/sol-handler2-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,37 @@ extern "C" {
/// Callback: read next dual/variable value
double NLW2_ReadSolVal(void* p_api_data);

/// Suffix information
typedef struct NLW2_SuffixInfo_C {
int kind_;
const char* name_;
const char* table_;
} NLW2_SuffixInfo_C;

/// Number of suffix non-zero elements
int NLW2_IntSuffixNNZ(void* p_api_data);
/// Number of suffix non-zero elements
int NLW2_DblSuffixNNZ(void* p_api_data);
/// Read suffix entry
void NLW2_ReadIntSuffixEntry(
void* p_api_data, int* , int*);
/// Read suffix entry
void NLW2_ReadDblSuffixEntry(
void* p_api_data, int* , double*);
/// Report suffix error.
/// This causes NLW2_DblSuffixNNZ() to return 0.
void NLW2_ReportDblSuffixError(
void* p_api_data, const char* msg);
/// Report suffix error.
/// This causes NLW2_IntSuffixNNZ() to return 0.
void NLW2_ReportIntSuffixError(
void* p_api_data, const char* msg);
/// Check suffix read result
int NLW2_IntSuffixReadOK(void* p_api_data);
/// Check suffix read result
int NLW2_DblSuffixReadOK(void* p_api_data);


/**
* AMPL internal options.
*/
Expand Down Expand Up @@ -93,7 +124,7 @@ typedef struct NLW2_SOLHandler2_C {

/**
* Receive notification of the objective index
* used by the driver (solver option 'objno').
* used by the driver (solver option 'objno'-1).
*/
void (*OnObjno)(void* p_user_data, int );

Expand All @@ -110,32 +141,33 @@ typedef struct NLW2_SOLHandler2_C {
* Sparse representation - can be empty
* (i.e., all values zero.)
*
* const auto& si = sr.SufInfo();
* int kind = si.Kind();
* int nmax = nitems_max[kind & 3];
* const std::string& name = si.Name();
* const std::string& table = si.Table();
* while (sr.Size()) {
* std::pair<int, int> val = sr.ReadNext();
* if (val.first<0 || val.first>=nmax) {
* sr.SetError(mp::SOL_Read_Bad_Suffix,
* "bad suffix element index");
* int kind = si.kind_;
* int nmax = nitems_max[kind & 3]; // {vars, cons, objs, 1}
* const char* name = si.name_;
* const char* table = si.table_;
* int i;
* int v;
* while (NLW2_IntSuffixNNZ(p_api_data)) {
* NLW2_ReadIntSuffixEntry(p_api_data, &i, &v);
* if (i<0 || i>=nmax) {
* NLW2_ReportIntSuffixError(
* p_api_data, "bad suffix element index");
* return;
* }
* suf[val.first] = val.second;
* suf[i] = v;
* }
* if (mp::SOL_Read_OK == sr.ReadResult()) // Can check
* if (NLW2_IntSuffixReadOK(p_api_data)) // Can check
* RegisterSuffix(kind, name, table, suf);
*/
// template <class SuffixReader>
// void OnIntSuffix(SuffixReader& ) { }
void (*OnIntSuffix)(
void* p_user_data, NLW2_SuffixInfo_C si, void* p_api_data);

/**
* Same as OnIntSuffix(), but
* sr.ReadNext() returns pair<int, double>
* use NLW2_ReadDblSuffixEntry() etc.
*/
// template <class SuffixReader>
// void OnDblSuffix(SuffixReader& ) { }
void (*OnDblSuffix)(
void* p_user_data, NLW2_SuffixInfo_C si, void* p_api_data);

} NLW2_SOLHandler2_C;

Expand Down
17 changes: 13 additions & 4 deletions nl-writer2/include/mp/sol-handler2.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ class SOLHandler2 {
* duals.push_back(rd.ReadNext());
*/
template <class VecReader>
void OnDualSolution(VecReader& ) { }
void OnDualSolution(VecReader& rd) {
while (rd.Size())
rd.ReadNext();
}

/**
* Variable values, if provided.
Expand All @@ -128,7 +131,7 @@ class SOLHandler2 {

/**
* Receive notification of the objective index
* used by the driver (solver option 'objno').
* used by the driver (solver option 'objno'-1).
*/
void OnObjno(int ) { }

Expand Down Expand Up @@ -163,14 +166,20 @@ class SOLHandler2 {
* RegisterSuffix(kind, name, table, suf);
*/
template <class SuffixReader>
void OnIntSuffix(SuffixReader& ) { }
void OnIntSuffix(SuffixReader& sr) {
while (sr.Size())
sr.ReadNext();
}

/**
* Same as OnIntSuffix(), but
* sr.ReadNext() returns pair<int, double>
*/
template <class SuffixReader>
void OnDblSuffix(SuffixReader& ) { }
void OnDblSuffix(SuffixReader& sr) {
while (sr.Size())
sr.ReadNext();
}

};

Expand Down
80 changes: 75 additions & 5 deletions nl-writer2/src/c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ void NLW2_DestroyNLUtils_C_Default(NLW2_NLUtils_C* )

/////////////////// SOLHandler2_C /////////////////////

///////////////////////////////////////////////////////
/// Callbacks

double NLW2_ReadSolVal(void* p_api_data) {
Expand All @@ -535,8 +536,62 @@ double NLW2_ReadSolVal(void* p_api_data) {
return ((mp::VecReader<double>*)p_api_data)
->ReadNext();
}
/// Number of suffix non-zero elements
int NLW2_IntSuffixNNZ(void* p_api_data) {
return ((mp::SuffixReader<int>*)p_api_data)
->Size();
}
/// Number of suffix non-zero elements
int NLW2_DblSuffixNNZ(void* p_api_data) {
return ((mp::SuffixReader<double>*)p_api_data)
->Size();
}
/// Read suffix entry
void NLW2_ReadIntSuffixEntry(
void* p_api_data, int* pi, int* pv) {
auto iv = ((mp::SuffixReader<int>*)p_api_data)
->ReadNext();
*pi = iv.first;
*pv = iv.second;
}
/// Read suffix entry
void NLW2_ReadDblSuffixEntry(
void* p_api_data, int* pi, double* pv) {
auto iv = ((mp::SuffixReader<double>*)p_api_data)
->ReadNext();
*pi = iv.first;
*pv = iv.second;
}
/// Report suffix error.
/// This causes NLW2_DblSuffixNNZ() to return 0.
void NLW2_ReportDblSuffixError(
void* p_api_data, const char* msg) {
((mp::SuffixReader<double>*)p_api_data)
->SetError(mp::SOL_Read_Bad_Suffix, msg);
}
/// Report suffix error.
/// This causes NLW2_IntSuffixNNZ() to return 0.
void NLW2_ReportIntSuffixError(
void* p_api_data, const char* msg) {
((mp::SuffixReader<int>*)p_api_data)
->SetError(mp::SOL_Read_Bad_Suffix, msg);
}
/// Check suffix read result
int NLW2_IntSuffixReadOK(void* p_api_data) {
return mp::SOL_Read_OK
== ((mp::SuffixReader<int>*)p_api_data)
->ReadResult();
}
/// Check suffix read result
int NLW2_DblSuffixReadOK(void* p_api_data) {
return mp::SOL_Read_OK
== ((mp::SuffixReader<double>*)p_api_data)
->ReadResult();
}



///////////////////////////////////////////////////////
/// Default methods
static void NLW2_OnSolveMessage_C_Default(
void* p_user_data, const char* s, int nbs) {
Expand All @@ -548,13 +603,28 @@ static void NLW2_OnSolveMessage_C_Default(
static int NLW2_OnAMPLOptions_C_Default(
void* p_user_data, AMPLOptions_C ) { return 0; }
static void NLW2_OnDualSolution_C_Default(
void* p_user_data, int nvals, void* p_api_data) { }
void* p_user_data, int nvals, void* p_api_data) {
while (nvals--)
NLW2_ReadSolVal(p_api_data);
}
static void NLW2_OnPrimalSolution_C_Default(
void* p_user_data, int nvals, void* p_api_data) { }
static void NLW2_OnObjno_C_Default(void* p_user_data, int ) { }
static void NLW2_OnSolveCode_C_Default(void* p_user_data, int ) { }
// void OnIntSuffix(SuffixReader& ) { }
// void OnDblSuffix(SuffixReader& ) { }
static void NLW2_OnIntSuffix_C_Default(
void* p_user_data, NLW2_SuffixInfo_C si, void* p_api_data) {
int i;
int v;
while (NLW2_IntSuffixNNZ(p_api_data))
NLW2_ReadIntSuffixEntry(p_api_data, &i, &v);
}
static void NLW2_OnDblSuffix_C_Default(
void* p_user_data, NLW2_SuffixInfo_C si, void* p_api_data) {
int i;
double v;
while (NLW2_DblSuffixNNZ(p_api_data))
NLW2_ReadDblSuffixEntry(p_api_data, &i, &v);
}


NLW2_SOLHandler2_C NLW2_MakeSOLHandler2_C_Default(void) {
Expand All @@ -572,8 +642,8 @@ NLW2_SOLHandler2_C NLW2_MakeSOLHandler2_C_Default(void) {
result.OnPrimalSolution = NLW2_OnPrimalSolution_C_Default;
result.OnObjno = NLW2_OnObjno_C_Default;
result.OnSolveCode = NLW2_OnSolveCode_C_Default;
// void OnIntSuffix(SuffixReader& ) { }
// void OnDblSuffix(SuffixReader& ) { }
result.OnIntSuffix = NLW2_OnIntSuffix_C_Default;
result.OnDblSuffix = NLW2_OnDblSuffix_C_Default;

return result;
}
Expand Down

0 comments on commit 0f8fca6

Please sign in to comment.