From 8a139859d22012436be404388fd611fb6126bc7f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 11 Mar 2019 09:58:15 +0100 Subject: mg2d: make the refinement depth/exact solve size configurable API bump --- libmg2d.v | 2 +- mg2d.c | 27 +++++++++++++++++---------- mg2d.h | 12 ++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/libmg2d.v b/libmg2d.v index c01a69f..3e4fb25 100644 --- a/libmg2d.v +++ b/libmg2d.v @@ -1,4 +1,4 @@ -LIBMG2D_10 { +LIBMG2D_11 { global: mg2d_*; local: *; }; diff --git a/mg2d.c b/mg2d.c index 8c9a15b..a6c6f5d 100644 --- a/mg2d.c +++ b/mg2d.c @@ -34,8 +34,6 @@ #include "mg2d_boundary_internal.h" #include "mg2d_constants.h" -#define LEVELS_MAX 16 - typedef struct MG2DLevel { unsigned int depth; @@ -523,21 +521,32 @@ static int threadpool_init(MG2DContext *ctx) return 0; } +static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size); + int mg2d_solve(MG2DContext *ctx) { MG2DInternal *priv = ctx->priv; - MG2DLevel *root = priv->root; - EGSContext *s_root = root->solver; + MG2DLevel *root; + EGSContext *s_root; int64_t time_start; double res_orig, res_prev, res_cur; int ret; + if (!priv->root) { + ret = mg_levels_alloc(ctx, ctx->domain_size); + if (ret < 0) + return ret; + } + if (!priv->tp) { ret = threadpool_init(ctx); if (ret < 0) return ret; } + root = priv->root; + s_root = root->solver; + time_start = gettime(); ret = mg_levels_init(ctx); @@ -648,7 +657,7 @@ static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size) dst = &priv->root; next_size = domain_size; - for (int depth = 0; depth < LEVELS_MAX; depth++) { + for (int depth = 0; depth < ctx->max_levels; depth++) { enum EGSType cur_type; size_t cur_size = next_size; @@ -662,7 +671,7 @@ static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size) } else next_size = (cur_size >> 1) + 1; - cur_type = (depth == LEVELS_MAX - 1 || cur_size < 9) ? EGS_SOLVER_EXACT : EGS_SOLVER_RELAXATION; + cur_type = (cur_size <= ctx->max_exact_size) ? EGS_SOLVER_EXACT : EGS_SOLVER_RELAXATION; *dst = mg_level_alloc(cur_type, cur_size); if (!*dst) @@ -735,12 +744,10 @@ MG2DContext *mg2d_solver_alloc(size_t domain_size) } ctx->diff_coeffs_stride = domain_size; - ret = mg_levels_alloc(ctx, domain_size); - if (ret < 0) - goto fail; - ctx->domain_size = domain_size; + ctx->max_levels = 16; + ctx->max_exact_size = 5; ctx->maxiter = 16; ctx->tol = 1e-12; ctx->nb_cycles = 1; diff --git a/mg2d.h b/mg2d.h index 234d8cf..6452526 100644 --- a/mg2d.h +++ b/mg2d.h @@ -148,6 +148,18 @@ typedef struct MG2DContext { * effect when log_callback is overridden. */ enum MG2DLogLevel log_level; + + /** + * Maximum number of refinement levels. May only be modified by the caller + * before the first call to mg2d_solve(). + */ + unsigned int max_levels; + + /** + * Maximum size (along one dimensions) of a refinement level on which an + * exact solve is performed. + */ + size_t max_exact_size; } MG2DContext; /** -- cgit v1.2.3