interface.cpp
Go to the documentation of this file.
1 // Copyright 2019, University of Maryland and the MANGO development team.
2 //
3 // This file is part of MANGO.
4 //
5 // MANGO is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // MANGO is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with MANGO. If not, see
17 // <https://www.gnu.org/licenses/>.
18 
19 #include <iostream>
20 #include <stdexcept>
21 #include "mango.hpp"
22 // This interface to C and Fortran should only "know" about mango's public API (i.e. the API to outside codes that use mango), not about
23 // the implementation details in Problem_data and Least_squares_data. So Problem_data.hpp and Least_squares_data.hpp should NOT be included here!
24 
25 // The value in the next line must match the corresponding value in mango.F90
26 #define mango_interface_string_length 256
27 
28 // C interfaces to C++ subroutines
29 // See https://modelingguru.nasa.gov/docs/DOC-2642
30 // and http://fortranwiki.org/fortran/show/Fortran+and+Cpp+objects
31 
32 extern "C" {
33  /* mango::Problem *mango_problem_create() {
34  return new mango::Problem;
35  } */
36  /*
37  mango::Problem *mango_problem_create(int N_parameters) {
38  return new mango::Problem(N_parameters);
39  }
40  mango::Problem *mango_problem_create_least_squares(int N_parameters, int N_terms) {
41  return new mango::Problem(N_parameters,N_terms);
42  } */
43  mango::Problem *mango_problem_create(int* N_parameters, double* state_vector, mango::objective_function_type objective_function) {
44  if (false) {
45  std::cout << "interface.cpp subroutine mango_problem_create: objective_function=" << (long int)objective_function << std::endl;
46 
47  std::cout << "From interface.cpp, N_parameters=" << *N_parameters;
48  for (int j=0; j<*N_parameters; j++) {
49  std::cout << ", state_vector["<<j<<"]=" << state_vector[j];
50  }
51  //std::cout << std::endl << "dummy=" << *dummy;
52  }
53  /*
54  std::cout << " About to call objective function from interface.cpp\n";
55  double f;
56  int failed_temp;
57  objective_function(N_parameters, state_vector, &f, &failed_temp, this);
58  std::cout << "Value of objective function: " << f << "\n";
59  */
60  return new mango::Problem(*N_parameters, state_vector, objective_function, 0, NULL);
61 
62  }
63 
64  mango::Least_squares_problem *mango_problem_create_least_squares(int* N_parameters, double* state_vector, int* N_terms, double* targets, double* sigmas,
65  double* best_residual_function, mango::vector_function_type residual_function) {
66  return new mango::Least_squares_problem(*N_parameters, state_vector, *N_terms, targets, sigmas, best_residual_function, residual_function, 0, NULL);
67  }
68 
69 
71  delete This;
72  }
73 
75  This->set_algorithm(*algorithm);
76  }
77 
79  This->set_algorithm(algorithm_name);
80  }
81 
83  This->read_input_file(filename);
84  }
85 
87  This->set_output_filename(filename);
88  }
89 
90  // For converting communicators between Fortran and C, see
91  // https://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node59.htm
92  void mango_mpi_init(mango::Problem *This, MPI_Fint *comm) {
93  This->mpi_init(MPI_Comm_f2c(*comm));
94  }
95 
96  void mango_mpi_partition_set_custom(mango::Problem *This, MPI_Fint *comm_world, MPI_Fint *comm_group_leaders, MPI_Fint *comm_worker_groups) {
97  This->mpi_partition.set_custom(MPI_Comm_f2c(*comm_world), MPI_Comm_f2c(*comm_group_leaders), MPI_Comm_f2c(*comm_worker_groups));
98  }
99 
100  void mango_set_N_worker_groups(mango::Problem *This, int* N_worker_groups) {
101  This->mpi_partition.set_N_worker_groups(*N_worker_groups);
102  }
103 
105  return This->mpi_partition.get_N_worker_groups();
106  }
107 
109  return This->optimize();
110  }
111 
113  return This->mpi_partition.get_rank_world();
114  }
115 
117  return This->mpi_partition.get_rank_worker_groups();
118  }
119 
121  return This->mpi_partition.get_rank_group_leaders();
122  }
123 
125  return This->mpi_partition.get_N_procs_world();
126  }
127 
130  }
131 
134  }
135 
137  return This->mpi_partition.get_proc0_world() ? 1 : 0;
138  }
139 
141  return This->mpi_partition.get_proc0_worker_groups() ? 1 : 0;
142  }
143 
145  return (int) MPI_Comm_c2f(This->mpi_partition.get_comm_world());
146  }
147 
149  return (int) MPI_Comm_c2f(This->mpi_partition.get_comm_worker_groups());
150  }
151 
153  return (int) MPI_Comm_c2f(This->mpi_partition.get_comm_group_leaders());
154  }
155 
157  return (int) This->get_N_parameters();
158  }
159 
161  return (int) This->get_N_terms();
162  }
163 
165  return (int) This->mpi_partition.get_worker_group();
166  }
167 
169  return (int) This->get_best_function_evaluation();
170  }
171 
173  return (int) This->get_function_evaluations();
174  }
175 
178  }
179 
180  void mango_set_centered_differences(mango::Problem *This, int* centered_differences_int) {
181  if (*centered_differences_int==1) {
182  This->set_centered_differences(true);
183  } else if (*centered_differences_int==0) {
184  This->set_centered_differences(false);
185  } else {
186  throw std::runtime_error("Error in interface.cpp mango_set_centered_differences");
187  }
188  }
189 
191  bool return_bool = mango::does_algorithm_exist(algorithm_name);
192  // Convert bool to integer:
193  return(return_bool ? 1 : 0);
194  }
195 
197  This->set_finite_difference_step_size(*step);
198  }
199 
200  void mango_set_bound_constraints(mango::Problem *This, double* lower_bounds, double* upper_bounds) {
201  This->set_bound_constraints(lower_bounds, upper_bounds);
202  }
203 
204  void mango_set_verbose(mango::Problem *This, int* verbose) {
205  This->set_verbose(*verbose);
206  }
207 
208  void mango_set_print_residuals_in_output_file(mango::Least_squares_problem *This, int* print_residuals_in_output_file_int) {
209  if (*print_residuals_in_output_file_int==1) {
211  } else if (*print_residuals_in_output_file_int==0) {
213  } else {
214  throw std::runtime_error("Error in interface.cpp mango_set_print_residuals_in_output_file");
215  }
216  }
217 
218  void mango_set_user_data(mango::Problem *This, void* user_data) {
219  This->set_user_data(user_data);
220  }
221 
223  This->mpi_partition.stop_workers();
224  }
225 
228  }
229 
231  int return_bool = This->mpi_partition.continue_worker_loop();
232  return (return_bool ? 1 : 0);
233  }
234 
236  This->mpi_partition.write(filename);
237  }
238 
239  void mango_set_relative_bound_constraints(mango::Problem *This, double* min_factor, double* max_factor, double* min_radius, int* preserve_sign) {
240  if (*preserve_sign != 0 && *preserve_sign != 1) throw std::runtime_error("preserve_sign should be 0 or 1.");
241  This->set_relative_bound_constraints(*min_factor, *max_factor, *min_radius, (*preserve_sign)==1);
242  }
243 
245  This->set_N_line_search(*N);
246  }
247 
248 }
mango::MPI_Partition::set_N_worker_groups
void set_N_worker_groups(int N_worker_groups)
Set the number of worker groups to the given integer.
Definition: mpi_partition.cpp:106
mango_mpi_partition_write
void mango_mpi_partition_write(mango::Problem *This, char filename[mango_interface_string_length])
Definition: interface.cpp:235
mango_set_algorithm_from_string
void mango_set_algorithm_from_string(mango::Problem *This, char algorithm_name[mango_interface_string_length])
Definition: interface.cpp:78
mango_get_mpi_comm_worker_groups
int mango_get_mpi_comm_worker_groups(mango::Problem *This)
Definition: interface.cpp:148
mango_get_function_evaluations
int mango_get_function_evaluations(mango::Problem *This)
Definition: interface.cpp:172
mango::Problem::set_N_line_search
void set_N_line_search(int N_line_search)
Sets the number of points considered as a set for parallel line searches.
Definition: Problem.cpp:176
mango::MPI_Partition::stop_workers
void stop_workers()
Tell the worker MPI processes (i.e. those that are not group leaders) that the optimization problem i...
Definition: mpi_partition.cpp:111
mango_set_bound_constraints
void mango_set_bound_constraints(mango::Problem *This, double *lower_bounds, double *upper_bounds)
Definition: interface.cpp:200
mango::Least_squares_problem::set_print_residuals_in_output_file
void set_print_residuals_in_output_file(bool print)
Determine whether or not to print each individual residual in the MANGO output file.
Definition: Least_squares_problem.cpp:61
mango_interface_string_length
#define mango_interface_string_length
Definition: interface.cpp:26
mango_read_input_file
void mango_read_input_file(mango::Problem *This, char filename[mango_interface_string_length])
Definition: interface.cpp:82
mango_set_output_filename
void mango_set_output_filename(mango::Problem *This, char filename[mango_interface_string_length])
Definition: interface.cpp:86
mango_set_verbose
void mango_set_verbose(mango::Problem *This, int *verbose)
Definition: interface.cpp:204
mango_set_centered_differences
void mango_set_centered_differences(mango::Problem *This, int *centered_differences_int)
Definition: interface.cpp:180
mango::MPI_Partition::get_comm_world
MPI_Comm get_comm_world()
Get the MPI communicator for MANGO's world communicator.
Definition: mpi_partition.cpp:41
mango::MPI_Partition::get_proc0_worker_groups
bool get_proc0_worker_groups()
Determine whether this MPI processor has rank 0 in MANGO's "worker groups" communicator.
Definition: mpi_partition.cpp:61
mango_set_N_worker_groups
void mango_set_N_worker_groups(mango::Problem *This, int *N_worker_groups)
Definition: interface.cpp:100
mango::MPI_Partition::get_comm_group_leaders
MPI_Comm get_comm_group_leaders()
Get the MPI communicator for MANGO's "group leaders" communicator.
Definition: mpi_partition.cpp:51
mango::Problem::get_N_parameters
int get_N_parameters()
Get the number of independent variables for an optimization problem.
Definition: Problem.cpp:42
mango::Problem::set_user_data
void set_user_data(void *user_data)
Pass the prescribed pointer to the objective function whenever it is called.
Definition: Problem.cpp:85
mango_get_N_procs_group_leaders
int mango_get_N_procs_group_leaders(mango::Problem *This)
Definition: interface.cpp:132
mango::does_algorithm_exist
bool does_algorithm_exist(std::string algorithm_name)
Checks whether or not a string corresponds to the name of one of the optimization algorithms known by...
Definition: algorithms.cpp:72
mango_mpi_partition_set_custom
void mango_mpi_partition_set_custom(mango::Problem *This, MPI_Fint *comm_world, MPI_Fint *comm_group_leaders, MPI_Fint *comm_worker_groups)
Definition: interface.cpp:96
mango::Problem::mpi_partition
MPI_Partition mpi_partition
Definition: mango.hpp:449
mango::algorithm_type
algorithm_type
A list of the algorithms that MANGO can potentially use.
Definition: mango.hpp:75
mango_stop_workers
void mango_stop_workers(mango::Problem *This)
Definition: interface.cpp:222
mango_set_relative_bound_constraints
void mango_set_relative_bound_constraints(mango::Problem *This, double *min_factor, double *max_factor, double *min_radius, int *preserve_sign)
Definition: interface.cpp:239
mango::MPI_Partition::get_worker_group
int get_worker_group()
Returns an integer indicating the worker group to which this MPI process belongs.
Definition: mpi_partition.cpp:96
mango_get_mpi_rank_world
int mango_get_mpi_rank_world(mango::Problem *This)
Definition: interface.cpp:112
mango_get_mpi_rank_group_leaders
int mango_get_mpi_rank_group_leaders(mango::Problem *This)
Definition: interface.cpp:120
mango_set_finite_difference_step_size
void mango_set_finite_difference_step_size(mango::Problem *This, double *step)
Definition: interface.cpp:196
mango::Problem::set_max_function_evaluations
void set_max_function_evaluations(int N)
Set the maximum number of evaluations of the objective function that will be allowed before the optim...
Definition: Problem.cpp:72
mango::Problem::set_verbose
void set_verbose(int verbose)
Control how much diagnostic information is printed by MANGO.
Definition: Problem.cpp:77
mango::MPI_Partition::set_custom
void set_custom(MPI_Comm comm_world, MPI_Comm comm_group_leaders, MPI_Comm comm_worker_groups)
Use a user-supplied partitioning of the MPI processes into worker groups.
Definition: mpi_partition_set_custom.cpp:24
mango::Problem::get_best_function_evaluation
int get_best_function_evaluation()
For an optimization problem that has already been solved, return the index of the function evaluation...
Definition: Problem.cpp:46
mango::Problem::set_algorithm
void set_algorithm(algorithm_type algorithm)
Sets the optimization algorithm.
Definition: algorithms.cpp:25
mango_set_user_data
void mango_set_user_data(mango::Problem *This, void *user_data)
Definition: interface.cpp:218
mango::vector_function_type
void(* vector_function_type)(int *N_parameters, const double *state_vector, int *N_terms, double *residuals, int *failed, mango::Problem *problem, void *user_data)
Format for the user-supplied subroutine that computes the residuals for a least-squares optimization ...
Definition: mango.hpp:439
mango::Problem::set_output_filename
void set_output_filename(std::string filename)
Sets the name of the output file that will record values of the objective function at each evaluation...
Definition: Problem.cpp:81
mango_get_proc0_worker_groups
int mango_get_proc0_worker_groups(mango::Problem *This)
Definition: interface.cpp:140
mango_problem_create
mango::Problem * mango_problem_create(int *N_parameters, double *state_vector, mango::objective_function_type objective_function)
Definition: interface.cpp:43
mango::Least_squares_problem
Definition: mango.hpp:658
mango::Problem::set_centered_differences
void set_centered_differences(bool centered_differences)
Control whether 1-sided or centered finite differences will be used to compute derivatives of the obj...
Definition: Problem.cpp:64
mango_problem_destroy
void mango_problem_destroy(mango::Problem *This)
Definition: interface.cpp:70
mango_get_best_function_evaluation
int mango_get_best_function_evaluation(mango::Problem *This)
Definition: interface.cpp:168
mango_continue_worker_loop
int mango_continue_worker_loop(mango::Problem *This)
Definition: interface.cpp:230
mango.hpp
mango::MPI_Partition::get_rank_group_leaders
int get_rank_group_leaders()
Get the MPI rank of this processor in MANGO's "group leaders" communicator.
Definition: mpi_partition.cpp:76
mango::Problem::set_finite_difference_step_size
void set_finite_difference_step_size(double finite_difference_step_size)
Set an absolute step size for finite difference derivatives.
Definition: Problem.cpp:68
mango::MPI_Partition::get_N_procs_group_leaders
int get_N_procs_group_leaders()
Get the number of processors in MANGO's "group leaders" communicator.
Definition: mpi_partition.cpp:91
mango::MPI_Partition::get_N_procs_worker_groups
int get_N_procs_worker_groups()
Get the number of processors in MANGO's "worker groups" communicator.
Definition: mpi_partition.cpp:86
mango_get_N_procs_world
int mango_get_N_procs_world(mango::Problem *This)
Definition: interface.cpp:124
mango::MPI_Partition::get_rank_world
int get_rank_world()
Get the MPI rank of this processor in MANGO's world communicator.
Definition: mpi_partition.cpp:66
mango::objective_function_type
void(* objective_function_type)(int *N_parameters, const double *state_vector, double *objective_value, int *failed, mango::Problem *problem, void *user_data)
Format for the user-supplied subroutine that computes the objective function for a general (non least...
Definition: mango.hpp:424
mango_set_max_function_evaluations
void mango_set_max_function_evaluations(mango::Problem *This, int *N)
Definition: interface.cpp:176
mango_problem_create_least_squares
mango::Least_squares_problem * mango_problem_create_least_squares(int *N_parameters, double *state_vector, int *N_terms, double *targets, double *sigmas, double *best_residual_function, mango::vector_function_type residual_function)
Definition: interface.cpp:64
mango_get_mpi_comm_world
int mango_get_mpi_comm_world(mango::Problem *This)
Definition: interface.cpp:144
mango_get_N_terms
int mango_get_N_terms(mango::Least_squares_problem *This)
Definition: interface.cpp:160
mango::MPI_Partition::get_proc0_world
bool get_proc0_world()
Determine whether this MPI processor has rank 0 in MANGO's world communicator.
Definition: mpi_partition.cpp:56
mango_does_algorithm_exist
int mango_does_algorithm_exist(char algorithm_name[mango_interface_string_length])
Definition: interface.cpp:190
mango::MPI_Partition::get_N_worker_groups
int get_N_worker_groups()
Returns the number of worker groups.
Definition: mpi_partition.cpp:101
mango_set_N_line_search
void mango_set_N_line_search(mango::Problem *This, int *N)
Definition: interface.cpp:244
mango_get_mpi_comm_group_leaders
int mango_get_mpi_comm_group_leaders(mango::Problem *This)
Definition: interface.cpp:152
mango::MPI_Partition::get_rank_worker_groups
int get_rank_worker_groups()
Get the MPI rank of this processor in MANGO's "worker groups" communicator.
Definition: mpi_partition.cpp:71
mango_get_mpi_rank_worker_groups
int mango_get_mpi_rank_worker_groups(mango::Problem *This)
Definition: interface.cpp:116
mango_set_print_residuals_in_output_file
void mango_set_print_residuals_in_output_file(mango::Least_squares_problem *This, int *print_residuals_in_output_file_int)
Definition: interface.cpp:208
mango_get_worker_group
int mango_get_worker_group(mango::Problem *This)
Definition: interface.cpp:164
mango::MPI_Partition::get_comm_worker_groups
MPI_Comm get_comm_worker_groups()
Get the MPI communicator for MANGO's "worker groups" communicator.
Definition: mpi_partition.cpp:46
mango::Problem::mpi_init
void mpi_init(MPI_Comm mpi_comm)
Initialize MANGO's internal MPI data that describes the partitioning of the processes into worker gro...
Definition: Problem.cpp:90
mango::Problem::set_relative_bound_constraints
void set_relative_bound_constraints(double min_factor, double max_factor, double min_radius, bool preserve_sign)
Impose bound constraints on an optimization problem, with the bounds chosen as multiples of the initi...
Definition: Problem.cpp:126
mango_get_N_parameters
int mango_get_N_parameters(mango::Problem *This)
Definition: interface.cpp:156
mango::Problem::get_function_evaluations
int get_function_evaluations()
For an optimization problem that has already been solved, return the number of times the objective fu...
Definition: Problem.cpp:54
mango::MPI_Partition::mobilize_workers
void mobilize_workers()
Tell the worker MPI processes (i.e. those that are not group leaders) to begin an evaluation of the o...
Definition: mpi_partition.cpp:118
mango::MPI_Partition::continue_worker_loop
bool continue_worker_loop()
For an MPI worker, determine whether to carry out another evaluation of the objective function or exi...
Definition: mpi_partition.cpp:125
mango::Least_squares_problem::get_N_terms
int get_N_terms()
Return the number of least-squares terms that are summed to form the objective function.
Definition: Least_squares_problem.cpp:65
mango_get_N_worker_groups
int mango_get_N_worker_groups(mango::Problem *This)
Definition: interface.cpp:104
mango::Problem::read_input_file
void read_input_file(std::string filename)
Reads in the number of worker groups and algorithm from a file.
Definition: read_input_file.cpp:25
mango::Problem::optimize
double optimize()
Solve the optimization problem that has been set up.
Definition: Problem.cpp:119
mango::MPI_Partition::get_N_procs_world
int get_N_procs_world()
Get the number of processors in MANGO's world communicator.
Definition: mpi_partition.cpp:81
mango_mobilize_workers
void mango_mobilize_workers(mango::Problem *This)
Definition: interface.cpp:226
mango_get_proc0_world
int mango_get_proc0_world(mango::Problem *This)
Definition: interface.cpp:136
mango_set_algorithm
void mango_set_algorithm(mango::Problem *This, mango::algorithm_type *algorithm)
Definition: interface.cpp:74
mango::MPI_Partition::write
void write(std::string filename)
Write a file with the given filename, showing the worker group assignments and rank of each process i...
Definition: mpi_partition_print.cpp:51
mango_optimize
double mango_optimize(mango::Problem *This)
Definition: interface.cpp:108
mango_get_N_procs_worker_groups
int mango_get_N_procs_worker_groups(mango::Problem *This)
Definition: interface.cpp:128
mango::Problem::set_bound_constraints
void set_bound_constraints(double *lower, double *upper)
Sets bound constraints for the optimization problem.
Definition: Problem.cpp:58
mango::Problem
Definition: mango.hpp:442
mango_mpi_init
void mango_mpi_init(mango::Problem *This, MPI_Fint *comm)
Definition: interface.cpp:92