1 /*
2 HMat-OSS (HMatrix library, open source software)
3
4 Copyright (C) 2014-2015 Airbus Group SAS
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 http://github.com/jeromerobert/hmat-oss
21 */
22
23 #include "config.h"
24 #include "hmat/hmat.h"
25 #include "coordinates.hpp"
26 #include "hmat_cpp_interface.hpp"
27 #include "default_engine.hpp"
28 #include "clustering.hpp"
29 #include "admissibility.hpp"
30 #include "c_wrapping.hpp"
31 #include "common/my_assert.h"
32
33 using namespace hmat;
34
hmat_create_clustering_median()35 hmat_clustering_algorithm_t * hmat_create_clustering_median()
36 {
37 return (hmat_clustering_algorithm_t*) new MedianBisectionAlgorithm();
38 }
39
hmat_create_clustering_ntilesrecursive(int nTiles)40 hmat_clustering_algorithm_t * hmat_create_clustering_ntilesrecursive(int nTiles)
41 {
42 return (hmat_clustering_algorithm_t*) new NTilesRecursiveAlgorithm( nTiles );
43 }
44
hmat_create_clustering_geometric()45 hmat_clustering_algorithm_t * hmat_create_clustering_geometric()
46 {
47 return (hmat_clustering_algorithm_t*) new GeometricBisectionAlgorithm();
48 }
49
hmat_create_clustering_hybrid()50 hmat_clustering_algorithm_t * hmat_create_clustering_hybrid()
51 {
52 return (hmat_clustering_algorithm_t*) new HybridBisectionAlgorithm();
53 }
54
hmat_delete_clustering(hmat_clustering_algorithm_t * algo)55 void hmat_delete_clustering(hmat_clustering_algorithm_t* algo)
56 {
57 delete (ClusteringAlgorithm*) algo;
58 }
59
hmat_set_clustering_divider(hmat_clustering_algorithm_t * algo,int divider)60 void hmat_set_clustering_divider(hmat_clustering_algorithm_t* algo, int divider)
61 {
62 ((ClusteringAlgorithm*) algo)->setDivider(divider);
63 }
64
65 hmat_clustering_algorithm_t*
hmat_create_clustering_max_dof(const hmat_clustering_algorithm_t * algo,int max_dof)66 hmat_create_clustering_max_dof(const hmat_clustering_algorithm_t* algo, int max_dof)
67 {
68 ClusteringAlgorithm* result = static_cast<const ClusteringAlgorithm*>((void*) algo)->clone();
69 result->setMaxLeafSize(max_dof);
70 return static_cast<hmat_clustering_algorithm_t*>((void*) result);
71 }
72
hmat_create_clustering_span(const hmat_clustering_algorithm_t * algo,double ratio)73 hmat_clustering_algorithm_t* hmat_create_clustering_span(
74 const hmat_clustering_algorithm_t* algo, double ratio) {
75 SpanClusteringAlgorithm* result = new SpanClusteringAlgorithm(
76 *(reinterpret_cast<const ClusteringAlgorithm*>(algo)), ratio);
77 return reinterpret_cast<hmat_clustering_algorithm_t*>(result);
78 }
79
80 hmat_clustering_algorithm_t*
hmat_create_void_clustering(const hmat_clustering_algorithm_t * algo)81 hmat_create_void_clustering(const hmat_clustering_algorithm_t* algo)
82 {
83 VoidClusteringAlgorithm* result = new VoidClusteringAlgorithm(*(static_cast<const ClusteringAlgorithm*>((void*) algo)));
84 return static_cast<hmat_clustering_algorithm_t*>((void*) result);
85 }
86
87 hmat_clustering_algorithm_t*
hmat_create_shuffle_clustering(const hmat_clustering_algorithm_t * algo,int from_divider,int to_divider)88 hmat_create_shuffle_clustering(const hmat_clustering_algorithm_t* algo, int from_divider, int to_divider)
89 {
90 ShuffleClusteringAlgorithm* result = new ShuffleClusteringAlgorithm(*(static_cast<const ClusteringAlgorithm*>((void*) algo)), from_divider, to_divider);
91 return static_cast<hmat_clustering_algorithm_t*>((void*) result);
92 }
93
hmat_create_cluster_tree(double * coord,int dimension,int size,hmat_clustering_algorithm_t * algo)94 hmat_cluster_tree_t * hmat_create_cluster_tree(double* coord, int dimension, int size, hmat_clustering_algorithm_t* algo)
95 {
96 struct hmat_cluster_tree_create_context_t ctx;
97 memset(&ctx, 0, sizeof(ctx));
98 ctx.coordinates = coord;
99 ctx.dimension = dimension;
100 ctx.number_of_points = size;
101 ctx.number_of_dof = ctx.number_of_points;
102 ctx.span_offsets = NULL;
103 ctx.spans = NULL;
104 ctx.group_index = NULL;
105 ClusterTreeBuilder builder(*reinterpret_cast<ClusteringAlgorithm*>(algo));
106 ctx.builder = reinterpret_cast<hmat_cluster_tree_builder_t*>(&builder);
107 return hmat_create_cluster_tree_generic(&ctx);
108 }
109
hmat_create_cluster_tree_generic(struct hmat_cluster_tree_create_context_t * ctx)110 hmat_cluster_tree_t * hmat_create_cluster_tree_generic(struct hmat_cluster_tree_create_context_t * ctx) {
111 DofCoordinates dofs(ctx->coordinates, ctx->dimension, ctx->number_of_points, true,
112 ctx->number_of_dof, ctx->span_offsets, ctx->spans);
113 ClusterTree * r = reinterpret_cast<const ClusterTreeBuilder*>(ctx->builder)->build(dofs, ctx->group_index);
114 return reinterpret_cast<hmat_cluster_tree_t *>(r);
115 }
116
hmat_create_cluster_tree_builder(const hmat_clustering_algorithm_t * algo)117 hmat_cluster_tree_builder_t* hmat_create_cluster_tree_builder(const hmat_clustering_algorithm_t* algo)
118 {
119 ClusterTreeBuilder* result = new ClusterTreeBuilder(*static_cast<const ClusteringAlgorithm*>((void*) algo));
120 return static_cast<hmat_cluster_tree_builder_t*>((void*) result);
121 }
122
123 /* Specify an algorithm for nodes at given depth and below */
hmat_cluster_tree_builder_add_algorithm(hmat_cluster_tree_builder_t * ctb,int level,const hmat_clustering_algorithm_t * algo)124 void hmat_cluster_tree_builder_add_algorithm(hmat_cluster_tree_builder_t* ctb, int level, const hmat_clustering_algorithm_t* algo)
125 {
126 ClusterTreeBuilder* ct_builder = static_cast<ClusterTreeBuilder*>((void*) ctb);
127 ct_builder->addAlgorithm(level, *static_cast<const ClusteringAlgorithm*>((void*) algo));
128 }
129
hmat_delete_cluster_tree_builder(hmat_cluster_tree_builder_t * ctb)130 void hmat_delete_cluster_tree_builder(hmat_cluster_tree_builder_t* ctb)
131 {
132 delete static_cast<ClusterTreeBuilder*>((void*)ctb);
133 }
134
135 /* Create a ClusterTree from the DoFs coordinates. */
hmat_create_cluster_tree_from_builder(double * coord,int dimension,int size,const hmat_cluster_tree_builder_t * ctb)136 hmat_cluster_tree_t * hmat_create_cluster_tree_from_builder(double* coord, int dimension, int size, const hmat_cluster_tree_builder_t* ctb)
137 {
138 struct hmat_cluster_tree_create_context_t ctx;
139 memset(&ctx, 0, sizeof(ctx));
140 ctx.coordinates = coord;
141 ctx.dimension = dimension;
142 ctx.number_of_points = size;
143 ctx.number_of_dof = ctx.number_of_points;
144 ctx.span_offsets = NULL;
145 ctx.spans = NULL;
146 ctx.group_index = NULL;
147 ctx.builder = ctb;
148 return hmat_create_cluster_tree_generic(&ctx);
149 }
150
hmat_delete_cluster_tree(const hmat_cluster_tree_t * tree)151 void hmat_delete_cluster_tree(const hmat_cluster_tree_t * tree) {
152 delete ((ClusterTree*)tree);
153 }
154
hmat_copy_cluster_tree(const hmat_cluster_tree_t * tree)155 hmat_cluster_tree_t * hmat_copy_cluster_tree(const hmat_cluster_tree_t * tree) {
156 return reinterpret_cast<hmat_cluster_tree_t *>(
157 reinterpret_cast<const ClusterTree*>(tree)->copy());
158 }
159
hmat_tree_nodes_count(const hmat_cluster_tree_t * tree)160 int hmat_tree_nodes_count(const hmat_cluster_tree_t * tree)
161 {
162 return ((ClusterTree*)tree)->nodesCount();
163 }
164
hmat_cluster_get_son(hmat_cluster_tree_t * tree,int index)165 hmat_cluster_tree_t *hmat_cluster_get_son( hmat_cluster_tree_t * tree, int index )
166 {
167 ClusterTree *son = reinterpret_cast<ClusterTree*>(tree)->getChild(index);
168 return (hmat_cluster_tree_t*)son;
169 }
170
hmat_cluster_get_info(hmat_cluster_tree_t * tree,hmat_cluster_info_t * info)171 int hmat_cluster_get_info(hmat_cluster_tree_t *tree, hmat_cluster_info_t* info)
172 {
173 ClusterTree* cl = static_cast<ClusterTree*>((void*) tree);
174 info->spatial_dimension = cl->data.coordinates()->dimension();
175 info->dimension = cl->data.coordinates()->numberOfDof();
176 info->nr_tree_nodes = cl->nodesCount();
177 return 0;
178 }
179
hmat_cluster_get_indices(const hmat_cluster_tree_t * tree)180 const int * hmat_cluster_get_indices(const hmat_cluster_tree_t *tree) {
181 return reinterpret_cast<const ClusterTree*>(tree)->data.indices();
182 }
183
hmat_init_admissibility_param(hmat_admissibility_param_t * p)184 void hmat_init_admissibility_param(hmat_admissibility_param_t * p) {
185 p->eta = 2;
186 p->ratio = 0.0;
187 p->max_width = (size_t)-1L;
188 }
189
hmat_create_admissibility(hmat_admissibility_param_t * p)190 hmat_admissibility_t* hmat_create_admissibility(hmat_admissibility_param_t * p) {
191 hmat::StandardAdmissibilityCondition * r =
192 new hmat::StandardAdmissibilityCondition(p->eta, p->ratio);
193 r->setMaxWidth(p->max_width);
194 return reinterpret_cast<hmat_admissibility_t*>(r);
195 }
196
hmat_update_admissibility(hmat_admissibility_t * cond,hmat_admissibility_param_t * p)197 void hmat_update_admissibility(hmat_admissibility_t* cond, hmat_admissibility_param_t *p) {
198 hmat::AdmissibilityCondition * r = reinterpret_cast<AdmissibilityCondition*>(cond);
199 r->setRatio(p->ratio);
200 r->setMaxWidth(p->max_width);
201 }
202
hmat_create_admissibility_standard(double eta)203 hmat_admissibility_t* hmat_create_admissibility_standard(double eta)
204 {
205 return static_cast<hmat_admissibility_t*>((void*) new hmat::StandardAdmissibilityCondition(eta));
206 }
207
hmat_create_admissibility_always(size_t max_size,unsigned int min_block,int split_rows,int split_cols)208 hmat_admissibility_t* hmat_create_admissibility_always(
209 size_t max_size, unsigned int min_block, int split_rows, int split_cols) {
210 return reinterpret_cast<hmat_admissibility_t*>(
211 new hmat::AlwaysAdmissibilityCondition(max_size, min_block, split_rows, split_cols));
212 }
213
hmat_create_admissibility_never(size_t max_size,unsigned int min_block,int split_rows,int split_cols)214 hmat_admissibility_t* hmat_create_admissibility_never(
215 size_t max_size, unsigned int min_block, int split_rows, int split_cols) {
216 hmat::AlwaysAdmissibilityCondition * r = new hmat::AlwaysAdmissibilityCondition(
217 max_size, min_block, split_rows, split_cols);
218 r->never(true);
219 return reinterpret_cast<hmat_admissibility_t*>(r);
220 }
221
hmat_delete_admissibility(hmat_admissibility_t * cond)222 void hmat_delete_admissibility(hmat_admissibility_t * cond) {
223 delete static_cast<AdmissibilityCondition*>((void*)cond);
224 }
225
hmat_init_default_interface(hmat_interface_t * i,hmat_value_t type)226 void hmat_init_default_interface(hmat_interface_t * i, hmat_value_t type)
227 {
228 i->value_type = type;
229 switch (type) {
230 case HMAT_SIMPLE_PRECISION: createCInterface<S_t, DefaultEngine>(i); break;
231 case HMAT_DOUBLE_PRECISION: createCInterface<D_t, DefaultEngine>(i); break;
232 case HMAT_SIMPLE_COMPLEX: createCInterface<C_t, DefaultEngine>(i); break;
233 case HMAT_DOUBLE_COMPLEX: createCInterface<Z_t, DefaultEngine>(i); break;
234 default: HMAT_ASSERT(false);
235 }
236 }
237
hmat_get_parameters(hmat_settings_t * settings)238 void hmat_get_parameters(hmat_settings_t* settings)
239 {
240 HMatSettings& settingsCxx = HMatSettings::getInstance();
241 settings->compressionMinLeafSize = settingsCxx.compressionMinLeafSize;
242 settings->coarseningEpsilon = settingsCxx.coarseningEpsilon;
243 settings->maxLeafSize = settingsCxx.maxLeafSize;
244 settings->coarsening = settingsCxx.coarsening;
245 settings->validateNullRowCol = settingsCxx.validateNullRowCol;
246 settings->validateCompression = settingsCxx.validateCompression;
247 settings->validationErrorThreshold = settingsCxx.validationErrorThreshold;
248 settings->validationReRun = settingsCxx.validationReRun;
249 settings->dumpTrace = settingsCxx.dumpTrace;
250 settings->validationDump = settingsCxx.validationDump;
251 }
252
hmat_set_parameters(hmat_settings_t * settings)253 int hmat_set_parameters(hmat_settings_t* settings)
254 {
255 HMAT_ASSERT(settings != NULL);
256 int rc = 0;
257 HMatSettings& settingsCxx = HMatSettings::getInstance();
258 settingsCxx.compressionMinLeafSize = settings->compressionMinLeafSize;
259 settingsCxx.coarseningEpsilon = settings->coarseningEpsilon;
260 settingsCxx.maxLeafSize = settings->maxLeafSize;
261 settingsCxx.coarsening = settings->coarsening;
262 settingsCxx.validateNullRowCol = settings->validateNullRowCol;
263 settingsCxx.validateCompression = settings->validateCompression;
264 settingsCxx.validationErrorThreshold = settings->validationErrorThreshold;
265 settingsCxx.validationReRun = settings->validationReRun;
266 settingsCxx.dumpTrace = settings->dumpTrace;
267 settingsCxx.validationDump = settings->validationDump;
268 settingsCxx.setParameters();
269 return rc;
270 }
271
hmat_get_version()272 const char * hmat_get_version()
273 {
274 return HMAT_VERSION;
275 }
276
hmat_get_build_date(const char ** date,const char ** time)277 void hmat_get_build_date(const char **date, const char **time)
278 {
279 #ifdef HMAT_EXPORT_BUILD_DATE
280 *date=(const char*)&__DATE__;
281 *time=(const char*)&__TIME__;
282 #else
283 *date="N/A";
284 *time="N/A";
285 #endif
286 }
287
hmat_assemble_context_init(hmat_assemble_context_t * context)288 void hmat_assemble_context_init(hmat_assemble_context_t * context) {
289 context->compression = NULL;
290 context->assembly = NULL;
291 context->simple_compute = NULL;
292 context->block_compute = NULL;
293 context->advanced_compute = NULL;
294 context->user_context = NULL;
295 context->prepare = NULL;
296 context->lower_symmetric = 0;
297 context->factorization = hmat_factorization_none;
298 context->progress = DefaultProgress::getInstance();
299 }
300
hmat_factorization_context_init(hmat_factorization_context_t * context)301 void hmat_factorization_context_init(hmat_factorization_context_t *context) {
302 context->factorization = hmat_factorization_lu;
303 context->progress = DefaultProgress::getInstance();
304 }
305
hmat_delete_procedure(hmat_procedure_t * proc)306 void hmat_delete_procedure(hmat_procedure_t* proc) {
307 switch (proc->value_type) {
308 case HMAT_SIMPLE_PRECISION: delete static_cast<hmat::TreeProcedure<HMatrix<S_t> >*>(proc->internal); break;
309 case HMAT_DOUBLE_PRECISION: delete static_cast<hmat::TreeProcedure<HMatrix<D_t> >*>(proc->internal); break;
310 case HMAT_SIMPLE_COMPLEX: delete static_cast<hmat::TreeProcedure<HMatrix<C_t> >*>(proc->internal); break;
311 case HMAT_DOUBLE_COMPLEX: delete static_cast<hmat::TreeProcedure<HMatrix<Z_t> >*>(proc->internal); break;
312 default: HMAT_ASSERT(false);
313 }
314 delete proc;
315 }
316
hmat_delete_leaf_procedure(hmat_leaf_procedure_t * proc)317 void hmat_delete_leaf_procedure(hmat_leaf_procedure_t* proc) {
318 switch (proc->value_type) {
319 case HMAT_SIMPLE_PRECISION: delete static_cast<const hmat::LeafProcedure<HMatrix<S_t> >*>(proc->internal); break;
320 case HMAT_DOUBLE_PRECISION: delete static_cast<const hmat::LeafProcedure<HMatrix<D_t> >*>(proc->internal); break;
321 case HMAT_SIMPLE_COMPLEX: delete static_cast<const hmat::LeafProcedure<HMatrix<C_t> >*>(proc->internal); break;
322 case HMAT_DOUBLE_COMPLEX: delete static_cast<const hmat::LeafProcedure<HMatrix<Z_t> >*>(proc->internal); break;
323 default: HMAT_ASSERT(false);
324 }
325 delete proc;
326 }
327
hmat_create_compression_svd(double epsilon)328 hmat_compression_algorithm_t* hmat_create_compression_svd(double epsilon) {
329 return static_cast<hmat_compression_algorithm_t*>((void*) new hmat::CompressionSVD(epsilon));
330 }
331
hmat_create_compression_aca_full(double epsilon)332 hmat_compression_algorithm_t* hmat_create_compression_aca_full(double epsilon) {
333 return static_cast<hmat_compression_algorithm_t*>((void*) new hmat::CompressionAcaFull(epsilon));
334 }
335
hmat_create_compression_aca_partial(double epsilon)336 hmat_compression_algorithm_t* hmat_create_compression_aca_partial(double epsilon) {
337 return static_cast<hmat_compression_algorithm_t*>((void*) new hmat::CompressionAcaPartial(epsilon));
338 }
339
hmat_create_compression_aca_plus(double epsilon)340 hmat_compression_algorithm_t* hmat_create_compression_aca_plus(double epsilon) {
341 return static_cast<hmat_compression_algorithm_t*>((void*) new hmat::CompressionAcaPlus(epsilon));
342 }
343
hmat_create_compression_aca_random(double epsilon)344 hmat_compression_algorithm_t* hmat_create_compression_aca_random(double epsilon) {
345 return static_cast<hmat_compression_algorithm_t*>((void*) new hmat::CompressionAcaRandom(epsilon));
346 }
347
hmat_delete_compression(const hmat_compression_algorithm_t * algo)348 void hmat_delete_compression(const hmat_compression_algorithm_t* algo) {
349 delete static_cast<hmat::CompressionAlgorithm*>((void*)algo);
350 }
351
hmat_tracing_dump(char * filename)352 void hmat_tracing_dump(char *filename) {
353 tracing_dump(filename);
354 }
355
hmat_default_progress()356 hmat_progress_t * hmat_default_progress() {
357 return DefaultProgress::getInstance();
358 }
359
hmat_set_worker_index_function(int (* f)())360 void hmat_set_worker_index_function(int (*f)()) {
361 tracing_set_worker_index_func(f);
362 }
363