aboutsummaryrefslogtreecommitdiff
path: root/ell_grid_solve.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 /ell_grid_solve.c
parent8c35e7648cf7db413e1d2a9478edec797eac5df3 (diff)
Add and use a new timer API.
Diffstat (limited to 'ell_grid_solve.c')
-rw-r--r--ell_grid_solve.c141
1 files changed, 74 insertions, 67 deletions
diff --git a/ell_grid_solve.c b/ell_grid_solve.c
index e792b47..a01f124 100644
--- a/ell_grid_solve.c
+++ b/ell_grid_solve.c
@@ -37,6 +37,7 @@
#include "mg2d_constants.h"
#include "ndarray.h"
#include "residual_calc.h"
+#include "timer.h"
static const double relax_factors[FD_STENCIL_MAX] = {
[0] = 1.0 / 5,
@@ -118,9 +119,8 @@ static void residual_calc(EGSContext *ctx)
{
EGSInternal *priv = ctx->priv;
const double *diff_coeffs[MG2D_DIFF_COEFF_NB];
- int64_t start;
- start = gettime();
+ mg2di_timer_start(&ctx->timer_res_calc);
for (int i = 0; i < ARRAY_ELEMS(diff_coeffs); i++)
diff_coeffs[i] = NDPTR2D(ctx->diff_coeffs[i], priv->residual_calc_offset[1], priv->residual_calc_offset[0]);
@@ -134,8 +134,7 @@ static void residual_calc(EGSContext *ctx)
ctx->rhs->stride[0],
diff_coeffs, ctx->diff_coeffs[0]->stride[0], priv->fd_factors);
- ctx->time_res_calc += gettime() - start;
- ctx->count_res++;
+ mg2di_timer_stop(&ctx->timer_res_calc);
}
static void boundaries_apply_fixval(double *dst, const ptrdiff_t dst_stride[2],
@@ -200,9 +199,9 @@ static void boundaries_apply(EGSContext *ctx, int init)
static const enum MG2DBCType bnd_type_order[] = { MG2D_BC_TYPE_FIXVAL, MG2D_BC_TYPE_REFLECT, MG2D_BC_TYPE_FALLOFF };
EGSInternal *priv = ctx->priv;
const ptrdiff_t strides[2] = { 1, ctx->u->stride[0] };
- int64_t start, start_bnd;
- start = gettime();
+ mg2di_timer_start(&ctx->timer_bnd);
+
for (int order_idx = 0; order_idx < ARRAY_ELEMS(bnd_type_order); order_idx++) {
for (int i = 0; i < ARRAY_ELEMS(ctx->boundaries); i++) {
MG2DBoundary *bnd = ctx->boundaries[i];
@@ -222,31 +221,28 @@ static void boundaries_apply(EGSContext *ctx, int init)
switch (bnd->type) {
case MG2D_BC_TYPE_FIXVAL:
if (init && !priv->bnd_zero[i]) {
- start_bnd = gettime();
+ mg2di_timer_start(&ctx->timer_bnd_fixval);
boundaries_apply_fixval(dst, dst_strides, bnd->val,
bnd->val_stride, size_boundary);
- ctx->time_bnd_fixval += gettime() - start_bnd;
- ctx->count_bnd_fixval++;
+ mg2di_timer_stop(&ctx->timer_bnd_fixval);
}
break;
case MG2D_BC_TYPE_REFLECT:
- start_bnd = gettime();
+ mg2di_timer_start(&ctx->timer_bnd_reflect);
boundaries_apply_reflect(dst, dst_strides, size_boundary);
- ctx->time_bnd_reflect += gettime() - start_bnd;
- ctx->count_bnd_reflect++;
+ mg2di_timer_stop(&ctx->timer_bnd_reflect);
break;
case MG2D_BC_TYPE_FALLOFF:
- start_bnd = gettime();
+ mg2di_timer_start(&ctx->timer_bnd_falloff);
boundaries_apply_falloff(dst, dst_strides, size_boundary, ctx);
- ctx->time_bnd_falloff += gettime() - start_bnd;
- ctx->count_bnd_falloff++;
+ mg2di_timer_stop(&ctx->timer_bnd_falloff);
break;
}
}
}
/* fill in the corner ghosts */
- start_bnd = gettime();
+ mg2di_timer_start(&ctx->timer_bnd_corners);
for (int pos_y = 0; pos_y < 2; pos_y++) {
enum MG2DBoundaryLoc loc_y = mg2d_bnd_id(1, pos_y);
MG2DBoundary *bnd_y = ctx->boundaries[loc_y];
@@ -277,11 +273,8 @@ static void boundaries_apply(EGSContext *ctx, int init)
}
}
}
- ctx->time_bnd_corners += gettime() - start_bnd;
- ctx->count_bnd_corners++;
-
- ctx->time_boundaries += gettime() - start;
- ctx->count_boundaries++;
+ mg2di_timer_stop(&ctx->timer_bnd_corners);
+ mg2di_timer_stop(&ctx->timer_bnd);
}
#if HAVE_EXTERNAL_ASM
@@ -316,14 +309,11 @@ static int residual_add_task(void *arg, unsigned int job_idx, unsigned int threa
static int solve_relax_step(EGSContext *ctx)
{
EGSRelaxContext *r = ctx->solver_data;
- int64_t start;
- start = gettime();
+ mg2di_timer_start(&r->timer_correct);
tp_execute(ctx->tp, ctx->domain_size[1], residual_add_task, ctx);
-
- r->time_correct += gettime() - start;
- r->count_correct++;
+ mg2di_timer_stop(&r->timer_correct);
boundaries_apply(ctx, 0);
residual_calc(ctx);
@@ -583,10 +573,9 @@ static int solve_exact(EGSContext *ctx)
EGSInternal *priv = ctx->priv;
EGSExactContext *ec = ctx->solver_data;
EGSExactInternal *e = &priv->e;
- int64_t start;
int ret;
- start = gettime();
+ mg2di_timer_start(&ec->timer_mat_construct);
if (!e->mat_filled) {
memset(e->mat, 0, SQR(e->N) * sizeof(*e->mat));
@@ -602,29 +591,27 @@ static int solve_exact(EGSContext *ctx)
e->rhs[mat_row_idx] = e->rhs_factor[mat_row_idx] * (*NDPTR2D(ctx->rhs, idx0, idx1)) + e->rhs_mat[mat_row_idx];
}
- ec->time_mat_construct += gettime() - start;
- ec->count_mat_construct++;
-
- start = gettime();
+ mg2di_timer_stop(&ec->timer_mat_construct);
+ mg2di_timer_start(&ec->timer_bicgstab);
ret = mg2di_bicgstab_solve(e->bicgstab, e->mat, e->rhs, e->x);
if (ret >= 0)
ec->bicgstab_iterations += ret;
- ec->time_bicgstab_solve += gettime() - start;
- ec->count_bicgstab_solve++;
+ mg2di_timer_stop(&ec->timer_bicgstab);
if (ret < 0) {
char equed = 'N';
double cond, ferr, berr, rpivot;
- start = gettime();
+ mg2di_timer_start(&ec->timer_lu_solve);
ret = LAPACKE_dgesvx(LAPACK_COL_MAJOR, 'N', 'N', e->N, 1,
e->mat, e->N, e->mat_f, e->N, e->ipiv, &equed, NULL, NULL,
e->rhs, e->N, e->x, e->N, &cond, &ferr, &berr, &rpivot);
if (ret == 0)
ret = LAPACKE_dgetri(LAPACK_COL_MAJOR, e->N, e->mat_f, e->N, e->ipiv);
+ mg2di_timer_stop(&ec->timer_lu_solve);
if (ret != 0) {
mg2di_log(&ctx->logger, MG2D_LOG_ERROR,
"Error solving the linear system: %d\n", ret);
@@ -635,21 +622,17 @@ static int solve_exact(EGSContext *ctx)
"condition number %16.16g; forward error %16.16g backward error %16.16g\n",
e->N, e->N, cond, ferr, berr);
- ec->time_lu_solve += gettime() - start;
- ec->count_lu_solve++;
-
ret = mg2di_bicgstab_init(e->bicgstab, e->mat_f, e->x);
if (ret < 0)
return ret;
}
- start = gettime();
+ mg2di_timer_start(&ec->timer_export);
for (size_t idx1 = 0; idx1 < ctx->domain_size[1]; idx1++)
memcpy(ctx->u->data + idx1 * ctx->u->stride[0], e->x + idx1 * ctx->domain_size[0], ctx->domain_size[0] * sizeof(*e->x));
- ec->time_export += gettime() - start;
- ec->count_export++;
+ mg2di_timer_stop(&ec->timer_export);
boundaries_apply(ctx, 0);
residual_calc(ctx);
@@ -659,10 +642,9 @@ static int solve_exact(EGSContext *ctx)
int mg2di_egs_solve(EGSContext *ctx)
{
- int64_t start;
int ret;
- start = gettime();
+ mg2di_timer_start(&ctx->timer_solve);
switch (ctx->solver_type) {
case EGS_SOLVER_RELAXATION: ret = solve_relax_step(ctx); break;
@@ -670,7 +652,7 @@ int mg2di_egs_solve(EGSContext *ctx)
default: ret = -EINVAL;
}
- ctx->time_total += gettime() - start;
+ mg2di_timer_stop(&ctx->timer_solve);
return ret;
}
@@ -678,16 +660,15 @@ int mg2di_egs_solve(EGSContext *ctx)
int mg2di_egs_init(EGSContext *ctx, int flags)
{
EGSInternal *priv = ctx->priv;
- int64_t start, start_init;
- int ret;
-
- start = gettime();
+ int ret = 0;
- start_init = gettime();
+ mg2di_timer_start(&ctx->timer_solve);
+ mg2di_timer_start(&ctx->timer_init);
if (ctx->step[0] <= DBL_EPSILON || ctx->step[1] <= DBL_EPSILON) {
mg2di_log(&ctx->logger, 0, "Spatial step size too small\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto finish;
}
if (ctx->solver_type == EGS_SOLVER_RELAXATION) {
@@ -718,7 +699,7 @@ int mg2di_egs_init(EGSContext *ctx, int flags)
if (!ctx->tp) {
ret = tp_init(&priv->tp_internal, 1);
if (ret < 0)
- return ret;
+ goto finish;
ctx->tp = priv->tp_internal;
}
@@ -735,7 +716,8 @@ int mg2di_egs_init(EGSContext *ctx, int flags)
default:
mg2di_log(&ctx->logger, 0, "Invalid finite difference stencil: %zd\n",
ctx->fd_stencil);
- return -EINVAL;
+ ret = -EINVAL;
+ goto finish;
}
if (e->scratch_lines_allocated < nb_threads) {
@@ -745,8 +727,10 @@ int mg2di_egs_init(EGSContext *ctx, int flags)
e->scratch_lines = calloc(e->N_ghosts * nb_threads,
sizeof(*e->scratch_lines));
- if (!e->scratch_lines)
- return -ENOMEM;
+ if (!e->scratch_lines) {
+ ret = -ENOMEM;
+ goto finish;
+ }
e->scratch_lines_allocated = nb_threads;
}
}
@@ -782,17 +766,19 @@ int mg2di_egs_init(EGSContext *ctx, int flags)
ret = mg2di_residual_calc_init(priv->rescalc);
if (ret < 0)
- return ret;
+ goto finish;
- ctx->time_init += gettime() - start_init;
- ctx->count_init++;
+finish:
+ mg2di_timer_stop(&ctx->timer_init);
- boundaries_apply(ctx, 1);
- residual_calc(ctx);
+ if (ret >= 0) {
+ boundaries_apply(ctx, 1);
+ residual_calc(ctx);
+ }
- ctx->time_total += gettime() - start;
+ mg2di_timer_stop(&ctx->timer_solve);
- return 0;
+ return ret;
}
static int arrays_alloc(EGSContext *ctx, const size_t domain_size[2])
@@ -902,16 +888,28 @@ EGSContext *mg2di_egs_alloc(enum EGSType type, size_t domain_size[2])
goto fail;
switch (type) {
- case EGS_SOLVER_RELAXATION:
- ctx->solver_data = calloc(1, sizeof(EGSRelaxContext));
- if (!ctx->solver_data)
+ case EGS_SOLVER_RELAXATION: {
+ EGSRelaxContext *r;
+ r = calloc(1, sizeof(EGSRelaxContext));
+ if (!r)
goto fail;
+ ctx->solver_data = r;
+ mg2di_timer_init(&r->timer_correct);
break;
- case EGS_SOLVER_EXACT:
- ctx->solver_data = calloc(1, sizeof(EGSExactContext));
- if (!ctx->solver_data)
+ }
+ case EGS_SOLVER_EXACT: {
+ EGSExactContext *e;
+ e = calloc(1, sizeof(EGSExactContext));
+ if (!e)
goto fail;
+ ctx->solver_data = e;
+
+ mg2di_timer_init(&e->timer_mat_construct);
+ mg2di_timer_init(&e->timer_bicgstab);
+ mg2di_timer_init(&e->timer_lu_solve);
+ mg2di_timer_init(&e->timer_export);
break;
+ }
default: goto fail;
}
ctx->solver_type = type;
@@ -931,6 +929,15 @@ EGSContext *mg2di_egs_alloc(enum EGSType type, size_t domain_size[2])
if (!ctx->priv->rescalc)
goto fail;
+ mg2di_timer_init(&ctx->timer_bnd);
+ mg2di_timer_init(&ctx->timer_bnd_fixval);
+ mg2di_timer_init(&ctx->timer_bnd_falloff);
+ mg2di_timer_init(&ctx->timer_bnd_reflect);
+ mg2di_timer_init(&ctx->timer_bnd_corners);
+ mg2di_timer_init(&ctx->timer_res_calc);
+ mg2di_timer_init(&ctx->timer_init);
+ mg2di_timer_init(&ctx->timer_solve);
+
return ctx;
fail:
mg2di_egs_free(&ctx);