Skip to content
Failed

Console Output

Started by an SCM change
Obtained jenkins_tests/clubb_release_diff_test/Jenkinsfile from git https://github.com/larson-group/clubb.git
[Pipeline] Start of Pipeline
[Pipeline] node
Still waiting to schedule task
‘condella’ is offline
‘malan’ is offline
‘overlie’ is offline
Running on Jenkins in /home/jenkins/workspace/clubb_release_diff_test
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
The recommended git tool is: git
Cloning the remote Git repository
Cloning repository https://github.com/larson-group/clubb.git
 > git init /home/jenkins/workspace/clubb_release_diff_test # timeout=10
Fetching upstream changes from https://github.com/larson-group/clubb.git
 > git --version # timeout=10
 > git --version # 'git version 2.34.1'
using GIT_ASKPASS to set credentials larsongroupsysadmin github token
 > git fetch --tags --force --progress -- https://github.com/larson-group/clubb.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url https://github.com/larson-group/clubb.git # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
Avoid second fetch
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
Checking out Revision d2415bd01044655b03328e22070af55f99511a59 (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f d2415bd01044655b03328e22070af55f99511a59 # timeout=10
Commit message: "Clubb timer upgrade (#1328)"
 > git rev-list --no-walk be5e217cd91196f514fb60f9668106e072c14c1b # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Checkout Clubb and Clubb_Release)
[Pipeline] sh
+ git clone https://github.com/larson-group/clubb.git
Cloning into 'clubb'...
+ git clone https://github.com/larson-group/clubb_release.git
Cloning into 'clubb_release'...
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Diff)
[Pipeline] sh
+ diff --exclude=.git --exclude=version_clubb_core.txt --exclude=version_silhs.txt -r clubb clubb_release
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/clubb_python_api/CMakeLists.txt clubb_release/clubb_python_api/CMakeLists.txt
44,45d43
< get_filename_component(F2PY_PYTHON_BIN_DIR "${F2PY_PYTHON_EXECUTABLE}" DIRECTORY)
< 
103d100
<     "PATH=${F2PY_PYTHON_BIN_DIR}:$ENV{PATH}"
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/clubb_python_api/run_pytests.sh clubb_release/clubb_python_api/run_pytests.sh
34,35c34,35
< if ! compgen -G "$F2PY_DIR/libclubb_f2py_backend.*" > /dev/null; then
<   echo "libclubb_f2py_backend library not found in: $F2PY_DIR" >&2
---
> if [[ ! -f "$F2PY_DIR/libclubb_f2py_backend.so" ]]; then
>   echo "libclubb_f2py_backend.so not found in: $F2PY_DIR" >&2
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/cmake/deps/GPTLDependency.cmake clubb_release/cmake/deps/GPTLDependency.cmake
131,133c131,133
<     # Remove stale objects when configure flags change, then drop problematic instrumentation and build.
<     make clean || true &&
<     find . -name Makefile | xargs perl -pi -e 's/-finstrument-functions//g' &&
---
>     find . -name Makefile -exec sed -i.bak 's/-finstrument-functions//g' {} + &&
>     find . -name '*.bak' -delete &&
>     (make clean >/dev/null 2>&1 || true) &&
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/cmake/toolchains/linux_x86_64_nvhpc.cmake clubb_release/cmake/toolchains/linux_x86_64_nvhpc.cmake
50,52d49
<     # NVHPC GPU links can report temporary /tmp/pgcuda*.o files in linker depfiles.
<     set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)
< 
68a66
> 
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/compile.py clubb_release/compile.py
218c218
<         f"-DPython_EXECUTABLE={sys.executable}",
---
>         f"-DPython_EXECUTABLE={shutil.which('python')}",
301c301
<             [sys.executable, clubbstandards_script] + files,
---
>             ["python", clubbstandards_script] + files,
374,375d373
<     subdir_suffix += "_OPENMP" if args.openmp else ""
<     subdir_suffix += "_TUNING" if args.tuning else ""
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/dash_app/compile_tab/runtime.py clubb_release/dash_app/compile_tab/runtime.py
18a19,20
> 
> BUILD_STATUS_TIMEOUT = 8
193a196,201
> def _last_output_line(output):
>     """Return the last non-empty line from command output."""
>     lines = [line.strip() for line in (output or "").splitlines() if line.strip()]
>     return lines[-1] if lines else ""
> 
> 
218a227,244
> def _tool_path(candidate, fallback_name):
>     """Return an executable build-tool path if one is available."""
>     if candidate and Path(candidate).is_file():
>         return candidate
>     return shutil.which(fallback_name) or ""
> 
> 
> def _planned_ninja_lines(output):
>     """Return dry-run lines that describe actual planned target work."""
>     planned = []
>     for line in (output or "").splitlines():
>         stripped = line.strip()
>         if not stripped or stripped.startswith("ninja:"):
>             continue
>         planned.append(stripped)
>     return planned
> 
> 
220,236c246,272
<     """Ask whether CLUBB runtime targets need work using directory timestamp scanning."""
<     # Get maximum modification time of the build artifacts (executables and libraries)
<     build_path_obj = Path(path)
<     max_build_time = 0.0
<     try:
<         for p in build_path_obj.rglob('*'):
<             if p.is_file():
<                 # Skip intermediate files and folders generated by CMake
<                 if p.suffix in ['.o', '.mod', '.stamp', '.make', '.cmake', '.txt', '.log', '.ts', '.json']:
<                     continue
<                 if 'CMakeFiles' in p.parts:
<                     continue
<                 # If it's a library (.a, .so, .dylib) or an executable file
<                 if p.suffix in ['.a', '.so', '.dylib'] or (p.stat().st_mode & 0o111):
<                     max_build_time = max(max_build_time, p.stat().st_mtime)
<     except OSError as exc:
<         return _status("unknown", detail=f"Error scanning build directory: {exc}")
---
>     """Ask the native build tool whether CLUBB runtime targets need work."""
>     generator = cache.get("CMAKE_GENERATOR", "")
>     make_program = cache.get("CMAKE_MAKE_PROGRAM", "")
> 
>     if generator == "Ninja":
>         tool = _tool_path(make_program, "ninja")
>         if not tool:
>             return _status(
>                 "unknown",
>                 detail=f"Ninja build tool not found for {path}.",
>             )
>         command = [tool, "-C", path, "-n", *targets]
>         query_kind = "ninja dry-run"
>     elif generator == "Unix Makefiles":
>         tool = _tool_path(make_program, "make")
>         if not tool:
>             return _status(
>                 "unknown",
>                 detail=f"Make build tool not found for {path}.",
>             )
>         command = [tool, "-C", path, "-q", *targets]
>         query_kind = "make query"
>     else:
>         return _status(
>             "unknown",
>             detail=f"Unsupported CMake generator for freshness checks: {generator or 'unknown'}.",
>         )
238,245d273
<     # Scan whitelisted directories and files to find max source and config mtimes
<     whitelist_dirs = ["src", "clubb_python_api", "cmake"]
<     whitelist_files = ["CMakeLists.txt"]
<     
<     max_src_time = 0.0
<     max_config_time = 0.0
<     repo_root = Path(REPO_ROOT)
<     
247,267c275,290
<         # 1. Check whitelisted files at the root
<         for f_name in whitelist_files:
<             p = repo_root / f_name
<             if p.is_file():
<                 mtime = p.stat().st_mtime
<                 max_src_time = max(max_src_time, mtime)
<                 if p.name == "CMakeLists.txt" or p.suffix == ".cmake":
<                     max_config_time = max(max_config_time, mtime)
<                     
<         # 2. Check whitelisted directories recursively
<         for d_name in whitelist_dirs:
<             d_path = repo_root / d_name
<             if d_path.is_dir():
<                 for p in d_path.rglob("*"):
<                     if p.is_file():
<                         mtime = p.stat().st_mtime
<                         # Only track relevant source, header, config, or scripting files
<                         if p.suffix in [".f90", ".F90", ".c", ".h", ".cpp", ".F", ".txt", ".cmake", ".py"]:
<                             max_src_time = max(max_src_time, mtime)
<                             if p.name == "CMakeLists.txt" or p.suffix == ".cmake":
<                                 max_config_time = max(max_config_time, mtime)
---
>         proc = subprocess.run(
>             command,
>             cwd=REPO_ROOT,
>             stdout=subprocess.PIPE,
>             stderr=subprocess.STDOUT,
>             text=True,
>             errors="replace",
>             timeout=BUILD_STATUS_TIMEOUT,
>             check=False,
>         )
>     except subprocess.TimeoutExpired:
>         return _status(
>             "unknown",
>             detail=f"{query_kind} timed out after {BUILD_STATUS_TIMEOUT}s.",
>             command=command,
>         )
269,272c292
<         return _status("unknown", detail=f"Error scanning source directory: {exc}")
< 
<     cache_path = Path(path) / "CMakeCache.txt"
<     cache_time = cache_path.stat().st_mtime if cache_path.is_file() else 0.0
---
>         return _status("unknown", detail=str(exc), command=command)
274c294,297
<     if max_config_time > cache_time:
---
>     output = proc.stdout or ""
>     lower_output = output.lower()
>     detail = _last_output_line(output)
>     if "re-running cmake" in lower_output:
278,279c301,304
<             detail="CMake configuration files have changed.",
<             output=f"Max config modification time: {time.ctime(max_config_time)}\nCMakeCache modification time: {time.ctime(cache_time)}",
---
>             detail=detail or "CMake would reconfigure this build.",
>             output=output,
>             command=command,
>             returncode=proc.returncode,
281c306,332
<     elif max_build_time == 0.0:
---
>     if generator == "Ninja":
>         if proc.returncode != 0:
>             return _status(
>                 "unknown",
>                 detail=detail or f"Ninja dry-run failed with exit {proc.returncode}.",
>                 output=output,
>                 command=command,
>                 returncode=proc.returncode,
>             )
>         if "no work to do" in lower_output:
>             return _status(
>                 "current",
>                 detail="CLUBB runtime targets are current.",
>                 output=output,
>                 command=command,
>                 returncode=proc.returncode,
>             )
>         planned = _planned_ninja_lines(output)
>         if planned:
>             return _status(
>                 "needs_rebuild",
>                 "needs rebuild",
>                 detail=planned[0],
>                 output=output,
>                 command=command,
>                 returncode=proc.returncode,
>             )
283,286c334,347
<             "needs_rebuild",
<             "needs rebuild",
<             detail="Build artifacts not found.",
<             output="No build artifacts (libraries or executables) found in the build directory.",
---
>             "current",
>             detail="CLUBB runtime targets are current.",
>             output=output,
>             command=command,
>             returncode=proc.returncode,
>         )
> 
>     if proc.returncode == 0:
>         return _status(
>             "current",
>             detail="CLUBB runtime targets are current.",
>             output=output,
>             command=command,
>             returncode=proc.returncode,
288c349
<     elif max_src_time > max_build_time:
---
>     if proc.returncode == 1:
292,293c353,356
<             detail="Source files have changed since the last build.",
<             output=f"Max source modification time: {time.ctime(max_src_time)}\nMax build modification time: {time.ctime(max_build_time)}",
---
>             detail=detail or "Make reports at least one CLUBB runtime target is out of date.",
>             output=output,
>             command=command,
>             returncode=proc.returncode,
295,297d357
<     
<     # Generate user-facing mock command explanation for compatibility
<     command_str = f"Directory scan of source directories: {', '.join(whitelist_dirs)}"
299,303c359,363
<         "current",
<         detail="CLUBB runtime targets are current.",
<         output=f"Directory scan results:\n  Max source modification time: {time.ctime(max_src_time)}\n  Max build modification time: {time.ctime(max_build_time)}\n  CMakeCache modification time: {time.ctime(cache_time)}",
<         command=[command_str],
<         returncode=0,
---
>         "unknown",
>         detail=detail or f"Make query failed with exit {proc.returncode}.",
>         output=output,
>         command=command,
>         returncode=proc.returncode,
422d481
< 
Only in clubb/dash_app: DEVELOPMENT.md
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/dash_app/run_tab/callbacks_runs.py clubb_release/dash_app/run_tab/callbacks_runs.py
443a444
>                 runtime_txt = format_runtime(runtime_secs)
465a467,472
>                     existing = logs.get(case_name, "")
>                     if existing and not existing.endswith("\n"):
>                         existing += "\n"
>                     result_txt = "completed" if status == 0 else f"failed (exit {status})"
>                     logs[case_name] = append_log_tail(existing, f"--- {result_txt}; runtime: {runtime_txt} ---\n")
>                     logs_changed = True
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/README clubb_release/README
539,547d538
< Timing output:
<   - CLUBB writes timing results next to the rest of the case output using the
<     case file prefix with a ".timing" suffix.  For example, running the ARM
<     case normally writes clubb/output/arm.timing.
<   - When CLUBB is compiled without GPTL, this file contains the built-in
<     cpu_time timing summary, including call counts, inclusive time, exclusive
<     time, and average inclusive time.  When CLUBB is compiled with GPTL, the
<     same timing file is written using GPTL output format.
< 
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/run_scripts/run_scm.py clubb_release/run_scripts/run_scm.py
8d7
< import time
349c348
<     return result
---
>     sys.exit(result)
353,361c352
<     start_time = time.perf_counter()
<     try:
<         exit_code = main()
<     finally:
<         elapsed_time = time.perf_counter() - start_time
<         print("-" * 50)
<         print(f"run_scm.py total runtime: {elapsed_time:.2f} s")
<         print("-" * 50)
<     sys.exit(exit_code)
---
>     main()
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/CLUBB_core/CMakeLists.txt clubb_release/src/CLUBB_core/CMakeLists.txt
84c84
<     target_link_libraries(clubb_core_lib PUBLIC gptl)
---
>     target_link_libraries(clubb_core_lib PRIVATE gptl)
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/CLUBB_core/code_timer_module.F90 clubb_release/src/CLUBB_core/code_timer_module.F90
1,58c1
< !-------------------------------------------------------------------------------
< ! code_timer_module.F90
< !
< ! Centralized named timing calls for CLUBB.
< !
< ! Usage:
< !
< !   Call once before timed regions:
< !     - timer_initialize(): initialize the active timing backend
< !
< !
< !   Call around each timed region:
< !     - timer_start(): begin a named timer region
< !
< !     - timer_stop(): end the most recent matching named timer region
< !
< !
< !   Call once after timed regions:
< !     - timer_finalize(): write timer output and finalize the active backend
< !
< !
< ! Understanding:
< !
< !   Backends:
< !     - When CLUBB is compiled with GPTL, timer_initialize(), timer_start(),
< !       timer_stop(), and timer_finalize() forward to the matching GPTL calls.
< !
< !     - When CLUBB is compiled without GPTL, this module uses a small cpu_time
< !       backend that records a flat table of named timers.
< !
< !   Timer names:
< !     - Timer regions are identified by the character string passed to
< !       timer_start() and timer_stop().  The cpu_time backend creates timer
< !       registry entries dynamically when new names are first started.
< !
< !     - Timer names must not be empty.  The same name string must be passed to
< !       timer_stop() that was passed to the matching timer_start().
< !
< !   Nesting:
< !     - Timer calls must be explicitly nested.  For example, if timer B starts
< !       inside timer A, timer B must stop before timer A stops.
< !
< !     - The cpu_time backend enforces this stack order and reports an error if
< !       timer_stop() is called for the wrong active timer.
< !
< !   cpu_time output:
< !     - The cpu_time backend writes a summary table to the file passed to
< !       timer_finalize().  The table includes call count, inclusive time,
< !       exclusive time, average inclusive time per call, and exclusive percent.
< !
< !     - Inclusive time is the full elapsed time in a timer region.  Exclusive
< !       time subtracts time spent in nested timer regions.
< !
< !   GPTL output:
< !     - The GPTL backend writes output through GPTLpr_file() using the file
< !       passed to timer_finalize().  GPTL controls the exact output format.
< !
< !-------------------------------------------------------------------------------
---
> ! $Id$
61,84c4,6
<   use iso_fortran_env, only: &
<     output_unit
< 
< #ifndef GPTL
<   use clubb_precision, only: &
<     core_rknd
< #endif
< 
<   use constants_clubb, only: &
<     fstderr
< 
< #ifdef GPTL
<   use gptl, only: &
<     GPTLsetoption, &
<     GPTLprint_method, &
<     GPTLfull_tree, &
<     GPTLoverhead, &
<     GPTLabort_on_error, &
<     GPTLinitialize, &
<     GPTLstart, &
<     GPTLstop, &
<     GPTLpr_file, &
<     GPTLfinalize
< #endif
---
> ! Description:
> !   This module contains a diagnostic timer utility that can be used
> !   to time a piece of code.
90,131c12,18
<   logical :: &
<     l_timer_initialized = .false., &
<     l_timer_enabled = .true.
< 
<   !$omp threadprivate( l_timer_initialized, l_timer_enabled )
< 
< #ifndef GPTL
<   integer, parameter :: &
<     registry_chunk_size = 16, & ! Number of timer entries to add when the registry grows.
<     stack_chunk_size    = 32, & ! Number of stack entries to add when the stack grows.
<     display_name_length = 48    ! Width of the timer name in the cpu_time printout.
< 
<   type timer_entry_t
<     character(len=:), allocatable :: name
<     real( kind = core_rknd ) :: inclusive_time = 0.0_core_rknd
<     real( kind = core_rknd ) :: exclusive_time = 0.0_core_rknd
<     integer :: call_count = 0
<   end type timer_entry_t
< 
<   type timer_stack_entry_t
<     integer :: timer_id = 0
<     real( kind = core_rknd ) :: start_time = 0.0_core_rknd
<     real( kind = core_rknd ) :: child_time = 0.0_core_rknd
<   end type timer_stack_entry_t
< 
<   type(timer_entry_t), allocatable :: timer_entries(:)
<   type(timer_stack_entry_t), allocatable :: timer_stack(:)
< 
<   integer :: &
<     num_timers = 0, &
<     stack_depth = 0
< 
<   !$omp threadprivate( timer_entries, timer_stack )
<   !$omp threadprivate( num_timers, stack_depth )
< #endif
< 
<   public :: &
<     timer_initialize, &
<     timer_disable, &
<     timer_start, &
<     timer_stop, &
<     timer_finalize
---
>   ! A timer!!
>   type timer_t
>     real :: time_elapsed        ! Time elapsed [sec]
>     real :: secstart            ! Timer starting time
>   end type timer_t
> 
>   public :: timer_t, timer_start, timer_stop
136c23
<   subroutine timer_initialize()
---
>   subroutine timer_start( timer )
139,168c26
<   !   Initializes the active timing backend.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
< #ifdef GPTL
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       ret_code    ! Return code from GPTL calls. [-]
< #endif
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     l_timer_enabled = .true.
< 
< #ifdef GPTL
<     if ( l_timer_initialized ) then
<       ret_code = GPTLfinalize()
<     end if
< 
<     ret_code = GPTLsetoption( GPTLprint_method, GPTLfull_tree )
<     ret_code = GPTLsetoption( GPTLabort_on_error, 1 )
<     ret_code = GPTLsetoption( GPTLoverhead, 0 )
<     ret_code = GPTLinitialize()
<     if ( ret_code /= 0 ) call timer_fail( "GPTLinitialize failed." )
< #else
<     if ( l_timer_initialized ) call require_empty_stack( "timer_initialize" )
< 
<     call reset_cpu_timer_state()
< #endif
---
>   !   Starts the timer
170,180c28,29
<     l_timer_initialized = .true.
< 
<     return
<   end subroutine timer_initialize
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine timer_disable()
< 
<   ! Description:
<   !   Disables the active timing backend and discards any recorded timer state.
---
>   ! References:
>   !   None
185,199c34,35
< #ifdef GPTL
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       ret_code    ! Return code from GPTL calls. [-]
< #endif
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( l_timer_initialized ) then
< #ifdef GPTL
<       ret_code = GPTLfinalize()
< #else
<       call reset_cpu_timer_state()
< #endif
<     end if
---
>     ! Input/Output Variables
>     type(timer_t), intent(inout) :: timer
201,212d36
<     l_timer_initialized = .false.
<     l_timer_enabled = .false.
< 
<     return
<   end subroutine timer_disable
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine timer_start( timer_name )
< 
<   ! Description:
<   !   Starts or enters a named timer region.
214,238c38,39
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Name of the timer region. [-]
< 
< #ifdef GPTL
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       ret_code    ! Return code from GPTL calls. [-]
< #endif
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( .not. l_timer_enabled ) return
< 
<     if ( .not. l_timer_initialized ) call timer_initialize()
< 
< #ifdef GPTL
<     ret_code = GPTLstart( trim( timer_name ) )
< #else
<     call cpu_timer_start( timer_name )
< #endif
< 
---
>     !----- Begin Code -----
>     call cpu_time( timer%secstart ) ! intent(inout)
244,502c45
<   subroutine timer_stop( timer_name )
< 
<   ! Description:
<   !   Stops or exits a named timer region.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Name of the timer region. [-]
< 
< #ifdef GPTL
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       ret_code    ! Return code from GPTL calls. [-]
< #endif
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( .not. l_timer_enabled ) return
< 
<     if ( .not. l_timer_initialized ) then
<       call timer_fail( "timer_stop called before timer_initialize or timer_start." )
<     end if
< 
< #ifdef GPTL
<     ret_code = GPTLstop( trim( timer_name ) )
< #else
<     call cpu_timer_stop( timer_name )
< #endif
< 
<     return
<   end subroutine timer_stop
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine timer_finalize( output_file )
< 
<   ! Description:
<   !   Prints timer output and finalizes the active timing backend.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       output_file    ! File used for timer output. [-]
< 
< #ifdef GPTL
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       ret_code    ! Return code from GPTL calls. [-]
< #else
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       file_unit, & ! Unit used for the cpu_time summary file. [-]
<       io_status   ! Status from opening the cpu_time summary file. [-]
< #endif
< 
<     character(len=1024) :: &
<       output_path    ! Absolute path used for timer output. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( .not. l_timer_enabled ) return
< 
<     if ( .not. l_timer_initialized ) return
< 
<     if ( len_trim( output_file ) < 1 ) then
<       call timer_fail( "Timer output file must not be empty." )
<     end if
< 
<     output_path = timer_absolute_path( output_file )
<     write( output_unit, '(a)' ) "Writing timing results to: " // trim( output_path )
< 
< #ifdef GPTL
<     ret_code = GPTLpr_file( trim( output_path ) )
<     ret_code = GPTLfinalize()
< #else
<     call require_empty_stack( "timer_finalize" )
< 
<     open( newunit = file_unit, file = trim( output_path ), status = "replace", &
<           action = "write", iostat = io_status )
<     if ( io_status /= 0 ) then
<       call timer_fail( "Unable to open timer output file: " // trim( output_path ) )
<     end if
<     call print_cpu_timer_summary( file_unit )
<     close( file_unit )
< 
<     call reset_cpu_timer_state()
< #endif
< 
<     l_timer_initialized = .false.
< 
<     return
<   end subroutine timer_finalize
<   !-----------------------------------------------------------------------
< 
< #ifndef GPTL
<   !-----------------------------------------------------------------------
<   subroutine cpu_timer_start( timer_name )
< 
<   ! Description:
<   !   Starts or enters a named timer region using cpu_time.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Name of the timer region. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       timer_id    ! Registry index for timer_name. [-]
< 
<     real( kind = core_rknd ) :: &
<       start_time    ! cpu_time value at timer start. [s]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     call cpu_time( start_time )
< 
<     timer_id = get_timer_id( timer_name, l_create = .true. )
< 
<     call ensure_stack_capacity( stack_depth + 1 )
< 
<     stack_depth = stack_depth + 1
<     timer_stack(stack_depth)%timer_id = timer_id
< 
<     timer_entries(timer_id)%call_count = timer_entries(timer_id)%call_count + 1
< 
<     timer_stack(stack_depth)%start_time = start_time
<     timer_stack(stack_depth)%child_time = 0.0_core_rknd
< 
<     return
<   end subroutine cpu_timer_start
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine cpu_timer_stop( timer_name )
< 
<   ! Description:
<   !   Stops or exits the current named cpu_time timer region.  Timer stops
<   !   must match the most recent active timer start.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Name of the timer region. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     integer :: &
<       timer_id    ! Registry index for timer_name. [-]
< 
<     real( kind = core_rknd ) :: &
<       stop_time, & ! cpu_time value at timer stop. [s]
<       elapsed      ! Elapsed inclusive timer duration. [s]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     call cpu_time( stop_time )
< 
<     timer_id = get_timer_id( timer_name, l_create = .false. )
< 
<     if ( stack_depth < 1 ) then
<       call timer_fail( "timer_stop called with no active timers: " // trim( timer_name ) )
<     end if
< 
<     if ( timer_stack(stack_depth)%timer_id /= timer_id ) then
<       call timer_fail( "timer_stop nesting mismatch. Expected " &
<                        // trim( timer_entries(timer_stack(stack_depth)%timer_id)%name ) &
<                        // " but received " // trim( timer_name ) // "." )
<     end if
< 
<     elapsed = stop_time - timer_stack(stack_depth)%start_time
< 
<     timer_entries(timer_id)%inclusive_time = timer_entries(timer_id)%inclusive_time + elapsed
<     timer_entries(timer_id)%exclusive_time = timer_entries(timer_id)%exclusive_time &
<                                              + elapsed - timer_stack(stack_depth)%child_time
< 
<     stack_depth = stack_depth - 1
< 
<     if ( stack_depth > 0 ) then
<       timer_stack(stack_depth)%child_time = timer_stack(stack_depth)%child_time + elapsed
<     end if
< 
<     return
<   end subroutine cpu_timer_stop
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   function get_timer_id( timer_name, l_create ) result( timer_id )
< 
<   ! Description:
<   !   Returns the registry index for timer_name, optionally creating a new
<   !   entry when the name has not been seen before.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Name of the timer region. [-]
< 
<     logical, intent(in) :: &
<       l_create    ! Whether to create a missing timer entry. [-]
< 
<     !--------------------------- Output Variables ---------------------------
<     integer :: &
<       timer_id    ! Registry index for timer_name, or 0 if not found. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     character(len=:), allocatable :: &
<       trimmed_name    ! Timer name without trailing blanks. [-]
< 
<     integer :: &
<       i    ! Loop index. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     trimmed_name = trim( timer_name )
< 
<     if ( len( trimmed_name ) < 1 ) then
<       call timer_fail( "Timer name must not be empty." )
<     end if
< 
<     timer_id = 0
< 
<     do i = 1, num_timers
<       if ( timer_entries(i)%name == trimmed_name ) then
<         timer_id = i
<         return
<       end if
<     end do
< 
<     if ( .not. l_create ) then
<       call timer_fail( "Unknown timer name: " // trimmed_name )
<     end if
< 
<     call ensure_registry_capacity( num_timers + 1 )
< 
<     num_timers = num_timers + 1
<     timer_entries(num_timers)%name = trimmed_name
<     timer_entries(num_timers)%inclusive_time = 0.0_core_rknd
<     timer_entries(num_timers)%exclusive_time = 0.0_core_rknd
<     timer_entries(num_timers)%call_count = 0
< 
<     timer_id = num_timers
< 
<     return
<   end function get_timer_id
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine ensure_registry_capacity( required_capacity )
---
>   subroutine timer_stop( timer )
505,542c48
<   !   Grows the timer registry if required_capacity exceeds its current size.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     integer, intent(in) :: &
<       required_capacity    ! Minimum required number of registry slots. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     type(timer_entry_t), allocatable :: &
<       expanded_entries(:)    ! Temporary expanded timer registry. [-]
< 
<     integer :: &
<       old_capacity, & ! Existing registry capacity. [-]
<       new_capacity    ! Expanded registry capacity. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( .not. allocated( timer_entries ) ) then
<       allocate( timer_entries( max( registry_chunk_size, required_capacity ) ) )
<       return
<     end if
< 
<     old_capacity = size( timer_entries )
< 
<     if ( required_capacity <= old_capacity ) return
< 
<     new_capacity = max( required_capacity, old_capacity + registry_chunk_size )
<     allocate( expanded_entries( new_capacity ) )
< 
<     expanded_entries(1:old_capacity) = timer_entries(1:old_capacity)
< 
<     call move_alloc( expanded_entries, timer_entries )
< 
<     return
<   end subroutine ensure_registry_capacity
<   !-----------------------------------------------------------------------
---
>   !   Stops the timer
543a50,51
>   ! References:
>   !   None
545,550d52
<   subroutine ensure_stack_capacity( required_capacity )
< 
<   ! Description:
<   !   Grows the active timer stack if required_capacity exceeds its current size.
<   !-----------------------------------------------------------------------
< 
553,581c55,56
<     !--------------------------- Input Variables ---------------------------
<     integer, intent(in) :: &
<       required_capacity    ! Minimum required number of stack slots. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     type(timer_stack_entry_t), allocatable :: &
<       expanded_stack(:)    ! Temporary expanded timer stack. [-]
< 
<     integer :: &
<       old_capacity, & ! Existing stack capacity. [-]
<       new_capacity    ! Expanded stack capacity. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( .not. allocated( timer_stack ) ) then
<       allocate( timer_stack( max( stack_chunk_size, required_capacity ) ) )
<       return
<     end if
< 
<     old_capacity = size( timer_stack )
< 
<     if ( required_capacity <= old_capacity ) return
< 
<     new_capacity = max( required_capacity, old_capacity + stack_chunk_size )
<     allocate( expanded_stack( new_capacity ) )
< 
<     expanded_stack(1:old_capacity) = timer_stack(1:old_capacity)
< 
<     call move_alloc( expanded_stack, timer_stack )
---
>     ! Input/Output Variables
>     type(timer_t), intent(inout) :: timer
583,585c58,59
<     return
<   end subroutine ensure_stack_capacity
<   !-----------------------------------------------------------------------
---
>     ! Local Variables
>     real :: secend
588c62,63
<   subroutine print_cpu_timer_summary( timer_unit )
---
>     !----- Begin Code -----
>     call cpu_time( secend )
590,592d64
<   ! Description:
<   !   Prints a flat summary of the cpu_time backend timer registry.
<   !-----------------------------------------------------------------------
594,658c66,67
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     integer, intent(in) :: &
<       timer_unit    ! Unit used for timer output. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     real( kind = core_rknd ) :: &
<       total_exclusive_time, & ! Sum of exclusive time over all timers. [s]
<       average_time, &         ! Inclusive time per timer call. [s]
<       exclusive_percent       ! Percentage of total exclusive time. [%]
< 
<     integer :: &
<       i    ! Loop index. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     write( unit = timer_unit, fmt = '(a)' ) &
<       "========================= CLUBB TIMER SUMMARY ========================="
<     write( unit = timer_unit, fmt = '(a)' ) &
<       "Backend: cpu_time"
< 
<     if ( num_timers < 1 ) then
<       write( unit = timer_unit, fmt = '(a)' ) "No timers were recorded."
<       write( unit = timer_unit, fmt = '(a)' ) &
<         "======================================================================="
<       return
<     end if
< 
<     total_exclusive_time = sum( timer_entries(1:num_timers)%exclusive_time )
< 
<     write( unit = timer_unit, fmt = '(a48,1x,a10,1x,a14,1x,a14,1x,a14,1x,a10)' ) &
<       "Timer", "Calls", "Inclusive(s)", "Exclusive(s)", "Avg Inc(s)", "Excl Pct"
<     write( unit = timer_unit, fmt = '(a48,1x,a10,1x,a14,1x,a14,1x,a14,1x,a10)' ) &
<       repeat( "-", display_name_length ), repeat( "-", 10 ), repeat( "-", 14 ), &
<       repeat( "-", 14 ), repeat( "-", 14 ), repeat( "-", 10 )
< 
<     do i = 1, num_timers
< 
<       average_time = timer_entries(i)%inclusive_time &
<                      / real( timer_entries(i)%call_count, kind = core_rknd )
< 
<       if ( total_exclusive_time > 0.0_core_rknd ) then
<         exclusive_percent = 100.0_core_rknd * timer_entries(i)%exclusive_time &
<                             / total_exclusive_time
<       else
<         exclusive_percent = 0.0_core_rknd
<       end if
< 
<       write( unit = timer_unit, fmt = '(a48,1x,i10,1x,f14.6,1x,f14.6,1x,f14.6,1x,f10.2)' ) &
<         timer_display_name( timer_entries(i)%name ), &
<         timer_entries(i)%call_count, &
<         timer_entries(i)%inclusive_time, &
<         timer_entries(i)%exclusive_time, &
<         average_time, &
<         exclusive_percent
< 
<     end do
< 
<     write( unit = timer_unit, fmt = '(a)' ) &
<       "----------------------------------------------------------------------"
<     write( unit = timer_unit, fmt = '(a,f14.6)' ) &
<       "Total exclusive timed cpu_time seconds: ", total_exclusive_time
<     write( unit = timer_unit, fmt = '(a)' ) &
<       "======================================================================="
---
>     timer%time_elapsed = timer%time_elapsed + (secend - timer%secstart)
>     timer%secstart = 0.0
661,804c70
<   end subroutine print_cpu_timer_summary
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   function timer_display_name( timer_name ) result( display_name )
< 
<   ! Description:
<   !   Returns a fixed-width timer name for the cpu_time summary table.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       timer_name    ! Full timer name. [-]
< 
<     !--------------------------- Output Variables ---------------------------
<     character(len=display_name_length) :: &
<       display_name    ! Fixed-width display name. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     display_name = " "
< 
<     if ( len_trim( timer_name ) <= display_name_length ) then
<       display_name(1:len_trim( timer_name )) = trim( timer_name )
<     else
<       display_name(1:display_name_length-3) = timer_name(1:display_name_length-3)
<       display_name(display_name_length-2:display_name_length) = "..."
<     end if
< 
<     return
<   end function timer_display_name
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine require_empty_stack( caller_name )
< 
<   ! Description:
<   !   Verifies that no cpu_time timer regions are active.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       caller_name    ! Name of the routine checking the stack. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( stack_depth > 0 ) then
<       call timer_fail( trim( caller_name ) // " called while timer " &
<                        // trim( timer_entries(timer_stack(stack_depth)%timer_id)%name ) &
<                        // " is still active." )
<     end if
< 
<     return
<   end subroutine require_empty_stack
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine reset_cpu_timer_state()
< 
<   ! Description:
<   !   Clears the cpu_time timer registry and active stack.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     if ( allocated( timer_entries ) ) deallocate( timer_entries )
<     if ( allocated( timer_stack ) ) deallocate( timer_stack )
< 
<     num_timers = 0
<     stack_depth = 0
< 
<     return
<   end subroutine reset_cpu_timer_state
<   !-----------------------------------------------------------------------
< #endif
< 
<   !-----------------------------------------------------------------------
<   function timer_absolute_path( file_path ) result( absolute_path )
< 
<   ! Description:
<   !   Returns an absolute timer output path, using PWD for relative paths.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       file_path    ! Timer output path, absolute or relative. [-]
< 
<     !--------------------------- Output Variables ---------------------------
<     character(len=1024) :: &
<       absolute_path    ! Absolute timer output path. [-]
< 
<     !--------------------------- Local Variables ---------------------------
<     character(len=1024) :: &
<       cwd    ! Current working directory from the environment. [-]
< 
<     integer :: &
<       env_status    ! Status from get_environment_variable. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     absolute_path = " "
< 
<     if ( file_path(1:1) == "/" ) then
<       absolute_path = trim( file_path )
<     else
<       call get_environment_variable( "PWD", cwd, status = env_status )
<       if ( env_status == 0 .and. len_trim( cwd ) > 0 ) then
<         absolute_path = trim( cwd ) // "/" // trim( file_path )
<       else
<         absolute_path = trim( file_path )
<       end if
<     end if
< 
<     return
<   end function timer_absolute_path
<   !-----------------------------------------------------------------------
< 
<   !-----------------------------------------------------------------------
<   subroutine timer_fail( message )
< 
<   ! Description:
<   !   Reports an unrecoverable timer API error and stops execution.
<   !-----------------------------------------------------------------------
< 
<     implicit none
< 
<     !--------------------------- Input Variables ---------------------------
<     character(len=*), intent(in) :: &
<       message    ! Error message. [-]
< 
<     !--------------------------- Begin Code ---------------------------
< 
<     write( unit = fstderr, fmt = '(a)' ) "CLUBB timer error: " // trim( message )
<     error stop "CLUBB timer error"
< 
<   end subroutine timer_fail
---
>   end subroutine timer_stop
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/CLUBB_core/stats_netcdf.F90 clubb_release/src/CLUBB_core/stats_netcdf.F90
2961c2961
<     character(len=REG_LINE_LEN), allocatable, dimension(:) :: entry
---
>     character(len=REG_LINE_LEN) , dimension(NML_REG_MAX_ENTRIES) :: entry
2968,2973d2967
< 
<     allocate( entry(NML_REG_MAX_ENTRIES), stat=ios )
<     if ( ios /= 0 ) then
<       ierr = ios
<       return
<     end if
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/clubb_driver.F90 clubb_release/src/clubb_driver.F90
26,31c26,36
<   use code_timer_module, only: &
<     timer_initialize, &
<     timer_disable, &
<     timer_start, &
<     timer_stop, &
<     timer_finalize
---
> #ifdef GPTL
>    use gptl, only: &
>      GPTLsetoption, &
>      GPTLprint_method, &
>      GPTLfull_tree, &
>      GPTLoverhead, &
>      GPTLabort_on_error, &
>      GPTLinitialize, &
>      GPTLpr, &
>      GPTLfinalize
> #endif
192a198,200
>   real( kind = core_rknd ) , parameter ::  &
>     timing_tol = 0.01_core_rknd   ! allowed tolerance for the timing budget check
> 
1243,1245d1250
< 
<     call timer_initialize()
<     call timer_start( "init_clubb_case" )
1376d1380
<         call timer_stop( "init_clubb_case" )
1384d1387
<         call timer_stop( "init_clubb_case" )
1414d1416
<         call timer_stop( "init_clubb_case" )
1422d1423
<         call timer_stop( "init_clubb_case" )
1430d1430
<         call timer_stop( "init_clubb_case" )
1438d1437
<         call timer_stop( "init_clubb_case" )
1546d1544
<     call timer_start( "read_namelists" )
1557,1561d1554
<     open(unit=iunit, file=runfile, status='old', action='read')
<     read(unit=iunit, nml=configurable_clubb_flags_nl)
<     close(unit=iunit)
<     call timer_stop( "read_namelists" )
< 
1616a1610,1613
>     open(unit=iunit, file=runfile, status='old', action='read')
>     read(unit=iunit, nml=configurable_clubb_flags_nl)
>     close(unit=iunit)
> 
1623c1620
<     ! The case prefix including output directory.
---
>     ! The case prefix including output di
1650d1646
<       call timer_stop( "init_clubb_case" )
1661d1656
<       call timer_stop( "init_clubb_case" )
1672,1675d1666
<     if ( debug_level < 0 ) then
<       call timer_stop( "init_clubb_case" )
<       call timer_disable()
<     end if
1680,1681d1670
<       call timer_start( "write_case_info" )
< 
1954,1955d1942
<       call timer_stop( "write_case_info" )
< 
2096,2097d2082
<       call timer_start( "write_case_info" )
< 
2126,2127d2110
<       call timer_stop( "write_case_info" )
< 
2144d2126
<         call timer_stop( "init_clubb_case" )
2164d2145
<           call timer_stop( "init_clubb_case" )
2534d2514
<       call timer_stop( "init_clubb_case" )
2544d2523
<       call timer_stop( "init_clubb_case" )
2552d2530
<       call timer_stop( "init_clubb_case" )
2589d2566
<         call timer_stop( "init_clubb_case" )
2610d2586
<       call timer_start( "stats_init_api" )
2673d2648
<       call timer_stop( "stats_init_api" )
2679d2653
<           call timer_stop( "init_clubb_case" )
2691d2664
<       call timer_stop( "init_clubb_case" )
2706d2678
<       call timer_stop( "init_clubb_case" )
2841d2812
<     call timer_stop( "init_clubb_case" )
2899,2900d2869
<     call timer_start( "set_case_initial_conditions" )
< 
2911d2879
<         call timer_stop( "set_case_initial_conditions" )
2918,2921c2886
<         if ( any( err_info%err_code == clubb_fatal_error ) ) then
<           call timer_stop( "set_case_initial_conditions" )
<           return
<         end if
---
>         if ( any( err_info%err_code == clubb_fatal_error ) ) return
2934d2898
<         call timer_stop( "set_case_initial_conditions" )
3188c3152
<     end if 
---
>     end if
3324d3287
<         call timer_stop( "set_case_initial_conditions" )
3332,3333d3294
<     call timer_stop( "set_case_initial_conditions" )
< 
3431a3393,3411
> #ifdef GPTL
>     integer :: &
>       ret_code
> #endif
> 
>     ! coarse-grained timing budget of main time stepping loop
>     real( kind = core_rknd ) :: &
>       time_loop_init,  &           ! time spent in the beginning part of the main loop [s]
>       time_loop_end, &             ! time spent in the end part of the main loop [s]
>       time_adapt_grid, &           ! Time spent adapting the grid and remapping all the values
>       time_clubb_advance, &        ! time spent in advance_clubb_core [s]
>       time_clubb_pdf, &            ! time spent in setup_pdf_parameters
>                                     !    and hydrometeor_mixed_moments [s]
>       time_SILHS,    &             ! time needed to compute subcolumns [s]q
>       time_microphys_scheme, &     ! time needed for calc_microphys_scheme_tendcies [s]
>       time_microphys_advance, &    ! time needed for advance_microphys [s]
>       time_stop, time_start,  &    ! help variables to measure the time [s]
>       time_total                   ! control timer for the overall time spent in the main loop [s]
>           
3452c3432,3453
<     call timer_start( "advance_clubb_to_end" )
---
>     !initialize timers    
>     time_loop_init = 0.0_core_rknd
>     time_clubb_advance = 0.0_core_rknd
>     time_clubb_pdf = 0.0_core_rknd
>     time_SILHS = 0.0_core_rknd
>     time_microphys_advance = 0.0_core_rknd
>     time_microphys_scheme = 0.0_core_rknd
>     time_loop_end = 0.0_core_rknd
>     time_adapt_grid = 0.0_core_rknd
>     time_total = 0.0_core_rknd
>     time_stop = 0.0_core_rknd
>     time_start = 0.0_core_rknd
> #ifdef GPTL
>     ret_code = GPTLsetoption(GPTLprint_method, GPTLfull_tree)
>     ret_code = GPTLsetoption(GPTLabort_on_error, 1) ! Abort on GPTL error
>     ret_code = GPTLsetoption(GPTLoverhead, 0)       ! Turn off overhead estimate
>     ret_code = GPTLinitialize()                     ! Initialize GPTL
> #endif
> 
>     ! Save time before main loop starts
>     call cpu_time( time_start )
>     time_total = time_start
3468c3469,3471
< 
---
>       
>       call cpu_time( time_start ) ! start timer for initial part of main loop
>       
3470d3472
<         call timer_start( "stats_begin_timestep_api" )
3472d3473
<         call timer_stop( "stats_begin_timestep_api" )
3486,3487d3486
<         call timer_start( "input_fields" )
< 
3536d3534
<         call timer_stop( "input_fields" )
3541,3542d3538
<         call timer_start( "invalid_model_arrays" )
< 
3563d3558
<             call timer_stop( "invalid_model_arrays" )
3569d3563
<         call timer_stop( "invalid_model_arrays" )
3578d3571
<       call timer_start( "prescribe_forcings" )
3602d3594
<       call timer_stop( "prescribe_forcings" )
3660d3651
<         call timer_start( "calculate_thlp2_rad_api" )
3664d3654
<         call timer_stop( "calculate_thlp2_rad_api" )
3666a3657,3661
>       
>       ! Measure time in the beginning part of the main loop
>       call cpu_time(time_stop)      
>       time_loop_init = time_loop_init + time_stop - time_start      
>       call cpu_time(time_start) ! initialize timer for advance_clubb_core
3672d3666
<         call timer_start( "advance_clubb_core_api" )
3713,3716c3707,3709
<               cloudy_updraft_frac, cloudy_downdraft_frac, &        ! Intent(out)
<               rcm_in_layer, cloud_cover, invrs_tau_zm, &           ! Intent(out)
<               Lscale )
<         call timer_stop( "advance_clubb_core_api" )
---
>                 cloudy_updraft_frac, cloudy_downdraft_frac, &        ! Intent(out)
>                 rcm_in_layer, cloud_cover, invrs_tau_zm, &           ! Intent(out)
>                 Lscale )
3723d3715
<         call timer_start( "clubb_generalized_grid_testing" )
3767d3758
<         call timer_stop( "clubb_generalized_grid_testing" )
3786a3778,3782
>       ! Measure time in advance_clubb_core
>       call cpu_time(time_stop)
>       time_clubb_advance = time_clubb_advance + time_stop - time_start
>       call cpu_time(time_start) ! initialize timer for setup_pdf_parameters
> 
3792,3795c3788
<       if ( trim( microphys_scheme ) /= "none" .or. &
<            lh_microphys_type /= lh_microphys_disabled .or. l_silhs_rad ) then
< 
<         if ( .not. l_test_grid_generalization ) then
---
>       if ( .not. l_test_grid_generalization ) then
3799d3791
<           call timer_start( "pdf_hydromet_microphys_prep" )
3809a3802
>                 time_clubb_pdf, time_stop, time_start,           & ! In/Out
3822d3814
<           call timer_stop( "pdf_hydromet_microphys_prep" )
3824c3816
<         else ! l_test_grid_generalization
---
>       else ! l_test_grid_generalization
3826d3817
<           call timer_start( "silhs_generalized_grid_testing" )
3836a3828
>                 time_clubb_pdf, time_stop, time_start,           & ! In/Out
3849d3840
<           call timer_stop( "silhs_generalized_grid_testing" )
3851,3853c3842
<         endif
< 
<       end if
---
>       endif
3863a3853,3857
>       ! Measure time in SILHS
>       call cpu_time(time_stop)
>       time_SILHS = time_SILHS + time_stop - time_start
>       call cpu_time(time_start) ! initialize timer for calc_microphys_scheme_tendcies
> 
3870,3871d3863
<         call timer_start( "calc_microphys_scheme_tendcies" )
< 
3933,3934c3925,3928
<         call timer_stop( "calc_microphys_scheme_tendcies" )
<         call timer_start( "advance_microphys" )
---
>         ! Measure time in calc_microphys_scheme_tendcies
>         call cpu_time(time_stop)
>         time_microphys_scheme = time_microphys_scheme + time_stop - time_start
>         call cpu_time(time_start) ! initialize timer for advance_microphys
3968c3962,3965
<         call timer_stop( "advance_microphys" )
---
>         ! Measure time in calc_microphys_scheme_tendcies
>         call cpu_time(time_stop)
>         time_microphys_advance = time_microphys_advance + time_stop - time_start
>         call cpu_time(time_start) ! Measure time in the end part of the main loop
3982,3983d3978
<           call timer_start( "cloud_drop_sed" )
< 
4001,4002d3995
<           call timer_stop( "cloud_drop_sed" )
< 
4034d4026
<         call timer_start( "advance_clubb_radiation" )
4048d4039
<         call timer_stop( "advance_clubb_radiation" )
4059a4051,4056
>         ! interrupt stopping time for time_loop_end if grid gets adapted to save time specific
>         ! for calculating the normalized grid density and updating the stats vars
>         call cpu_time(time_stop)
>         time_loop_end = time_loop_end + time_stop - time_start
>         call cpu_time(time_start)
> 
4061d4057
<         call timer_start( "calc_grid_dens" )
4084d4079
<         call timer_stop( "calc_grid_dens" )
4089d4083
<         call timer_start( "normalize_grid_density" )
4098d4091
<         call timer_stop( "normalize_grid_density" )
4101d4093
<           call timer_start( "stats_update_grid_adaptation" )
4115d4106
<           call timer_stop( "stats_update_grid_adaptation" )
4117a4109,4112
>         call cpu_time(time_stop)
>         time_adapt_grid = time_adapt_grid + time_stop - time_start
>         call cpu_time(time_start)
> 
4125d4119
<         call timer_start( "stats_update_grid" )
4128d4121
<         call timer_stop( "stats_update_grid" )
4138a4132,4133
>         call cpu_time(time_start)
> 
4141d4135
<         call timer_start( "adapt_grid" )
4183d4176
<         call timer_stop( "adapt_grid" )
4196d4188
<           call timer_start( "initialize_t_dependent_input" )
4201d4192
<           call timer_stop( "initialize_t_dependent_input" )
4203a4195,4196
>         call cpu_time(time_stop)
>         time_adapt_grid = time_adapt_grid + time_stop - time_start
4213d4205
<         call timer_start( "stats_end_timestep_api" )
4215d4206
<         call timer_stop( "stats_end_timestep_api" )
4238,4239c4229,4230
<       if ( l_stdout .and. clubb_at_least_debug_level_api( 0 ) ) then
<         write(unit=fstdout,fmt='(a,i8,a,i8,a,f10.1,a,f10.1,a)') &
---
>       if ( l_stdout ) then
>         write(unit=fstdout,fmt='(a,i8,a,i8,a,f10.1,a,f10.1)') &
4241c4232
<           ' -- time = ', time_current, 's / ', time_final, 's'
---
>           ' -- time = ', time_current, ' / ', time_final
4245c4236
<         call timer_start( "write_grid_adaptation" )
---
>         call cpu_time(time_start)
4247c4238,4239
<         call timer_stop( "write_grid_adaptation" )
---
>         call cpu_time(time_stop)
>         time_adapt_grid = time_adapt_grid + time_stop - time_start
4257c4249,4269
<     call timer_stop( "advance_clubb_to_end" )
---
>     ! Measure overall time in the main loop
>     call cpu_time(time_stop)
>     time_total = time_stop - time_total ! subtract previously saved start time 
> 
>     ! Print timers 
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_loop_init =         ', time_loop_init
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_clubb_advance =     ', time_clubb_advance
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_clubb_pdf =         ', time_clubb_pdf
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_SILHS =             ', time_SILHS
>     write(unit=fstdout, fmt='(a,f10.4)') &
>       'CLUBB-TIMER time_microphys_scheme =  ', time_microphys_scheme
>     write(unit=fstdout, fmt='(a,f10.4)') &
>       'CLUBB-TIMER time_microphys_advance = ', time_microphys_advance
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_loop_end =          ', time_loop_end
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_adapt_grid =        ', time_adapt_grid
>     write(unit=fstdout, fmt='(a,f10.4)') 'CLUBB-TIMER time_total =             ', time_total
> 
> #ifdef GPTL
>     ret_code = GPTLpr(1)
>     ret_code = GPTLfinalize()
> #endif
4327,4329c4339
< 
<     call timer_start( "clean_up_clubb" )
< 
---
>       
4420d4429
<     call timer_start( "stats_finalize_api" )
4422d4430
<     call timer_stop( "stats_finalize_api" )
4719,4722d4726
< 
<     call timer_stop( "clean_up_clubb" )
< 
<     call timer_finalize( trim( output_file_prefix ) // ".timing" )
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/CMakeLists.txt clubb_release/src/CMakeLists.txt
45c45,46
<     target_link_libraries(clubb_driver_lib PUBLIC gptl)
---
>     target_link_libraries(clubb_driver_lib PRIVATE gptl)
>     include_directories("${CMAKE_BINARY_DIR}/gptl_install/include")
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/generalized_grid_test.F90 clubb_release/src/generalized_grid_test.F90
1734a1735
>                time_clubb_pdf, time_stop, time_start,           & ! In/Out
1868a1870,1874
>     real( kind = core_rknd ), intent(inout) :: &
>       time_clubb_pdf, & ! time spent in setup_pdf_parameters and hydrometeor_mixed_moments [s]
>       time_start,     & ! help variables to measure the time [s]
>       time_stop         ! help variables to measure the time [s]
> 
2073a2080
>              time_clubb_pdf, time_stop, time_start,           & ! In/Out
2109a2117
> 
2122a2131
>              time_clubb_pdf, time_stop, time_start,           & ! In/Out
diff '--exclude=.git' '--exclude=version_clubb_core.txt' '--exclude=version_silhs.txt' -r clubb/src/Microphys/pdf_hydromet_microphys_wrapper.F90 clubb_release/src/Microphys/pdf_hydromet_microphys_wrapper.F90
22a23
>                time_clubb_pdf, time_stop, time_start,           & ! In/Out
43,46d43
<     use code_timer_module, only: &
<         timer_start, &
<         timer_stop
< 
171a169,173
>     real( kind = core_rknd ), intent(inout) :: &
>       time_clubb_pdf, & ! time spent in setup_pdf_parameters and hydrometeor_mixed_moments [s]
>       time_start,     & ! help variables to measure the time [s]
>       time_stop         ! help variables to measure the time [s]
> 
245,246c247
<       !!! Setup the PDF parameters
<       call timer_start( "setup_pdf_parameters_api" )
---
>       !!! Setup the PDF parameters.
270d270
<       call timer_stop( "setup_pdf_parameters_api" )
282d281
<       call timer_start( "hydrometeor_mixed_moments" )
294d292
<       call timer_stop( "hydrometeor_mixed_moments" )
302a301,305
>     ! Measure time in setup_pdf_parameters and hydrometeor_mixed_moments
>     call cpu_time(time_stop)
>     time_clubb_pdf = time_clubb_pdf + time_stop - time_start
>     call cpu_time(time_start) ! initialize timer for SILHS
>       
357d359
<       call timer_start( "generate_silhs_sample_api" )
372d373
<       call timer_stop( "generate_silhs_sample_api" )
384d384
<       call timer_start( "clip_transform_silhs_output_api" )
393d392
<       call timer_stop( "clip_transform_silhs_output_api" )
399d397
<         call timer_start( "stats_accumulate_lh_api" )
410d407
<         call timer_stop( "stats_accumulate_lh_api" )
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] script
[Pipeline] {
[Pipeline] cleanWs
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
[WS-CLEANUP] done
[Pipeline] }
[Pipeline] // script
[Pipeline] script
[Pipeline] {
[Pipeline] emailext
Sending email to: messnermet@uwm.edu
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE