aboutsummaryrefslogtreecommitdiff
path: root/mg2d.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2019-04-17 14:38:23 +0200
committerAnton Khirnov <anton@khirnov.net>2019-04-19 17:11:40 +0200
commit5b94910fc4c6a47856290e9c23f9a905cf63c1eb (patch)
treee33245aef4e7885b801e1a2474c18e1ed9737518 /mg2d.c
parent8c35e7648cf7db413e1d2a9478edec797eac5df3 (diff)
Add and use a new timer API.
Diffstat (limited to 'mg2d.c')
-rw-r--r--mg2d.c144
1 files changed, 68 insertions, 76 deletions
diff --git a/mg2d.c b/mg2d.c
index a22a0a5..6639879 100644
--- a/mg2d.c
+++ b/mg2d.c
@@ -34,6 +34,7 @@
#include "mg2d_boundary_internal.h"
#include "mg2d_constants.h"
#include "ndarray.h"
+#include "timer.h"
#include "transfer.h"
typedef struct MG2DLevel {
@@ -52,11 +53,11 @@ typedef struct MG2DLevel {
/* timings */
int64_t count_cycles;
- int64_t time_solve;
- int64_t time_prolong;
- int64_t time_restrict;
- int64_t time_correct;
- int64_t time_reinit;
+ Timer timer_solve;
+ Timer timer_prolong;
+ Timer timer_restrict;
+ Timer timer_correct;
+ Timer timer_reinit;
} MG2DLevel;
struct MG2DInternal {
@@ -74,10 +75,8 @@ struct MG2DInternal {
int cpuflags;
- int64_t time_solve;
- int64_t count_solve;
- int64_t time_levels_init;
- int64_t count_levels_init;
+ Timer timer_solve;
+ Timer timer_levels_init;
};
static void log_callback(MG2DLogger *log, int level, const char *fmt, va_list vl)
@@ -113,16 +112,13 @@ static int coarse_correct_task(void *arg, unsigned int job_idx, unsigned int thr
static int mg_relax_step(MG2DContext *ctx, MG2DLevel *level, const char *step_desc)
{
double res_old;
- int64_t start;
int ret;
res_old = level->solver->residual_max;
- start = gettime();
-
+ mg2di_timer_start(&level->timer_solve);
ret = mg2di_egs_solve(level->solver);
-
- level->time_solve += gettime() - start;
+ mg2di_timer_stop(&level->timer_solve);
if (ret < 0)
return ret;
@@ -140,7 +136,7 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level)
/* on the refined levels, use zero as the initial guess for the
* solution (correction for the upper level) */
if (level->depth > 0) {
- int64_t start = gettime();
+ mg2di_timer_start(&level->timer_reinit);
memset(level->solver->u->data, 0, sizeof(*level->solver->u->data) * level->solver->u->stride[0] *
level->solver->domain_size[1]);
@@ -149,9 +145,8 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level)
ret = mg2di_egs_init(level->solver, level->egs_init_flags);
if (ret < 0)
return ret;
+ mg2di_timer_stop(&level->timer_reinit);
level->egs_init_flags |= EGS_INIT_FLAG_SAME_DIFF_COEFFS;
-
- level->time_reinit += gettime() - start;
}
res_old = level->solver->residual_max;
@@ -168,7 +163,6 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level)
for (int i = 0; i < ctx->nb_cycles; i++) {
double res_prev;
- int64_t start;
/* pre-restrict relaxation */
for (int j = 0; j < ctx->nb_relax_pre; j++) {
@@ -178,12 +172,12 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level)
}
/* restrict the residual as to the coarser-level rhs */
- start = gettime();
+ mg2di_timer_start(&level->timer_restrict);
ret = mg2di_gt_transfer(level->transfer_restrict, level->child->solver->rhs,
level->solver->residual);
+ mg2di_timer_stop(&level->timer_restrict);
if (ret < 0)
return ret;
- level->time_restrict += gettime() - start;
/* solve on the coarser level */
ret = mg_solve_subgrid(ctx, level->child);
@@ -191,27 +185,25 @@ static int mg_solve_subgrid(MG2DContext *ctx, MG2DLevel *level)
return ret;
/* prolongate the coarser-level correction */
- start = gettime();
+ mg2di_timer_start(&level->timer_prolong);
ret = mg2di_gt_transfer(level->transfer_prolong, level->prolong_tmp,
level->child->solver->u);
+ mg2di_timer_stop(&level->timer_prolong);
if (ret < 0)
return ret;
- level->time_prolong += gettime() - start;
/* apply the correction */
- start = gettime();
-
+ mg2di_timer_start(&level->timer_correct);
tp_execute(ctx->priv->tp, level->solver->domain_size[1], coarse_correct_task, level);
-
- level->time_correct += gettime() - start;
+ mg2di_timer_stop(&level->timer_correct);
/* re-init the current-level solver (re-calc the residual) */
res_prev = level->solver->residual_max;
- start = gettime();
+ mg2di_timer_start(&level->timer_reinit);
ret = mg2di_egs_init(level->solver, 0);
+ mg2di_timer_stop(&level->timer_reinit);
if (ret < 0)
return ret;
- level->time_reinit += gettime() - start;
log_relax_step(ctx, level, "correct", res_prev, level->solver->residual_max);
@@ -488,7 +480,6 @@ int mg2d_solve(MG2DContext *ctx)
MG2DInternal *priv = ctx->priv;
MG2DLevel *root;
EGSContext *s_root;
- int64_t time_start, start;
double res_orig, res_prev, res_cur;
int ret;
@@ -507,24 +498,19 @@ int mg2d_solve(MG2DContext *ctx)
root = priv->root;
s_root = root->solver;
- time_start = gettime();
-
- start = gettime();
+ mg2di_timer_start(&priv->timer_solve);
+ mg2di_timer_start(&priv->timer_levels_init);
ret = mg_levels_init(ctx);
+ mg2di_timer_stop(&priv->timer_levels_init);
if (ret < 0)
- return ret;
-
- priv->time_levels_init += gettime() - start;
- priv->count_levels_init++;
-
- start = gettime();
+ goto finish;
+ mg2di_timer_start(&root->timer_reinit);
ret = mg2di_egs_init(s_root, 0);
+ mg2di_timer_stop(&root->timer_reinit);
if (ret < 0)
- return ret;
-
- root->time_reinit += gettime() - start;
+ goto finish;
res_orig = s_root->residual_max;
res_prev = res_orig;
@@ -542,10 +528,7 @@ int mg2d_solve(MG2DContext *ctx)
//mg2di_ndarray_copy(priv->u, s_root->u);
- priv->time_solve += gettime() - time_start;
- priv->count_solve++;
-
- return 0;
+ goto finish;
}
mg2di_log(&priv->logger, MG2D_LOG_VERBOSE,
@@ -564,6 +547,8 @@ int mg2d_solve(MG2DContext *ctx)
"Maximum number of iterations (%d) reached\n", ctx->maxiter);
fail:
mg2di_log(&priv->logger, MG2D_LOG_ERROR, "The solver failed to converge\n");
+finish:
+ mg2di_timer_stop(&priv->timer_solve);
return ret;
}
@@ -607,6 +592,12 @@ static MG2DLevel *mg_level_alloc(enum EGSType type, const size_t domain_size)
if (!level->solver)
goto fail;
+ mg2di_timer_init(&level->timer_solve);
+ mg2di_timer_init(&level->timer_prolong);
+ mg2di_timer_init(&level->timer_restrict);
+ mg2di_timer_init(&level->timer_correct);
+ mg2di_timer_init(&level->timer_reinit);
+
return level;
fail:
mg_level_free(&level);
@@ -738,6 +729,9 @@ MG2DContext *mg2d_solver_alloc(size_t domain_size)
ctx->log_level = MG2D_LOG_INFO;
ctx->nb_threads = 1;
+ mg2di_timer_init(&priv->timer_levels_init);
+ mg2di_timer_init(&priv->timer_solve);
+
return ctx;
fail:
mg2d_solver_free(&ctx);
@@ -788,8 +782,8 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix)
prefix = "";
mg2di_log(&priv->logger, MG2D_LOG_VERBOSE, "%s%ld solves; %g s total time; %g ms avg per call; %g avg cycles per solve\n",
- prefix, priv->count_solve, priv->time_solve / 1e6, priv->time_solve / 1e3 / priv->count_solve,
- (double)level->count_cycles / priv->count_solve);
+ prefix, priv->timer_solve.nb_runs, priv->timer_solve.time_nsec / 1e9, priv->timer_solve.time_nsec / 1e6 / priv->timer_solve.nb_runs,
+ (double)level->count_cycles / priv->timer_solve.nb_runs);
while (level) {
char buf[1024], *p;
@@ -798,70 +792,68 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix)
EGSRelaxContext *r = NULL;
EGSExactContext *e = NULL;
- int64_t level_total = level->time_solve + level->time_prolong + level->time_restrict +
- level->time_correct + level->time_reinit;
+ int64_t level_total = level->timer_solve.time_nsec + level->timer_prolong.time_nsec + level->timer_restrict.time_nsec +
+ level->timer_correct.time_nsec + level->timer_reinit.time_nsec;
if (level->solver->solver_type == EGS_SOLVER_RELAXATION)
r = level->solver->solver_data;
else if (level->solver->solver_type == EGS_SOLVER_EXACT)
e = level->solver->solver_data;
- level_total = level->time_solve + level->time_prolong + level->time_restrict +
- level->time_correct + level->time_reinit;
-
levels_total += level_total;
p = buf;
ret = snprintf(p, sizeof(buf) - (p - buf),
"%2.2f%% level %d: %ld cycles %g s total time %g ms avg per call",
- level_total * 100.0 / priv->time_solve, level->depth, level->count_cycles,
- level_total / 1e6, level_total / 1e3 / level->count_cycles);
+ level_total * 100.0 / priv->timer_solve.time_nsec, level->depth, level->count_cycles,
+ level_total / 1e9, level_total / 1e6 / level->count_cycles);
if (ret > 0)
p += ret;
ret = snprintf(p, sizeof(buf) - (p - buf),
"||%2.2f%% solve %2.2f%% reinit ",
- level->time_solve * 100.0 / level_total,
- level->time_reinit * 100.0 / level_total);
+ level->timer_solve.time_nsec * 100.0 / level_total,
+ level->timer_reinit.time_nsec * 100.0 / level_total);
if (ret > 0)
p += ret;
if (level->child) {
ret = snprintf(p, sizeof(buf) - (p - buf),
"%2.2f%% prolong %2.2f%% restrict %2.2f%% correct",
- level->time_prolong * 100.0 / level_total,
- level->time_restrict * 100.0 / level_total,
- level->time_correct * 100.0 / level_total);
+ level->timer_prolong.time_nsec * 100.0 / level_total,
+ level->timer_restrict.time_nsec * 100.0 / level_total,
+ level->timer_correct.time_nsec * 100.0 / level_total);
if (ret > 0)
p += ret;
}
ret = snprintf(p, sizeof(buf) - (p - buf),
"||%2.2f%% init %2.2f%% residual %2.2f%% boundaries (%2.2f%% fixval %2.2f%% reflect %2.2f%% falloff %2.2f%% corners)",
- level->solver->time_init * 100.0 / level->solver->time_total,
- level->solver->time_res_calc * 100.0 / level->solver->time_total,
- level->solver->time_boundaries * 100.0 / level->solver->time_total,
- level->solver->time_bnd_fixval * 100.0 / level->solver->time_total,
- level->solver->time_bnd_reflect * 100.0 / level->solver->time_total,
- level->solver->time_bnd_falloff * 100.0 / level->solver->time_total,
- level->solver->time_bnd_corners * 100.0 / level->solver->time_total);
+ level->solver->timer_init.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_res_calc.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_bnd.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_bnd_fixval.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_bnd_reflect.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_bnd_falloff.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ level->solver->timer_bnd_corners.time_nsec * 100.0 / level->solver->timer_solve.time_nsec);
if (ret > 0)
p += ret;
if (r) {
ret = snprintf(p, sizeof(buf) - (p - buf),
" %2.2f%% correct",
- r->time_correct * 100.0 / level->solver->time_total);
+ r->timer_correct.time_nsec * 100.0 / level->solver->timer_solve.time_nsec);
if (ret > 0)
p += ret;
} else if (e) {
ret = snprintf(p, sizeof(buf) - (p - buf),
" %2.2f%% const %2.2f%% bicgstab (%ld; %g it/slv) %2.2f%% lu (%ld) %2.2f%% export",
- e->time_mat_construct * 100.0 / level->solver->time_total,
- e->time_bicgstab_solve * 100.0 / level->solver->time_total, e->count_bicgstab_solve, (double)e->bicgstab_iterations / e->count_bicgstab_solve,
- e->time_lu_solve * 100.0 / level->solver->time_total, e->count_lu_solve,
- e->time_export * 100.0 / level->solver->time_total);
+ e->timer_mat_construct.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ e->timer_bicgstab.time_nsec * 100.0 / level->solver->timer_solve.time_nsec,
+ e->timer_bicgstab.nb_runs, (double)e->bicgstab_iterations / e->timer_bicgstab.nb_runs,
+ e->timer_lu_solve.time_nsec * 100.0 / level->solver->timer_solve.time_nsec, e->timer_lu_solve.nb_runs,
+ e->timer_export.time_nsec * 100.0 / level->solver->timer_solve.time_nsec);
if (ret > 0)
p += ret;
}
@@ -872,14 +864,14 @@ void mg2d_print_stats(MG2DContext *ctx, const char *prefix)
mg2di_log(&priv->logger, MG2D_LOG_VERBOSE,
"%s%2.2f%% levels init %g s total time %g ms avg per call\n",
- prefix, priv->time_levels_init * 100.0 / priv->time_solve,
- priv->time_levels_init / 1e6, priv->time_levels_init / 1e3 / priv->count_levels_init);
+ prefix, priv->timer_levels_init.time_nsec * 100.0 / priv->timer_solve.time_nsec,
+ priv->timer_levels_init.time_nsec / 1e9, priv->timer_levels_init.time_nsec / 1e6 / priv->timer_levels_init.nb_runs);
- other = priv->time_solve - levels_total - priv->time_levels_init;
+ other = priv->timer_solve.time_nsec - levels_total - priv->timer_levels_init.time_nsec;
mg2di_log(&priv->logger, MG2D_LOG_VERBOSE,
"%s%2.2f%% other %g s total time %g ms avg per call\n",
- prefix, other * 100.0 / priv->time_solve,
- other / 1e6, other / 1e3 / priv->count_solve);
+ prefix, other * 100.0 / priv->timer_solve.time_nsec,
+ other / 1e9, other / 1e6 / priv->timer_solve.nb_runs);
}