From 5b94910fc4c6a47856290e9c23f9a905cf63c1eb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Apr 2019 14:38:23 +0200 Subject: Add and use a new timer API. --- ell_grid_solve.c | 141 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 67 deletions(-) (limited to 'ell_grid_solve.c') 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); -- cgit v1.2.3