18using namespace std::string_literals;
31 std::cerr << s <<
" (" << code <<
")\n";
34auto checked(F &&func, std::string_view msg) {
35 return [msg, func{std::forward<F>(func)}]<
class... Args>(
36 Args &&...args)
mutable {
38 std::forward<F>(func)(&status, std::forward<Args>(args)...);
56 [func{std::forward<F>(func)}](
void *) { func(); }};
63 auto load() -> F::signature_t * {
67 template <
class F,
class...
Args>
74 if (!std::filesystem::is_regular_file(p))
75 throw std::invalid_argument(
"CUTEstLoader: OUTSDIF path does not "
76 "exist or is not a regular file: \"" +
85 log_if_error(
"Failed to close OUTSDIF.d file", status);
94 log_if_error(
"Failed to call cutest_cterminate", status);
101 namespace fs = std::filesystem;
103 if (fs::is_directory(path))
104 path /=
"PROBLEM.so";
112 path.replace_filename(
"OUTSDIF.d");
118 throw_if_error(
"Failed to call cutest_cdimen", status);
161 throw_if_error(
"Failed to call cutest_csetup", status);
166 throw std::runtime_error(
167 "Unconstrained CUTEst problems are currently unsupported");
201 throw_if_error(
"Failed to call CUTEST_probname", status);
202 if (
auto last = name.find_last_not_of(
' ');
last != name.npos)
203 name.resize(
last + 1);
211 throw_if_error(
"Failed to call CUTEST_creport", status);
214 throw_if_error(
"Failed to call CUTEST_ureport", status);
241 resize(
static_cast<length_t>(impl->nvar),
245 impl->setup_problem(x0, y0, C, D);
246 name = impl->get_name();
253CUTEstProblem::~CUTEstProblem() =
default;
258 impl->get_report(calls, time);
259 const bool constr = impl->ncon > 0;
262 .
objective =
static_cast<unsigned>(calls[0]),
263 .objective_grad =
static_cast<unsigned>(calls[1]),
264 .objective_hess =
static_cast<unsigned>(calls[2]),
265 .hessian_times_vector =
static_cast<unsigned>(calls[3]),
266 .constraints = constr ?
static_cast<unsigned>(calls[4]) : 0,
267 .constraints_grad = constr ?
static_cast<unsigned>(calls[5]) : 0,
268 .constraints_hess = constr ?
static_cast<unsigned>(calls[6]) : 0,
270 .time_setup = time[0],
279 checked(impl->funcs.cofg,
"eval_f: CUTEST_cofg")(&impl->nvar, x.data(), &f,
288 checked(
impl->funcs.cofg,
"eval_grad_f: CUTEST_cofg")(
296 checked(
impl->funcs.ccfg,
"eval_g: CUTEST_ccfg")(
307 checked(
impl->funcs.cjprod,
"eval_grad_g_prod: CUTEST_cjprod")(
323 checked(
impl->funcs.ccfsg,
"eval_jac_g: CUTEST_ccfsg")(
333 checked(
impl->funcs.ccfg,
"eval_jac_g: CUTEST_ccfg")(
346 checked(
impl->funcs.cdimsj,
347 "get_jac_g_sparsity: CUTEST_cdimsj")(&
nnz_J);
353 checked(
impl->funcs.csjp,
"eval_jac_g: CUTEST_csjp")(
363 .order = SparseCOO::Unsorted,
371 checked(
impl->funcs.cigr,
"eval_grad_gi: CUTEST_cigr")(
372 &
impl->nvar, &
iprob, x.data(), grad_gi.data());
380 const auto *
mult = y.data();
386 checked(
impl->funcs.chprod,
"eval_hess_L_prod: CUTEST_chprod")(
388 const_cast<real_t *
>(
v.data()),
Hv.data());
399 auto &&ζ =
impl->work.topRows(
impl->ncon);
400 auto &&ŷ =
impl->work2.topRows(
impl->ncon);
403 ζ += y.cwiseQuotient(Σ);
407 ŷ.array() *= Σ.array();
420 checked(
impl->funcs.cjprod,
"eval_hess_ψ_prod: CUTEST_cjprod-1")(
424 Jv.array() *= ζ.array();
429 checked(
impl->funcs.cjprod,
"eval_hess_ψ_prod: CUTEST_cjprod-2")(
439 const auto *
mult = y.data();
451 checked(
impl->funcs.csh,
"eval_hess_L: CUTEST_csh")(
460 checked(
impl->funcs.cdh,
461 "eval_hess_L: CUTEST_cdh")(&
impl->nvar, &
impl->ncon, x.data(),
475 checked(
impl->funcs.cdimsh,
476 "get_hess_L_sparsity: CUTEST_cdimsh")(&
nnz_H);
481 checked(
impl->funcs.cshp,
"eval_hess_L: CUTEST_cshp")(
492 .order = SparseCOO::Unsorted,
501 checked(impl->funcs.cofg,
"eval_f_grad_f: CUTEST_cofg")(
509 checked(impl->funcs.cfn,
"eval_f_g: CUTEST_cfn")(&impl->nvar, &impl->ncon,
510 x.data(), &f, g.data());
519 checked(
impl->funcs.clfg,
"eval_f_g: CUTEST_clfg")(
520 &
impl->nvar, &
impl->ncon, x.data(), y.data(), &L, grad_L.data(), &
grad);
525 os <<
"CUTEst problem: " <<
name <<
"\r\n\n"
526 <<
"Number of variables: " <<
n <<
"\r\n"
527 <<
"Number of constraints: " <<
m <<
"\r\n\n"
528 <<
"Objective function evaluations: "
530 <<
"Objective function gradient evaluations: "
532 <<
"Objective function Hessian evaluations: "
534 <<
"Hessian times vector products: "
537 os <<
"Constraint function evaluations: "
539 <<
"Constraint function gradients evaluations: "
541 <<
"Constraint function Hessian evaluations: "
544 return os <<
"Setup time: " << r.
time_setup <<
"s\r\n"
545 <<
"Time since setup: " << r.
time <<
"s";
Implements common problem functions for minimization problems with box constraints.
void eval_proj_diff_g(crvec z, rvec p) const
length_t m
Number of constraints, dimension of g(x) and z.
length_t n
Number of decision variables, dimension of x.
Box D
Other constraints, .
cleanup_t cutest_terminate
Responsible for calling CUTEST_xterminate.
cutest::ccifg::signature_t * ccifg
cutest::cigr::signature_t * cigr
cutest::cfn::signature_t * cfn
integer ncon
Number of constraints.
cutest::ccfsg::signature_t * ccfsg
std::shared_ptr< void > cleanup_t
cutest::csjp::signature_t * csjp
cleanup_t cleanup_outsdif
Responsible for closing the OUTSDIF.d file.
cutest::cdimsh::signature_t * cdimsh
CUTEstLoader(const char *so_fname, const char *outsdif_fname, DynamicLoadFlags dl_flags)
integer iout
Fortran Unit Number for standard output.
cutest::cdimsj::signature_t * cdimsj
integer funit
Fortran Unit Number for OUTSDIF.d file.
decltype(auto) call(Args &&...args)
cutest::csh::signature_t * csh
cutest::clfg::signature_t * clfg
cleanup_t load_outsdif(const char *outsdif_fname)
cutest::cofg::signature_t * cofg
cleanup_t cleanup(F &&func)
integer nvar
Number of decision variabls.
std::shared_ptr< void > so_handle
dlopen handle to shared library
cutest::cjprod::signature_t * cjprod
cutest::cdh::signature_t * cdh
Eigen::VectorX< logical > logical_vec
Pointers to loaded problem functions.
cutest::chprod::signature_t * chprod
void setup_problem(rvec x0, rvec y0, Box &C, Box &D)
logical_vec equatn
whether the constraint is an equality
cutest::cshp::signature_t * cshp
auto load() -> F::signature_t *
void get_report(double *calls, double *time)
cutest::ccfg::signature_t * ccfg
logical_vec linear
whether the constraint is linear
integer io_buffer
Fortran Unit Number for internal IO.
Wrapper for CUTEst problems loaded from an external shared library.
Eigen::VectorX< int > cols
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
Calls calls
Function call counters.
void eval_jac_g(crvec x, rvec J_values) const
unsigned constraints_grad
Number of calls to the constraint gradients.
Sparsity get_jac_g_sparsity() const
real_t eval_f_g(crvec x, rvec g) const
double time_setup
CPU time (in seconds) for CUTEST_csetup.
Sparsity get_hess_L_sparsity() const
CUTEstProblem(const char *so_fname, const char *outsdif_fname=nullptr, bool sparse=false, DynamicLoadFlags dl_flags={})
Load a CUTEst problem from the given shared library and OUTSDIF.d file.
unsigned objective
Number of calls to the objective function.
struct alpaqa::CUTEstProblem::SparseStorage storage_hess_L
void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const
unsigned constraints
Number of calls to the constraint functions.
std::string name
Problem name.
Eigen::VectorX< int > rows
util::copyable_unique_ptr< class CUTEstLoader > impl
real_t eval_f_grad_f(crvec x, rvec grad_fx) const
double time
CPU time (in seconds) since the end of CUTEST_csetup.
void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const
void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
void eval_grad_f(crvec x, rvec grad_fx) const
real_t eval_f(crvec x) const
void eval_g(crvec x, rvec gx) const
unsigned objective_hess
Number of calls to the objective Hessian.
struct alpaqa::CUTEstProblem::SparseStorage storage_jac_g
std::ostream & format_report(std::ostream &os, const Report &r) const
void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const
unsigned constraints_hess
Number of calls to the constraint Hessians.
CUTEstProblem & operator=(const CUTEstProblem &)
unsigned objective_grad
Number of calls to the objective gradient.
void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
The report generated by CUTEst.
#define USING_ALPAQA_CONFIG(Conf)
constexpr size_t fstring_len
@ Unsymmetric
No symmetry.
@ Upper
Symmetric, upper-triangular part is stored.
std::shared_ptr< void > load_lib(const std::filesystem::path &so_filename, DynamicLoadFlags flags)
Load a DLL or SO file.
typename Conf::real_t real_t
typename Conf::index_t index_t
typename Conf::length_t length_t
typename Conf::crvec crvec
auto checked(F &&func, std::string_view msg)
void throw_error(std::string_view s, int code)
void throw_if_error(std::string_view s, int code)
void log_if_error(std::string_view s, int code)
Flags to be passed to dlopen.
Sparse coordinate list structure (COO).
Stores any of the supported sparsity patterns.