ALL 0.9.3
A Loadbalacing Library
Loading...
Searching...
No Matches
ALL_fortran.cpp
Go to the documentation of this file.
1/*
2Copyright 2018-2020 Rene Halver, Forschungszentrum Juelich GmbH, Germany
3Copyright 2018-2020 Godehard Sutmann, Forschungszentrum Juelich GmbH, Germany
4Copyright 2019-2020 Stephan Schulz, Ruhr-Universität Bochum, Germany
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
91. Redistributions of source code must retain the above copyright notice, this
10 list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright notice,
13this list of conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its contributors
17may be used to endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#include "../include/ALL.hpp"
35#include <cassert>
36#include <cstring>
37#include <vector>
38
39static int ALL_errno;
40static const char* ALL_errdesc;
41
43
44#ifdef ALL_FORTRAN_ERROR_ABORT
45#define ALL_try
46#define ALL_catch
47#else
48#define ALL_try try {
49#define ALL_catch } catch (ALL::CustomException &e) { \
50 ALL_errno = e.get_error_id(); \
51 ALL_errdesc = e.what(); \
52}
53#endif
54
55/*
56This interface is unstable and subject to change! It is only used for the
57Fortran interface. Several safety checks are only done on the Fortran side. Use
58the C++ API or Fortran interfaces
59*/
60
61extern "C" {
62// wrapper to create a ALL::ALL<double,double> object (should be the
63// most commonly used one)
64ALL_t *all_init_c(ALL::LB_t method, const int dim, double gamma) {
66 return new ALL::ALL<double, double>(method, dim, gamma);
68 return NULL;
69}
70
71// delete ALL object
72void all_finalize_c(ALL_t *all_obj) {
73 delete all_obj;
74 // todo(s.schulz): does this throw if all_obj is already deleted? can we detect it?
75}
76
77void all_set_gamma_c(ALL_t *all_obj, double gamma) {
79 all_obj->setGamma(gamma);
81}
82
83// set grid parameters
84void all_set_proc_grid_params_c(ALL_t *all_obj, int nloc,
85 int *loc, int nsize, int *size) {
87 int dim = all_obj->getDimension();
88 if (dim != nloc)
90 __FILE__, __func__, __LINE__,
91 "Length of index array does not match dimension");
92 if (dim != nsize)
94 __FILE__, __func__, __LINE__,
95 "Length of size array does not match dimension");
96 std::vector<int> vloc(loc, loc+nloc);
97 std::vector<int> vsize(size, size+nsize);
98 all_obj->setProcGridParams(vloc, vsize);
100}
101
102// wrapper to set the minimum domain size
103void all_set_min_domain_size_c(ALL_t *all_obj, int dim,
104 double *domain_size) {
105 ALL_try
106 if (all_obj->getDimension() != dim)
108 __FILE__, __func__, __LINE__,
109 "Length of array does not match dimension");
110 std::vector<double> t_domain_size(domain_size, domain_size+dim);
111 all_obj->setMinDomainSize(t_domain_size);
113}
114
115// wrapper to set the work (scalar only for the moment)
116void all_set_work_c(ALL_t *all_obj, double work) {
117 ALL_try
118 all_obj->setWork(work);
120}
121
122// set multidimensional work
123void all_set_work_multi_c(ALL_t *all_obj, double *work, int dim) {
124 ALL_try
125 std::vector<double> t_work(work, work+dim);
126 all_obj->setWork(t_work);
128}
129
130// wrapper to set the vertices (using an array of double values and dimension)
131void all_set_vertices_c(ALL_t *all_obj, const int n,
132 const int dim, const double *vertices) {
133 ALL_try
134 std::vector<ALL::Point<double>> points(n, ALL::Point<double>(dim));
135 if (dim != all_obj->getDimension())
137 __FILE__, __func__, __LINE__,
138 "Dimension of ALL::Points in input vector do not match dimension of "
139 "ALL "
140 "object.");
141 for (int i = 0; i < n; ++i) {
142 for (int d = 0; d < dim; ++d) {
143 points.at(i)[d] = vertices[i * dim + d];
144 }
145 }
146 all_obj->setVertices(points);
148}
149
150// wrapper to set the communicator
151void all_set_communicator_c(ALL_t *all_obj, MPI_Fint fcomm) {
152 ALL_try
153 MPI_Comm cComm = MPI_Comm_f2c(fcomm);
154 all_obj->setCommunicator(cComm);
156}
157
158void all_set_sys_size_c(ALL_t *all_obj, double *size, int dim) {
159 ALL_try
160 std::vector<double> t_size(size, size+dim);
161 all_obj->setSysSize(t_size);
163}
164
165// wrapper to setup routine
166void all_setup_c(ALL_t *all_obj) {
167 ALL_try
168 all_obj->setup();
170}
171
172void all_set_method_data_histogram_c(ALL_t *all_obj, int *nbins) { all_obj->setMethodData(nbins); }
173
174// wrapper to call balance routine
175void all_balance_c(ALL_t *all_obj) {
176 ALL_try
177 all_obj->balance();
179}
180
181void all_get_gamma_c(ALL_t *all_obj, double *gamma) { *gamma = all_obj->getGamma(); }
182
183// wrapper to get number of new vertices
184void all_get_number_of_vertices_c(ALL_t *all_obj, int *n_vertices) {
185 ALL_try
186 *n_vertices = (all_obj->getVertices()).size();
188}
189
190// wrapper to return new vertices
191void all_get_vertices_c(ALL_t *all_obj, int n_vertices,
192 double *vertices) {
193 ALL_try
194 std::vector<ALL::Point<double>> tmp_vertices = all_obj->getVertices();
195 int dimension = all_obj->getDimension();
196 assert(n_vertices = tmp_vertices.size());
197 for (int i = 0; i < n_vertices; ++i) {
198 for (int j = 0; j < dimension; ++j) {
199 vertices[i * dimension + j] = tmp_vertices.at(i)[j];
200 }
201 }
203}
204
205// set process tag
206void all_set_proc_tag_c(ALL_t *all_obj, int tag) {
207 ALL_try
208 all_obj->setProcTag(tag);
210}
211
212// wrapper to return new vertices
213void all_get_prev_vertices_c(ALL_t *all_obj, int n_vertices,
214 double *prevVertices) {
215 ALL_try
216 std::vector<ALL::Point<double>> tmp_vertices = all_obj->getPrevVertices();
217 int dimension = all_obj->getDimension();
218 assert(n_vertices = tmp_vertices.size());
219 for (int i = 0; i < n_vertices; ++i) {
220 for (int j = 0; j < dimension; ++j) {
221 prevVertices[i * dimension + j] = tmp_vertices.at(i)[j];
222 }
223 }
225}
226
227// get currently set dimension
228void all_get_dimension_c(ALL_t *all_obj, int *dim) {
229 ALL_try
230 *dim = all_obj->getDimension();
232}
233
234void all_get_length_of_work_c(ALL_t *all_obj, int *length) {
235 ALL_try
236 std::vector<double> work;
237 all_obj->getWork(work);
238 *length = work.size();
240}
241
242void all_get_work_c(ALL_t *all_obj, double *work) {
243 ALL_try
244 *work = all_obj->getWork();
246}
247
248void all_get_work_array_c(ALL_t *all_obj, double *work, int length) {
249 ALL_try
250 std::vector<double> all_work;
251 all_obj->getWork(all_work);
252 assert((int)all_work.size() == length);
253 memcpy(work,&all_work[0],length*sizeof(*work));
255}
256
257void all_get_number_of_neighbors_c(ALL_t *all_obj, int *count) {
258 ALL_try
259 std::vector<int> neighbors = all_obj->getNeighbors();
260 *count = neighbors.size();
262}
263
264void all_get_neighbors_c(ALL_t *all_obj, int *neighbors, int count) {
265 ALL_try
266 std::vector<int> all_neighbors = all_obj->getNeighbors();
267 assert((int)all_neighbors.size() == count);
268 memcpy(neighbors,&all_neighbors[0],count*sizeof(*neighbors));
270}
271
272#ifdef ALL_VTK_OUTPUT
273// print VTK outlines
275 // todo(s.schulz): Should this function even be declared if ALL_VTK_OUTPUT isn't?
276 ALL_try
277 all_obj->printVTKoutlines(step);
279}
280
282 // todo(s.schulz): Should this function even be declared if ALL_VTK_OUTPUT isn't?
283 ALL_try
284 all_obj->printVTKvertices(step);
286}
287#endif
288
289// retrieve error number
290int all_errno_c(void) { return ALL_errno; }
291
292// set error number
294 ALL_errno = 0;
295 ALL_errdesc = NULL;
296}
297
298// retrieve error description
299void all_errdesc_c(char *description, size_t len) {
300 if(ALL_errdesc) {
301 strncpy(description, ALL_errdesc, len);
302 } else {
303 strncpy(description, "No error", len);
304 }
305 // Use space padding instead of zero padding
306 // WARNING: The result is no longer a zero terminated string!
307 size_t msg_len = strlen(description);
308 memset(description+msg_len, ' ', len-msg_len);
309}
310}//extern "C"
311
312// VIM modeline for indentation
313// vim: sw=2 et ts=2
#define known_unused
Definition ALL_Defines.h:49
int all_errno_c(void)
void all_get_prev_vertices_c(ALL_t *all_obj, int n_vertices, double *prevVertices)
#define ALL_try
void all_set_gamma_c(ALL_t *all_obj, double gamma)
void all_setup_c(ALL_t *all_obj)
#define ALL_catch
void all_balance_c(ALL_t *all_obj)
void all_set_work_c(ALL_t *all_obj, double work)
void all_get_length_of_work_c(ALL_t *all_obj, int *length)
ALL::ALL< double, double > ALL_t
ALL_t * all_init_c(ALL::LB_t method, const int dim, double gamma)
void all_errdesc_c(char *description, size_t len)
void all_get_vertices_c(ALL_t *all_obj, int n_vertices, double *vertices)
void all_get_work_array_c(ALL_t *all_obj, double *work, int length)
void all_finalize_c(ALL_t *all_obj)
void all_set_sys_size_c(ALL_t *all_obj, double *size, int dim)
void all_set_communicator_c(ALL_t *all_obj, MPI_Fint fcomm)
void all_set_min_domain_size_c(ALL_t *all_obj, int dim, double *domain_size)
void all_get_number_of_vertices_c(ALL_t *all_obj, int *n_vertices)
void all_set_work_multi_c(ALL_t *all_obj, double *work, int dim)
void all_set_vertices_c(ALL_t *all_obj, const int n, const int dim, const double *vertices)
void all_get_number_of_neighbors_c(ALL_t *all_obj, int *count)
void all_reset_errno_c()
void all_print_vtk_outlines_c(ALL_t *all_obj known_unused, int known_unused step)
void all_print_vtk_vertices_c(ALL_t *all_obj known_unused, int known_unused step)
void all_get_gamma_c(ALL_t *all_obj, double *gamma)
void all_get_neighbors_c(ALL_t *all_obj, int *neighbors, int count)
void all_set_proc_tag_c(ALL_t *all_obj, int tag)
void all_set_proc_grid_params_c(ALL_t *all_obj, int nloc, int *loc, int nsize, int *size)
void all_get_work_c(ALL_t *all_obj, double *work)
void all_set_method_data_histogram_c(ALL_t *all_obj, int *nbins)
void all_get_dimension_c(ALL_t *all_obj, int *dim)
T getGamma()
Definition ALL.hpp:273
void setSysSize(const std::vector< T > &sysSize)
Definition ALL.hpp:474
void setProcGridParams(const std::vector< int > &loc, const std::vector< int > &size)
Definition ALL.hpp:494
std::vector< Point< T > > & getPrevVertices()
Definition ALL.hpp:415
void setMethodData(const void *data)
Definition ALL.hpp:486
void setCommunicator(const MPI_Comm comm)
Definition ALL.hpp:211
std::vector< int > & getNeighbors()
Definition ALL.hpp:442
void getWork(std::vector< W > &result)
Definition ALL.hpp:433
std::vector< Point< T > > & getVertices()
Definition ALL.hpp:423
void setMinDomainSize(const std::vector< T > &minSize)
Definition ALL.hpp:510
void setWork(const W work)
Definition ALL.hpp:281
void setup()
Definition ALL.hpp:292
std::vector< Point< T > > & balance()
Definition ALL.hpp:299
void setVertices(const std::vector< Point< T > > &inp)
Definition ALL.hpp:195
int getDimension()
Definition ALL.hpp:428
void setGamma(const T g)
Definition ALL.hpp:277
void setProcTag(int tag)
Definition ALL.hpp:504
LB_t
enum type to describe the different balancing methods
Definition ALL.hpp:80
Exception to be used for missmatches in dimension for ALL::Point class.