Console Output
+ 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" )