/* Included only by the instrumented private copy of cvode_solver.c. * Public SUN solver ops wrap the unchanged implementations from the same * CVODE library. No private CVODE layouts or substituted numerical kernels. */ #include static int (*original_lu)(SUNLinearSolver,SUNMatrix); static int (*original_solve)(SUNLinearSolver,SUNMatrix,N_Vector,N_Vector,sunrealtype); static int (*original_newton)(SUNNonlinearSolver,N_Vector,N_Vector,N_Vector,sunrealtype,sunbooleantype,void *); static SUNErrCode (*original_setsys)(SUNNonlinearSolver,SUNNonlinSolSysFn); static SUNErrCode (*original_setsetup)(SUNNonlinearSolver,SUNNonlinSolLSetupFn); static SUNNonlinSolSysFn original_residual; static SUNNonlinSolLSetupFn original_setup; static int profiled_lu(SUNLinearSolver ls,SUNMatrix a) { PROFILE_SCOPE(P_LU); int flag=original_lu(ls,a);if(flag)profile_add(C_LU_FAILURES,0,1);return flag; } static int profiled_solve(SUNLinearSolver ls,SUNMatrix a,N_Vector x,N_Vector b,sunrealtype tol) { PROFILE_SCOPE(P_LSOLVE); int flag=original_solve(ls,a,x,b,tol);if(flag)profile_add(C_SOLVE_FAILURES,0,1);return flag; } static int profiled_residual(N_Vector y,N_Vector f,void *mem) { PROFILE_SCOPE(P_RESIDUAL);return original_residual(y,f,mem); } static int profiled_setup(sunbooleantype bad,sunbooleantype *current,void *mem) { PROFILE_SCOPE(P_LSETUP); long int before=0,after=0; int first=CVodeGetNumJacEvals(mem,&before); int flag=original_setup(bad,current,mem); int last=CVodeGetNumJacEvals(mem,&after); /* Count successful linear setups which actually reused the stored J. This is unrelated to scalar/kernel memoization inside a fresh J. */ if(flag)profile_add(C_SETUP_FAILURES,0,1); else profile_add(after==before?C_JAC_REUSES:C_JAC_REFRESHES,first||last,1); return flag; } static SUNErrCode profiled_setsys(SUNNonlinearSolver nls,SUNNonlinSolSysFn fn) { original_residual=fn;return original_setsys(nls,fn?profiled_residual:NULL); } static SUNErrCode profiled_setsetup(SUNNonlinearSolver nls,SUNNonlinSolLSetupFn fn) { original_setup=fn;return original_setsetup(nls,fn?profiled_setup:NULL); } static int profiled_newton(SUNNonlinearSolver nls,N_Vector y0,N_Vector y,N_Vector w, sunrealtype tol,sunbooleantype setup,void *mem) { PROFILE_SCOPE(P_NEWTON);return original_newton(nls,y0,y,w,tol,setup,mem); } static SUNNonlinearSolver profile_attach_newton(N_Vector y,SUNContext ctx) { SUNNonlinearSolver nls=SUNNonlinSol_Newton(y,ctx); if(!nls)return NULL; original_newton=nls->ops->solve;original_setsys=nls->ops->setsysfn;original_setsetup=nls->ops->setlsetupfn; nls->ops->solve=profiled_newton;nls->ops->setsysfn=profiled_setsys;nls->ops->setlsetupfn=profiled_setsetup; return nls; } static int profiled_cvode(void *solver,sunrealtype end,N_Vector y,sunrealtype *next,int task) { PROFILE_SCOPE(P_CVODE);return CVode(solver,end,y,next,task); }