Skip to content

Commit

Permalink
[BREAKING] NLW2 C API: write names #30
Browse files Browse the repository at this point in the history
Breaking is the change of NLSOL_C accessor names
  • Loading branch information
glebbelov committed Nov 30, 2023
1 parent c5bc35c commit 2e7d6a2
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 139 deletions.
8 changes: 4 additions & 4 deletions nl-writer2/examples/c/nlsol_ex_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ int main(int argc, const char* const* argv) {
NLW2_NLSOL_C nlsol = NLW2_MakeNLSOL_C(&feeder, &solhnd, &utils);

// Solve
NLW2_SetSolver(&nlsol, solver);
NLW2_SetSolverOptions(&nlsol, sopts);
if (0==NLW2_Solve(&nlsol, stub)) {
printf("%s\n", NLW2_GetErrorMessage(&nlsol));
NLW2_NLSOL_C_SetSolver(&nlsol, solver);
NLW2_NLSOL_C_SetSolverOptions(&nlsol, sopts);
if (0==NLW2_NLSOL_C_Solve(&nlsol, stub)) {
printf("%s\n", NLW2_NLSOL_C_GetErrorMessage(&nlsol));
exit(EXIT_FAILURE);
}
PrintSolution_C(&example, stub);
Expand Down
2 changes: 1 addition & 1 deletion nl-writer2/examples/c/nlsol_ex_c_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// #include "api/c/nl-header.h"
//#include "mp/nl-opcodes.h" // When non-linearities

/**
/*
* A linear model for NL Writer C API example.
* Illustrates NL variable order (continuous -> integer),
* linear constraints, var/con/obj names.
Expand Down
65 changes: 15 additions & 50 deletions nl-writer2/examples/c/nlsol_ex_c_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,22 +361,22 @@ void FeedSuffixes(void* p_user_data, void* p_api_data) {


//////////////////// 14. ROW/COLUMN NAMES ETC /////////////////////
/** FeedRowAndObjNames:
* Provide constraint, then objective names.
* Name information is optional.
*
* Implementation:
* if ((output_desired) && wrt)
* for (i: ....)
* wrt << name[i].c_str();
*/
// void FeedRowAndObjNames(RowObjNameWriter& wrt) { }
void FeedRowAndObjNames(void* p_user_data, void* p_api_data) {
CAPIExample* pex = (CAPIExample*)p_user_data;
for (int i=0; i<pex->n_con; ++i)
NLW2_WriteName(p_api_data, pex->con_name[i]);
NLW2_WriteName(p_api_data, pex->obj_name);
}

/** Provide deleted row names.*/
// void FeedDelRowNames(DelRowNameWriter& ) { }

/** Provide variable names. */
// void FeedColNames(ColNameWriter& ) { }
void FeedColNames(void* p_user_data, void* p_api_data) {
CAPIExample* pex = (CAPIExample*)p_user_data;
for (int i=0; i<pex->n_var; ++i)
NLW2_WriteName(p_api_data, pex->var_name[i]);
}

/** Provide unused variable names. */
// void FeedUnusedVarNames(UnusedVarNameWriter& ) { }
Expand Down Expand Up @@ -559,46 +559,11 @@ NLW2_NLFeeder2_C MakeNLFeeder2_C(
result.FeedSuffixes = FeedSuffixes;

//////////////////// 14. ROW/COLUMN NAMES ETC /////////////////////
/** FeedRowAndObjNames:
* Provide constraint, then objective names.
* Name information is optional.
*
* Implementation:
* if ((output_desired) && wrt)
* for (i: ....)
* wrt << name[i].c_str();
*/
// void FeedRowAndObjNames(RowObjNameWriter& wrt) { }
result.want_row_and_obj_names_ = 1;
result.want_col_names_ = 1;

/** Provide deleted row names.*/
// void FeedDelRowNames(DelRowNameWriter& ) { }

/** Provide variable names. */
// void FeedColNames(ColNameWriter& ) { }

/** Provide unused variable names. */
// void FeedUnusedVarNames(UnusedVarNameWriter& ) { }

/** Provide {fixed variable, extra info} pairs.
* This includes defined eliminated variables.
*
* Implementation:
* if ((output_desired) && wrt)
* for (....)
* wrt << typename Writer::StrStrValue
* { name[i].c_str(), comment[i].c_str() };
*/
// void FeedFixedVarNames(FixedVarNameWriter& ) { }

/** Provide {obj name, constant term} pairs.
*
* Implementation:
* if (wrt)
* for (....)
* wrt << typename Writer::StrDblValue
* { name[i].c_str(), (double)obj_offset[i] };
*/
// void FeedObjAdj(ObjOffsetWriter& ) { }
result.FeedRowAndObjNames = FeedRowAndObjNames;
result.FeedColNames = FeedColNames;


return result;
Expand Down
68 changes: 62 additions & 6 deletions nl-writer2/include/api/c/nl-feeder2-c-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,19 +374,55 @@ class NLW2_NLFeeder2_C_Impl
* wrt << name[i].c_str();
*/
template <class RowObjNameWriter>
void FeedRowAndObjNames(RowObjNameWriter& wrt) { }
void FeedRowAndObjNames(RowObjNameWriter& wrt) {
assert(NLF().FeedRowAndObjNames);
if (NLF().want_row_and_obj_names_ && wrt) {
std::function<void(const char*)> wrt_c
= [&wrt](const char* name) {
wrt << name;
};
NLF().FeedRowAndObjNames(NLF().p_user_data_, &wrt_c);
}
}

/** Provide deleted row names.*/
template <class DelRowNameWriter>
void FeedDelRowNames(DelRowNameWriter& ) { }
void FeedDelRowNames(DelRowNameWriter& wrt) {
assert(NLF().FeedDelRowNames);
if (NLF().want_del_row_names_ && wrt) {
std::function<void(const char*)> wrt_c
= [&wrt](const char* name) {
wrt << name;
};
NLF().FeedDelRowNames(NLF().p_user_data_, &wrt_c);
}
}

/** Provide variable names. */
template <class ColNameWriter>
void FeedColNames(ColNameWriter& ) { }
void FeedColNames(ColNameWriter& wrt) {
assert(NLF().FeedColNames);
if (NLF().want_col_names_ && wrt) {
std::function<void(const char*)> wrt_c
= [&wrt](const char* name) {
wrt << name;
};
NLF().FeedColNames(NLF().p_user_data_, &wrt_c);
}
}

/** Provide unused variable names. */
template <class UnusedVarNameWriter>
void FeedUnusedVarNames(UnusedVarNameWriter& ) { }
void FeedUnusedVarNames(UnusedVarNameWriter& wrt) {
assert(NLF().FeedUnusedVarNames);
if (NLF().want_unused_var_names_ && wrt) {
std::function<void(const char*)> wrt_c
= [&wrt](const char* name) {
wrt << name;
};
NLF().FeedUnusedVarNames(NLF().p_user_data_, &wrt_c);
}
}

/** Provide {fixed variable, extra info} pairs.
* This includes defined eliminated variables.
Expand All @@ -398,7 +434,17 @@ class NLW2_NLFeeder2_C_Impl
* { name[i].c_str(), comment[i].c_str() };
*/
template <class FixedVarNameWriter>
void FeedFixedVarNames(FixedVarNameWriter& ) { }
void FeedFixedVarNames(FixedVarNameWriter& wrt) {
assert(NLF().FeedFixedVarNames);
if (NLF().want_fixed_var_names_ && wrt) {
std::function<void(const char*, const char*)> wrt_c
= [&wrt](const char* name, const char* comment) {
wrt << typename FixedVarNameWriter::StrStrValue
{ name, comment };
};
NLF().FeedFixedVarNames(NLF().p_user_data_, &wrt_c);
}
}

/** Provide {obj name, constant term} pairs.
*
Expand All @@ -409,7 +455,17 @@ class NLW2_NLFeeder2_C_Impl
* { name[i].c_str(), (double)obj_offset[i] };
*/
template <class ObjOffsetWriter>
void FeedObjAdj(ObjOffsetWriter& ) { }
void FeedObjAdj(ObjOffsetWriter& wrt) {
assert(NLF().FeedObjAdj);
if (NLF().want_obj_adj_ && wrt) {
std::function<void(const char*, double)> wrt_c
= [&wrt](const char* name, double num) {
wrt << typename ObjOffsetWriter::StrDblValue
{ name, num };
};
NLF().FeedObjAdj(NLF().p_user_data_, &wrt_c);
}
}


protected:
Expand Down
57 changes: 38 additions & 19 deletions nl-writer2/include/api/c/nl-feeder2-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ void* NLW2_StartIntSuffix(void* p_api_1,
void* NLW2_StartDblSuffix(void* p_api_1,
const char* suf_name, int kind, int nnz);

/// Callback: write model item name
void NLW2_WriteName(void* p_api_data, const char* name);
/// Callback: write fixed var name and comment
void NLW2_WriteNameAndComment(
void* p_api_data, const char* name, const char* comment);
/// Callback: write obj name and offset
void NLW2_WriteNameAndNumber(
void* p_api_data, const char* name, double val);


/** Wrap mp::NLFeeder2 for C API.
Expand Down Expand Up @@ -453,61 +462,71 @@ typedef struct NLW2_NLFeeder2_C {
* p_api_data, suf_name, kind, n_nonzeros);
* for (int i=0; i<n_nonzeros; ++i)
* NLW2_WriteSparseIntEntry(p_api_2, // or ...DblEntry
* index[i], value[i]); // <- new API pointer
* index[i], value[i]); // <- p_api_2 here
* }
*/
void (*FeedSuffixes)(void* p_user_data, void* p_api_data);


//////////////////// 14. ROW/COLUMN NAMES ETC /////////////////////

/// Want row/obj names?
int want_row_and_obj_names_;
/// Want del row names?
int want_del_row_names_;
/// Want col names?
int want_col_names_;
/// Want unused var names?
int want_unused_var_names_;
/// Want fixed var names?
int want_fixed_var_names_;
/// Want objective offsets?
int want_obj_adj_;

/** FeedRowAndObjNames:
* Provide constraint, then objective names.
* Name information is optional.
*
* Implementation:
* if ((output_desired) && wrt)
* for (i: ....)
* wrt << name[i].c_str();
* for (i: {algcons, logcons, objs})
* NLW2_WriteName( p_api_data, con_obj_name[i] );
*/
// void FeedRowAndObjNames(RowObjNameWriter& wrt) { }
void (*FeedRowAndObjNames)(void* p_user_data, void* p_api_data);

/** Provide deleted row names.*/
// void FeedDelRowNames(DelRowNameWriter& ) { }
void (*FeedDelRowNames)(void* p_user_data, void* p_api_data);

/** Provide variable names. */
// void FeedColNames(ColNameWriter& ) { }
void (*FeedColNames)(void* p_user_data, void* p_api_data);

/** Provide unused variable names. */
// void FeedUnusedVarNames(UnusedVarNameWriter& ) { }
void (*FeedUnusedVarNames)(void* p_user_data, void* p_api_data);

/** Provide {fixed variable, extra info} pairs.
* This includes defined eliminated variables.
*
* Implementation:
* if ((output_desired) && wrt)
* for (....)
* wrt << typename Writer::StrStrValue
* { name[i].c_str(), comment[i].c_str() };
* NLW2_WriteNameAndComment(
* p_api_data, name[i], comment[i] );
*/
// void FeedFixedVarNames(FixedVarNameWriter& ) { }
void (*FeedFixedVarNames)(void* p_user_data, void* p_api_data);

/** Provide {obj name, constant term} pairs.
*
* Implementation:
* if (wrt)
* for (....)
* wrt << typename Writer::StrDblValue
* { name[i].c_str(), (double)obj_offset[i] };
* NLW2_WriteNameAndNumber(
* p_api_data, name[i], obj_offset[i] );
*/
// void FeedObjAdj(ObjOffsetWriter& ) { }
void (*FeedObjAdj)(void* p_user_data, void* p_api_data);

} NLW2_NLFeeder2_C;


/// Return NLFeeder2_C with default options / methods
/// Return NLW2_NLFeeder2_C with default options / methods
NLW2_NLFeeder2_C NLW2_MakeNLFeeder2_C_Default(void);

/// Destroy NLFeeder2_C created by NLW2_MakeNLFeeder2_C_default()
/// Destroy NLW2_NLFeeder2_C created by NLW2_MakeNLFeeder2_C_default()
void NLW2_DestroyNLFeeder2_C_Default(NLW2_NLFeeder2_C* );

#ifdef __cplusplus
Expand Down
4 changes: 2 additions & 2 deletions nl-writer2/include/api/c/nl-writer2-misc-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ typedef struct NLW2_NLUtils_C {

} NLW2_NLUtils_C;

/// Create a default NLUtils_C wrapper object.
/// Create a default NLW2_NLUtils_C wrapper object.
/// User application might change some methods
/// and use the p_user_data_ pointer.
NLW2_NLUtils_C NLW2_MakeNLUtils_C_Default(void);

/// Destroy the NLUtils_C object created by the API
/// Destroy the NLW2_NLUtils_C object created by the API
void NLW2_DestroyNLUtils_C_Default(NLW2_NLUtils_C*);

#ifdef __cplusplus
Expand Down
24 changes: 15 additions & 9 deletions nl-writer2/include/api/c/nlsol-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ extern "C" {
/// model representation.
///
/// To create / destroy,
/// use NLW2_MakeNLSOL_C / NLW2_Destroy...().
/// use NLW2_MakeNLSOL_C() / NLW2_DestroyNLSOL_C().
///
/// Usage: see the C API example and the below API.
/// To manipulate, use NLW2_SetSolver(), NLW2_SetSolverOptions(),
/// etc, see the below API.
///
/// @see the C API example.
typedef struct NLW2_NLSOL_C {
/// Internal data
void *p_nlf_, *p_solh_, *p_utl_, *p_nlsol_;
Expand All @@ -42,31 +45,34 @@ NLW2_NLSOL_C NLW2_MakeNLSOL_C(
void NLW2_DestroyNLSOL_C(NLW2_NLSOL_C* );

/// Set solver, such as "gurobi", "highs", "ipopt"
void NLW2_SetSolver(NLW2_NLSOL_C* , const char* solver);
void NLW2_NLSOL_C_SetSolver(NLW2_NLSOL_C* , const char* solver);

/// Set solver options, such as "outlev=1 lim:time=500"
void NLW2_SetSolverOptions(NLW2_NLSOL_C* , const char* sopts);
void NLW2_NLSOL_C_SetSolverOptions(NLW2_NLSOL_C* , const char* sopts);

/// Solve.
/// @param filestub: filename stub to be used
/// for input files (.nl, .col., .row, etc.),
/// and output files (.sol).
/// @return true if all ok.
int NLW2_Solve(NLW2_NLSOL_C* , const char* filestub);
int NLW2_NLSOL_C_Solve(NLW2_NLSOL_C* , const char* filestub);

/// Get error message.
const char* NLW2_GetErrorMessage(NLW2_NLSOL_C* );
const char* NLW2_NLSOL_C_GetErrorMessage(NLW2_NLSOL_C* );

/// Substep: write NL and any accompanying files.
int NLW2_WriteNLFile(NLW2_NLSOL_C* , const char* filestub);
/// @return true if all ok.
int NLW2_NLSOL_C_WriteNLFile(NLW2_NLSOL_C* , const char* filestub);

/// Substep: invoke chosen solver for \a filestub.
int NLW2_InvokeSolver(NLW2_NLSOL_C* , const char* filestub);
/// @return true if all ok.
int NLW2_NLSOL_C_InvokeSolver(NLW2_NLSOL_C* , const char* filestub);

/// Substep: read solution.
/// @param filename: complete file name,
/// normally (stub).sol.
int NLW2_ReadSolution(NLW2_NLSOL_C* , const char* filename);
/// @return true if all ok.
int NLW2_NLSOL_C_ReadSolution(NLW2_NLSOL_C* , const char* filename);


#ifdef __cplusplus
Expand Down
Loading

0 comments on commit 2e7d6a2

Please sign in to comment.