MFEM  v4.6.0
Finite element discretization library
hiop.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_HIOP
13 #define MFEM_HIOP
14 
15 #include "../config/config.hpp"
16 
17 #ifdef MFEM_USE_HIOP
18 #include "../general/globals.hpp"
19 #include "solvers.hpp"
20 
21 #ifdef MFEM_USE_MPI
22 #include "operator.hpp"
23 #endif
24 
25 #include "hiopInterface.hpp"
26 #include "hiopNlpFormulation.hpp"
27 
28 namespace mfem
29 {
30 
31 /// Internal class - adapts the OptimizationProblem class to HiOp's interface.
32 class HiopOptimizationProblem : public hiop::hiopInterfaceDenseConstraints
33 {
34 private:
35 
36 #ifdef MFEM_USE_MPI
37  MPI_Comm comm;
38 #endif
39 
40  // Problem info.
41  const OptimizationProblem &problem;
42 
43  // Local and global number of variables and constraints.
44  const hiop::size_type ntdofs_loc, m_total;
45  hiop::size_type ntdofs_glob;
46 
47  // Initial guess.
48  const Vector *x_start;
49 
50  Vector constr_vals;
51  DenseMatrix constr_grads;
52  bool constr_info_is_current;
53  void UpdateConstrValsGrads(const Vector x);
54 
55 public:
57  : problem(prob),
58  ntdofs_loc(prob.input_size), m_total(prob.GetNumConstraints()),
59  ntdofs_glob(ntdofs_loc),
60  x_start(NULL),
61  constr_vals(m_total), constr_grads(m_total, ntdofs_loc),
62  constr_info_is_current(false)
63  {
64 #ifdef MFEM_USE_MPI
65  // Used when HiOp with MPI support is called by a serial driver.
66  comm = MPI_COMM_WORLD;
67 #endif
68  }
69 
70 #ifdef MFEM_USE_MPI
71  HiopOptimizationProblem(const MPI_Comm& comm_,
73  : comm(comm_),
74  problem(prob),
75  ntdofs_loc(prob.input_size), m_total(prob.GetNumConstraints()),
76  ntdofs_glob(0),
77  x_start(NULL),
78  constr_vals(m_total), constr_grads(m_total, ntdofs_loc),
79  constr_info_is_current(false)
80  {
81  MPI_Allreduce(&ntdofs_loc, &ntdofs_glob, 1, MPI_HIOP_SIZE_TYPE, MPI_SUM, comm);
82  }
83 #endif
84 
85  void setStartingPoint(const Vector &x0) { x_start = &x0; }
86 
87  /** Extraction of problem dimensions:
88  * n is the number of variables, m is the number of constraints. */
89  virtual bool get_prob_sizes(hiop::size_type& n, hiop::size_type& m);
90 
91  /** Provide an primal starting point. This point is subject to adjustments
92  * internally in HiOp. */
93  virtual bool get_starting_point(const hiop::size_type &n, double *x0);
94 
95  using hiop::hiopInterfaceBase::get_starting_point;
96 
97  virtual bool get_vars_info(const hiop::size_type &n, double *xlow, double* xupp,
98  NonlinearityType* type);
99 
100  /** bounds on the constraints
101  * (clow<=-1e20 means no lower bound, cupp>=1e20 means no upper bound) */
102  virtual bool get_cons_info(const hiop::size_type &m, double *clow, double *cupp,
103  NonlinearityType* type);
104 
105  /** Objective function evaluation.
106  * Each rank returns the global objective value. */
107  virtual bool eval_f(const hiop::size_type &n, const double *x, bool new_x,
108  double& obj_value);
109 
110  /** Gradient of the objective function (local chunk). */
111  virtual bool eval_grad_f(const hiop::size_type &n, const double *x, bool new_x,
112  double *gradf);
113 
114  /** Evaluates a subset of the constraints cons(x). The subset is of size
115  * num_cons and is described by indexes in the idx_cons array,
116  * i.e. cons[c] = C(x)[idx_cons[c]] where c = 0 .. num_cons-1.
117  * The methods may be called multiple times, each time for a subset of the
118  * constraints, for example, for the subset containing the equalities and
119  * for the subset containing the inequalities. However, each constraint will
120  * be inquired EXACTLY once. This is done for performance considerations,
121  * to avoid temporary holders and memory copying.
122  *
123  * Parameters:
124  * - n, m: the global number of variables and constraints
125  * - num_cons, idx_cons (array of size num_cons): the number and indexes of
126  * constraints to be evaluated
127  * - x: the point where the constraints are to be evaluated
128  * - new_x: whether x has been changed from the previous call to f, grad_f,
129  * or Jac
130  * - cons: array of size num_cons containing the value of the constraints
131  * indicated by idx_cons
132  *
133  * When MPI enabled, every rank populates cons, since the constraints are
134  * not distributed.
135  */
136  virtual bool eval_cons(const hiop::size_type &n, const hiop::size_type &m,
137  const hiop::size_type &num_cons,
138  const hiop::index_type *idx_cons,
139  const double *x, bool new_x, double *cons);
140 
141  using hiop::hiopInterfaceBase::eval_cons;
142 
143  /** Evaluates the Jacobian of the subset of constraints indicated by
144  * idx_cons. The idx_cons is assumed to be of size num_cons.
145  * Example: if cons[c] = C(x)[idx_cons[c]] where c = 0 .. num_cons-1, then
146  * one needs to do Jac[c][j] = d cons[c] / dx_j, j = 1 .. n_loc.
147  * Jac is computed and stored in a contiguous vector (offset by rows).
148  *
149  * Parameters: see eval_cons().
150  *
151  * When MPI enabled, each rank computes only the local columns of the
152  * Jacobian, that is the partials with respect to local variables.
153  */
154  virtual bool eval_Jac_cons(const hiop::size_type &n, const hiop::size_type &m,
155  const hiop::size_type &num_cons,
156  const hiop::index_type *idx_cons,
157  const double *x, bool new_x, double *Jac);
158 
159  using hiop::hiopInterfaceDenseConstraints::eval_Jac_cons;
160 
161  /** Specifies column partitioning for distributed memory vectors.
162  * Process p owns vector entries with indices cols[p] to cols[p+1]-1,
163  * where p = 0 .. nranks-1. The cols array is of size nranks + 1.
164  * Example: for a vector x of 6 entries (globally) on 3 ranks, the uniform
165  * column partitioning is cols=[0,2,4,6].
166  */
167  virtual bool get_vecdistrib_info(hiop::size_type global_n,
168  hiop::index_type *cols);
169 
170  virtual void solution_callback(hiop::hiopSolveStatus status,
171  hiop::size_type n,
172  const double *x,
173  const double *z_L,
174  const double *z_U,
175  hiop::size_type m,
176  const double *g,
177  const double *lambda,
178  double obj_value);
179 
180  virtual bool iterate_callback(int iter,
181  double obj_value,
182  double logbar_obj_value,
183  int n,
184  const double *x,
185  const double *z_L,
186  const double *z_U,
187  int m_ineq,
188  const double *s,
189  int m,
190  const double *g,
191  const double *lambda,
192  double inf_pr,
193  double inf_du,
194  double onenorm_pr_,
195  double mu,
196  double alpha_du,
197  double alpha_pr,
198  int ls_trials);
199 
200 #ifdef MFEM_USE_MPI
201  virtual bool get_MPI_comm(MPI_Comm &comm_out)
202  {
203  comm_out = comm;
204  return true;
205  }
206 #endif
207 };
208 
209 /// Users can inherit this class to access to HiOp-specific functionality.
211 {
212 public:
213  HiOpProblem(int insize, const Operator *C_, const Operator *D_)
214  : OptimizationProblem(insize, C_, D_) { }
215 
216  /// See hiopInterfaceBase::solution_callback(...).
217  virtual void SolutionCallback(hiop::hiopSolveStatus status,
218  hiop::size_type n,
219  const double *x,
220  const double *z_L,
221  const double *z_U,
222  hiop::size_type m,
223  const double *g,
224  const double *lambda,
225  double obj_value) const
226  { }
227 
228  /// See hiopInterfaceBase::iterate_callback(...).
229  virtual bool IterateCallback(int iter,
230  double obj_value,
231  double logbar_obj_value,
232  int n,
233  const double *x,
234  const double *z_L,
235  const double *z_U,
236  int m_ineq,
237  const double *s,
238  int m,
239  const double *g,
240  const double *lambda,
241  double inf_pr,
242  double inf_du,
243  double onenorm_pr_,
244  double mu,
245  double alpha_du,
246  double alpha_pr,
247  int ls_trials) const
248  { return true; }
249 };
250 
251 /// Adapts the HiOp functionality to the MFEM OptimizationSolver interface.
253 {
254 protected:
256 
257 #ifdef MFEM_USE_MPI
258  MPI_Comm comm;
259 #endif
260 
261 public:
263 #ifdef MFEM_USE_MPI
264  HiopNlpOptimizer(MPI_Comm comm_);
265 #endif
266  virtual ~HiopNlpOptimizer();
267 
268  virtual void SetOptimizationProblem(const OptimizationProblem &prob);
269 
270  /// Solves the optimization problem with xt as initial guess.
271  virtual void Mult(const Vector &xt, Vector &x) const;
272 };
273 
274 } // mfem namespace
275 
276 #endif //MFEM_USE_HIOP
277 #endif //MFEM_HIOP guard
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
Definition: hiop.cpp:320
void setStartingPoint(const Vector &x0)
Definition: hiop.hpp:85
Users can inherit this class to access to HiOp-specific functionality.
Definition: hiop.hpp:210
virtual void SolutionCallback(hiop::hiopSolveStatus status, hiop::size_type n, const double *x, const double *z_L, const double *z_U, hiop::size_type m, const double *g, const double *lambda, double obj_value) const
See hiopInterfaceBase::solution_callback(...).
Definition: hiop.hpp:217
virtual bool iterate_callback(int iter, double obj_value, double logbar_obj_value, int n, const double *x, const double *z_L, const double *z_U, int m_ineq, const double *s, int m, const double *g, const double *lambda, double inf_pr, double inf_du, double onenorm_pr_, double mu, double alpha_du, double alpha_pr, int ls_trials)
Definition: hiop.cpp:211
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
virtual bool eval_cons(const hiop::size_type &n, const hiop::size_type &m, const hiop::size_type &num_cons, const hiop::index_type *idx_cons, const double *x, bool new_x, double *cons)
Definition: hiop.cpp:113
virtual void solution_callback(hiop::hiopSolveStatus status, hiop::size_type n, const double *x, const double *z_L, const double *z_U, hiop::size_type m, const double *g, const double *lambda, double obj_value)
Definition: hiop.cpp:196
virtual bool get_cons_info(const hiop::size_type &m, double *clow, double *cupp, NonlinearityType *type)
Definition: hiop.cpp:58
virtual void Mult(const Vector &xt, Vector &x) const
Solves the optimization problem with xt as initial guess.
Definition: hiop.cpp:334
virtual ~HiopNlpOptimizer()
Definition: hiop.cpp:315
virtual bool get_MPI_comm(MPI_Comm &comm_out)
Definition: hiop.hpp:201
HiOpProblem(int insize, const Operator *C_, const Operator *D_)
Definition: hiop.hpp:213
prob_type prob
Definition: ex25.cpp:154
virtual bool get_vars_info(const hiop::size_type &n, double *xlow, double *xupp, NonlinearityType *type)
Definition: hiop.cpp:43
virtual bool eval_Jac_cons(const hiop::size_type &n, const hiop::size_type &m, const hiop::size_type &num_cons, const hiop::index_type *idx_cons, const double *x, bool new_x, double *Jac)
Definition: hiop.cpp:140
virtual bool IterateCallback(int iter, double obj_value, double logbar_obj_value, int n, const double *x, const double *z_L, const double *z_U, int m_ineq, const double *s, int m, const double *g, const double *lambda, double inf_pr, double inf_du, double onenorm_pr_, double mu, double alpha_du, double alpha_pr, int ls_trials) const
See hiopInterfaceBase::iterate_callback(...).
Definition: hiop.hpp:229
virtual bool get_starting_point(const hiop::size_type &n, double *x0)
Definition: hiop.cpp:33
int problem
Definition: ex15.cpp:62
virtual bool get_vecdistrib_info(hiop::size_type global_n, hiop::index_type *cols)
Definition: hiop.cpp:172
Adapts the HiOp functionality to the MFEM OptimizationSolver interface.
Definition: hiop.hpp:252
virtual bool eval_grad_f(const hiop::size_type &n, const double *x, bool new_x, double *gradf)
Definition: hiop.cpp:97
Abstract solver for OptimizationProblems.
Definition: solvers.hpp:865
double mu
Definition: ex25.cpp:140
HiopOptimizationProblem(const MPI_Comm &comm_, const OptimizationProblem &prob)
Definition: hiop.hpp:71
virtual bool get_prob_sizes(hiop::size_type &n, hiop::size_type &m)
Definition: hiop.cpp:25
virtual bool eval_f(const hiop::size_type &n, const double *x, bool new_x, double &obj_value)
Definition: hiop.cpp:82
Vector data type.
Definition: vector.hpp:58
RefCoord s[3]
Abstract operator.
Definition: operator.hpp:24
HiopOptimizationProblem * hiop_problem
Definition: hiop.hpp:255
HiopOptimizationProblem(const OptimizationProblem &prob)
Definition: hiop.hpp:56
Internal class - adapts the OptimizationProblem class to HiOp&#39;s interface.
Definition: hiop.hpp:32